mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #135748 - compiler-errors:len-2, r=RalfJung,oli-obk
Lower index bounds checking to `PtrMetadata`, this time with the right fake borrow semantics 😸
Change `Rvalue::RawRef` to take a `RawRefKind` instead of just a `Mutability`. Then introduce `RawRefKind::FakeForPtrMetadata` and use that for lowering index bounds checking to a `PtrMetadata`. This new `RawRefKind::FakeForPtrMetadata` acts like a shallow fake borrow in borrowck, which mimics the semantics of the old `Rvalue::Len` operation we're replacing.
We can then use this `RawRefKind` instead of using a span desugaring hack in CTFE.
cc ``@scottmcm`` ``@RalfJung``
This commit is contained in:
commit
21ddd7ab89
@ -1284,15 +1284,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
&Rvalue::RawPtr(mutability, place) => {
|
||||
let access_kind = match mutability {
|
||||
Mutability::Mut => (
|
||||
&Rvalue::RawPtr(kind, place) => {
|
||||
let access_kind = match kind {
|
||||
RawPtrKind::Mut => (
|
||||
Deep,
|
||||
Write(WriteKind::MutableBorrow(BorrowKind::Mut {
|
||||
kind: MutBorrowKind::Default,
|
||||
})),
|
||||
),
|
||||
Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
|
||||
RawPtrKind::Const => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
|
||||
RawPtrKind::FakeForPtrMetadata => {
|
||||
(Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
|
||||
}
|
||||
};
|
||||
|
||||
self.access_place(
|
||||
|
@ -3,11 +3,7 @@ use std::ops::ControlFlow;
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::{
|
||||
self, BasicBlock, Body, BorrowKind, FakeBorrowKind, InlineAsmOperand, Location, Mutability,
|
||||
NonDivergingIntrinsic, Operand, Place, Rvalue, Statement, StatementKind, Terminator,
|
||||
TerminatorKind,
|
||||
};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::debug;
|
||||
|
||||
@ -60,7 +56,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
|
||||
StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {
|
||||
self.consume_operand(location, op);
|
||||
}
|
||||
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
|
||||
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
|
||||
src,
|
||||
dst,
|
||||
count,
|
||||
@ -273,15 +269,18 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
|
||||
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
||||
}
|
||||
|
||||
&Rvalue::RawPtr(mutability, place) => {
|
||||
let access_kind = match mutability {
|
||||
Mutability::Mut => (
|
||||
&Rvalue::RawPtr(kind, place) => {
|
||||
let access_kind = match kind {
|
||||
RawPtrKind::Mut => (
|
||||
Deep,
|
||||
Write(WriteKind::MutableBorrow(BorrowKind::Mut {
|
||||
kind: mir::MutBorrowKind::Default,
|
||||
kind: MutBorrowKind::Default,
|
||||
})),
|
||||
),
|
||||
Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
|
||||
RawPtrKind::Const => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
|
||||
RawPtrKind::FakeForPtrMetadata => {
|
||||
(Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
|
||||
}
|
||||
};
|
||||
|
||||
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
|
||||
|
@ -349,8 +349,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let maybe_uneval = match constant.const_ {
|
||||
Const::Ty(_, ct) => match ct.kind() {
|
||||
ty::ConstKind::Unevaluated(_) => {
|
||||
bug!("should not encounter unevaluated Const::Ty here, got {:?}", ct)
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None })
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
|
@ -612,9 +612,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
mir::Rvalue::CopyForDeref(place) => {
|
||||
self.codegen_operand(bx, &mir::Operand::Copy(place))
|
||||
}
|
||||
mir::Rvalue::RawPtr(mutability, place) => {
|
||||
let mk_ptr =
|
||||
move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| Ty::new_ptr(tcx, ty, mutability);
|
||||
mir::Rvalue::RawPtr(kind, place) => {
|
||||
let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
|
||||
Ty::new_ptr(tcx, ty, kind.to_mutbl_lossy())
|
||||
};
|
||||
self.codegen_place_to_pointer(bx, place, mk_ptr)
|
||||
}
|
||||
|
||||
|
@ -518,7 +518,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
}
|
||||
|
||||
Rvalue::Ref(_, BorrowKind::Mut { .. }, place)
|
||||
| Rvalue::RawPtr(Mutability::Mut, place) => {
|
||||
| Rvalue::RawPtr(RawPtrKind::Mut, place) => {
|
||||
// Inside mutable statics, we allow arbitrary mutable references.
|
||||
// We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
|
||||
// reasons why are lost to history), and there is no reason to restrict that to
|
||||
@ -536,7 +536,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
}
|
||||
|
||||
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake(_), place)
|
||||
| Rvalue::RawPtr(Mutability::Not, place) => {
|
||||
| Rvalue::RawPtr(RawPtrKind::Const, place) => {
|
||||
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
|
||||
self.ccx,
|
||||
&mut |local| self.qualifs.has_mut_interior(self.ccx, local, location),
|
||||
@ -548,6 +548,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
Rvalue::RawPtr(RawPtrKind::FakeForPtrMetadata, place) => {
|
||||
// These are only inserted for slice length, so the place must already be indirect.
|
||||
// This implies we do not have to worry about whether the borrow escapes.
|
||||
assert!(place.is_indirect(), "fake borrows are always indirect");
|
||||
}
|
||||
|
||||
Rvalue::Cast(
|
||||
CastKind::PointerCoercion(
|
||||
PointerCoercion::MutToConstPointer
|
||||
@ -586,12 +592,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
) => {}
|
||||
Rvalue::ShallowInitBox(_, _) => {}
|
||||
|
||||
Rvalue::UnaryOp(_, operand) => {
|
||||
Rvalue::UnaryOp(op, operand) => {
|
||||
let ty = operand.ty(self.body, self.tcx);
|
||||
if is_int_bool_float_or_char(ty) {
|
||||
// Int, bool, float, and char operations are fine.
|
||||
} else {
|
||||
span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
|
||||
match op {
|
||||
UnOp::Not | UnOp::Neg => {
|
||||
if is_int_bool_float_or_char(ty) {
|
||||
// Int, bool, float, and char operations are fine.
|
||||
} else {
|
||||
span_bug!(
|
||||
self.span,
|
||||
"non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}",
|
||||
);
|
||||
}
|
||||
}
|
||||
UnOp::PtrMetadata => {
|
||||
// Getting the metadata from a pointer is always const.
|
||||
// We already validated the type is valid in the validator.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self.write_immediate(*val, &dest)?;
|
||||
}
|
||||
|
||||
RawPtr(_, place) => {
|
||||
RawPtr(kind, place) => {
|
||||
// Figure out whether this is an addr_of of an already raw place.
|
||||
let place_base_raw = if place.is_indirect_first_projection() {
|
||||
let ty = self.frame().body.local_decls[place.local].ty;
|
||||
@ -250,8 +250,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
let src = self.eval_place(place)?;
|
||||
let place = self.force_allocation(&src)?;
|
||||
let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
|
||||
if !place_base_raw {
|
||||
// If this was not already raw, it needs retagging.
|
||||
if !place_base_raw && !kind.is_fake() {
|
||||
// If this was not already raw, it needs retagging -- except for "fake"
|
||||
// raw borrows whose defining property is that they do not get retagged.
|
||||
val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
|
||||
}
|
||||
self.write_immediate(*val, &dest)?;
|
||||
|
@ -180,6 +180,59 @@ pub enum BorrowKind {
|
||||
Mut { kind: MutBorrowKind },
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
|
||||
#[derive(Hash, HashStable)]
|
||||
pub enum RawPtrKind {
|
||||
Mut,
|
||||
Const,
|
||||
/// Creates a raw pointer to a place that will only be used to access its metadata,
|
||||
/// not the data behind the pointer. Note that this limitation is *not* enforced
|
||||
/// by the validator.
|
||||
///
|
||||
/// The borrow checker allows overlap of these raw pointers with references to the
|
||||
/// data. This is sound even if the pointer is "misused" since any such use is anyway
|
||||
/// unsafe. In terms of the operational semantics (i.e., Miri), this is equivalent
|
||||
/// to `RawPtrKind::Mut`, but will never incur a retag.
|
||||
FakeForPtrMetadata,
|
||||
}
|
||||
|
||||
impl From<Mutability> for RawPtrKind {
|
||||
fn from(other: Mutability) -> Self {
|
||||
match other {
|
||||
Mutability::Mut => RawPtrKind::Mut,
|
||||
Mutability::Not => RawPtrKind::Const,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RawPtrKind {
|
||||
pub fn is_fake(self) -> bool {
|
||||
match self {
|
||||
RawPtrKind::Mut | RawPtrKind::Const => false,
|
||||
RawPtrKind::FakeForPtrMetadata => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_mutbl_lossy(self) -> Mutability {
|
||||
match self {
|
||||
RawPtrKind::Mut => Mutability::Mut,
|
||||
RawPtrKind::Const => Mutability::Not,
|
||||
|
||||
// We have no type corresponding to a fake borrow, so use
|
||||
// `*const` as an approximation.
|
||||
RawPtrKind::FakeForPtrMetadata => Mutability::Not,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ptr_str(self) -> &'static str {
|
||||
match self {
|
||||
RawPtrKind::Mut => "mut",
|
||||
RawPtrKind::Const => "const",
|
||||
RawPtrKind::FakeForPtrMetadata => "const (fake)",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
|
||||
#[derive(Hash, HashStable)]
|
||||
pub enum MutBorrowKind {
|
||||
@ -1356,7 +1409,7 @@ pub enum Rvalue<'tcx> {
|
||||
///
|
||||
/// Like with references, the semantics of this operation are heavily dependent on the aliasing
|
||||
/// model.
|
||||
RawPtr(Mutability, Place<'tcx>),
|
||||
RawPtr(RawPtrKind, Place<'tcx>),
|
||||
|
||||
/// Yields the length of the place, as a `usize`.
|
||||
///
|
||||
|
@ -206,9 +206,9 @@ impl<'tcx> Rvalue<'tcx> {
|
||||
let place_ty = place.ty(local_decls, tcx).ty;
|
||||
Ty::new_ref(tcx, reg, place_ty, bk.to_mutbl_lossy())
|
||||
}
|
||||
Rvalue::RawPtr(mutability, ref place) => {
|
||||
Rvalue::RawPtr(kind, ref place) => {
|
||||
let place_ty = place.ty(local_decls, tcx).ty;
|
||||
Ty::new_ptr(tcx, place_ty, mutability)
|
||||
Ty::new_ptr(tcx, place_ty, kind.to_mutbl_lossy())
|
||||
}
|
||||
Rvalue::Len(..) => tcx.types.usize,
|
||||
Rvalue::Cast(.., ty) => ty,
|
||||
|
@ -15,6 +15,7 @@ TrivialTypeTraversalImpls! {
|
||||
SourceScopeLocalData,
|
||||
UserTypeAnnotationIndex,
|
||||
BorrowKind,
|
||||
RawPtrKind,
|
||||
CastKind,
|
||||
BasicBlock,
|
||||
SwitchTargets,
|
||||
|
@ -685,12 +685,15 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
Rvalue::RawPtr(m, path) => {
|
||||
let ctx = match m {
|
||||
Mutability::Mut => PlaceContext::MutatingUse(
|
||||
RawPtrKind::Mut => PlaceContext::MutatingUse(
|
||||
MutatingUseContext::RawBorrow
|
||||
),
|
||||
Mutability::Not => PlaceContext::NonMutatingUse(
|
||||
RawPtrKind::Const => PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::RawBorrow
|
||||
),
|
||||
RawPtrKind::FakeForPtrMetadata => PlaceContext::NonMutatingUse(
|
||||
NonMutatingUseContext::Inspect
|
||||
),
|
||||
};
|
||||
self.visit_place(path, ctx, location);
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
|
||||
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
|
||||
),
|
||||
ExprKind::RawBorrow { mutability, arg } => Ok(
|
||||
Rvalue::RawPtr(*mutability, self.parse_place(*arg)?)
|
||||
Rvalue::RawPtr((*mutability).into(), self.parse_place(*arg)?)
|
||||
),
|
||||
ExprKind::Binary { op, lhs, rhs } => Ok(
|
||||
Rvalue::BinaryOp(*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?)))
|
||||
|
@ -630,6 +630,69 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
block.and(base_place.index(idx))
|
||||
}
|
||||
|
||||
/// Given a place that's either an array or a slice, returns an operand
|
||||
/// with the length of the array/slice.
|
||||
///
|
||||
/// For arrays it'll be `Operand::Constant` with the actual length;
|
||||
/// For slices it'll be `Operand::Move` of a local using `PtrMetadata`.
|
||||
fn len_of_slice_or_array(
|
||||
&mut self,
|
||||
block: BasicBlock,
|
||||
place: Place<'tcx>,
|
||||
span: Span,
|
||||
source_info: SourceInfo,
|
||||
) -> Operand<'tcx> {
|
||||
let place_ty = place.ty(&self.local_decls, self.tcx).ty;
|
||||
match place_ty.kind() {
|
||||
ty::Array(_elem_ty, len_const) => {
|
||||
// We know how long an array is, so just use that as a constant
|
||||
// directly -- no locals needed. We do need one statement so
|
||||
// that borrow- and initialization-checking consider it used,
|
||||
// though. FIXME: Do we really *need* to count this as a use?
|
||||
// Could partial array tracking work off something else instead?
|
||||
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
|
||||
let const_ = Const::Ty(self.tcx.types.usize, *len_const);
|
||||
Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
|
||||
}
|
||||
ty::Slice(_elem_ty) => {
|
||||
let ptr_or_ref = if let [PlaceElem::Deref] = place.projection[..]
|
||||
&& let local_ty = self.local_decls[place.local].ty
|
||||
&& local_ty.is_trivially_pure_clone_copy()
|
||||
{
|
||||
// It's extremely common that we have something that can be
|
||||
// directly passed to `PtrMetadata`, so avoid an unnecessary
|
||||
// temporary and statement in those cases. Note that we can
|
||||
// only do that for `Copy` types -- not `&mut [_]` -- because
|
||||
// the MIR we're building here needs to pass NLL later.
|
||||
Operand::Copy(Place::from(place.local))
|
||||
} else {
|
||||
let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
|
||||
let slice_ptr = self.temp(ptr_ty, span);
|
||||
self.cfg.push_assign(
|
||||
block,
|
||||
source_info,
|
||||
slice_ptr,
|
||||
Rvalue::RawPtr(RawPtrKind::FakeForPtrMetadata, place),
|
||||
);
|
||||
Operand::Move(slice_ptr)
|
||||
};
|
||||
|
||||
let len = self.temp(self.tcx.types.usize, span);
|
||||
self.cfg.push_assign(
|
||||
block,
|
||||
source_info,
|
||||
len,
|
||||
Rvalue::UnaryOp(UnOp::PtrMetadata, ptr_or_ref),
|
||||
);
|
||||
|
||||
Operand::Move(len)
|
||||
}
|
||||
_ => {
|
||||
span_bug!(span, "len called on place of type {place_ty:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bounds_check(
|
||||
&mut self,
|
||||
block: BasicBlock,
|
||||
@ -638,25 +701,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
expr_span: Span,
|
||||
source_info: SourceInfo,
|
||||
) -> BasicBlock {
|
||||
let usize_ty = self.tcx.types.usize;
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
// bounds check:
|
||||
let len = self.temp(usize_ty, expr_span);
|
||||
let lt = self.temp(bool_ty, expr_span);
|
||||
let slice = slice.to_place(self);
|
||||
|
||||
// len = len(slice)
|
||||
self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self)));
|
||||
let len = self.len_of_slice_or_array(block, slice, expr_span, source_info);
|
||||
|
||||
// lt = idx < len
|
||||
let bool_ty = self.tcx.types.bool;
|
||||
let lt = self.temp(bool_ty, expr_span);
|
||||
self.cfg.push_assign(
|
||||
block,
|
||||
source_info,
|
||||
lt,
|
||||
Rvalue::BinaryOp(
|
||||
BinOp::Lt,
|
||||
Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))),
|
||||
Box::new((Operand::Copy(Place::from(index)), len.to_copy())),
|
||||
),
|
||||
);
|
||||
let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
|
||||
let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) };
|
||||
|
||||
// assert!(lt, "...")
|
||||
self.assert(block, Operand::Move(lt), true, msg, expr_span)
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
hir::Mutability::Not => this.as_read_only_place(block, arg),
|
||||
hir::Mutability::Mut => this.as_place(block, arg),
|
||||
};
|
||||
let address_of = Rvalue::RawPtr(mutability, unpack!(block = place));
|
||||
let address_of = Rvalue::RawPtr(mutability.into(), unpack!(block = place));
|
||||
this.cfg.push_assign(block, source_info, destination, address_of);
|
||||
block.unit()
|
||||
}
|
||||
|
@ -700,7 +700,7 @@ where
|
||||
statements: vec![
|
||||
self.assign(
|
||||
ptr,
|
||||
Rvalue::RawPtr(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
|
||||
Rvalue::RawPtr(RawPtrKind::Mut, tcx.mk_place_index(self.place, cur)),
|
||||
),
|
||||
self.assign(
|
||||
cur.into(),
|
||||
@ -816,7 +816,7 @@ where
|
||||
|
||||
let mut delegate_block = BasicBlockData {
|
||||
statements: vec![
|
||||
self.assign(Place::from(array_ptr), Rvalue::RawPtr(Mutability::Mut, self.place)),
|
||||
self.assign(Place::from(array_ptr), Rvalue::RawPtr(RawPtrKind::Mut, self.place)),
|
||||
self.assign(
|
||||
Place::from(slice_ptr),
|
||||
Rvalue::Cast(
|
||||
|
@ -192,7 +192,7 @@ enum AggregateTy<'tcx> {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
enum AddressKind {
|
||||
Ref(BorrowKind),
|
||||
Address(Mutability),
|
||||
Address(RawPtrKind),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
@ -504,7 +504,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
mplace.layout.ty,
|
||||
bk.to_mutbl_lossy(),
|
||||
),
|
||||
AddressKind::Address(mutbl) => Ty::new_ptr(self.tcx, mplace.layout.ty, mutbl),
|
||||
AddressKind::Address(mutbl) => {
|
||||
Ty::new_ptr(self.tcx, mplace.layout.ty, mutbl.to_mutbl_lossy())
|
||||
}
|
||||
};
|
||||
let layout = self.ecx.layout_of(ty).ok()?;
|
||||
ImmTy::from_immediate(pointer, layout).into()
|
||||
|
@ -46,7 +46,6 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
|
||||
}
|
||||
ctx.simplify_bool_cmp(rvalue);
|
||||
ctx.simplify_ref_deref(rvalue);
|
||||
ctx.simplify_len(rvalue);
|
||||
ctx.simplify_ptr_aggregate(rvalue);
|
||||
ctx.simplify_cast(rvalue);
|
||||
ctx.simplify_repeated_aggregate(rvalue);
|
||||
@ -166,18 +165,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Transform `Len([_; N])` ==> `N`.
|
||||
fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||
if let Rvalue::Len(ref place) = *rvalue {
|
||||
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||
if let ty::Array(_, len) = *place_ty.kind() {
|
||||
let const_ = Const::Ty(self.tcx.types.usize, len);
|
||||
let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
|
||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
|
||||
fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
|
||||
if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
|
||||
|
@ -125,7 +125,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
dst,
|
||||
Rvalue::RawPtr(Mutability::Mut, *lhs),
|
||||
Rvalue::RawPtr(RawPtrKind::Mut, *lhs),
|
||||
))),
|
||||
};
|
||||
|
||||
@ -146,7 +146,7 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
src,
|
||||
Rvalue::RawPtr(Mutability::Not, *rhs),
|
||||
Rvalue::RawPtr(RawPtrKind::Const, *rhs),
|
||||
))),
|
||||
};
|
||||
|
||||
|
@ -2,17 +2,11 @@ use std::iter;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_abi::{FieldIdx, VariantIdx};
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_const_eval::interpret;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use rustc_middle::mir::{
|
||||
BasicBlock, BasicBlockData, Body, CallSource, CastKind, CoercionSource, Const, ConstOperand,
|
||||
ConstValue, Local, LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue,
|
||||
SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnwindAction,
|
||||
UnwindTerminateReason,
|
||||
};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
@ -345,7 +339,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||
.tcx
|
||||
.mk_place_elems(&[PlaceElem::Deref, PlaceElem::Field(field, field_ty)]),
|
||||
};
|
||||
self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
|
||||
self.put_temp_rvalue(Rvalue::RawPtr(RawPtrKind::Mut, place))
|
||||
}
|
||||
|
||||
/// If given Self is an enum puts `to_drop: *mut FieldTy` on top of
|
||||
@ -365,7 +359,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
|
||||
PlaceElem::Field(field, field_ty),
|
||||
]),
|
||||
};
|
||||
self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
|
||||
self.put_temp_rvalue(Rvalue::RawPtr(RawPtrKind::Mut, place))
|
||||
}
|
||||
|
||||
/// If given Self is an enum puts `to_drop: *mut FieldTy` on top of
|
||||
|
@ -1128,14 +1128,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
UnOp::PtrMetadata => {
|
||||
if !matches!(self.body.phase, MirPhase::Runtime(_)) {
|
||||
// It would probably be fine to support this in earlier phases, but at
|
||||
// the time of writing it's only ever introduced from intrinsic
|
||||
// lowering or other runtime-phase optimization passes, so earlier
|
||||
// things can just `bug!` on it.
|
||||
self.fail(location, "PtrMetadata should be in runtime MIR only");
|
||||
}
|
||||
|
||||
check_kinds!(
|
||||
a,
|
||||
"Cannot PtrMetadata non-pointer non-reference type {:?}",
|
||||
|
@ -232,6 +232,18 @@ impl<'tcx> Stable<'tcx> for mir::Mutability {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
|
||||
type T = stable_mir::mir::RawPtrKind;
|
||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||
use mir::RawPtrKind::*;
|
||||
match *self {
|
||||
Const => stable_mir::mir::RawPtrKind::Const,
|
||||
Mut => stable_mir::mir::RawPtrKind::Mut,
|
||||
FakeForPtrMetadata => stable_mir::mir::RawPtrKind::FakeForPtrMetadata,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for mir::BorrowKind {
|
||||
type T = stable_mir::mir::BorrowKind;
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
|
@ -457,7 +457,7 @@ pub enum Rvalue {
|
||||
///
|
||||
/// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
|
||||
/// `&raw v` or `addr_of!(v)`.
|
||||
AddressOf(Mutability, Place),
|
||||
AddressOf(RawPtrKind, Place),
|
||||
|
||||
/// Creates an aggregate value, like a tuple or struct.
|
||||
///
|
||||
@ -577,7 +577,7 @@ impl Rvalue {
|
||||
}
|
||||
Rvalue::AddressOf(mutability, place) => {
|
||||
let place_ty = place.ty(locals)?;
|
||||
Ok(Ty::new_ptr(place_ty, *mutability))
|
||||
Ok(Ty::new_ptr(place_ty, mutability.to_mutable_lossy()))
|
||||
}
|
||||
Rvalue::Len(..) => Ok(Ty::usize_ty()),
|
||||
Rvalue::Cast(.., ty) => Ok(*ty),
|
||||
@ -903,6 +903,24 @@ impl BorrowKind {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum RawPtrKind {
|
||||
Mut,
|
||||
Const,
|
||||
FakeForPtrMetadata,
|
||||
}
|
||||
|
||||
impl RawPtrKind {
|
||||
pub fn to_mutable_lossy(self) -> Mutability {
|
||||
match self {
|
||||
RawPtrKind::Mut { .. } => Mutability::Mut,
|
||||
RawPtrKind::Const => Mutability::Not,
|
||||
// FIXME: There's no type corresponding to a shallow borrow, so use `&` as an approximation.
|
||||
RawPtrKind::FakeForPtrMetadata => Mutability::Not,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum MutBorrowKind {
|
||||
Default,
|
||||
|
@ -6,7 +6,9 @@ use std::{fmt, io, iter};
|
||||
use fmt::{Display, Formatter};
|
||||
|
||||
use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
|
||||
use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents};
|
||||
use crate::mir::{
|
||||
Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
|
||||
};
|
||||
use crate::ty::{AdtKind, IndexedVal, MirConst, Ty, TyConst};
|
||||
use crate::{Body, CrateDef, Mutability, with};
|
||||
|
||||
@ -325,7 +327,7 @@ fn pretty_ty_const(ct: &TyConst) -> String {
|
||||
fn pretty_rvalue<W: Write>(writer: &mut W, rval: &Rvalue) -> io::Result<()> {
|
||||
match rval {
|
||||
Rvalue::AddressOf(mutability, place) => {
|
||||
write!(writer, "&raw {} {:?}", pretty_mut(*mutability), place)
|
||||
write!(writer, "&raw {} {:?}", pretty_raw_ptr_kind(*mutability), place)
|
||||
}
|
||||
Rvalue::Aggregate(aggregate_kind, operands) => {
|
||||
// FIXME: Add pretty_aggregate function that returns a pretty string
|
||||
@ -437,3 +439,11 @@ fn pretty_mut(mutability: Mutability) -> &'static str {
|
||||
Mutability::Mut => "mut ",
|
||||
}
|
||||
}
|
||||
|
||||
fn pretty_raw_ptr_kind(kind: RawPtrKind) -> &'static str {
|
||||
match kind {
|
||||
RawPtrKind::Const => "const",
|
||||
RawPtrKind::Mut => "mut",
|
||||
RawPtrKind::FakeForPtrMetadata => "const (fake)",
|
||||
}
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ pub trait MirVisitor {
|
||||
fn super_rvalue(&mut self, rvalue: &Rvalue, location: Location) {
|
||||
match rvalue {
|
||||
Rvalue::AddressOf(mutability, place) => {
|
||||
let pcx = PlaceContext { is_mut: *mutability == Mutability::Mut };
|
||||
let pcx = PlaceContext { is_mut: *mutability == RawPtrKind::Mut };
|
||||
self.visit_place(place, pcx, location);
|
||||
}
|
||||
Rvalue::Aggregate(_, operands) => {
|
||||
|
35
src/tools/miri/tests/pass/disjoint-array-accesses.rs
Normal file
35
src/tools/miri/tests/pass/disjoint-array-accesses.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// This is a regression test for issue #135671 where a MIR refactor about arrays and their lengths
|
||||
// unexpectedly caused borrowck errors for disjoint borrows of array elements, for which we had no
|
||||
// tests. This is a collection of a few code samples from that issue.
|
||||
|
||||
//@revisions: stack tree
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
|
||||
struct Test {
|
||||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
fn one() {
|
||||
let inputs: &mut [_] = &mut [Test { a: 0, b: 0 }];
|
||||
let a = &mut inputs[0].a;
|
||||
let b = &mut inputs[0].b;
|
||||
|
||||
*a = 0;
|
||||
*b = 1;
|
||||
}
|
||||
|
||||
fn two() {
|
||||
let slice = &mut [(0, 0)][..];
|
||||
std::mem::swap(&mut slice[0].0, &mut slice[0].1);
|
||||
}
|
||||
|
||||
fn three(a: &mut [(i32, i32)], i: usize, j: usize) -> (&mut i32, &mut i32) {
|
||||
(&mut a[i].0, &mut a[j].1)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
one();
|
||||
two();
|
||||
three(&mut [(1, 2), (3, 4)], 0, 1);
|
||||
}
|
@ -7,8 +7,7 @@ fn main() -> () {
|
||||
let mut _5: u32;
|
||||
let mut _6: *mut usize;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let mut _8: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
let mut _2: usize;
|
||||
@ -41,9 +40,8 @@ fn main() -> () {
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
_7 = copy _2;
|
||||
_8 = Len(_1);
|
||||
_9 = Lt(copy _7, copy _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
|
||||
_8 = Lt(copy _7, const 3_usize);
|
||||
assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -7,8 +7,7 @@ fn main() -> () {
|
||||
let mut _5: u32;
|
||||
let mut _6: *mut usize;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let mut _8: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
let mut _2: usize;
|
||||
@ -41,9 +40,8 @@ fn main() -> () {
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
_7 = copy _2;
|
||||
_8 = Len(_1);
|
||||
_9 = Lt(copy _7, copy _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
|
||||
_8 = Lt(copy _7, const 3_usize);
|
||||
assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -0,0 +1,31 @@
|
||||
// MIR for `index_array` after built
|
||||
|
||||
fn index_array(_1: &[i32; 7], _2: usize) -> &i32 {
|
||||
debug array => _1;
|
||||
debug index => _2;
|
||||
let mut _0: &i32;
|
||||
let _3: &i32;
|
||||
let _4: usize;
|
||||
let mut _5: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
FakeRead(ForIndex, (*_1));
|
||||
_5 = Lt(copy _4, const 7_usize);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _4) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &(*_1)[_4];
|
||||
_0 = &(*_3);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
// MIR for `index_const_generic_array` after built
|
||||
|
||||
fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 {
|
||||
debug array => _1;
|
||||
debug index => _2;
|
||||
let mut _0: &i32;
|
||||
let _3: &i32;
|
||||
let _4: usize;
|
||||
let mut _5: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
FakeRead(ForIndex, (*_1));
|
||||
_5 = Lt(copy _4, const N);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", const N, copy _4) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &(*_1)[_4];
|
||||
_0 = &(*_3);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// MIR for `index_custom` after built
|
||||
|
||||
fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 {
|
||||
debug custom => _1;
|
||||
debug index => _2;
|
||||
let mut _0: &i32;
|
||||
let _3: &i32;
|
||||
let _4: usize;
|
||||
let mut _5: *const [i32];
|
||||
let mut _6: usize;
|
||||
let mut _7: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
_5 = &raw const (fake) ((*_1).1: [i32]);
|
||||
_6 = PtrMetadata(move _5);
|
||||
_7 = Lt(copy _4, copy _6);
|
||||
assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &((*_1).1: [i32])[_4];
|
||||
_0 = &(*_3);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// MIR for `index_mut_slice` after built
|
||||
|
||||
fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 {
|
||||
debug slice => _1;
|
||||
debug index => _2;
|
||||
let mut _0: &i32;
|
||||
let _3: &i32;
|
||||
let _4: usize;
|
||||
let mut _5: *const [i32];
|
||||
let mut _6: usize;
|
||||
let mut _7: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
_5 = &raw const (fake) (*_1);
|
||||
_6 = PtrMetadata(move _5);
|
||||
_7 = Lt(copy _4, copy _6);
|
||||
assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &(*_1)[_4];
|
||||
_0 = &(*_3);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// MIR for `index_slice` after built
|
||||
|
||||
fn index_slice(_1: &[i32], _2: usize) -> &i32 {
|
||||
debug slice => _1;
|
||||
debug index => _2;
|
||||
let mut _0: &i32;
|
||||
let _3: &i32;
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
_5 = PtrMetadata(copy _1);
|
||||
_6 = Lt(copy _4, copy _5);
|
||||
assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &(*_1)[_4];
|
||||
_0 = &(*_3);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
71
tests/mir-opt/building/index_array_and_slice.rs
Normal file
71
tests/mir-opt/building/index_array_and_slice.rs
Normal file
@ -0,0 +1,71 @@
|
||||
//@ compile-flags: -C opt-level=0
|
||||
|
||||
// EMIT_MIR index_array_and_slice.index_array.built.after.mir
|
||||
fn index_array(array: &[i32; 7], index: usize) -> &i32 {
|
||||
// CHECK: bb0:
|
||||
// CHECK: [[LT:_.+]] = Lt(copy _2, const 7_usize);
|
||||
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const 7_usize, copy _2) -> [success: bb1, unwind
|
||||
|
||||
// CHECK: bb1:
|
||||
// CHECK: _0 = &(*_1)[_2];
|
||||
&array[index]
|
||||
}
|
||||
|
||||
// EMIT_MIR index_array_and_slice.index_const_generic_array.built.after.mir
|
||||
fn index_const_generic_array<const N: usize>(array: &[i32; N], index: usize) -> &i32 {
|
||||
// CHECK: bb0:
|
||||
// CHECK: [[LT:_.+]] = Lt(copy _2, const N);
|
||||
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const N, copy _2) -> [success: bb1, unwind
|
||||
|
||||
// CHECK: bb1:
|
||||
// CHECK: _0 = &(*_1)[_2];
|
||||
&array[index]
|
||||
}
|
||||
|
||||
// EMIT_MIR index_array_and_slice.index_slice.built.after.mir
|
||||
fn index_slice(slice: &[i32], index: usize) -> &i32 {
|
||||
// CHECK: bb0:
|
||||
// CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
|
||||
// CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
|
||||
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
|
||||
|
||||
// CHECK: bb1:
|
||||
// CHECK: _0 = &(*_1)[_2];
|
||||
&slice[index]
|
||||
}
|
||||
|
||||
// EMIT_MIR index_array_and_slice.index_mut_slice.built.after.mir
|
||||
fn index_mut_slice(slice: &mut [i32], index: usize) -> &i32 {
|
||||
// While the filecheck here is identical to the above test, the emitted MIR is different.
|
||||
// This cannot `copy _1` in the *built* MIR, only in the *runtime* MIR.
|
||||
|
||||
// CHECK: bb0:
|
||||
// CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
|
||||
// CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
|
||||
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
|
||||
|
||||
// CHECK: bb1:
|
||||
// CHECK: _0 = &(*_1)[_2];
|
||||
&slice[index]
|
||||
}
|
||||
|
||||
struct WithSliceTail(f64, [i32]);
|
||||
|
||||
// EMIT_MIR index_array_and_slice.index_custom.built.after.mir
|
||||
fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 {
|
||||
// CHECK: bb0:
|
||||
// CHECK: [[PTR:_.+]] = &raw const (fake) ((*_1).1: [i32]);
|
||||
// CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]);
|
||||
// CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
|
||||
// CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
|
||||
|
||||
// CHECK: bb1:
|
||||
// CHECK: _0 = &((*_1).1: [i32])[_2];
|
||||
&custom.1[index]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
index_array(&[1, 2, 3, 4, 5, 6, 7], 3);
|
||||
index_slice(&[1, 2, 3, 4, 5, 6, 7][..], 3);
|
||||
_ = index_custom;
|
||||
}
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -32,11 +32,12 @@
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = const 3_usize;
|
||||
_7 = Len((*_1));
|
||||
- _7 = PtrMetadata(copy _1);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = Lt(const 3_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -32,11 +32,12 @@
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = const 3_usize;
|
||||
_7 = Len((*_1));
|
||||
- _7 = PtrMetadata(copy _1);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = Lt(const 3_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -32,11 +32,12 @@
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = const 3_usize;
|
||||
_7 = Len((*_1));
|
||||
- _7 = PtrMetadata(copy _1);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = Lt(const 3_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -32,11 +32,12 @@
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = const 3_usize;
|
||||
_7 = Len((*_1));
|
||||
- _7 = PtrMetadata(copy _1);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = Lt(const 3_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const false;
|
||||
+ assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,12 @@
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
_7 = Len((*_2));
|
||||
- _7 = PtrMetadata(copy _2);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = Lt(const 1_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,11 +30,12 @@
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
_7 = Len((*_2));
|
||||
- _7 = PtrMetadata(copy _2);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = Lt(const 1_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,11 +30,12 @@
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
_7 = Len((*_2));
|
||||
- _7 = PtrMetadata(copy _2);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = Lt(const 1_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -30,11 +30,12 @@
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
_7 = Len((*_2));
|
||||
- _7 = PtrMetadata(copy _2);
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
|
||||
+ _8 = Lt(const 1_usize, copy _7);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -18,8 +18,7 @@
|
||||
let mut _15: !;
|
||||
let mut _17: i32;
|
||||
let _18: usize;
|
||||
let mut _19: usize;
|
||||
let mut _20: bool;
|
||||
let mut _19: bool;
|
||||
scope 1 {
|
||||
debug sum => _1;
|
||||
let _2: [i32; 4];
|
||||
@ -92,11 +91,10 @@
|
||||
StorageLive(_17);
|
||||
- StorageLive(_18);
|
||||
- _18 = copy _16;
|
||||
_19 = Len(_2);
|
||||
- _20 = Lt(copy _18, copy _19);
|
||||
- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind unreachable];
|
||||
+ _20 = Lt(copy _16, copy _19);
|
||||
+ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind unreachable];
|
||||
- _19 = Lt(copy _18, const 4_usize);
|
||||
- assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind unreachable];
|
||||
+ _19 = Lt(copy _16, const 4_usize);
|
||||
+ assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
|
@ -18,8 +18,7 @@
|
||||
let mut _15: !;
|
||||
let mut _17: i32;
|
||||
let _18: usize;
|
||||
let mut _19: usize;
|
||||
let mut _20: bool;
|
||||
let mut _19: bool;
|
||||
scope 1 {
|
||||
debug sum => _1;
|
||||
let _2: [i32; 4];
|
||||
@ -92,11 +91,10 @@
|
||||
StorageLive(_17);
|
||||
- StorageLive(_18);
|
||||
- _18 = copy _16;
|
||||
_19 = Len(_2);
|
||||
- _20 = Lt(copy _18, copy _19);
|
||||
- assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind continue];
|
||||
+ _20 = Lt(copy _16, copy _19);
|
||||
+ assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind continue];
|
||||
- _19 = Lt(copy _18, const 4_usize);
|
||||
- assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind continue];
|
||||
+ _19 = Lt(copy _16, const 4_usize);
|
||||
+ assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind continue];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u32;
|
||||
let mut _2: [u32; 4];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 4_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 4_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,10 @@ fn main() {
|
||||
|
||||
// CHECK: [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = PtrMetadata(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK-NOT: assert(move _
|
||||
// CHECK: {{_.*}} = const 4_usize;
|
||||
// CHECK: {{_.*}} = const 2_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true
|
||||
// CHECK: [[x]] = copy [[array_lit]][2 of 3];
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
let _1: u8;
|
||||
let mut _2: [u8; 5000];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _4: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -18,11 +17,9 @@
|
||||
_2 = [const 0_u8; 5000];
|
||||
StorageLive(_3);
|
||||
_3 = const 2_usize;
|
||||
- _4 = Len(_2);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const 5000_usize;
|
||||
+ _5 = const true;
|
||||
- _4 = Lt(copy _3, const 5000_usize);
|
||||
- assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _4 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ fn main() {
|
||||
|
||||
// CHECK: debug x => [[x:_.*]];
|
||||
// CHECK: [[array_lit:_.*]] = [const 0_u8; 5000];
|
||||
// CHECK: {{_.*}} = const 5000_usize;
|
||||
// CHECK: {{_.*}} = const 2_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true
|
||||
// CHECK: [[x]] = copy [[array_lit]][2 of 3];
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@
|
||||
let mut _2: u32;
|
||||
let mut _3: [u32; 8];
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: bool;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
}
|
||||
@ -20,11 +19,9 @@
|
||||
_3 = [const 42_u32; 8];
|
||||
StorageLive(_4);
|
||||
_4 = const 2_usize;
|
||||
- _5 = Len(_3);
|
||||
- _6 = Lt(copy _4, copy _5);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const 8_usize;
|
||||
+ _6 = const true;
|
||||
- _5 = Lt(copy _4, const 8_usize);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
|
||||
+ _5 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,9 @@ fn main() {
|
||||
|
||||
// CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = PtrMetadata(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK: {{_.*}} = const 8_usize;
|
||||
// CHECK: {{_.*}} = const 2_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: u32;
|
||||
let mut _2: &[u32];
|
||||
let mut _3: &[u32; 3];
|
||||
let _4: &[u32; 3];
|
||||
let _5: [u32; 3];
|
||||
let _6: usize;
|
||||
let mut _7: usize;
|
||||
let mut _8: bool;
|
||||
let mut _10: &[u32];
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
let mut _14: &[u32; 3];
|
||||
scope 1 {
|
||||
debug local => _1;
|
||||
let _9: u32;
|
||||
scope 2 {
|
||||
debug constant => _9;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_14 = const main::promoted[0];
|
||||
_4 = copy _14;
|
||||
_3 = copy _4;
|
||||
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
- _7 = Len((*_2));
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _1 = copy (*_2)[_6];
|
||||
+ _1 = copy (*_2)[1 of 2];
|
||||
StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_2);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = const main::SLICE;
|
||||
StorageLive(_11);
|
||||
_11 = const 1_usize;
|
||||
- _12 = Len((*_10));
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
|
||||
+ _12 = const 3_usize;
|
||||
+ _13 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _9 = copy (*_10)[_11];
|
||||
+ _9 = copy (*_10)[1 of 2];
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const ();
|
||||
StorageDead(_9);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: u32;
|
||||
let mut _2: &[u32];
|
||||
let mut _3: &[u32; 3];
|
||||
let _4: &[u32; 3];
|
||||
let _5: [u32; 3];
|
||||
let _6: usize;
|
||||
let mut _7: usize;
|
||||
let mut _8: bool;
|
||||
let mut _10: &[u32];
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
let mut _14: &[u32; 3];
|
||||
scope 1 {
|
||||
debug local => _1;
|
||||
let _9: u32;
|
||||
scope 2 {
|
||||
debug constant => _9;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_14 = const main::promoted[0];
|
||||
_4 = copy _14;
|
||||
_3 = copy _4;
|
||||
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
- _7 = Len((*_2));
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _1 = copy (*_2)[_6];
|
||||
+ _1 = copy (*_2)[1 of 2];
|
||||
StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_2);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = const main::SLICE;
|
||||
StorageLive(_11);
|
||||
_11 = const 1_usize;
|
||||
- _12 = Len((*_10));
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
|
||||
+ _12 = const 3_usize;
|
||||
+ _13 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _9 = copy (*_10)[_11];
|
||||
+ _9 = copy (*_10)[1 of 2];
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const ();
|
||||
StorageDead(_9);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: u32;
|
||||
let mut _2: &[u32];
|
||||
let mut _3: &[u32; 3];
|
||||
let _4: &[u32; 3];
|
||||
let _5: [u32; 3];
|
||||
let _6: usize;
|
||||
let mut _7: usize;
|
||||
let mut _8: bool;
|
||||
let mut _10: &[u32];
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
let mut _14: &[u32; 3];
|
||||
scope 1 {
|
||||
debug local => _1;
|
||||
let _9: u32;
|
||||
scope 2 {
|
||||
debug constant => _9;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_14 = const main::promoted[0];
|
||||
_4 = copy _14;
|
||||
_3 = copy _4;
|
||||
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
- _7 = Len((*_2));
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _1 = copy (*_2)[_6];
|
||||
+ _1 = copy (*_2)[1 of 2];
|
||||
StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_2);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = const main::SLICE;
|
||||
StorageLive(_11);
|
||||
_11 = const 1_usize;
|
||||
- _12 = Len((*_10));
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
|
||||
+ _12 = const 3_usize;
|
||||
+ _13 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _9 = copy (*_10)[_11];
|
||||
+ _9 = copy (*_10)[1 of 2];
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const ();
|
||||
StorageDead(_9);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `main` before DataflowConstProp
|
||||
+ // MIR for `main` after DataflowConstProp
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
let _1: u32;
|
||||
let mut _2: &[u32];
|
||||
let mut _3: &[u32; 3];
|
||||
let _4: &[u32; 3];
|
||||
let _5: [u32; 3];
|
||||
let _6: usize;
|
||||
let mut _7: usize;
|
||||
let mut _8: bool;
|
||||
let mut _10: &[u32];
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
let mut _14: &[u32; 3];
|
||||
scope 1 {
|
||||
debug local => _1;
|
||||
let _9: u32;
|
||||
scope 2 {
|
||||
debug constant => _9;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_14 = const main::promoted[0];
|
||||
_4 = copy _14;
|
||||
_3 = copy _4;
|
||||
_2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
_6 = const 1_usize;
|
||||
- _7 = Len((*_2));
|
||||
- _8 = Lt(copy _6, copy _7);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
|
||||
+ _7 = const 3_usize;
|
||||
+ _8 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _1 = copy (*_2)[_6];
|
||||
+ _1 = copy (*_2)[1 of 2];
|
||||
StorageDead(_6);
|
||||
StorageDead(_4);
|
||||
StorageDead(_2);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
_10 = const main::SLICE;
|
||||
StorageLive(_11);
|
||||
_11 = const 1_usize;
|
||||
- _12 = Len((*_10));
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
|
||||
+ _12 = const 3_usize;
|
||||
+ _13 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _9 = copy (*_10)[_11];
|
||||
+ _9 = copy (*_10)[1 of 2];
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const ();
|
||||
StorageDead(_9);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ test-mir-pass: DataflowConstProp
|
||||
//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg
|
||||
// EMIT_MIR_FOR_EACH_BIT_WIDTH
|
||||
|
||||
// EMIT_MIR slice_len.main.DataflowConstProp.diff
|
||||
|
||||
// CHECK-LABEL: fn main(
|
||||
fn main() {
|
||||
// CHECK: debug local => [[local:_.*]];
|
||||
// CHECK: debug constant => [[constant:_.*]];
|
||||
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK-NOT: assert(move _
|
||||
// CHECK: {{_.*}} = const 3_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true,
|
||||
|
||||
// CHECK: [[local]] = copy (*{{_.*}})[1 of 2];
|
||||
let local = (&[1u32, 2, 3] as &[u32])[1];
|
||||
|
||||
// CHECK-NOT: {{_.*}} = Len(
|
||||
// CHECK-NOT: {{_.*}} = Lt(
|
||||
// CHECK-NOT: assert(move _
|
||||
const SLICE: &[u32] = &[1, 2, 3];
|
||||
// CHECK: {{_.*}} = const 3_usize;
|
||||
// CHECK: {{_.*}} = const true;
|
||||
// CHECK: assert(const true,
|
||||
|
||||
// CHECK-NOT: [[constant]] = {{copy|move}} (*{{_.*}})[_
|
||||
// CHECK: [[constant]] = copy (*{{_.*}})[1 of 2];
|
||||
let constant = SLICE[1];
|
||||
}
|
@ -53,7 +53,7 @@
|
||||
StorageLive(_8);
|
||||
- _8 = copy _2;
|
||||
+ _8 = const usize::MAX;
|
||||
_9 = Len((*_1));
|
||||
_9 = PtrMetadata(copy _1);
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
|
||||
+ _10 = Lt(const usize::MAX, copy _9);
|
||||
@ -72,7 +72,7 @@
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
_11 = const 0_usize;
|
||||
_12 = Len((*_1));
|
||||
_12 = PtrMetadata(copy _1);
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
|
||||
+ _13 = Lt(const 0_usize, copy _12);
|
||||
|
@ -53,7 +53,7 @@
|
||||
StorageLive(_8);
|
||||
- _8 = copy _2;
|
||||
+ _8 = const usize::MAX;
|
||||
_9 = Len((*_1));
|
||||
_9 = PtrMetadata(copy _1);
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
|
||||
+ _10 = Lt(const usize::MAX, copy _9);
|
||||
@ -72,7 +72,7 @@
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
_11 = const 0_usize;
|
||||
_12 = Len((*_1));
|
||||
_12 = PtrMetadata(copy _1);
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
|
||||
+ _13 = Lt(const 0_usize, copy _12);
|
||||
|
@ -0,0 +1,72 @@
|
||||
- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
|
||||
+ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
|
||||
|
||||
fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
|
||||
debug x => _1;
|
||||
let mut _0: [i32; 3];
|
||||
let mut _2: i32;
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _6: i32;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let mut _10: i32;
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const 42_usize;
|
||||
_4 = PtrMetadata(copy _1);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
+ _5 = Lt(const 42_usize, copy _4);
|
||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _2 = copy (*_1)[_3];
|
||||
+ _2 = copy (*_1)[42 of 43];
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = const 13_usize;
|
||||
- _8 = PtrMetadata(copy _1);
|
||||
- _9 = Lt(copy _7, copy _8);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
|
||||
+ _8 = copy _4;
|
||||
+ _9 = Lt(const 13_usize, copy _4);
|
||||
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _6 = copy (*_1)[_7];
|
||||
+ _6 = copy (*_1)[13 of 14];
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = const 7_usize;
|
||||
- _12 = PtrMetadata(copy _1);
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind unreachable];
|
||||
+ _12 = copy _4;
|
||||
+ _13 = Lt(const 7_usize, copy _4);
|
||||
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
- _10 = copy (*_1)[_11];
|
||||
+ _10 = copy (*_1)[7 of 8];
|
||||
_0 = [move _2, move _6, move _10];
|
||||
StorageDead(_10);
|
||||
StorageDead(_6);
|
||||
StorageDead(_2);
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
|
||||
+ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
|
||||
|
||||
fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
|
||||
debug x => _1;
|
||||
let mut _0: [i32; 3];
|
||||
let mut _2: i32;
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _6: i32;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let mut _10: i32;
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const 42_usize;
|
||||
_4 = PtrMetadata(copy _1);
|
||||
- _5 = Lt(copy _3, copy _4);
|
||||
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
+ _5 = Lt(const 42_usize, copy _4);
|
||||
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
- _2 = copy (*_1)[_3];
|
||||
+ _2 = copy (*_1)[42 of 43];
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = const 13_usize;
|
||||
- _8 = PtrMetadata(copy _1);
|
||||
- _9 = Lt(copy _7, copy _8);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
|
||||
+ _8 = copy _4;
|
||||
+ _9 = Lt(const 13_usize, copy _4);
|
||||
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _6 = copy (*_1)[_7];
|
||||
+ _6 = copy (*_1)[13 of 14];
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = const 7_usize;
|
||||
- _12 = PtrMetadata(copy _1);
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind continue];
|
||||
+ _12 = copy _4;
|
||||
+ _13 = Lt(const 7_usize, copy _4);
|
||||
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
- _10 = copy (*_1)[_11];
|
||||
+ _10 = copy (*_1)[7 of 8];
|
||||
_0 = [move _2, move _6, move _10];
|
||||
StorageDead(_10);
|
||||
StorageDead(_6);
|
||||
StorageDead(_2);
|
||||
StorageDead(_11);
|
||||
StorageDead(_7);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -10,13 +10,11 @@
|
||||
let _5: ();
|
||||
let mut _6: T;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let _10: ();
|
||||
let mut _11: T;
|
||||
let _12: usize;
|
||||
let mut _13: usize;
|
||||
let mut _14: bool;
|
||||
let mut _8: bool;
|
||||
let _9: ();
|
||||
let mut _10: T;
|
||||
let _11: usize;
|
||||
let mut _12: bool;
|
||||
scope 1 {
|
||||
debug a => _3;
|
||||
}
|
||||
@ -32,12 +30,10 @@
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = const 0_usize;
|
||||
- _8 = Len(_3);
|
||||
- _9 = Lt(copy _7, copy _8);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = const N;
|
||||
+ _9 = Lt(const 0_usize, const N);
|
||||
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
|
||||
- _8 = Lt(copy _7, const N);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind unreachable];
|
||||
+ _8 = Lt(const 0_usize, const N);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
@ -51,29 +47,27 @@
|
||||
StorageDead(_6);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
_12 = copy _2;
|
||||
- _13 = Len(_3);
|
||||
- _14 = Lt(copy _12, copy _13);
|
||||
- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind unreachable];
|
||||
+ _13 = const N;
|
||||
+ _14 = Lt(copy _2, const N);
|
||||
+ assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
|
||||
_11 = copy _2;
|
||||
- _12 = Lt(copy _11, const N);
|
||||
- assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind unreachable];
|
||||
+ _12 = Lt(copy _2, const N);
|
||||
+ assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
- _11 = copy _3[_12];
|
||||
- _10 = opaque::<T>(move _11) -> [return: bb4, unwind unreachable];
|
||||
+ _11 = copy _1;
|
||||
+ _10 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
|
||||
- _10 = copy _3[_11];
|
||||
- _9 = opaque::<T>(move _10) -> [return: bb4, unwind unreachable];
|
||||
+ _10 = copy _1;
|
||||
+ _9 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_12);
|
||||
StorageDead(_10);
|
||||
StorageDead(_11);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_3);
|
||||
return;
|
||||
|
@ -10,13 +10,11 @@
|
||||
let _5: ();
|
||||
let mut _6: T;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let _10: ();
|
||||
let mut _11: T;
|
||||
let _12: usize;
|
||||
let mut _13: usize;
|
||||
let mut _14: bool;
|
||||
let mut _8: bool;
|
||||
let _9: ();
|
||||
let mut _10: T;
|
||||
let _11: usize;
|
||||
let mut _12: bool;
|
||||
scope 1 {
|
||||
debug a => _3;
|
||||
}
|
||||
@ -32,12 +30,10 @@
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = const 0_usize;
|
||||
- _8 = Len(_3);
|
||||
- _9 = Lt(copy _7, copy _8);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind continue];
|
||||
+ _8 = const N;
|
||||
+ _9 = Lt(const 0_usize, const N);
|
||||
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
|
||||
- _8 = Lt(copy _7, const N);
|
||||
- assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind continue];
|
||||
+ _8 = Lt(const 0_usize, const N);
|
||||
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
@ -51,29 +47,27 @@
|
||||
StorageDead(_6);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageLive(_9);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
_12 = copy _2;
|
||||
- _13 = Len(_3);
|
||||
- _14 = Lt(copy _12, copy _13);
|
||||
- assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind continue];
|
||||
+ _13 = const N;
|
||||
+ _14 = Lt(copy _2, const N);
|
||||
+ assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
|
||||
_11 = copy _2;
|
||||
- _12 = Lt(copy _11, const N);
|
||||
- assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind continue];
|
||||
+ _12 = Lt(copy _2, const N);
|
||||
+ assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
- _11 = copy _3[_12];
|
||||
- _10 = opaque::<T>(move _11) -> [return: bb4, unwind continue];
|
||||
+ _11 = copy _1;
|
||||
+ _10 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
|
||||
- _10 = copy _3[_11];
|
||||
- _9 = opaque::<T>(move _10) -> [return: bb4, unwind continue];
|
||||
+ _10 = copy _1;
|
||||
+ _9 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_12);
|
||||
StorageDead(_10);
|
||||
StorageDead(_11);
|
||||
StorageDead(_9);
|
||||
_0 = const ();
|
||||
StorageDead(_3);
|
||||
return;
|
||||
|
@ -835,6 +835,25 @@ fn array_len(x: &mut [i32; 42]) -> usize {
|
||||
std::intrinsics::ptr_metadata(x)
|
||||
}
|
||||
|
||||
// Check that we only load the length once, rather than all 3 times.
|
||||
fn dedup_multiple_bounds_checks_lengths(x: &[i32]) -> [i32; 3] {
|
||||
// CHECK-LABEL: fn dedup_multiple_bounds_checks_lengths
|
||||
// CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
|
||||
// CHECK: Lt(const 42_usize, copy [[LEN]]);
|
||||
// CHECK: assert{{.+}}copy [[LEN]]
|
||||
// CHECK: [[A:_.+]] = copy (*_1)[42 of 43];
|
||||
// CHECK-NOT: PtrMetadata
|
||||
// CHECK: Lt(const 13_usize, copy [[LEN]]);
|
||||
// CHECK: assert{{.+}}copy [[LEN]]
|
||||
// CHECK: [[B:_.+]] = copy (*_1)[13 of 14];
|
||||
// CHECK-NOT: PtrMetadata
|
||||
// CHECK: Lt(const 7_usize, copy [[LEN]]);
|
||||
// CHECK: assert{{.+}}copy [[LEN]]
|
||||
// CHECK: [[C:_.+]] = copy (*_1)[7 of 8];
|
||||
// CHECK: _0 = [move [[A]], move [[B]], move [[C]]]
|
||||
[x[42], x[13], x[7]]
|
||||
}
|
||||
|
||||
#[custom_mir(dialect = "runtime")]
|
||||
fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) {
|
||||
// CHECK-LABEL: fn generic_cast_metadata
|
||||
@ -1109,6 +1128,7 @@ enum Never {}
|
||||
// EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
|
||||
// EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
|
||||
// EMIT_MIR gvn.array_len.GVN.diff
|
||||
// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
|
||||
// EMIT_MIR gvn.generic_cast_metadata.GVN.diff
|
||||
// EMIT_MIR gvn.cast_pointer_eq.GVN.diff
|
||||
// EMIT_MIR gvn.aggregate_struct_then_transmute.GVN.diff
|
||||
|
@ -10,62 +10,60 @@
|
||||
let mut _6: &i32;
|
||||
let _7: &i32;
|
||||
let _8: usize;
|
||||
let mut _9: usize;
|
||||
let mut _10: bool;
|
||||
let mut _12: *const dyn std::marker::Send;
|
||||
let _13: &dyn std::marker::Send;
|
||||
let mut _14: &i32;
|
||||
let _15: &i32;
|
||||
let _16: usize;
|
||||
let mut _17: usize;
|
||||
let mut _9: bool;
|
||||
let mut _11: *const dyn std::marker::Send;
|
||||
let _12: &dyn std::marker::Send;
|
||||
let mut _13: &i32;
|
||||
let _14: &i32;
|
||||
let _15: usize;
|
||||
let mut _16: bool;
|
||||
let _17: ();
|
||||
let mut _18: bool;
|
||||
let _19: ();
|
||||
let mut _20: bool;
|
||||
let mut _19: *const dyn std::marker::Send;
|
||||
let mut _20: *const dyn std::marker::Send;
|
||||
let mut _21: *const dyn std::marker::Send;
|
||||
let mut _22: *const dyn std::marker::Send;
|
||||
let mut _23: *const dyn std::marker::Send;
|
||||
let _24: ();
|
||||
let mut _25: bool;
|
||||
let _22: ();
|
||||
let mut _23: bool;
|
||||
let mut _24: *const dyn std::marker::Send;
|
||||
let mut _25: *const dyn std::marker::Send;
|
||||
let mut _26: *const dyn std::marker::Send;
|
||||
let mut _27: *const dyn std::marker::Send;
|
||||
let mut _28: *const dyn std::marker::Send;
|
||||
let _29: ();
|
||||
let mut _30: bool;
|
||||
let _27: ();
|
||||
let mut _28: bool;
|
||||
let mut _29: *const dyn std::marker::Send;
|
||||
let mut _30: *const dyn std::marker::Send;
|
||||
let mut _31: *const dyn std::marker::Send;
|
||||
let mut _32: *const dyn std::marker::Send;
|
||||
let mut _33: *const dyn std::marker::Send;
|
||||
let _34: ();
|
||||
let mut _35: bool;
|
||||
let _32: ();
|
||||
let mut _33: bool;
|
||||
let mut _34: *const dyn std::marker::Send;
|
||||
let mut _35: *const dyn std::marker::Send;
|
||||
let mut _36: *const dyn std::marker::Send;
|
||||
let mut _37: *const dyn std::marker::Send;
|
||||
let mut _38: *const dyn std::marker::Send;
|
||||
let _39: ();
|
||||
let mut _40: bool;
|
||||
let _37: ();
|
||||
let mut _38: bool;
|
||||
let mut _39: *const dyn std::marker::Send;
|
||||
let mut _40: *const dyn std::marker::Send;
|
||||
let mut _41: *const dyn std::marker::Send;
|
||||
let mut _42: *const dyn std::marker::Send;
|
||||
let mut _43: *const dyn std::marker::Send;
|
||||
let _44: ();
|
||||
let mut _45: bool;
|
||||
let _42: ();
|
||||
let mut _43: bool;
|
||||
let mut _44: *const dyn std::marker::Send;
|
||||
let mut _45: *const dyn std::marker::Send;
|
||||
let mut _46: *const dyn std::marker::Send;
|
||||
let mut _47: *const dyn std::marker::Send;
|
||||
let mut _48: *const dyn std::marker::Send;
|
||||
let mut _49: &[i32; 2];
|
||||
let mut _47: &[i32; 2];
|
||||
scope 1 {
|
||||
debug slice => _1;
|
||||
let _3: *const dyn std::marker::Send;
|
||||
scope 2 {
|
||||
debug a => _3;
|
||||
let _11: *const dyn std::marker::Send;
|
||||
let _10: *const dyn std::marker::Send;
|
||||
scope 3 {
|
||||
debug b => _11;
|
||||
debug b => _10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_49 = const wide_ptr_same_provenance::promoted[0];
|
||||
_1 = &(*_49);
|
||||
_47 = const wide_ptr_same_provenance::promoted[0];
|
||||
_1 = &(*_47);
|
||||
StorageLive(_3);
|
||||
- StorageLive(_4);
|
||||
+ nop;
|
||||
@ -74,11 +72,9 @@
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = const 0_usize;
|
||||
- _9 = Len((*_1));
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind unreachable];
|
||||
+ _9 = const 2_usize;
|
||||
+ _10 = const true;
|
||||
- _9 = Lt(copy _8, const 2_usize);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind unreachable];
|
||||
+ _9 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
@ -95,170 +91,168 @@
|
||||
+ nop;
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
- StorageLive(_12);
|
||||
StorageLive(_10);
|
||||
- StorageLive(_11);
|
||||
+ nop;
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
_16 = const 1_usize;
|
||||
- _17 = Len((*_1));
|
||||
- _18 = Lt(copy _16, copy _17);
|
||||
- assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind unreachable];
|
||||
+ _17 = const 2_usize;
|
||||
+ _18 = const true;
|
||||
_15 = const 1_usize;
|
||||
- _16 = Lt(copy _15, const 2_usize);
|
||||
- assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind unreachable];
|
||||
+ _16 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _15 = &(*_1)[_16];
|
||||
+ _15 = &(*_1)[1 of 2];
|
||||
_14 = &(*_15);
|
||||
_13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_14);
|
||||
_12 = &raw const (*_13);
|
||||
- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
- StorageDead(_12);
|
||||
+ _11 = copy _12;
|
||||
+ nop;
|
||||
StorageDead(_15);
|
||||
- _14 = &(*_1)[_15];
|
||||
+ _14 = &(*_1)[1 of 2];
|
||||
_13 = &(*_14);
|
||||
_12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_13);
|
||||
_11 = &raw const (*_12);
|
||||
- _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
- StorageDead(_11);
|
||||
+ _10 = copy _11;
|
||||
+ nop;
|
||||
StorageDead(_14);
|
||||
StorageDead(_12);
|
||||
StorageLive(_17);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
- _19 = copy _3;
|
||||
+ _19 = copy _4;
|
||||
StorageLive(_20);
|
||||
StorageLive(_21);
|
||||
- _21 = copy _3;
|
||||
+ _21 = copy _4;
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
- _23 = copy _11;
|
||||
- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _23 = copy _12;
|
||||
+ _22 = copy _12;
|
||||
StorageDead(_23);
|
||||
- _20 = Eq(move _21, move _22);
|
||||
+ _20 = Eq(copy _4, copy _12);
|
||||
StorageDead(_22);
|
||||
- _21 = copy _10;
|
||||
- _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _21 = copy _11;
|
||||
+ _20 = copy _11;
|
||||
StorageDead(_21);
|
||||
_19 = opaque::<bool>(move _20) -> [return: bb3, unwind unreachable];
|
||||
- _18 = Eq(move _19, move _20);
|
||||
+ _18 = Eq(copy _4, copy _11);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
_17 = opaque::<bool>(move _18) -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
StorageLive(_24);
|
||||
- _24 = copy _3;
|
||||
+ _24 = copy _4;
|
||||
StorageLive(_25);
|
||||
StorageLive(_26);
|
||||
- _26 = copy _3;
|
||||
+ _26 = copy _4;
|
||||
StorageLive(_27);
|
||||
StorageLive(_28);
|
||||
- _28 = copy _11;
|
||||
- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _28 = copy _12;
|
||||
+ _27 = copy _12;
|
||||
StorageDead(_28);
|
||||
- _25 = Ne(move _26, move _27);
|
||||
+ _25 = Ne(copy _4, copy _12);
|
||||
StorageDead(_27);
|
||||
- _26 = copy _10;
|
||||
- _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _26 = copy _11;
|
||||
+ _25 = copy _11;
|
||||
StorageDead(_26);
|
||||
_24 = opaque::<bool>(move _25) -> [return: bb4, unwind unreachable];
|
||||
- _23 = Ne(move _24, move _25);
|
||||
+ _23 = Ne(copy _4, copy _11);
|
||||
StorageDead(_25);
|
||||
StorageDead(_24);
|
||||
_22 = opaque::<bool>(move _23) -> [return: bb4, unwind unreachable];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_25);
|
||||
StorageDead(_24);
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
StorageLive(_27);
|
||||
StorageLive(_28);
|
||||
StorageLive(_29);
|
||||
- _29 = copy _3;
|
||||
+ _29 = copy _4;
|
||||
StorageLive(_30);
|
||||
StorageLive(_31);
|
||||
- _31 = copy _3;
|
||||
+ _31 = copy _4;
|
||||
StorageLive(_32);
|
||||
StorageLive(_33);
|
||||
- _33 = copy _11;
|
||||
- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _33 = copy _12;
|
||||
+ _32 = copy _12;
|
||||
StorageDead(_33);
|
||||
- _30 = Lt(move _31, move _32);
|
||||
+ _30 = Lt(copy _4, copy _12);
|
||||
StorageDead(_32);
|
||||
- _31 = copy _10;
|
||||
- _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _31 = copy _11;
|
||||
+ _30 = copy _11;
|
||||
StorageDead(_31);
|
||||
_29 = opaque::<bool>(move _30) -> [return: bb5, unwind unreachable];
|
||||
- _28 = Lt(move _29, move _30);
|
||||
+ _28 = Lt(copy _4, copy _11);
|
||||
StorageDead(_30);
|
||||
StorageDead(_29);
|
||||
_27 = opaque::<bool>(move _28) -> [return: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_30);
|
||||
StorageDead(_29);
|
||||
StorageDead(_28);
|
||||
StorageDead(_27);
|
||||
StorageLive(_32);
|
||||
StorageLive(_33);
|
||||
StorageLive(_34);
|
||||
- _34 = copy _3;
|
||||
+ _34 = copy _4;
|
||||
StorageLive(_35);
|
||||
StorageLive(_36);
|
||||
- _36 = copy _3;
|
||||
+ _36 = copy _4;
|
||||
StorageLive(_37);
|
||||
StorageLive(_38);
|
||||
- _38 = copy _11;
|
||||
- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _38 = copy _12;
|
||||
+ _37 = copy _12;
|
||||
StorageDead(_38);
|
||||
- _35 = Le(move _36, move _37);
|
||||
+ _35 = Le(copy _4, copy _12);
|
||||
StorageDead(_37);
|
||||
- _36 = copy _10;
|
||||
- _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _36 = copy _11;
|
||||
+ _35 = copy _11;
|
||||
StorageDead(_36);
|
||||
_34 = opaque::<bool>(move _35) -> [return: bb6, unwind unreachable];
|
||||
- _33 = Le(move _34, move _35);
|
||||
+ _33 = Le(copy _4, copy _11);
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
_32 = opaque::<bool>(move _33) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
StorageDead(_33);
|
||||
StorageDead(_32);
|
||||
StorageLive(_37);
|
||||
StorageLive(_38);
|
||||
StorageLive(_39);
|
||||
- _39 = copy _3;
|
||||
+ _39 = copy _4;
|
||||
StorageLive(_40);
|
||||
StorageLive(_41);
|
||||
- _41 = copy _3;
|
||||
+ _41 = copy _4;
|
||||
StorageLive(_42);
|
||||
StorageLive(_43);
|
||||
- _43 = copy _11;
|
||||
- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _43 = copy _12;
|
||||
+ _42 = copy _12;
|
||||
StorageDead(_43);
|
||||
- _40 = Gt(move _41, move _42);
|
||||
+ _40 = Gt(copy _4, copy _12);
|
||||
StorageDead(_42);
|
||||
- _41 = copy _10;
|
||||
- _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _41 = copy _11;
|
||||
+ _40 = copy _11;
|
||||
StorageDead(_41);
|
||||
_39 = opaque::<bool>(move _40) -> [return: bb7, unwind unreachable];
|
||||
- _38 = Gt(move _39, move _40);
|
||||
+ _38 = Gt(copy _4, copy _11);
|
||||
StorageDead(_40);
|
||||
StorageDead(_39);
|
||||
_37 = opaque::<bool>(move _38) -> [return: bb7, unwind unreachable];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_40);
|
||||
StorageDead(_39);
|
||||
StorageDead(_38);
|
||||
StorageDead(_37);
|
||||
StorageLive(_42);
|
||||
StorageLive(_43);
|
||||
StorageLive(_44);
|
||||
- _44 = copy _3;
|
||||
+ _44 = copy _4;
|
||||
StorageLive(_45);
|
||||
StorageLive(_46);
|
||||
- _46 = copy _3;
|
||||
+ _46 = copy _4;
|
||||
StorageLive(_47);
|
||||
StorageLive(_48);
|
||||
- _48 = copy _11;
|
||||
- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _48 = copy _12;
|
||||
+ _47 = copy _12;
|
||||
StorageDead(_48);
|
||||
- _45 = Ge(move _46, move _47);
|
||||
+ _45 = Ge(copy _4, copy _12);
|
||||
StorageDead(_47);
|
||||
- _46 = copy _10;
|
||||
- _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _46 = copy _11;
|
||||
+ _45 = copy _11;
|
||||
StorageDead(_46);
|
||||
_44 = opaque::<bool>(move _45) -> [return: bb8, unwind unreachable];
|
||||
- _43 = Ge(move _44, move _45);
|
||||
+ _43 = Ge(copy _4, copy _11);
|
||||
StorageDead(_45);
|
||||
StorageDead(_44);
|
||||
_42 = opaque::<bool>(move _43) -> [return: bb8, unwind unreachable];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_45);
|
||||
StorageDead(_44);
|
||||
StorageDead(_43);
|
||||
StorageDead(_42);
|
||||
_0 = const ();
|
||||
StorageDead(_16);
|
||||
StorageDead(_11);
|
||||
StorageDead(_15);
|
||||
StorageDead(_10);
|
||||
StorageDead(_8);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
|
@ -10,62 +10,60 @@
|
||||
let mut _6: &i32;
|
||||
let _7: &i32;
|
||||
let _8: usize;
|
||||
let mut _9: usize;
|
||||
let mut _10: bool;
|
||||
let mut _12: *const dyn std::marker::Send;
|
||||
let _13: &dyn std::marker::Send;
|
||||
let mut _14: &i32;
|
||||
let _15: &i32;
|
||||
let _16: usize;
|
||||
let mut _17: usize;
|
||||
let mut _9: bool;
|
||||
let mut _11: *const dyn std::marker::Send;
|
||||
let _12: &dyn std::marker::Send;
|
||||
let mut _13: &i32;
|
||||
let _14: &i32;
|
||||
let _15: usize;
|
||||
let mut _16: bool;
|
||||
let _17: ();
|
||||
let mut _18: bool;
|
||||
let _19: ();
|
||||
let mut _20: bool;
|
||||
let mut _19: *const dyn std::marker::Send;
|
||||
let mut _20: *const dyn std::marker::Send;
|
||||
let mut _21: *const dyn std::marker::Send;
|
||||
let mut _22: *const dyn std::marker::Send;
|
||||
let mut _23: *const dyn std::marker::Send;
|
||||
let _24: ();
|
||||
let mut _25: bool;
|
||||
let _22: ();
|
||||
let mut _23: bool;
|
||||
let mut _24: *const dyn std::marker::Send;
|
||||
let mut _25: *const dyn std::marker::Send;
|
||||
let mut _26: *const dyn std::marker::Send;
|
||||
let mut _27: *const dyn std::marker::Send;
|
||||
let mut _28: *const dyn std::marker::Send;
|
||||
let _29: ();
|
||||
let mut _30: bool;
|
||||
let _27: ();
|
||||
let mut _28: bool;
|
||||
let mut _29: *const dyn std::marker::Send;
|
||||
let mut _30: *const dyn std::marker::Send;
|
||||
let mut _31: *const dyn std::marker::Send;
|
||||
let mut _32: *const dyn std::marker::Send;
|
||||
let mut _33: *const dyn std::marker::Send;
|
||||
let _34: ();
|
||||
let mut _35: bool;
|
||||
let _32: ();
|
||||
let mut _33: bool;
|
||||
let mut _34: *const dyn std::marker::Send;
|
||||
let mut _35: *const dyn std::marker::Send;
|
||||
let mut _36: *const dyn std::marker::Send;
|
||||
let mut _37: *const dyn std::marker::Send;
|
||||
let mut _38: *const dyn std::marker::Send;
|
||||
let _39: ();
|
||||
let mut _40: bool;
|
||||
let _37: ();
|
||||
let mut _38: bool;
|
||||
let mut _39: *const dyn std::marker::Send;
|
||||
let mut _40: *const dyn std::marker::Send;
|
||||
let mut _41: *const dyn std::marker::Send;
|
||||
let mut _42: *const dyn std::marker::Send;
|
||||
let mut _43: *const dyn std::marker::Send;
|
||||
let _44: ();
|
||||
let mut _45: bool;
|
||||
let _42: ();
|
||||
let mut _43: bool;
|
||||
let mut _44: *const dyn std::marker::Send;
|
||||
let mut _45: *const dyn std::marker::Send;
|
||||
let mut _46: *const dyn std::marker::Send;
|
||||
let mut _47: *const dyn std::marker::Send;
|
||||
let mut _48: *const dyn std::marker::Send;
|
||||
let mut _49: &[i32; 2];
|
||||
let mut _47: &[i32; 2];
|
||||
scope 1 {
|
||||
debug slice => _1;
|
||||
let _3: *const dyn std::marker::Send;
|
||||
scope 2 {
|
||||
debug a => _3;
|
||||
let _11: *const dyn std::marker::Send;
|
||||
let _10: *const dyn std::marker::Send;
|
||||
scope 3 {
|
||||
debug b => _11;
|
||||
debug b => _10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_49 = const wide_ptr_same_provenance::promoted[0];
|
||||
_1 = &(*_49);
|
||||
_47 = const wide_ptr_same_provenance::promoted[0];
|
||||
_1 = &(*_47);
|
||||
StorageLive(_3);
|
||||
- StorageLive(_4);
|
||||
+ nop;
|
||||
@ -74,11 +72,9 @@
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = const 0_usize;
|
||||
- _9 = Len((*_1));
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind continue];
|
||||
+ _9 = const 2_usize;
|
||||
+ _10 = const true;
|
||||
- _9 = Lt(copy _8, const 2_usize);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind continue];
|
||||
+ _9 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
@ -95,170 +91,168 @@
|
||||
+ nop;
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageLive(_11);
|
||||
- StorageLive(_12);
|
||||
StorageLive(_10);
|
||||
- StorageLive(_11);
|
||||
+ nop;
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
_16 = const 1_usize;
|
||||
- _17 = Len((*_1));
|
||||
- _18 = Lt(copy _16, copy _17);
|
||||
- assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind continue];
|
||||
+ _17 = const 2_usize;
|
||||
+ _18 = const true;
|
||||
_15 = const 1_usize;
|
||||
- _16 = Lt(copy _15, const 2_usize);
|
||||
- assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind continue];
|
||||
+ _16 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- _15 = &(*_1)[_16];
|
||||
+ _15 = &(*_1)[1 of 2];
|
||||
_14 = &(*_15);
|
||||
_13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_14);
|
||||
_12 = &raw const (*_13);
|
||||
- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
- StorageDead(_12);
|
||||
+ _11 = copy _12;
|
||||
+ nop;
|
||||
StorageDead(_15);
|
||||
- _14 = &(*_1)[_15];
|
||||
+ _14 = &(*_1)[1 of 2];
|
||||
_13 = &(*_14);
|
||||
_12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
|
||||
StorageDead(_13);
|
||||
_11 = &raw const (*_12);
|
||||
- _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
- StorageDead(_11);
|
||||
+ _10 = copy _11;
|
||||
+ nop;
|
||||
StorageDead(_14);
|
||||
StorageDead(_12);
|
||||
StorageLive(_17);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
- _19 = copy _3;
|
||||
+ _19 = copy _4;
|
||||
StorageLive(_20);
|
||||
StorageLive(_21);
|
||||
- _21 = copy _3;
|
||||
+ _21 = copy _4;
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
- _23 = copy _11;
|
||||
- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _23 = copy _12;
|
||||
+ _22 = copy _12;
|
||||
StorageDead(_23);
|
||||
- _20 = Eq(move _21, move _22);
|
||||
+ _20 = Eq(copy _4, copy _12);
|
||||
StorageDead(_22);
|
||||
- _21 = copy _10;
|
||||
- _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _21 = copy _11;
|
||||
+ _20 = copy _11;
|
||||
StorageDead(_21);
|
||||
_19 = opaque::<bool>(move _20) -> [return: bb3, unwind continue];
|
||||
- _18 = Eq(move _19, move _20);
|
||||
+ _18 = Eq(copy _4, copy _11);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
_17 = opaque::<bool>(move _18) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
StorageLive(_24);
|
||||
- _24 = copy _3;
|
||||
+ _24 = copy _4;
|
||||
StorageLive(_25);
|
||||
StorageLive(_26);
|
||||
- _26 = copy _3;
|
||||
+ _26 = copy _4;
|
||||
StorageLive(_27);
|
||||
StorageLive(_28);
|
||||
- _28 = copy _11;
|
||||
- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _28 = copy _12;
|
||||
+ _27 = copy _12;
|
||||
StorageDead(_28);
|
||||
- _25 = Ne(move _26, move _27);
|
||||
+ _25 = Ne(copy _4, copy _12);
|
||||
StorageDead(_27);
|
||||
- _26 = copy _10;
|
||||
- _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _26 = copy _11;
|
||||
+ _25 = copy _11;
|
||||
StorageDead(_26);
|
||||
_24 = opaque::<bool>(move _25) -> [return: bb4, unwind continue];
|
||||
- _23 = Ne(move _24, move _25);
|
||||
+ _23 = Ne(copy _4, copy _11);
|
||||
StorageDead(_25);
|
||||
StorageDead(_24);
|
||||
_22 = opaque::<bool>(move _23) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_25);
|
||||
StorageDead(_24);
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
StorageLive(_27);
|
||||
StorageLive(_28);
|
||||
StorageLive(_29);
|
||||
- _29 = copy _3;
|
||||
+ _29 = copy _4;
|
||||
StorageLive(_30);
|
||||
StorageLive(_31);
|
||||
- _31 = copy _3;
|
||||
+ _31 = copy _4;
|
||||
StorageLive(_32);
|
||||
StorageLive(_33);
|
||||
- _33 = copy _11;
|
||||
- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _33 = copy _12;
|
||||
+ _32 = copy _12;
|
||||
StorageDead(_33);
|
||||
- _30 = Lt(move _31, move _32);
|
||||
+ _30 = Lt(copy _4, copy _12);
|
||||
StorageDead(_32);
|
||||
- _31 = copy _10;
|
||||
- _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _31 = copy _11;
|
||||
+ _30 = copy _11;
|
||||
StorageDead(_31);
|
||||
_29 = opaque::<bool>(move _30) -> [return: bb5, unwind continue];
|
||||
- _28 = Lt(move _29, move _30);
|
||||
+ _28 = Lt(copy _4, copy _11);
|
||||
StorageDead(_30);
|
||||
StorageDead(_29);
|
||||
_27 = opaque::<bool>(move _28) -> [return: bb5, unwind continue];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_30);
|
||||
StorageDead(_29);
|
||||
StorageDead(_28);
|
||||
StorageDead(_27);
|
||||
StorageLive(_32);
|
||||
StorageLive(_33);
|
||||
StorageLive(_34);
|
||||
- _34 = copy _3;
|
||||
+ _34 = copy _4;
|
||||
StorageLive(_35);
|
||||
StorageLive(_36);
|
||||
- _36 = copy _3;
|
||||
+ _36 = copy _4;
|
||||
StorageLive(_37);
|
||||
StorageLive(_38);
|
||||
- _38 = copy _11;
|
||||
- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _38 = copy _12;
|
||||
+ _37 = copy _12;
|
||||
StorageDead(_38);
|
||||
- _35 = Le(move _36, move _37);
|
||||
+ _35 = Le(copy _4, copy _12);
|
||||
StorageDead(_37);
|
||||
- _36 = copy _10;
|
||||
- _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _36 = copy _11;
|
||||
+ _35 = copy _11;
|
||||
StorageDead(_36);
|
||||
_34 = opaque::<bool>(move _35) -> [return: bb6, unwind continue];
|
||||
- _33 = Le(move _34, move _35);
|
||||
+ _33 = Le(copy _4, copy _11);
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
_32 = opaque::<bool>(move _33) -> [return: bb6, unwind continue];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
StorageDead(_33);
|
||||
StorageDead(_32);
|
||||
StorageLive(_37);
|
||||
StorageLive(_38);
|
||||
StorageLive(_39);
|
||||
- _39 = copy _3;
|
||||
+ _39 = copy _4;
|
||||
StorageLive(_40);
|
||||
StorageLive(_41);
|
||||
- _41 = copy _3;
|
||||
+ _41 = copy _4;
|
||||
StorageLive(_42);
|
||||
StorageLive(_43);
|
||||
- _43 = copy _11;
|
||||
- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _43 = copy _12;
|
||||
+ _42 = copy _12;
|
||||
StorageDead(_43);
|
||||
- _40 = Gt(move _41, move _42);
|
||||
+ _40 = Gt(copy _4, copy _12);
|
||||
StorageDead(_42);
|
||||
- _41 = copy _10;
|
||||
- _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _41 = copy _11;
|
||||
+ _40 = copy _11;
|
||||
StorageDead(_41);
|
||||
_39 = opaque::<bool>(move _40) -> [return: bb7, unwind continue];
|
||||
- _38 = Gt(move _39, move _40);
|
||||
+ _38 = Gt(copy _4, copy _11);
|
||||
StorageDead(_40);
|
||||
StorageDead(_39);
|
||||
_37 = opaque::<bool>(move _38) -> [return: bb7, unwind continue];
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_40);
|
||||
StorageDead(_39);
|
||||
StorageDead(_38);
|
||||
StorageDead(_37);
|
||||
StorageLive(_42);
|
||||
StorageLive(_43);
|
||||
StorageLive(_44);
|
||||
- _44 = copy _3;
|
||||
+ _44 = copy _4;
|
||||
StorageLive(_45);
|
||||
StorageLive(_46);
|
||||
- _46 = copy _3;
|
||||
+ _46 = copy _4;
|
||||
StorageLive(_47);
|
||||
StorageLive(_48);
|
||||
- _48 = copy _11;
|
||||
- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _48 = copy _12;
|
||||
+ _47 = copy _12;
|
||||
StorageDead(_48);
|
||||
- _45 = Ge(move _46, move _47);
|
||||
+ _45 = Ge(copy _4, copy _12);
|
||||
StorageDead(_47);
|
||||
- _46 = copy _10;
|
||||
- _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
|
||||
+ _46 = copy _11;
|
||||
+ _45 = copy _11;
|
||||
StorageDead(_46);
|
||||
_44 = opaque::<bool>(move _45) -> [return: bb8, unwind continue];
|
||||
- _43 = Ge(move _44, move _45);
|
||||
+ _43 = Ge(copy _4, copy _11);
|
||||
StorageDead(_45);
|
||||
StorageDead(_44);
|
||||
_42 = opaque::<bool>(move _43) -> [return: bb8, unwind continue];
|
||||
}
|
||||
|
||||
bb8: {
|
||||
StorageDead(_45);
|
||||
StorageDead(_44);
|
||||
StorageDead(_43);
|
||||
StorageDead(_42);
|
||||
_0 = const ();
|
||||
StorageDead(_16);
|
||||
StorageDead(_11);
|
||||
StorageDead(_15);
|
||||
StorageDead(_10);
|
||||
StorageDead(_8);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `norm2` before InstSimplify-after-simplifycfg
|
||||
+ // MIR for `norm2` after InstSimplify-after-simplifycfg
|
||||
|
||||
fn norm2(_1: [f32; 2]) -> f32 {
|
||||
debug x => _1;
|
||||
let mut _0: f32;
|
||||
let _2: f32;
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let mut _10: f32;
|
||||
let mut _11: f32;
|
||||
let mut _12: f32;
|
||||
let mut _13: f32;
|
||||
let mut _14: f32;
|
||||
let mut _15: f32;
|
||||
scope 1 {
|
||||
debug a => _2;
|
||||
let _6: f32;
|
||||
scope 2 {
|
||||
debug b => _6;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const 0_usize;
|
||||
- _4 = Len(_1);
|
||||
+ _4 = const 2_usize;
|
||||
_5 = Lt(copy _3, copy _4);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = copy _1[_3];
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = const 1_usize;
|
||||
- _8 = Len(_1);
|
||||
+ _8 = const 2_usize;
|
||||
_9 = Lt(copy _7, copy _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_6 = copy _1[_7];
|
||||
StorageDead(_7);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = copy _2;
|
||||
StorageLive(_12);
|
||||
_12 = copy _2;
|
||||
_10 = Mul(move _11, move _12);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
_14 = copy _6;
|
||||
StorageLive(_15);
|
||||
_15 = copy _6;
|
||||
_13 = Mul(move _14, move _15);
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
_0 = Add(move _10, move _13);
|
||||
StorageDead(_13);
|
||||
StorageDead(_10);
|
||||
StorageDead(_6);
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
- // MIR for `norm2` before InstSimplify-after-simplifycfg
|
||||
+ // MIR for `norm2` after InstSimplify-after-simplifycfg
|
||||
|
||||
fn norm2(_1: [f32; 2]) -> f32 {
|
||||
debug x => _1;
|
||||
let mut _0: f32;
|
||||
let _2: f32;
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let _7: usize;
|
||||
let mut _8: usize;
|
||||
let mut _9: bool;
|
||||
let mut _10: f32;
|
||||
let mut _11: f32;
|
||||
let mut _12: f32;
|
||||
let mut _13: f32;
|
||||
let mut _14: f32;
|
||||
let mut _15: f32;
|
||||
scope 1 {
|
||||
debug a => _2;
|
||||
let _6: f32;
|
||||
scope 2 {
|
||||
debug b => _6;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const 0_usize;
|
||||
- _4 = Len(_1);
|
||||
+ _4 = const 2_usize;
|
||||
_5 = Lt(copy _3, copy _4);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = copy _1[_3];
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = const 1_usize;
|
||||
- _8 = Len(_1);
|
||||
+ _8 = const 2_usize;
|
||||
_9 = Lt(copy _7, copy _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_6 = copy _1[_7];
|
||||
StorageDead(_7);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = copy _2;
|
||||
StorageLive(_12);
|
||||
_12 = copy _2;
|
||||
_10 = Mul(move _11, move _12);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
_14 = copy _6;
|
||||
StorageLive(_15);
|
||||
_15 = copy _6;
|
||||
_13 = Mul(move _14, move _15);
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
_0 = Add(move _10, move _13);
|
||||
StorageDead(_13);
|
||||
StorageDead(_10);
|
||||
StorageDead(_6);
|
||||
StorageDead(_2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ test-mir-pass: InstSimplify-after-simplifycfg
|
||||
|
||||
// EMIT_MIR combine_array_len.norm2.InstSimplify-after-simplifycfg.diff
|
||||
fn norm2(x: [f32; 2]) -> f32 {
|
||||
// CHECK-LABEL: fn norm2(
|
||||
// CHECK-NOT: Len(
|
||||
let a = x[0];
|
||||
let b = x[1];
|
||||
a * a + b * b
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0);
|
||||
}
|
@ -4,15 +4,14 @@ fn foo(_1: [(Never, u32); 1]) -> u32 {
|
||||
debug xs => _1;
|
||||
let mut _0: u32;
|
||||
let _2: usize;
|
||||
let mut _3: usize;
|
||||
let mut _4: bool;
|
||||
let mut _3: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
_2 = const 0_usize;
|
||||
_3 = Len(_1);
|
||||
_4 = Lt(copy _2, copy _3);
|
||||
assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind: bb2];
|
||||
FakeRead(ForIndex, _1);
|
||||
_3 = Lt(copy _2, const 1_usize);
|
||||
assert(move _3, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _2) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -7,8 +7,7 @@ fn main() -> () {
|
||||
let mut _4: Foo;
|
||||
let mut _5: u64;
|
||||
let _6: usize;
|
||||
let mut _7: usize;
|
||||
let mut _8: bool;
|
||||
let mut _7: bool;
|
||||
scope 1 {
|
||||
let _2: [Foo; 2];
|
||||
scope 2 {
|
||||
@ -38,9 +37,9 @@ fn main() -> () {
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = const 0_usize;
|
||||
_7 = Len(_2);
|
||||
_8 = Lt(copy _6, copy _7);
|
||||
assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb3, unwind: bb5];
|
||||
FakeRead(ForIndex, _2);
|
||||
_7 = Lt(copy _6, const 2_usize);
|
||||
assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb3, unwind: bb5];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -6,8 +6,9 @@ fn foo(_1: Box<[T]>) -> T {
|
||||
let _2: T;
|
||||
let mut _3: &T;
|
||||
let _4: usize;
|
||||
let mut _5: usize;
|
||||
let mut _6: bool;
|
||||
let mut _5: *const [T];
|
||||
let mut _6: usize;
|
||||
let mut _7: bool;
|
||||
scope 1 {
|
||||
debug f => _2;
|
||||
}
|
||||
@ -17,9 +18,10 @@ fn foo(_1: Box<[T]>) -> T {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
_4 = const 0_usize;
|
||||
_5 = Len((*_1));
|
||||
_6 = Lt(copy _4, copy _5);
|
||||
assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb5];
|
||||
_5 = &raw const (fake) (*_1);
|
||||
_6 = PtrMetadata(move _5);
|
||||
_7 = Lt(copy _4, copy _6);
|
||||
assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb5];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
@ -15,7 +15,7 @@ fn fun(_1: &[T]) -> &T {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const 0_usize;
|
||||
_4 = Len((*_1));
|
||||
_4 = PtrMetadata(copy _1);
|
||||
_5 = Lt(copy _3, copy _4);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb2];
|
||||
}
|
||||
|
@ -11,16 +11,14 @@
|
||||
let mut _6: &[u8];
|
||||
let mut _7: &[u8; N];
|
||||
let _8: usize;
|
||||
let mut _9: usize;
|
||||
let mut _10: bool;
|
||||
let mut _9: bool;
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_3);
|
||||
+ nop;
|
||||
StorageLive(_4);
|
||||
_4 = copy _1;
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = &(*_2);
|
||||
@ -40,16 +38,13 @@
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
- _9 = Len((*_2));
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
|
||||
+ _9 = const N;
|
||||
+ _10 = copy _3;
|
||||
- _9 = Lt(copy _8, const N);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
|
||||
+ _9 = copy _3;
|
||||
+ assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
@ -61,8 +56,7 @@
|
||||
}
|
||||
|
||||
bb4: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
_0 = const 42_u8;
|
||||
goto -> bb5;
|
||||
|
@ -11,16 +11,14 @@
|
||||
let mut _6: &[u8];
|
||||
let mut _7: &[u8; N];
|
||||
let _8: usize;
|
||||
let mut _9: usize;
|
||||
let mut _10: bool;
|
||||
let mut _9: bool;
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_3);
|
||||
+ nop;
|
||||
StorageLive(_4);
|
||||
_4 = copy _1;
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = &(*_2);
|
||||
@ -40,16 +38,13 @@
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
- _9 = Len((*_2));
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
|
||||
+ _9 = const N;
|
||||
+ _10 = copy _3;
|
||||
- _9 = Lt(copy _8, const N);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
|
||||
+ _9 = copy _3;
|
||||
+ assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
|
||||
}
|
||||
|
||||
@ -61,8 +56,7 @@
|
||||
}
|
||||
|
||||
bb4: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
_0 = const 42_u8;
|
||||
goto -> bb5;
|
||||
|
@ -11,19 +11,16 @@
|
||||
let mut _6: &[u8];
|
||||
let mut _7: &[u8; N];
|
||||
let _8: usize;
|
||||
let mut _9: usize;
|
||||
let mut _10: bool;
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
let mut _9: bool;
|
||||
let _10: usize;
|
||||
let mut _11: bool;
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_3);
|
||||
+ nop;
|
||||
StorageLive(_4);
|
||||
_4 = copy _1;
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = &(*_2);
|
||||
@ -43,16 +40,13 @@
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
- _9 = Len((*_2));
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
|
||||
+ _9 = const N;
|
||||
+ _10 = copy _3;
|
||||
- _9 = Lt(copy _8, const N);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
|
||||
+ _9 = copy _3;
|
||||
+ assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
@ -64,23 +58,20 @@
|
||||
}
|
||||
|
||||
bb4: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_11);
|
||||
_11 = const 0_usize;
|
||||
- _12 = Len((*_2));
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
|
||||
+ _12 = const N;
|
||||
+ _13 = Lt(const 0_usize, const N);
|
||||
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
|
||||
StorageLive(_10);
|
||||
_10 = const 0_usize;
|
||||
- _11 = Lt(copy _10, const N);
|
||||
- assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind unreachable];
|
||||
+ _11 = Lt(const 0_usize, const N);
|
||||
+ assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
- (*_2)[_11] = const 42_u8;
|
||||
- (*_2)[_10] = const 42_u8;
|
||||
+ (*_2)[0 of 1] = const 42_u8;
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const 42_u8;
|
||||
goto -> bb6;
|
||||
}
|
||||
|
@ -11,19 +11,16 @@
|
||||
let mut _6: &[u8];
|
||||
let mut _7: &[u8; N];
|
||||
let _8: usize;
|
||||
let mut _9: usize;
|
||||
let mut _10: bool;
|
||||
let _11: usize;
|
||||
let mut _12: usize;
|
||||
let mut _13: bool;
|
||||
let mut _9: bool;
|
||||
let _10: usize;
|
||||
let mut _11: bool;
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_3);
|
||||
+ nop;
|
||||
StorageLive(_4);
|
||||
_4 = copy _1;
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
_7 = &(*_2);
|
||||
@ -43,16 +40,13 @@
|
||||
}
|
||||
|
||||
bb2: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_8);
|
||||
_8 = copy _1;
|
||||
- _9 = Len((*_2));
|
||||
- _10 = Lt(copy _8, copy _9);
|
||||
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
|
||||
+ _9 = const N;
|
||||
+ _10 = copy _3;
|
||||
- _9 = Lt(copy _8, const N);
|
||||
- assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
|
||||
+ _9 = copy _3;
|
||||
+ assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
|
||||
}
|
||||
|
||||
@ -64,23 +58,20 @@
|
||||
}
|
||||
|
||||
bb4: {
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_11);
|
||||
_11 = const 0_usize;
|
||||
- _12 = Len((*_2));
|
||||
- _13 = Lt(copy _11, copy _12);
|
||||
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
|
||||
+ _12 = const N;
|
||||
+ _13 = Lt(const 0_usize, const N);
|
||||
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
|
||||
StorageLive(_10);
|
||||
_10 = const 0_usize;
|
||||
- _11 = Lt(copy _10, const N);
|
||||
- assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind continue];
|
||||
+ _11 = Lt(const 0_usize, const N);
|
||||
+ assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
- (*_2)[_11] = const 42_u8;
|
||||
- (*_2)[_10] = const 42_u8;
|
||||
+ (*_2)[0 of 1] = const 42_u8;
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = const 42_u8;
|
||||
goto -> bb6;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
StorageDead(_4);
|
||||
StorageLive(_7);
|
||||
_7 = copy _1;
|
||||
_8 = Len((*_2));
|
||||
_8 = PtrMetadata(copy _2);
|
||||
_9 = Lt(copy _7, copy _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind unreachable];
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
StorageDead(_4);
|
||||
StorageLive(_7);
|
||||
_7 = copy _1;
|
||||
_8 = Len((*_2));
|
||||
_8 = PtrMetadata(copy _2);
|
||||
_9 = Lt(copy _7, copy _8);
|
||||
assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind continue];
|
||||
}
|
||||
|
@ -27,20 +27,19 @@ fn main() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: [usize; ValTree(Leaf(0x00000003): usize)];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _7: bool;
|
||||
let _8: bool;
|
||||
let mut _9: usize;
|
||||
let _10: bool;
|
||||
let mut _4: bool;
|
||||
let mut _6: bool;
|
||||
let _7: bool;
|
||||
let mut _8: usize;
|
||||
let _9: bool;
|
||||
scope 1 {
|
||||
debug v => _1;
|
||||
let _2: &'?3 usize;
|
||||
scope 2 {
|
||||
debug p => _2;
|
||||
let _6: &'?4 usize;
|
||||
let _5: &'?4 usize;
|
||||
scope 3 {
|
||||
debug q => _6;
|
||||
debug q => _5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,50 +51,50 @@ fn main() -> () {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const ConstValue(Scalar(0x00000000): usize);
|
||||
_4 = Len(_1);
|
||||
_5 = Lt(copy _3, copy _4);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
|
||||
FakeRead(ForIndex, _1);
|
||||
_4 = Lt(copy _3, const ValTree(Leaf(0x00000003): usize));
|
||||
assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = &'?2 _1[_3];
|
||||
FakeRead(ForLet(None), _2);
|
||||
StorageLive(_5);
|
||||
_5 = copy _2;
|
||||
FakeRead(ForLet(None), _5);
|
||||
StorageLive(_6);
|
||||
_6 = copy _2;
|
||||
FakeRead(ForLet(None), _6);
|
||||
StorageLive(_7);
|
||||
_7 = const ConstValue(Scalar(0x01): bool);
|
||||
switchInt(move _7) -> [0: bb4, otherwise: bb2];
|
||||
_6 = const ConstValue(Scalar(0x01): bool);
|
||||
switchInt(move _6) -> [0: bb4, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy (*_6);
|
||||
_8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
|
||||
_8 = copy (*_5);
|
||||
_7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
_0 = const ConstValue(ZeroSized: ());
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_10);
|
||||
_10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
|
||||
StorageLive(_9);
|
||||
_9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
_0 = const ConstValue(ZeroSized: ());
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
|
@ -27,20 +27,19 @@ fn main() -> () {
|
||||
let mut _0: ();
|
||||
let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)];
|
||||
let _3: usize;
|
||||
let mut _4: usize;
|
||||
let mut _5: bool;
|
||||
let mut _7: bool;
|
||||
let _8: bool;
|
||||
let mut _9: usize;
|
||||
let _10: bool;
|
||||
let mut _4: bool;
|
||||
let mut _6: bool;
|
||||
let _7: bool;
|
||||
let mut _8: usize;
|
||||
let _9: bool;
|
||||
scope 1 {
|
||||
debug v => _1;
|
||||
let _2: &'?3 usize;
|
||||
scope 2 {
|
||||
debug p => _2;
|
||||
let _6: &'?4 usize;
|
||||
let _5: &'?4 usize;
|
||||
scope 3 {
|
||||
debug q => _6;
|
||||
debug q => _5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,50 +51,50 @@ fn main() -> () {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = const ConstValue(Scalar(0x0000000000000000): usize);
|
||||
_4 = Len(_1);
|
||||
_5 = Lt(copy _3, copy _4);
|
||||
assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
|
||||
FakeRead(ForIndex, _1);
|
||||
_4 = Lt(copy _3, const ValTree(Leaf(0x0000000000000003): usize));
|
||||
assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_2 = &'?2 _1[_3];
|
||||
FakeRead(ForLet(None), _2);
|
||||
StorageLive(_5);
|
||||
_5 = copy _2;
|
||||
FakeRead(ForLet(None), _5);
|
||||
StorageLive(_6);
|
||||
_6 = copy _2;
|
||||
FakeRead(ForLet(None), _6);
|
||||
StorageLive(_7);
|
||||
_7 = const ConstValue(Scalar(0x01): bool);
|
||||
switchInt(move _7) -> [0: bb4, otherwise: bb2];
|
||||
_6 = const ConstValue(Scalar(0x01): bool);
|
||||
switchInt(move _6) -> [0: bb4, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = copy (*_6);
|
||||
_8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
|
||||
_8 = copy (*_5);
|
||||
_7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
_0 = const ConstValue(ZeroSized: ());
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_10);
|
||||
_10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
|
||||
StorageLive(_9);
|
||||
_9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
_0 = const ConstValue(ZeroSized: ());
|
||||
goto -> bb6;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
|
@ -7,17 +7,16 @@
|
||||
let mut _2: (i32, bool);
|
||||
let mut _4: [i32; 6];
|
||||
let _5: usize;
|
||||
let mut _6: usize;
|
||||
let mut _7: bool;
|
||||
let mut _9: u32;
|
||||
let mut _6: bool;
|
||||
let mut _8: u32;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
let _3: i32;
|
||||
scope 2 {
|
||||
debug y => _3;
|
||||
let _8: u32;
|
||||
let _7: u32;
|
||||
scope 3 {
|
||||
debug z => _8;
|
||||
debug z => _7;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,10 +37,9 @@
|
||||
_4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
|
||||
StorageLive(_5);
|
||||
_5 = const 3_usize;
|
||||
_6 = const 6_usize;
|
||||
- _7 = Lt(copy _5, copy _6);
|
||||
- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
|
||||
+ _7 = const true;
|
||||
- _6 = Lt(copy _5, const 6_usize);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
@ -50,13 +48,13 @@
|
||||
+ _3 = const 3_i32;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = const 42_u32;
|
||||
- _8 = copy _9;
|
||||
+ _8 = const 42_u32;
|
||||
StorageDead(_9);
|
||||
_8 = const 42_u32;
|
||||
- _7 = copy _8;
|
||||
+ _7 = const 42_u32;
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
|
@ -7,17 +7,16 @@
|
||||
let mut _2: (i32, bool);
|
||||
let mut _4: [i32; 6];
|
||||
let _5: usize;
|
||||
let mut _6: usize;
|
||||
let mut _7: bool;
|
||||
let mut _9: u32;
|
||||
let mut _6: bool;
|
||||
let mut _8: u32;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
let _3: i32;
|
||||
scope 2 {
|
||||
debug y => _3;
|
||||
let _8: u32;
|
||||
let _7: u32;
|
||||
scope 3 {
|
||||
debug z => _8;
|
||||
debug z => _7;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,10 +37,9 @@
|
||||
_4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
|
||||
StorageLive(_5);
|
||||
_5 = const 3_usize;
|
||||
_6 = const 6_usize;
|
||||
- _7 = Lt(copy _5, copy _6);
|
||||
- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
|
||||
+ _7 = const true;
|
||||
- _6 = Lt(copy _5, const 6_usize);
|
||||
- assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
|
||||
+ _6 = const true;
|
||||
+ assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
|
||||
}
|
||||
|
||||
@ -50,13 +48,13 @@
|
||||
+ _3 = const 3_i32;
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = const 42_u32;
|
||||
- _8 = copy _9;
|
||||
+ _8 = const 42_u32;
|
||||
StorageDead(_9);
|
||||
_8 = const 42_u32;
|
||||
- _7 = copy _8;
|
||||
+ _7 = const 42_u32;
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user