@@ -647,13 +647,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
647
647
648
648
match place_ty. kind ( ) {
649
649
ty:: Array ( _elem_ty, len_const) => {
650
- // We know how long an array is, so just use that as a constant
651
- // directly -- no locals needed. We do need one statement so
652
- // that borrow- and initialization-checking consider it used,
653
- // though. FIXME: Do we really *need* to count this as a use?
654
- // Could partial array tracking work off something else instead?
655
- self . cfg . push_fake_read ( block, source_info, FakeReadCause :: ForIndex , place) ;
656
- let const_ = Const :: from_ty_const ( * len_const, usize_ty, self . tcx ) ;
650
+ let ty_const = if let Some ( ( _, len_ty) ) = len_const. try_to_valtree ( )
651
+ && len_ty != self . tcx . types . usize
652
+ {
653
+ // Bad const generics can give us a constant from the type that's
654
+ // not actually a `usize`, so in that case give an error instead.
655
+ // FIXME: It'd be nice if the type checker made sure this wasn't
656
+ // possible, instead.
657
+ let err = self . tcx . dcx ( ) . span_delayed_bug (
658
+ span,
659
+ format ! (
660
+ "Array length should have already been a type error, as it's {len_ty:?}"
661
+ ) ,
662
+ ) ;
663
+ ty:: Const :: new_error ( self . tcx , err)
664
+ } else {
665
+ // We know how long an array is, so just use that as a constant
666
+ // directly -- no locals needed. We do need one statement so
667
+ // that borrow- and initialization-checking consider it used,
668
+ // though. FIXME: Do we really *need* to count this as a use?
669
+ // Could partial array tracking work off something else instead?
670
+ self . cfg . push_fake_read ( block, source_info, FakeReadCause :: ForIndex , place) ;
671
+ * len_const
672
+ } ;
673
+
674
+ let const_ = Const :: from_ty_const ( ty_const, usize_ty, self . tcx ) ;
657
675
Operand :: Constant ( Box :: new ( ConstOperand { span, user_ty : None , const_ } ) )
658
676
}
659
677
ty:: Slice ( _elem_ty) => {
0 commit comments