Check for array lengths that aren't actually usize
· rust-lang/rust@43a79a0 (original) (raw)
`@@ -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) => {
`