@@ -647,13 +647,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
647647
648648 match place_ty. kind ( ) {
649649 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 ) ;
657675 Operand :: Constant ( Box :: new ( ConstOperand { span, user_ty : None , const_ } ) )
658676 }
659677 ty:: Slice ( _elem_ty) => {
0 commit comments