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) => {

`