diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index 683d7b486171f..e8a805df4db4a 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -160,7 +160,11 @@ impl<'tcx> PlaceTy<'tcx> { /// Convenience wrapper around `projection_ty_core` for `PlaceElem`, /// where we can just use the `Ty` that is already stored inline on /// field projection elems. - pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> { + pub fn projection_ty( + self, + tcx: TyCtxt<'tcx>, + elem: ProjectionElem>, + ) -> PlaceTy<'tcx> { self.projection_ty_core(tcx, &elem, |ty| ty, |_, _, _, ty| ty, |ty| ty) } @@ -290,6 +294,30 @@ impl ProjectionElem { Self::UnwrapUnsafeBinder(..) => false, } } + + pub fn try_map( + self, + v: impl FnOnce(V) -> Option, + t: impl FnOnce(T) -> T2, + ) -> Option> { + Some(match self { + ProjectionElem::Deref => ProjectionElem::Deref, + ProjectionElem::Downcast(name, read_variant) => { + ProjectionElem::Downcast(name, read_variant) + } + ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, t(ty)), + ProjectionElem::ConstantIndex { offset, min_length, from_end } => { + ProjectionElem::ConstantIndex { offset, min_length, from_end } + } + ProjectionElem::Subslice { from, to, from_end } => { + ProjectionElem::Subslice { from, to, from_end } + } + ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(t(ty)), + ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(t(ty)), + ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(t(ty)), + ProjectionElem::Index(val) => ProjectionElem::Index(v(val)?), + }) + } } /// Alias for projections as they appear in `UserTypeProjection`, where we diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 929ebe1aee181..0578c0e88108c 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1402,6 +1402,23 @@ impl PlaceContext { ) } + /// Returns `true` if this place context may be used to know the address of the given place. + pub fn may_observe_address(self) -> bool { + matches!( + self, + PlaceContext::NonMutatingUse( + NonMutatingUseContext::SharedBorrow + | NonMutatingUseContext::RawBorrow + | NonMutatingUseContext::FakeBorrow + ) | PlaceContext::MutatingUse( + MutatingUseContext::Drop + | MutatingUseContext::Borrow + | MutatingUseContext::RawBorrow + | MutatingUseContext::AsmOutput + ) + ) + } + /// Returns `true` if this place context represents a storage live or storage dead marker. #[inline] pub fn is_storage_marker(self) -> bool { diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 83fd8ccba60e5..73e304067018d 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet, StdEntry}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; -use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; use tracing::debug; @@ -917,12 +917,7 @@ pub fn excluded_locals(body: &Body<'_>) -> DenseBitSet { impl<'tcx> Visitor<'tcx> for Collector { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { - if (context.is_borrow() - || context.is_address_of() - || context.is_drop() - || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput)) - && !place.is_indirect() - { + if context.may_observe_address() && !place.is_indirect() { // A pointer to a place could be used to access other places with the same local, // hence we have to exclude the local completely. self.result.insert(place.local); diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 6b11706d2b55f..37e1c03555051 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -88,12 +88,13 @@ use std::borrow::Cow; use either::Either; use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT, FieldIdx, Primitive, Size, VariantIdx}; +use rustc_arena::DroplessArena; use rustc_const_eval::const_eval::DummyMachine; use rustc_const_eval::interpret::{ ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar, intern_const_alloc_for_constprop, }; -use rustc_data_structures::fx::{FxIndexSet, MutableValues}; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet, MutableValues}; use rustc_data_structures::graph::dominators::Dominators; use rustc_hir::def::DefKind; use rustc_index::bit_set::DenseBitSet; @@ -105,7 +106,6 @@ use rustc_middle::mir::*; use rustc_middle::ty::layout::HasTypingEnv; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::DUMMY_SP; -use rustc_span::def_id::DefId; use smallvec::SmallVec; use tracing::{debug, instrument, trace}; @@ -127,12 +127,9 @@ impl<'tcx> crate::MirPass<'tcx> for GVN { // Clone dominators because we need them while mutating the body. let dominators = body.basic_blocks.dominators().clone(); - let mut state = VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls); - - for local in body.args_iter().filter(|&local| ssa.is_ssa(local)) { - let opaque = state.new_opaque(); - state.assign(local, opaque); - } + let arena = DroplessArena::default(); + let mut state = + VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls, &arena); let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec(); for bb in reverse_postorder { @@ -155,30 +152,22 @@ newtype_index! { struct VnIndex {} } -/// Computing the aggregate's type can be quite slow, so we only keep the minimal amount of -/// information to reconstruct it when needed. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -enum AggregateTy<'tcx> { - /// Invariant: this must not be used for an empty array. - Array, - Tuple, - Def(DefId, ty::GenericArgsRef<'tcx>), - RawPtr { - /// Needed for cast propagation. - data_pointer_ty: Ty<'tcx>, - /// The data pointer can be anything thin, so doesn't determine the output. - output_pointer_ty: Ty<'tcx>, - }, -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] enum AddressKind { Ref(BorrowKind), Address(RawPtrKind), } -#[derive(Debug, PartialEq, Eq, Hash)] -enum Value<'tcx> { +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +enum AddressBase { + /// This address is based on this local. + Local(Local), + /// This address is based on the deref of this pointer. + Deref(VnIndex), +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +enum Value<'a, 'tcx> { // Root values. /// Used to represent values we know nothing about. /// The `usize` is a counter incremented by `new_opaque`. @@ -193,12 +182,22 @@ enum Value<'tcx> { }, /// An aggregate value, either tuple/closure/struct/enum. /// This does not contain unions, as we cannot reason with the value. - Aggregate(AggregateTy<'tcx>, VariantIdx, Vec), + Aggregate(VariantIdx, &'a [VnIndex]), + /// A raw pointer aggregate built from a thin pointer and metadata. + RawPtr { + /// Thin pointer component. This is field 0 in MIR. + pointer: VnIndex, + /// Metadata component. This is field 1 in MIR. + metadata: VnIndex, + }, /// This corresponds to a `[value; count]` expression. Repeat(VnIndex, ty::Const<'tcx>), /// The address of a place. Address { - place: Place<'tcx>, + base: AddressBase, + // We do not use a plain `Place` as we want to be able to reason about indices. + // This does not contain any `Deref` projection. + projection: &'a [ProjectionElem>], kind: AddressKind, /// Give each borrow and pointer a different provenance, so we don't merge them. provenance: usize, @@ -206,7 +205,7 @@ enum Value<'tcx> { // Extractions. /// This is the *value* obtained by projecting another value. - Projection(VnIndex, ProjectionElem>), + Projection(VnIndex, ProjectionElem), /// Discriminant of the given value. Discriminant(VnIndex), /// Length of an array or slice. @@ -219,21 +218,22 @@ enum Value<'tcx> { Cast { kind: CastKind, value: VnIndex, - from: Ty<'tcx>, - to: Ty<'tcx>, }, } -struct VnState<'body, 'tcx> { +struct VnState<'body, 'a, 'tcx> { tcx: TyCtxt<'tcx>, ecx: InterpCx<'tcx, DummyMachine>, local_decls: &'body LocalDecls<'tcx>, + is_coroutine: bool, /// Value stored in each local. - locals: IndexVec>, + locals: IndexVec, /// Locals that are assigned that value. - // This vector does not hold all the values of `VnIndex` that we create. - rev_locals: IndexVec>, - values: FxIndexSet>, + // This vector holds the locals that are SSA. + rev_locals_ssa: IndexVec>, + // This vector holds the locals that are not SSA. + rev_locals_non_ssa: FxHashMap>, + values: FxIndexSet<(Value<'a, 'tcx>, Ty<'tcx>)>, /// Values evaluated as constants if possible. evaluated: IndexVec>>, /// Counter to generate different values. @@ -243,9 +243,10 @@ struct VnState<'body, 'tcx> { ssa: &'body SsaLocals, dominators: Dominators, reused_locals: DenseBitSet, + arena: &'a DroplessArena, } -impl<'body, 'tcx> VnState<'body, 'tcx> { +impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { fn new( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -253,6 +254,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ssa: &'body SsaLocals, dominators: Dominators, local_decls: &'body LocalDecls<'tcx>, + arena: &'a DroplessArena, ) -> Self { // Compute a rough estimate of the number of values in the body from the number of // statements. This is meant to reduce the number of allocations, but it's all right if @@ -261,12 +263,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let num_values = 2 * body.basic_blocks.iter().map(|bbdata| bbdata.statements.len()).sum::() + 4 * body.basic_blocks.len(); - VnState { + let mut this = VnState { tcx, ecx: InterpCx::new(tcx, DUMMY_SP, typing_env, DummyMachine), local_decls, - locals: IndexVec::from_elem(None, local_decls), - rev_locals: IndexVec::with_capacity(num_values), + is_coroutine: body.coroutine.is_some(), + locals: IndexVec::with_capacity(body.local_decls.len()), + rev_locals_ssa: IndexVec::with_capacity(num_values), + rev_locals_non_ssa: FxHashMap::default(), values: FxIndexSet::with_capacity_and_hasher(num_values, Default::default()), evaluated: IndexVec::with_capacity(num_values), next_opaque: 1, @@ -274,7 +278,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ssa, dominators, reused_locals: DenseBitSet::new_empty(local_decls.len()), + arena, + }; + let init_loc = Location { block: START_BLOCK, statement_index: 0 }; + for decl in body.local_decls.iter() { + let value = this.new_opaque(decl.ty); + let local = this.locals.push(value); + if ssa.is_ssa(local) { + this.rev_locals_ssa[value].push((local, init_loc)); + } else { + this.rev_locals_non_ssa.entry(value).or_default().push((local, init_loc)); + } } + this } fn typing_env(&self) -> ty::TypingEnv<'tcx> { @@ -282,15 +298,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } #[instrument(level = "trace", skip(self), ret)] - fn insert(&mut self, value: Value<'tcx>) -> VnIndex { - let (index, new) = self.values.insert_full(value); + fn insert(&mut self, ty: Ty<'tcx>, value: Value<'a, 'tcx>) -> VnIndex { + let (index, new) = self.values.insert_full((value, ty)); let index = VnIndex::from_usize(index); if new { // Grow `evaluated` and `rev_locals` here to amortize the allocations. let evaluated = self.eval_to_const(index); let _index = self.evaluated.push(evaluated); debug_assert_eq!(index, _index); - let _index = self.rev_locals.push(SmallVec::new()); + let _index = self.rev_locals_ssa.push(Default::default()); debug_assert_eq!(index, _index); } index @@ -305,28 +321,95 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { /// Create a new `Value` for which we have no information at all, except that it is distinct /// from all the others. #[instrument(level = "trace", skip(self), ret)] - fn new_opaque(&mut self) -> VnIndex { + fn new_opaque(&mut self, ty: Ty<'tcx>) -> VnIndex { let value = Value::Opaque(self.next_opaque()); - self.insert(value) + self.insert(ty, value) } /// Create a new `Value::Address` distinct from all the others. #[instrument(level = "trace", skip(self), ret)] - fn new_pointer(&mut self, place: Place<'tcx>, kind: AddressKind) -> VnIndex { - let value = Value::Address { place, kind, provenance: self.next_opaque() }; - self.insert(value) + fn new_pointer( + &mut self, + place: Place<'tcx>, + kind: AddressKind, + location: Location, + ) -> Option { + let pty = place.ty(self.local_decls, self.tcx).ty; + let ty = match kind { + AddressKind::Ref(bk) => { + Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, pty, bk.to_mutbl_lossy()) + } + AddressKind::Address(mutbl) => Ty::new_ptr(self.tcx, pty, mutbl.to_mutbl_lossy()), + }; + + let mut projection = place.projection.iter(); + let base = if place.is_indirect_first_projection() { + let base = self.locals[place.local]; + // Skip the initial `Deref`. + projection.next(); + AddressBase::Deref(base) + } else { + AddressBase::Local(place.local) + }; + // Do not try evaluating inside `Index`, this has been done by `simplify_place_value`. + let projection = self + .arena + .try_alloc_from_iter( + projection + .map(|proj| proj.try_map(|value| Some(self.locals[value]), |ty| ty).ok_or(())), + ) + .ok()?; + let value = Value::Address { base, projection, kind, provenance: self.next_opaque() }; + Some(self.insert(ty, value)) + } + + #[inline] + fn get(&self, index: VnIndex) -> Value<'a, 'tcx> { + self.values.get_index(index.as_usize()).unwrap().0 } - fn get(&self, index: VnIndex) -> &Value<'tcx> { - self.values.get_index(index.as_usize()).unwrap() + #[inline] + fn ty(&self, index: VnIndex) -> Ty<'tcx> { + self.values.get_index(index.as_usize()).unwrap().1 } - /// Record that `local` is assigned `value`. `local` must be SSA. + /// Record that `local` is assigned `value`. #[instrument(level = "trace", skip(self))] - fn assign(&mut self, local: Local, value: VnIndex) { - debug_assert!(self.ssa.is_ssa(local)); - self.locals[local] = Some(value); - self.rev_locals[value].push(local); + fn assign(&mut self, local: Local, value: VnIndex, loc: Location) { + self.locals[local] = value; + if self.ssa.is_ssa(local) { + self.rev_locals_ssa[value].push((local, loc)); + } else { + self.rev_locals_non_ssa.entry(value).or_default().push((local, loc)); + } + } + + #[instrument(level = "trace", skip(self))] + fn discard_place(&mut self, place: Place<'tcx>) { + let discard_local = |this: &mut Self, local| { + if this.ssa.is_ssa(local) { + return; + } + let value = this.locals[local]; + this.rev_locals_non_ssa.entry(value).or_default().retain(|(l, _)| *l != local); + this.locals[local] = this.new_opaque(this.ty(value)); + #[cfg(debug_assertions)] + for local_vec in this.rev_locals_non_ssa.iter() { + for (other, _) in local_vec.non_ssa { + debug_assert_ne!(*other, local); + } + } + }; + if place.is_indirect_first_projection() { + // Non-local mutation maybe invalidate deref. + self.invalidate_derefs(); + // Remove stored value from borrowed locals. + for local in self.ssa.borrowed_locals().iter() { + discard_local(self, local); + } + } else { + discard_local(self, place.local); + } } fn insert_constant(&mut self, value: Const<'tcx>) -> VnIndex { @@ -341,29 +424,29 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { debug_assert_ne!(disambiguator, 0); disambiguator }; - self.insert(Value::Constant { value, disambiguator }) + self.insert(value.ty(), Value::Constant { value, disambiguator }) } fn insert_bool(&mut self, flag: bool) -> VnIndex { // Booleans are deterministic. let value = Const::from_bool(self.tcx, flag); debug_assert!(value.is_deterministic()); - self.insert(Value::Constant { value, disambiguator: 0 }) + self.insert(self.tcx.types.bool, Value::Constant { value, disambiguator: 0 }) } - fn insert_scalar(&mut self, scalar: Scalar, ty: Ty<'tcx>) -> VnIndex { + fn insert_scalar(&mut self, ty: Ty<'tcx>, scalar: Scalar) -> VnIndex { // Scalars are deterministic. let value = Const::from_scalar(self.tcx, scalar, ty); debug_assert!(value.is_deterministic()); - self.insert(Value::Constant { value, disambiguator: 0 }) + self.insert(ty, Value::Constant { value, disambiguator: 0 }) } - fn insert_tuple(&mut self, values: Vec) -> VnIndex { - self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values)) + fn insert_tuple(&mut self, ty: Ty<'tcx>, values: &[VnIndex]) -> VnIndex { + self.insert(ty, Value::Aggregate(VariantIdx::ZERO, self.arena.alloc_slice(values))) } - fn insert_deref(&mut self, value: VnIndex) -> VnIndex { - let value = self.insert(Value::Projection(value, ProjectionElem::Deref)); + fn insert_deref(&mut self, ty: Ty<'tcx>, value: VnIndex) -> VnIndex { + let value = self.insert(ty, Value::Projection(value, ProjectionElem::Deref)); self.derefs.push(value); value } @@ -371,14 +454,23 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { fn invalidate_derefs(&mut self) { for deref in std::mem::take(&mut self.derefs) { let opaque = self.next_opaque(); - *self.values.get_index_mut2(deref.index()).unwrap() = Value::Opaque(opaque); + self.values.get_index_mut2(deref.index()).unwrap().0 = Value::Opaque(opaque); } } #[instrument(level = "trace", skip(self), ret)] fn eval_to_const(&mut self, value: VnIndex) -> Option> { use Value::*; - let op = match *self.get(value) { + let ty = self.ty(value); + // Avoid computing layouts inside a coroutine, as that can cause cycles. + let ty = if !self.is_coroutine || ty.is_scalar() { + self.ecx.layout_of(ty).ok()? + } else { + return None; + }; + let op = match self.get(value) { + _ if ty.is_zst() => ImmTy::uninit(ty).into(), + Opaque(_) => return None, // Do not bother evaluating repeat expressions. This would uselessly consume memory. Repeat(..) => return None, @@ -386,42 +478,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { Constant { ref value, disambiguator: _ } => { self.ecx.eval_mir_constant(value, DUMMY_SP, None).discard_err()? } - Aggregate(kind, variant, ref fields) => { + Aggregate(variant, ref fields) => { let fields = fields .iter() .map(|&f| self.evaluated[f].as_ref()) .collect::>>()?; - let ty = match kind { - AggregateTy::Array => { - assert!(fields.len() > 0); - Ty::new_array(self.tcx, fields[0].layout.ty, fields.len() as u64) - } - AggregateTy::Tuple => { - Ty::new_tup_from_iter(self.tcx, fields.iter().map(|f| f.layout.ty)) - } - AggregateTy::Def(def_id, args) => { - self.tcx.type_of(def_id).instantiate(self.tcx, args) - } - AggregateTy::RawPtr { output_pointer_ty, .. } => output_pointer_ty, - }; - let variant = if ty.is_enum() { Some(variant) } else { None }; - let ty = self.ecx.layout_of(ty).ok()?; - if ty.is_zst() { - ImmTy::uninit(ty).into() - } else if matches!(kind, AggregateTy::RawPtr { .. }) { - // Pointers don't have fields, so don't `project_field` them. - let data = self.ecx.read_pointer(fields[0]).discard_err()?; - let meta = if fields[1].layout.is_zst() { - MemPlaceMeta::None - } else { - MemPlaceMeta::Meta(self.ecx.read_scalar(fields[1]).discard_err()?) - }; - let ptr_imm = Immediate::new_pointer_with_meta(data, meta, &self.ecx); - ImmTy::from_immediate(ptr_imm, ty).into() - } else if matches!( - ty.backend_repr, - BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..) - ) { + let variant = if ty.ty.is_enum() { Some(variant) } else { None }; + if matches!(ty.backend_repr, BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..)) + { let dest = self.ecx.allocate(ty, MemoryKind::Stack).discard_err()?; let variant_dest = if let Some(variant) = variant { self.ecx.project_downcast(&dest, variant).discard_err()? @@ -446,60 +510,44 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return None; } } + RawPtr { pointer, metadata } => { + let pointer = self.evaluated[pointer].as_ref()?; + let metadata = self.evaluated[metadata].as_ref()?; + + // Pointers don't have fields, so don't `project_field` them. + let data = self.ecx.read_pointer(pointer).discard_err()?; + let meta = if metadata.layout.is_zst() { + MemPlaceMeta::None + } else { + MemPlaceMeta::Meta(self.ecx.read_scalar(metadata).discard_err()?) + }; + let ptr_imm = Immediate::new_pointer_with_meta(data, meta, &self.ecx); + ImmTy::from_immediate(ptr_imm, ty).into() + } Projection(base, elem) => { - let value = self.evaluated[base].as_ref()?; - let elem = match elem { - ProjectionElem::Deref => ProjectionElem::Deref, - ProjectionElem::Downcast(name, read_variant) => { - ProjectionElem::Downcast(name, read_variant) - } - ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty), - ProjectionElem::ConstantIndex { offset, min_length, from_end } => { - ProjectionElem::ConstantIndex { offset, min_length, from_end } - } - ProjectionElem::Subslice { from, to, from_end } => { - ProjectionElem::Subslice { from, to, from_end } - } - ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), - ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty), - ProjectionElem::UnwrapUnsafeBinder(ty) => { - ProjectionElem::UnwrapUnsafeBinder(ty) - } - // This should have been replaced by a `ConstantIndex` earlier. - ProjectionElem::Index(_) => return None, - }; - self.ecx.project(value, elem).discard_err()? + let base = self.evaluated[base].as_ref()?; + // `Index` by constants should have been replaces by `ConstantIndex` by + // `simplify_place_projection`. + let elem = elem.try_map(|_| None, |()| ty.ty)?; + self.ecx.project(base, elem).discard_err()? } - Address { place, kind, provenance: _ } => { - if !place.is_indirect_first_projection() { - return None; - } - let local = self.locals[place.local]?; - let pointer = self.evaluated[local].as_ref()?; + Address { base, projection, .. } => { + debug_assert!(!projection.contains(&ProjectionElem::Deref)); + let pointer = match base { + AddressBase::Deref(pointer) => self.evaluated[pointer].as_ref()?, + // We have no stack to point to. + AddressBase::Local(_) => return None, + }; let mut mplace = self.ecx.deref_pointer(pointer).discard_err()?; - for proj in place.projection.iter().skip(1) { - // We have no call stack to associate a local with a value, so we cannot - // interpret indexing. - if matches!(proj, ProjectionElem::Index(_)) { - return None; - } - mplace = self.ecx.project(&mplace, proj).discard_err()?; + for elem in projection { + // `Index` by constants should have been replaces by `ConstantIndex` by + // `simplify_place_projection`. + let elem = elem.try_map(|_| None, |ty| ty)?; + mplace = self.ecx.project(&mplace, elem).discard_err()?; } let pointer = mplace.to_ref(&self.ecx); - let ty = match kind { - AddressKind::Ref(bk) => Ty::new_ref( - self.tcx, - self.tcx.lifetimes.re_erased, - mplace.layout.ty, - bk.to_mutbl_lossy(), - ), - 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() + ImmTy::from_immediate(pointer, ty).into() } Discriminant(base) => { @@ -511,32 +559,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } Len(slice) => { let slice = self.evaluated[slice].as_ref()?; - let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); let len = slice.len(&self.ecx).discard_err()?; - let imm = ImmTy::from_uint(len, usize_layout); - imm.into() + ImmTy::from_uint(len, ty).into() } - NullaryOp(null_op, ty) => { - let layout = self.ecx.layout_of(ty).ok()?; + NullaryOp(null_op, arg_ty) => { + let arg_layout = self.ecx.layout_of(arg_ty).ok()?; if let NullOp::SizeOf | NullOp::AlignOf = null_op - && layout.is_unsized() + && arg_layout.is_unsized() { return None; } let val = match null_op { - NullOp::SizeOf => layout.size.bytes(), - NullOp::AlignOf => layout.align.abi.bytes(), + NullOp::SizeOf => arg_layout.size.bytes(), + NullOp::AlignOf => arg_layout.align.abi.bytes(), NullOp::OffsetOf(fields) => self .ecx .tcx - .offset_of_subfield(self.typing_env(), layout, fields.iter()) + .offset_of_subfield(self.typing_env(), arg_layout, fields.iter()) .bytes(), NullOp::UbChecks => return None, NullOp::ContractChecks => return None, }; - let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); - let imm = ImmTy::from_uint(val, usize_layout); - imm.into() + ImmTy::from_uint(val, ty).into() } UnaryOp(un_op, operand) => { let operand = self.evaluated[operand].as_ref()?; @@ -552,30 +596,27 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let val = self.ecx.binary_op(bin_op, &lhs, &rhs).discard_err()?; val.into() } - Cast { kind, value, from: _, to } => match kind { + Cast { kind, value } => match kind { CastKind::IntToInt | CastKind::IntToFloat => { let value = self.evaluated[value].as_ref()?; let value = self.ecx.read_immediate(value).discard_err()?; - let to = self.ecx.layout_of(to).ok()?; - let res = self.ecx.int_to_int_or_float(&value, to).discard_err()?; + let res = self.ecx.int_to_int_or_float(&value, ty).discard_err()?; res.into() } CastKind::FloatToFloat | CastKind::FloatToInt => { let value = self.evaluated[value].as_ref()?; let value = self.ecx.read_immediate(value).discard_err()?; - let to = self.ecx.layout_of(to).ok()?; - let res = self.ecx.float_to_float_or_int(&value, to).discard_err()?; + let res = self.ecx.float_to_float_or_int(&value, ty).discard_err()?; res.into() } CastKind::Transmute => { let value = self.evaluated[value].as_ref()?; - let to = self.ecx.layout_of(to).ok()?; // `offset` for immediates generally only supports projections that match the // type of the immediate. However, as a HACK, we exploit that it can also do // limited transmutes: it only works between types with the same layout, and // cannot transmute pointers to integers. if value.as_mplace_or_imm().is_right() { - let can_transmute = match (value.layout.backend_repr, to.backend_repr) { + let can_transmute = match (value.layout.backend_repr, ty.backend_repr) { (BackendRepr::Scalar(s1), BackendRepr::Scalar(s2)) => { s1.size(&self.ecx) == s2.size(&self.ecx) && !matches!(s1.primitive(), Primitive::Pointer(..)) @@ -595,13 +636,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return None; } } - value.offset(Size::ZERO, to, &self.ecx).discard_err()? + value.offset(Size::ZERO, ty, &self.ecx).discard_err()? } CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) => { let src = self.evaluated[value].as_ref()?; - let to = self.ecx.layout_of(to).ok()?; - let dest = self.ecx.allocate(to, MemoryKind::Stack).discard_err()?; - self.ecx.unsize_into(src, to, &dest.clone().into()).discard_err()?; + let dest = self.ecx.allocate(ty, MemoryKind::Stack).discard_err()?; + self.ecx.unsize_into(src, ty, &dest.clone().into()).discard_err()?; self.ecx .alloc_mark_immutable(dest.ptr().provenance.unwrap().alloc_id()) .discard_err()?; @@ -610,15 +650,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { CastKind::FnPtrToPtr | CastKind::PtrToPtr => { let src = self.evaluated[value].as_ref()?; let src = self.ecx.read_immediate(src).discard_err()?; - let to = self.ecx.layout_of(to).ok()?; - let ret = self.ecx.ptr_to_ptr(&src, to).discard_err()?; + let ret = self.ecx.ptr_to_ptr(&src, ty).discard_err()?; ret.into() } CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer, _) => { let src = self.evaluated[value].as_ref()?; let src = self.ecx.read_immediate(src).discard_err()?; - let to = self.ecx.layout_of(to).ok()?; - ImmTy::from_immediate(*src, to).into() + ImmTy::from_immediate(*src, ty).into() } _ => return None, }, @@ -626,33 +664,64 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { Some(op) } + /// Represent the *value* we obtain by dereferencing an `Address` value. + #[instrument(level = "trace", skip(self), ret)] + fn dereference_address( + &mut self, + base: AddressBase, + projection: &[ProjectionElem>], + ) -> Option { + let (mut place_ty, mut value) = match base { + // The base is a local, so we take the local's value and project from it. + AddressBase::Local(local) => { + let local = self.locals[local]; + let place_ty = PlaceTy::from_ty(self.ty(local)); + (place_ty, local) + } + // The base is a pointer's deref, so we introduce the implicit deref. + AddressBase::Deref(reborrow) => { + let place_ty = PlaceTy::from_ty(self.ty(reborrow)); + self.project(place_ty, reborrow, ProjectionElem::Deref)? + } + }; + for &proj in projection { + (place_ty, value) = self.project(place_ty, value, proj)?; + } + Some(value) + } + + #[instrument(level = "trace", skip(self), ret)] fn project( &mut self, - place: PlaceRef<'tcx>, + place_ty: PlaceTy<'tcx>, value: VnIndex, - proj: PlaceElem<'tcx>, - from_non_ssa_index: &mut bool, - ) -> Option { + proj: ProjectionElem>, + ) -> Option<(PlaceTy<'tcx>, VnIndex)> { + let projection_ty = place_ty.projection_ty(self.tcx, proj); let proj = match proj { ProjectionElem::Deref => { - let ty = place.ty(self.local_decls, self.tcx).ty; - if let Some(Mutability::Not) = ty.ref_mutability() - && let Some(pointee_ty) = ty.builtin_deref(true) - && pointee_ty.is_freeze(self.tcx, self.typing_env()) + if let Some(Mutability::Not) = place_ty.ty.ref_mutability() + && projection_ty.ty.is_freeze(self.tcx, self.typing_env()) { + if let Value::Address { base, projection, .. } = self.get(value) + && let Some(value) = self.dereference_address(base, projection) + { + return Some((projection_ty, value)); + } + // An immutable borrow `_x` always points to the same value for the // lifetime of the borrow, so we can merge all instances of `*_x`. - return Some(self.insert_deref(value)); + return Some((projection_ty, self.insert_deref(projection_ty.ty, value))); } else { return None; } } ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index), - ProjectionElem::Field(f, ty) => { - if let Value::Aggregate(_, _, fields) = self.get(value) { - return Some(fields[f.as_usize()]); + ProjectionElem::Field(f, _) => { + if let Value::Aggregate(_, fields) = self.get(value) { + return Some((projection_ty, fields[f.as_usize()])); } else if let Value::Projection(outer_value, ProjectionElem::Downcast(_, read_variant)) = self.get(value) - && let Value::Aggregate(_, written_variant, fields) = self.get(*outer_value) + && let Value::Aggregate(written_variant, fields) = self.get(outer_value) // This pass is not aware of control-flow, so we do not know whether the // replacement we are doing is actually reachable. We could be in any arm of // ``` @@ -670,30 +739,29 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // a downcast to an inactive variant. && written_variant == read_variant { - return Some(fields[f.as_usize()]); + return Some((projection_ty, fields[f.as_usize()])); } - ProjectionElem::Field(f, ty) + ProjectionElem::Field(f, ()) } ProjectionElem::Index(idx) => { if let Value::Repeat(inner, _) = self.get(value) { - *from_non_ssa_index |= self.locals[idx].is_none(); - return Some(*inner); + return Some((projection_ty, inner)); } - let idx = self.locals[idx]?; ProjectionElem::Index(idx) } ProjectionElem::ConstantIndex { offset, min_length, from_end } => { match self.get(value) { Value::Repeat(inner, _) => { - return Some(*inner); + return Some((projection_ty, inner)); } - Value::Aggregate(AggregateTy::Array, _, operands) => { + Value::Aggregate(_, operands) => { let offset = if from_end { operands.len() - offset as usize } else { offset as usize }; - return operands.get(offset).copied(); + let value = operands.get(offset).copied()?; + return Some((projection_ty, value)); } _ => {} }; @@ -702,12 +770,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ProjectionElem::Subslice { from, to, from_end } => { ProjectionElem::Subslice { from, to, from_end } } - ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), - ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty), - ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(ty), + ProjectionElem::OpaqueCast(_) => ProjectionElem::OpaqueCast(()), + ProjectionElem::Subtype(_) => ProjectionElem::Subtype(()), + ProjectionElem::UnwrapUnsafeBinder(_) => ProjectionElem::UnwrapUnsafeBinder(()), }; - Some(self.insert(Value::Projection(value, proj))) + let value = self.insert(projection_ty.ty, Value::Projection(value, proj)); + Some((projection_ty, value)) } /// Simplify the projection chain if we know better. @@ -716,7 +785,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // If the projection is indirect, we treat the local as a value, so can replace it with // another local. if place.is_indirect_first_projection() - && let Some(base) = self.locals[place.local] + && let base = self.locals[place.local] && let Some(new_local) = self.try_as_local(base, location) && place.local != new_local { @@ -728,9 +797,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { for i in 0..projection.len() { let elem = projection[i]; - if let ProjectionElem::Index(idx_local) = elem - && let Some(idx) = self.locals[idx_local] - { + if let ProjectionElem::Index(idx_local) = elem { + let idx = self.locals[idx_local]; if let Some(offset) = self.evaluated[idx].as_ref() && let Some(offset) = self.ecx.read_target_usize(offset).discard_err() && let Some(min_length) = offset.checked_add(1) @@ -756,29 +824,20 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { /// Represent the *value* which would be read from `place`, and point `place` to a preexisting /// place with the same value (if that already exists). #[instrument(level = "trace", skip(self), ret)] - fn simplify_place_value( + fn compute_place_value( &mut self, - place: &mut Place<'tcx>, + place: Place<'tcx>, location: Location, - ) -> Option { - self.simplify_place_projection(place, location); - + ) -> Result> { // Invariant: `place` and `place_ref` point to the same value, even if they point to // different memory locations. let mut place_ref = place.as_ref(); // Invariant: `value` holds the value up-to the `index`th projection excluded. - let mut value = self.locals[place.local]?; - let mut from_non_ssa_index = false; + let mut value = self.locals[place.local]; + // Invariant: `value` has type `place_ty`, with optional downcast variant if needed. + let mut place_ty = PlaceTy::from_ty(self.local_decls[place.local].ty); for (index, proj) in place.projection.iter().enumerate() { - if let Value::Projection(pointer, ProjectionElem::Deref) = *self.get(value) - && let Value::Address { place: mut pointee, kind, .. } = *self.get(pointer) - && let AddressKind::Ref(BorrowKind::Shared) = kind - && let Some(v) = self.simplify_place_value(&mut pointee, location) - { - value = v; - place_ref = pointee.project_deeper(&place.projection[index..], self.tcx).as_ref(); - } if let Some(local) = self.try_as_local(value, location) { // Both `local` and `Place { local: place.local, projection: projection[..index] }` // hold the same value. Therefore, following place holds the value in the original @@ -786,32 +845,50 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { place_ref = PlaceRef { local, projection: &place.projection[index..] }; } - let base = PlaceRef { local: place.local, projection: &place.projection[..index] }; - value = self.project(base, value, proj, &mut from_non_ssa_index)?; + let Some(proj) = proj.try_map(|value| Some(self.locals[value]), |ty| ty) else { + return Err(place_ref); + }; + let Some(ty_and_value) = self.project(place_ty, value, proj) else { + return Err(place_ref); + }; + (place_ty, value) = ty_and_value; } - if let Value::Projection(pointer, ProjectionElem::Deref) = *self.get(value) - && let Value::Address { place: mut pointee, kind, .. } = *self.get(pointer) - && let AddressKind::Ref(BorrowKind::Shared) = kind - && let Some(v) = self.simplify_place_value(&mut pointee, location) - { - value = v; - place_ref = pointee.project_deeper(&[], self.tcx).as_ref(); - } - if let Some(new_local) = self.try_as_local(value, location) { - place_ref = PlaceRef { local: new_local, projection: &[] }; - } else if from_non_ssa_index { - // If access to non-SSA locals is unavoidable, bail out. - return None; - } + Ok(value) + } - if place_ref.local != place.local || place_ref.projection.len() < place.projection.len() { - // By the invariant on `place_ref`. - *place = place_ref.project_deeper(&[], self.tcx); - self.reused_locals.insert(place_ref.local); - } + /// Represent the *value* which would be read from `place`, and point `place` to a preexisting + /// place with the same value (if that already exists). + #[instrument(level = "trace", skip(self), ret)] + fn simplify_place_value( + &mut self, + place: &mut Place<'tcx>, + location: Location, + ) -> Option { + self.simplify_place_projection(place, location); - Some(value) + match self.compute_place_value(*place, location) { + Ok(value) => { + if let Some(new_place) = self.try_as_place(value, location, true) + && (new_place.local != place.local + || new_place.projection.len() < place.projection.len()) + { + *place = new_place; + self.reused_locals.insert(new_place.local); + } + Some(value) + } + Err(place_ref) => { + if place_ref.local != place.local + || place_ref.projection.len() < place.projection.len() + { + // By the invariant on `place_ref`. + *place = place_ref.project_deeper(&[], self.tcx); + self.reused_locals.insert(place_ref.local); + } + None + } + } } #[instrument(level = "trace", skip(self), ret)] @@ -858,20 +935,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { Rvalue::Aggregate(..) => return self.simplify_aggregate(lhs, rvalue, location), Rvalue::Ref(_, borrow_kind, ref mut place) => { self.simplify_place_projection(place, location); - return Some(self.new_pointer(*place, AddressKind::Ref(borrow_kind))); + return self.new_pointer(*place, AddressKind::Ref(borrow_kind), location); } Rvalue::RawPtr(mutbl, ref mut place) => { self.simplify_place_projection(place, location); - return Some(self.new_pointer(*place, AddressKind::Address(mutbl))); + return self.new_pointer(*place, AddressKind::Address(mutbl), location); } - Rvalue::WrapUnsafeBinder(ref mut op, ty) => { + Rvalue::WrapUnsafeBinder(ref mut op, _) => { let value = self.simplify_operand(op, location)?; - Value::Cast { - kind: CastKind::Transmute, - value, - from: op.ty(self.local_decls, self.tcx), - to: ty, - } + Value::Cast { kind: CastKind::Transmute, value } } // Operations. @@ -896,18 +968,17 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // Unsupported values. Rvalue::ThreadLocalRef(..) | Rvalue::ShallowInitBox(..) => return None, }; - debug!(?value); - Some(self.insert(value)) + let ty = rvalue.ty(self.local_decls, self.tcx); + Some(self.insert(ty, value)) } fn simplify_discriminant(&mut self, place: VnIndex) -> Option { - if let Value::Aggregate(enum_ty, variant, _) = *self.get(place) - && let AggregateTy::Def(enum_did, enum_args) = enum_ty - && let DefKind::Enum = self.tcx.def_kind(enum_did) + let enum_ty = self.ty(place); + if enum_ty.is_enum() + && let Value::Aggregate(variant, _) = self.get(place) { - let enum_ty = self.tcx.type_of(enum_did).instantiate(self.tcx, enum_args); let discr = self.ecx.discriminant_for_variant(enum_ty, variant).discard_err()?; - return Some(self.insert_scalar(discr.to_scalar(), discr.layout.ty)); + return Some(self.insert_scalar(discr.layout.ty, discr.to_scalar())); } None @@ -915,30 +986,18 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { fn try_as_place_elem( &mut self, - proj: ProjectionElem>, + ty: Ty<'tcx>, + proj: ProjectionElem, loc: Location, ) -> Option> { - Some(match proj { - ProjectionElem::Deref => ProjectionElem::Deref, - ProjectionElem::Field(idx, ty) => ProjectionElem::Field(idx, ty), - ProjectionElem::Index(idx) => { - let Some(local) = self.try_as_local(idx, loc) else { - return None; - }; + proj.try_map( + |value| { + let local = self.try_as_local(value, loc)?; self.reused_locals.insert(local); - ProjectionElem::Index(local) - } - ProjectionElem::ConstantIndex { offset, min_length, from_end } => { - ProjectionElem::ConstantIndex { offset, min_length, from_end } - } - ProjectionElem::Subslice { from, to, from_end } => { - ProjectionElem::Subslice { from, to, from_end } - } - ProjectionElem::Downcast(symbol, idx) => ProjectionElem::Downcast(symbol, idx), - ProjectionElem::OpaqueCast(idx) => ProjectionElem::OpaqueCast(idx), - ProjectionElem::Subtype(idx) => ProjectionElem::Subtype(idx), - ProjectionElem::UnwrapUnsafeBinder(ty) => ProjectionElem::UnwrapUnsafeBinder(ty), - }) + Some(local) + }, + |()| ty, + ) } fn simplify_aggregate_to_copy( @@ -952,12 +1011,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let Some(&first_field) = fields.first() else { return None; }; - let Value::Projection(copy_from_value, _) = *self.get(first_field) else { + let Value::Projection(copy_from_value, _) = self.get(first_field) else { return None; }; // All fields must correspond one-to-one and come from the same aggregate value. if fields.iter().enumerate().any(|(index, &v)| { - if let Value::Projection(pointer, ProjectionElem::Field(from_index, _)) = *self.get(v) + if let Value::Projection(pointer, ProjectionElem::Field(from_index, _)) = self.get(v) && copy_from_value == pointer && from_index.index() == index { @@ -969,7 +1028,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } let mut copy_from_local_value = copy_from_value; - if let Value::Projection(pointer, proj) = *self.get(copy_from_value) + if let Value::Projection(pointer, proj) = self.get(copy_from_value) && let ProjectionElem::Downcast(_, read_variant) = proj { if variant_index == read_variant { @@ -983,8 +1042,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // Allow introducing places with non-constant offsets, as those are still better than // reconstructing an aggregate. - if let Some(place) = self.try_as_place(copy_from_local_value, location, true) - && rvalue.ty(self.local_decls, self.tcx) == place.ty(self.local_decls, self.tcx).ty + if self.ty(copy_from_local_value) == rvalue.ty(self.local_decls, self.tcx) + && let Some(place) = self.try_as_place(copy_from_local_value, location, true) { // Avoid creating `*a = copy (*b)`, as they might be aliases resulting in overlapping assignments. // FIXME: This also avoids any kind of projection, not just derefs. We can add allowed projections. @@ -998,15 +1057,18 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { None } + #[instrument(level = "trace", skip(self), ret)] fn simplify_aggregate( &mut self, lhs: &Place<'tcx>, rvalue: &mut Rvalue<'tcx>, location: Location, ) -> Option { + let tcx = self.tcx; + let ty = rvalue.ty(self.local_decls, tcx); + let Rvalue::Aggregate(box ref kind, ref mut field_ops) = *rvalue else { bug!() }; - let tcx = self.tcx; if field_ops.is_empty() { let is_zst = match *kind { AggregateKind::Array(..) @@ -1021,87 +1083,69 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { }; if is_zst { - let ty = rvalue.ty(self.local_decls, tcx); return Some(self.insert_constant(Const::zero_sized(ty))); } } - let (mut ty, variant_index) = match *kind { - AggregateKind::Array(..) => { - assert!(!field_ops.is_empty()); - (AggregateTy::Array, FIRST_VARIANT) - } - AggregateKind::Tuple => { + let fields = self.arena.alloc_from_iter(field_ops.iter_mut().map(|op| { + self.simplify_operand(op, location) + .unwrap_or_else(|| self.new_opaque(op.ty(self.local_decls, self.tcx))) + })); + + let variant_index = match *kind { + AggregateKind::Array(..) | AggregateKind::Tuple => { assert!(!field_ops.is_empty()); - (AggregateTy::Tuple, FIRST_VARIANT) - } - AggregateKind::Closure(did, args) - | AggregateKind::CoroutineClosure(did, args) - | AggregateKind::Coroutine(did, args) => (AggregateTy::Def(did, args), FIRST_VARIANT), - AggregateKind::Adt(did, variant_index, args, _, None) => { - (AggregateTy::Def(did, args), variant_index) + FIRST_VARIANT } + AggregateKind::Closure(..) + | AggregateKind::CoroutineClosure(..) + | AggregateKind::Coroutine(..) => FIRST_VARIANT, + AggregateKind::Adt(_, variant_index, _, _, None) => variant_index, // Do not track unions. AggregateKind::Adt(_, _, _, _, Some(_)) => return None, - AggregateKind::RawPtr(pointee_ty, mtbl) => { + AggregateKind::RawPtr(..) => { assert_eq!(field_ops.len(), 2); - let data_pointer_ty = field_ops[FieldIdx::ZERO].ty(self.local_decls, self.tcx); - let output_pointer_ty = Ty::new_ptr(self.tcx, pointee_ty, mtbl); - (AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty }, FIRST_VARIANT) - } - }; - - let mut fields: Vec<_> = field_ops - .iter_mut() - .map(|op| self.simplify_operand(op, location).unwrap_or_else(|| self.new_opaque())) - .collect(); - - if let AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty } = &mut ty { - let mut was_updated = false; + let [mut pointer, metadata] = fields.try_into().unwrap(); + + // Any thin pointer of matching mutability is fine as the data pointer. + let mut was_updated = false; + while let Value::Cast { kind: CastKind::PtrToPtr, value: cast_value } = + self.get(pointer) + && let ty::RawPtr(from_pointee_ty, from_mtbl) = self.ty(cast_value).kind() + && let ty::RawPtr(_, output_mtbl) = ty.kind() + && from_mtbl == output_mtbl + && from_pointee_ty.is_sized(self.tcx, self.typing_env()) + { + pointer = cast_value; + was_updated = true; + } - // Any thin pointer of matching mutability is fine as the data pointer. - while let Value::Cast { - kind: CastKind::PtrToPtr, - value: cast_value, - from: cast_from, - to: _, - } = self.get(fields[0]) - && let ty::RawPtr(from_pointee_ty, from_mtbl) = cast_from.kind() - && let ty::RawPtr(_, output_mtbl) = output_pointer_ty.kind() - && from_mtbl == output_mtbl - && from_pointee_ty.is_sized(self.tcx, self.typing_env()) - { - fields[0] = *cast_value; - *data_pointer_ty = *cast_from; - was_updated = true; - } + if was_updated && let Some(op) = self.try_as_operand(pointer, location) { + field_ops[FieldIdx::ZERO] = op; + } - if was_updated && let Some(op) = self.try_as_operand(fields[0], location) { - field_ops[FieldIdx::ZERO] = op; + return Some(self.insert(ty, Value::RawPtr { pointer, metadata })); } - } + }; - if let AggregateTy::Array = ty - && fields.len() > 4 - { + if ty.is_array() && fields.len() > 4 { let first = fields[0]; if fields.iter().all(|&v| v == first) { let len = ty::Const::from_target_usize(self.tcx, fields.len().try_into().unwrap()); if let Some(op) = self.try_as_operand(first, location) { *rvalue = Rvalue::Repeat(op, len); } - return Some(self.insert(Value::Repeat(first, len))); + return Some(self.insert(ty, Value::Repeat(first, len))); } } - if let AggregateTy::Def(_, _) = ty - && let Some(value) = - self.simplify_aggregate_to_copy(lhs, rvalue, location, &fields, variant_index) + if let Some(value) = + self.simplify_aggregate_to_copy(lhs, rvalue, location, &fields, variant_index) { return Some(value); } - Some(self.insert(Value::Aggregate(ty, variant_index, fields))) + Some(self.insert(ty, Value::Aggregate(variant_index, fields))) } #[instrument(level = "trace", skip(self), ret)] @@ -1112,6 +1156,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { location: Location, ) -> Option { let mut arg_index = self.simplify_operand(arg_op, location)?; + let arg_ty = self.ty(arg_index); + let ret_ty = op.ty(self.tcx, arg_ty); // PtrMetadata doesn't care about *const vs *mut vs & vs &mut, // so start by removing those distinctions so we can update the `Operand` @@ -1127,21 +1173,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // we can't always know exactly what the metadata are. // To allow things like `*mut (?A, ?T)` <-> `*mut (?B, ?T)`, // it's fine to get a projection as the type. - Value::Cast { kind: CastKind::PtrToPtr, value: inner, from, to } - if self.pointers_have_same_metadata(*from, *to) => + Value::Cast { kind: CastKind::PtrToPtr, value: inner } + if self.pointers_have_same_metadata(self.ty(inner), arg_ty) => { - arg_index = *inner; + arg_index = inner; was_updated = true; continue; } // `&mut *p`, `&raw *p`, etc don't change metadata. - Value::Address { place, kind: _, provenance: _ } - if let PlaceRef { local, projection: [PlaceElem::Deref] } = - place.as_ref() - && let Some(local_index) = self.locals[local] => + Value::Address { base: AddressBase::Deref(reborrowed), projection, .. } + if projection.is_empty() => { - arg_index = local_index; + arg_index = reborrowed; was_updated = true; continue; } @@ -1157,34 +1201,30 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } let value = match (op, self.get(arg_index)) { - (UnOp::Not, Value::UnaryOp(UnOp::Not, inner)) => return Some(*inner), - (UnOp::Neg, Value::UnaryOp(UnOp::Neg, inner)) => return Some(*inner), + (UnOp::Not, Value::UnaryOp(UnOp::Not, inner)) => return Some(inner), + (UnOp::Neg, Value::UnaryOp(UnOp::Neg, inner)) => return Some(inner), (UnOp::Not, Value::BinaryOp(BinOp::Eq, lhs, rhs)) => { - Value::BinaryOp(BinOp::Ne, *lhs, *rhs) + Value::BinaryOp(BinOp::Ne, lhs, rhs) } (UnOp::Not, Value::BinaryOp(BinOp::Ne, lhs, rhs)) => { - Value::BinaryOp(BinOp::Eq, *lhs, *rhs) - } - (UnOp::PtrMetadata, Value::Aggregate(AggregateTy::RawPtr { .. }, _, fields)) => { - return Some(fields[1]); + Value::BinaryOp(BinOp::Eq, lhs, rhs) } + (UnOp::PtrMetadata, Value::RawPtr { metadata, .. }) => return Some(metadata), // We have an unsizing cast, which assigns the length to wide pointer metadata. ( UnOp::PtrMetadata, Value::Cast { kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _), - from, - to, - .. + value: inner, }, - ) if let ty::Slice(..) = to.builtin_deref(true).unwrap().kind() - && let ty::Array(_, len) = from.builtin_deref(true).unwrap().kind() => + ) if let ty::Slice(..) = arg_ty.builtin_deref(true).unwrap().kind() + && let ty::Array(_, len) = self.ty(inner).builtin_deref(true).unwrap().kind() => { return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len))); } _ => Value::UnaryOp(op, arg_index), }; - Some(self.insert(value)) + Some(self.insert(ret_ty, value)) } #[instrument(level = "trace", skip(self), ret)] @@ -1197,28 +1237,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ) -> Option { let lhs = self.simplify_operand(lhs_operand, location); let rhs = self.simplify_operand(rhs_operand, location); + // Only short-circuit options after we called `simplify_operand` // on both operands for side effect. let mut lhs = lhs?; let mut rhs = rhs?; - let lhs_ty = lhs_operand.ty(self.local_decls, self.tcx); + let lhs_ty = self.ty(lhs); // If we're comparing pointers, remove `PtrToPtr` casts if the from // types of both casts and the metadata all match. if let BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge = op && lhs_ty.is_any_ptr() - && let Value::Cast { - kind: CastKind::PtrToPtr, value: lhs_value, from: lhs_from, .. - } = self.get(lhs) - && let Value::Cast { - kind: CastKind::PtrToPtr, value: rhs_value, from: rhs_from, .. - } = self.get(rhs) - && lhs_from == rhs_from - && self.pointers_have_same_metadata(*lhs_from, lhs_ty) + && let Value::Cast { kind: CastKind::PtrToPtr, value: lhs_value } = self.get(lhs) + && let Value::Cast { kind: CastKind::PtrToPtr, value: rhs_value } = self.get(rhs) + && let lhs_from = self.ty(lhs_value) + && lhs_from == self.ty(rhs_value) + && self.pointers_have_same_metadata(lhs_from, lhs_ty) { - lhs = *lhs_value; - rhs = *rhs_value; + lhs = lhs_value; + rhs = rhs_value; if let Some(lhs_op) = self.try_as_operand(lhs, location) && let Some(rhs_op) = self.try_as_operand(rhs, location) { @@ -1230,8 +1268,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { if let Some(value) = self.simplify_binary_inner(op, lhs_ty, lhs, rhs) { return Some(value); } + let ty = op.ty(self.tcx, lhs_ty, self.ty(rhs)); let value = Value::BinaryOp(op, lhs, rhs); - Some(self.insert(value)) + Some(self.insert(ty, value)) } fn simplify_binary_inner( @@ -1323,19 +1362,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { | BinOp::Shr, Left(0), _, - ) => self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty), + ) => self.insert_scalar(lhs_ty, Scalar::from_uint(0u128, layout.size)), // Attempt to simplify `x | ALL_ONES` to `ALL_ONES`. (BinOp::BitOr, _, Left(ones)) | (BinOp::BitOr, Left(ones), _) if ones == layout.size.truncate(u128::MAX) || (layout.ty.is_bool() && ones == 1) => { - self.insert_scalar(Scalar::from_uint(ones, layout.size), lhs_ty) + self.insert_scalar(lhs_ty, Scalar::from_uint(ones, layout.size)) } // Sub/Xor with itself. (BinOp::Sub | BinOp::SubWithOverflow | BinOp::SubUnchecked | BinOp::BitXor, a, b) if a == b => { - self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty) + self.insert_scalar(lhs_ty, Scalar::from_uint(0u128, layout.size)) } // Comparison: // - if both operands can be computed as bits, just compare the bits; @@ -1349,8 +1388,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { }; if op.is_overflowing() { + let ty = Ty::new_tup(self.tcx, &[self.ty(result), self.tcx.types.bool]); let false_val = self.insert_bool(false); - Some(self.insert_tuple(vec![result, false_val])) + Some(self.insert_tuple(ty, &[result, false_val])) } else { Some(result) } @@ -1366,9 +1406,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { use CastKind::*; use rustc_middle::ty::adjustment::PointerCoercion::*; - let mut from = initial_operand.ty(self.local_decls, self.tcx); let mut kind = *initial_kind; let mut value = self.simplify_operand(initial_operand, location)?; + let mut from = self.ty(value); if from == to { return Some(value); } @@ -1376,7 +1416,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_), _) = kind { // Each reification of a generic fn may get a different pointer. // Do not try to merge them. - return Some(self.new_opaque()); + return Some(self.new_opaque(to)); } let mut was_ever_updated = false; @@ -1399,25 +1439,24 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // If a cast just casts away the metadata again, then we can get it by // casting the original thin pointer passed to `from_raw_parts` if let PtrToPtr = kind - && let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) = - self.get(value) + && let Value::RawPtr { pointer, .. } = self.get(value) && let ty::RawPtr(to_pointee, _) = to.kind() && to_pointee.is_sized(self.tcx, self.typing_env()) { - from = *data_pointer_ty; - value = fields[0]; + from = self.ty(pointer); + value = pointer; was_updated_this_iteration = true; - if *data_pointer_ty == to { - return Some(fields[0]); + if from == to { + return Some(pointer); } } // Aggregate-then-Transmute can just transmute the original field value, // so long as the bytes of a value from only from a single field. if let Transmute = kind - && let Value::Aggregate(_aggregate_ty, variant_idx, field_values) = self.get(value) + && let Value::Aggregate(variant_idx, field_values) = self.get(value) && let Some((field_idx, field_ty)) = - self.value_is_all_in_one_field(from, *variant_idx) + self.value_is_all_in_one_field(from, variant_idx) { from = field_ty; value = field_values[field_idx.as_usize()]; @@ -1428,13 +1467,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } // Various cast-then-cast cases can be simplified. - if let Value::Cast { - kind: inner_kind, - value: inner_value, - from: inner_from, - to: inner_to, - } = *self.get(value) - { + if let Value::Cast { kind: inner_kind, value: inner_value } = self.get(value) { + let inner_from = self.ty(inner_value); let new_kind = match (inner_kind, kind) { // Even if there's a narrowing cast in here that's fine, because // things like `*mut [i32] -> *mut i32 -> *const i32` and @@ -1443,9 +1477,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // PtrToPtr-then-Transmute is fine so long as the pointer cast is identity: // `*const T -> *mut T -> NonNull` is fine, but we need to check for narrowing // to skip things like `*const [i32] -> *const i32 -> NonNull`. - (PtrToPtr, Transmute) - if self.pointers_have_same_metadata(inner_from, inner_to) => - { + (PtrToPtr, Transmute) if self.pointers_have_same_metadata(inner_from, from) => { Some(Transmute) } // Similarly, for Transmute-then-PtrToPtr. Note that we need to check different @@ -1456,7 +1488,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // If would be legal to always do this, but we don't want to hide information // from the backend that it'd otherwise be able to use for optimizations. (Transmute, Transmute) - if !self.type_may_have_niche_of_interest_to_backend(inner_to) => + if !self.type_may_have_niche_of_interest_to_backend(from) => { Some(Transmute) } @@ -1485,7 +1517,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { *initial_kind = kind; } - Some(self.insert(Value::Cast { kind, value, from, to })) + Some(self.insert(to, Value::Cast { kind, value })) } fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option { @@ -1499,26 +1531,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // The length information is stored in the wide pointer. // Reborrowing copies length information from one pointer to the other. - while let Value::Address { place: borrowed, .. } = self.get(inner) - && let [PlaceElem::Deref] = borrowed.projection[..] - && let Some(borrowed) = self.locals[borrowed.local] + while let Value::Address { base: AddressBase::Deref(borrowed), projection, .. } = + self.get(inner) + && projection.is_empty() { inner = borrowed; } // We have an unsizing cast, which assigns the length to wide pointer metadata. - if let Value::Cast { kind, from, to, .. } = self.get(inner) + if let Value::Cast { kind, value: from } = self.get(inner) && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind - && let Some(from) = from.builtin_deref(true) + && let Some(from) = self.ty(from).builtin_deref(true) && let ty::Array(_, len) = from.kind() - && let Some(to) = to.builtin_deref(true) + && let Some(to) = self.ty(inner).builtin_deref(true) && let ty::Slice(..) = to.kind() { return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len))); } // Fallback: a symbolic `Len`. - Some(self.insert(Value::Len(inner))) + Some(self.insert(self.tcx.types.usize, Value::Len(inner))) } fn pointers_have_same_metadata(&self, left_ptr_ty: Ty<'tcx>, right_ptr_ty: Ty<'tcx>) -> bool { @@ -1667,9 +1699,10 @@ fn op_to_prop_const<'tcx>( None } -impl<'tcx> VnState<'_, 'tcx> { +impl<'tcx> VnState<'_, '_, 'tcx> { /// If either [`Self::try_as_constant`] as [`Self::try_as_place`] succeeds, /// returns that result as an [`Operand`]. + #[instrument(level = "trace", skip(self), ret)] fn try_as_operand(&mut self, index: VnIndex, location: Location) -> Option> { if let Some(const_) = self.try_as_constant(index) { Some(Operand::Constant(Box::new(const_))) @@ -1682,11 +1715,12 @@ impl<'tcx> VnState<'_, 'tcx> { } /// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR. + #[instrument(level = "trace", skip(self), ret)] fn try_as_constant(&mut self, index: VnIndex) -> Option> { // This was already constant in MIR, do not change it. If the constant is not // deterministic, adding an additional mention of it in MIR will not give the same value as // the former mention. - if let Value::Constant { value, disambiguator: 0 } = *self.get(index) { + if let Value::Constant { value, disambiguator: 0 } = self.get(index) { debug_assert!(value.is_deterministic()); return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value }); } @@ -1725,9 +1759,14 @@ impl<'tcx> VnState<'_, 'tcx> { let place = Place { local, projection: self.tcx.mk_place_elems(projection.as_slice()) }; return Some(place); - } else if let Value::Projection(pointer, proj) = *self.get(index) + } else if projection.last() == Some(&PlaceElem::Deref) { + // `Deref` can only be the first projection in a place. + // If we are here, we failed to find a local, and we already have a `Deref`. + // Trying to add projections will only result in an ill-formed place. + return None; + } else if let Value::Projection(pointer, proj) = self.get(index) && (allow_complex_projection || proj.is_stable_offset()) - && let Some(proj) = self.try_as_place_elem(proj, loc) + && let Some(proj) = self.try_as_place_elem(self.ty(index), proj, loc) { projection.push(proj); index = pointer; @@ -1739,25 +1778,46 @@ impl<'tcx> VnState<'_, 'tcx> { /// If there is a local which is assigned `index`, and its assignment strictly dominates `loc`, /// return it. If you used this local, add it to `reused_locals` to remove storage statements. + #[instrument(level = "trace", skip(self), ret)] fn try_as_local(&mut self, index: VnIndex, loc: Location) -> Option { - let other = self.rev_locals.get(index)?; - other - .iter() - .find(|&&other| self.ssa.assignment_dominates(&self.dominators, other, loc)) - .copied() + let ssa = self.rev_locals_ssa.get(index)?; + let non_ssa = self.rev_locals_non_ssa.entry(index).or_default(); + ssa.iter() + .chain(non_ssa.iter()) + .find(|&&(other, assign_loc)| { + self.ssa.assignment_dominates(&self.dominators, other, loc) + || (assign_loc.block == loc.block + && assign_loc.statement_index < loc.statement_index) + }) + .map(|&(other, _)| other) } } -impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> { +impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } + fn visit_basic_block_data(&mut self, block: BasicBlock, bbdata: &mut BasicBlockData<'tcx>) { + self.rev_locals_non_ssa.clear(); + for local in self.locals.indices() { + if !self.ssa.is_ssa(local) { + let current = self.locals[local]; + let new = self.new_opaque(self.ty(current)); + self.locals[local] = new; + self.rev_locals_non_ssa + .entry(new) + .or_default() + .push((local, Location { block, statement_index: 0 })); + } + } + self.super_basic_block_data(block, bbdata); + } + fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { self.simplify_place_projection(place, location); - if context.is_mutating_use() && !place.projection.is_empty() { - // Non-local mutation maybe invalidate deref. - self.invalidate_derefs(); + if context.is_mutating_use() { + self.discard_place(*place); } self.super_place(place, context, location); } @@ -1767,46 +1827,48 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> { self.super_operand(operand, location); } - fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) { - if let StatementKind::Assign(box (ref mut lhs, ref mut rvalue)) = stmt.kind { - self.simplify_place_projection(lhs, location); - - let value = self.simplify_rvalue(lhs, rvalue, location); - let value = if let Some(local) = lhs.as_local() - && self.ssa.is_ssa(local) - // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark - // `local` as reusable if we have an exact type match. - && self.local_decls[local].ty == rvalue.ty(self.local_decls, self.tcx) + fn visit_assign( + &mut self, + lhs: &mut Place<'tcx>, + rvalue: &mut Rvalue<'tcx>, + location: Location, + ) { + self.simplify_place_projection(lhs, location); + + let value = self.simplify_rvalue(lhs, rvalue, location); + if let Some(value) = value { + if let Some(const_) = self.try_as_constant(value) { + *rvalue = Rvalue::Use(Operand::Constant(Box::new(const_))); + } else if let Some(place) = self.try_as_place(value, location, false) + && *rvalue != Rvalue::Use(Operand::Move(place)) + && *rvalue != Rvalue::Use(Operand::Copy(place)) { - let value = value.unwrap_or_else(|| self.new_opaque()); - self.assign(local, value); - Some(value) - } else { - value - }; - if let Some(value) = value { - if let Some(const_) = self.try_as_constant(value) { - *rvalue = Rvalue::Use(Operand::Constant(Box::new(const_))); - } else if let Some(place) = self.try_as_place(value, location, false) - && *rvalue != Rvalue::Use(Operand::Move(place)) - && *rvalue != Rvalue::Use(Operand::Copy(place)) - { - *rvalue = Rvalue::Use(Operand::Copy(place)); - self.reused_locals.insert(place.local); - } + *rvalue = Rvalue::Use(Operand::Copy(place)); + self.reused_locals.insert(place.local); } } - self.super_statement(stmt, location); + + self.discard_place(*lhs); + + if let Some(local) = lhs.as_local() + && let rvalue_ty = rvalue.ty(self.local_decls, self.tcx) + // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark + // `local` as reusable if we have an exact type match. + && self.local_decls[local].ty == rvalue_ty + { + let value = value.unwrap_or_else(|| self.new_opaque(rvalue_ty)); + self.assign(local, value, location); + } } fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { - if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator { - if let Some(local) = destination.as_local() - && self.ssa.is_ssa(local) - { - let opaque = self.new_opaque(); - self.assign(local, opaque); - } + self.super_terminator(terminator, location); + if let Terminator { kind: TerminatorKind::Call { destination, .. }, .. } = terminator + && let Some(local) = destination.as_local() + { + let ty = self.local_decls[local].ty; + let opaque = self.new_opaque(ty); + self.assign(local, opaque, location); } // Function calls and ASM may invalidate (nested) derefs. We must handle them carefully. // Currently, only preserving derefs for trivial terminators like SwitchInt and Goto. @@ -1817,7 +1879,6 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> { if !safe_to_preserve_derefs { self.invalidate_derefs(); } - self.super_terminator(terminator, location); } } diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 03b6f9b7ff3b8..ec84e219a4300 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -225,6 +225,9 @@ impl SsaVisitor<'_, '_> { impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> { fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) { + if ctxt.may_observe_address() { + self.borrowed_locals.insert(local); + } match ctxt { PlaceContext::MutatingUse(MutatingUseContext::Projection) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(), @@ -237,7 +240,6 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> { PlaceContext::NonMutatingUse( NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::FakeBorrow, ) => { - self.borrowed_locals.insert(local); self.check_dominates(local, loc); self.direct_uses[local] += 1; } diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map index 5f7e4ce58e97b..fcfa1dfc5be90 100644 --- a/tests/coverage/closure.cov-map +++ b/tests/coverage/closure.cov-map @@ -74,24 +74,22 @@ Number of file 0 mappings: 66 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) Highest counter ID seen: c1 -Function name: closure::main::{closure#0} -Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 28, 05, 00, 06, 01, 01, 0d, 00, 1a, 01, 00, 1d, 00, 1e, 01, 01, 0c, 00, 14, 05, 00, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 00, 17, 01, 00, 18, 00, 20, 01, 01, 05, 00, 06] +Function name: closure::main::{closure#0} (unused) +Raw bytes (49): 0x[01, 01, 00, 09, 00, 28, 05, 00, 06, 00, 01, 0d, 00, 1a, 00, 00, 1d, 00, 1e, 00, 01, 0c, 00, 14, 00, 00, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 00, 17, 00, 00, 18, 00, 20, 00, 01, 05, 00, 06] Number of files: 1 - file 0 => $DIR/closure.rs -Number of expressions: 1 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +Number of expressions: 0 Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 40, 5) to (start + 0, 6) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 26) -- Code(Counter(0)) at (prev + 0, 29) to (start + 0, 30) -- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 20) -- Code(Counter(1)) at (prev + 0, 21) to (start + 2, 10) -- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 23) -- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 32) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -Highest counter ID seen: c1 +- Code(Zero) at (prev + 40, 5) to (start + 0, 6) +- Code(Zero) at (prev + 1, 13) to (start + 0, 26) +- Code(Zero) at (prev + 0, 29) to (start + 0, 30) +- Code(Zero) at (prev + 1, 12) to (start + 0, 20) +- Code(Zero) at (prev + 0, 21) to (start + 2, 10) +- Code(Zero) at (prev + 2, 9) to (start + 0, 10) +- Code(Zero) at (prev + 1, 9) to (start + 0, 23) +- Code(Zero) at (prev + 0, 24) to (start + 0, 32) +- Code(Zero) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: (none) Function name: closure::main::{closure#10} (unused) Raw bytes (25): 0x[01, 01, 00, 04, 00, 9b, 01, 07, 00, 08, 00, 00, 09, 00, 11, 00, 00, 12, 00, 1e, 00, 00, 20, 00, 21] @@ -197,24 +195,22 @@ Number of file 0 mappings: 7 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10) Highest counter ID seen: c1 -Function name: closure::main::{closure#18} -Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 19, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e] +Function name: closure::main::{closure#18} (unused) +Raw bytes (49): 0x[01, 01, 00, 09, 00, 19, 0d, 00, 0e, 00, 01, 15, 00, 22, 00, 00, 25, 00, 26, 00, 01, 14, 00, 1c, 00, 00, 1d, 02, 12, 00, 02, 11, 00, 12, 00, 01, 11, 00, 1f, 00, 00, 20, 00, 28, 00, 01, 0d, 00, 0e] Number of files: 1 - file 0 => $DIR/closure.rs -Number of expressions: 1 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +Number of expressions: 0 Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 25, 13) to (start + 0, 14) -- Code(Counter(0)) at (prev + 1, 21) to (start + 0, 34) -- Code(Counter(0)) at (prev + 0, 37) to (start + 0, 38) -- Code(Counter(0)) at (prev + 1, 20) to (start + 0, 28) -- Code(Counter(1)) at (prev + 0, 29) to (start + 2, 18) -- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18) - = (c0 - c1) -- Code(Counter(0)) at (prev + 1, 17) to (start + 0, 31) -- Code(Counter(0)) at (prev + 0, 32) to (start + 0, 40) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14) -Highest counter ID seen: c1 +- Code(Zero) at (prev + 25, 13) to (start + 0, 14) +- Code(Zero) at (prev + 1, 21) to (start + 0, 34) +- Code(Zero) at (prev + 0, 37) to (start + 0, 38) +- Code(Zero) at (prev + 1, 20) to (start + 0, 28) +- Code(Zero) at (prev + 0, 29) to (start + 2, 18) +- Code(Zero) at (prev + 2, 17) to (start + 0, 18) +- Code(Zero) at (prev + 1, 17) to (start + 0, 31) +- Code(Zero) at (prev + 0, 32) to (start + 0, 40) +- Code(Zero) at (prev + 1, 13) to (start + 0, 14) +Highest counter ID seen: (none) Function name: closure::main::{closure#19} Raw bytes (51): 0x[01, 01, 01, 01, 05, 09, 01, 43, 0d, 00, 0e, 01, 01, 15, 00, 22, 01, 00, 25, 00, 26, 01, 01, 14, 00, 1c, 05, 00, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 00, 1f, 01, 00, 20, 00, 28, 01, 01, 0d, 00, 0e] diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map index 29d9604085ede..0047d52c89fab 100644 --- a/tests/coverage/conditions.cov-map +++ b/tests/coverage/conditions.cov-map @@ -1,95 +1,75 @@ Function name: conditions::main -Raw bytes (656): 0x[01, 01, 57, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 9f, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 9f, 01, 15, 0d, 11, 19, 45, 19, 97, 01, 45, 49, 97, 01, 4d, 45, 49, 19, 93, 01, 97, 01, 4d, 45, 49, 9f, 01, 9b, 02, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, 9b, 02, 1d, 15, 19, 21, 39, 21, e3, 01, 39, 3d, e3, 01, 41, 39, 3d, 21, df, 01, e3, 01, 41, 39, 3d, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 9b, 02, d7, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, d7, 02, 25, 1d, 21, 29, 2d, 29, cf, 02, 2d, 31, cf, 02, 35, 2d, 31, 29, cb, 02, cf, 02, 35, 2d, 31, d7, 02, db, 02, 1d, 21, 25, 29, 53, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 2a, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 9f, 01, 01, 0d, 00, 1a, 9f, 01, 00, 1d, 00, 1e, 9f, 01, 01, 0c, 00, 10, 9f, 01, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 9f, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 72, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 7a, 00, 21, 00, 2e, 7e, 00, 32, 00, 40, 93, 01, 00, 41, 02, 0e, 8e, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 9a, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, 9b, 02, 02, 09, 00, 16, 9b, 02, 00, 19, 00, 1a, 9b, 02, 01, 08, 00, 0c, 9b, 02, 00, 0d, 02, 06, 00, 02, 05, 00, 06, d7, 02, 02, 09, 00, 0a, 9b, 02, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, be, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, c6, 01, 00, 1d, 00, 2a, ca, 01, 00, 2e, 00, 3c, df, 01, 00, 3d, 02, 0a, da, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, 96, 02, 02, 0d, 00, 20, 96, 02, 00, 23, 00, 2c, 96, 02, 01, 09, 00, 11, 96, 02, 00, 12, 00, 1b, 96, 02, 01, 09, 00, 0f, db, 02, 03, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, aa, 02, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, b2, 02, 00, 1d, 00, 2a, b6, 02, 00, 2e, 00, 3c, cb, 02, 00, 3d, 02, 0a, c6, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, d2, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] +Raw bytes (595): 0x[01, 01, 43, 05, 09, 01, 05, 09, 51, 09, 13, 51, 55, 01, 03, 03, 0d, 11, 49, 11, 27, 49, 4d, 03, 63, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 63, 15, 0d, 11, 19, 41, 19, 5b, 41, 45, 63, cb, 01, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, cb, 01, 1d, 15, 19, 21, 39, 21, 93, 01, 39, 3d, cb, 01, 87, 02, 15, 19, 1d, 21, cb, 01, 87, 02, 15, 19, 1d, 21, cb, 01, 87, 02, 15, 19, 1d, 21, cb, 01, 87, 02, 15, 19, 1d, 21, cb, 01, 87, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, 87, 02, 25, 1d, 21, 29, 2d, 29, ff, 01, 2d, 31, ff, 01, 35, 2d, 31, 29, fb, 01, ff, 01, 35, 2d, 31, 87, 02, 8b, 02, 1d, 21, 25, 29, 53, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 09, 00, 3d, 02, 0a, 00, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 16, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 1e, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 11, 00, 3d, 02, 0a, 00, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 2a, 02, 09, 00, 0f, 63, 03, 08, 00, 0c, 63, 01, 0d, 00, 1a, 63, 00, 1d, 00, 1e, 63, 01, 0c, 00, 10, 63, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 63, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 4a, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 52, 00, 21, 00, 2e, 56, 00, 32, 00, 40, 19, 00, 41, 02, 0e, 00, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 5e, 02, 0d, 00, 13, 00, 02, 05, 00, 06, cb, 01, 02, 09, 00, 16, cb, 01, 00, 19, 00, 1a, cb, 01, 01, 08, 00, 0c, cb, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 87, 02, 02, 09, 00, 0a, cb, 01, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, 82, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, 8a, 01, 00, 1d, 00, 2a, 8e, 01, 00, 2e, 00, 3c, 21, 00, 3d, 02, 0a, 00, 02, 09, 00, 0a, 21, 01, 09, 00, 17, c6, 01, 02, 0d, 00, 20, c6, 01, 00, 23, 00, 2c, c6, 01, 01, 09, 00, 11, c6, 01, 00, 12, 00, 1b, c6, 01, 01, 09, 00, 0f, 8b, 02, 03, 09, 00, 0a, 87, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, da, 01, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, e2, 01, 00, 1d, 00, 2a, e6, 01, 00, 2e, 00, 3c, fb, 01, 00, 3d, 02, 0a, f6, 01, 02, 09, 00, 0a, 29, 01, 09, 00, 17, 82, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/conditions.rs -Number of expressions: 87 +Number of expressions: 67 - expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(0), rhs = Counter(1) -- expression 2 operands: lhs = Counter(2), rhs = Counter(23) -- expression 3 operands: lhs = Counter(2), rhs = Expression(9, Add) -- expression 4 operands: lhs = Counter(23), rhs = Counter(24) -- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(25) -- expression 6 operands: lhs = Counter(23), rhs = Counter(24) -- expression 7 operands: lhs = Counter(2), rhs = Expression(8, Add) -- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(25) -- expression 9 operands: lhs = Counter(23), rhs = Counter(24) -- expression 10 operands: lhs = Counter(0), rhs = Expression(0, Add) -- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(3) -- expression 12 operands: lhs = Counter(4), rhs = Counter(20) -- expression 13 operands: lhs = Counter(4), rhs = Expression(19, Add) -- expression 14 operands: lhs = Counter(20), rhs = Counter(21) -- expression 15 operands: lhs = Expression(19, Add), rhs = Counter(22) -- expression 16 operands: lhs = Counter(20), rhs = Counter(21) -- expression 17 operands: lhs = Counter(4), rhs = Expression(18, Add) -- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(22) -- expression 19 operands: lhs = Counter(20), rhs = Counter(21) -- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(39, Add) -- expression 21 operands: lhs = Counter(3), rhs = Counter(4) -- expression 22 operands: lhs = Counter(3), rhs = Counter(4) -- expression 23 operands: lhs = Counter(3), rhs = Counter(4) +- expression 2 operands: lhs = Counter(2), rhs = Counter(20) +- expression 3 operands: lhs = Counter(2), rhs = Expression(4, Add) +- expression 4 operands: lhs = Counter(20), rhs = Counter(21) +- expression 5 operands: lhs = Counter(0), rhs = Expression(0, Add) +- expression 6 operands: lhs = Expression(0, Add), rhs = Counter(3) +- expression 7 operands: lhs = Counter(4), rhs = Counter(18) +- expression 8 operands: lhs = Counter(4), rhs = Expression(9, Add) +- expression 9 operands: lhs = Counter(18), rhs = Counter(19) +- expression 10 operands: lhs = Expression(0, Add), rhs = Expression(24, Add) +- expression 11 operands: lhs = Counter(3), rhs = Counter(4) +- expression 12 operands: lhs = Counter(3), rhs = Counter(4) +- expression 13 operands: lhs = Counter(3), rhs = Counter(4) +- expression 14 operands: lhs = Counter(3), rhs = Counter(4) +- expression 15 operands: lhs = Counter(3), rhs = Counter(4) +- expression 16 operands: lhs = Counter(3), rhs = Counter(4) +- expression 17 operands: lhs = Counter(3), rhs = Counter(4) +- expression 18 operands: lhs = Expression(24, Add), rhs = Counter(5) +- expression 19 operands: lhs = Counter(3), rhs = Counter(4) +- expression 20 operands: lhs = Counter(6), rhs = Counter(16) +- expression 21 operands: lhs = Counter(6), rhs = Expression(22, Add) +- expression 22 operands: lhs = Counter(16), rhs = Counter(17) +- expression 23 operands: lhs = Expression(24, Add), rhs = Expression(50, Add) - expression 24 operands: lhs = Counter(3), rhs = Counter(4) -- expression 25 operands: lhs = Counter(3), rhs = Counter(4) -- expression 26 operands: lhs = Counter(3), rhs = Counter(4) -- expression 27 operands: lhs = Counter(3), rhs = Counter(4) -- expression 28 operands: lhs = Expression(39, Add), rhs = Counter(5) -- expression 29 operands: lhs = Counter(3), rhs = Counter(4) -- expression 30 operands: lhs = Counter(6), rhs = Counter(17) -- expression 31 operands: lhs = Counter(6), rhs = Expression(37, Add) -- expression 32 operands: lhs = Counter(17), rhs = Counter(18) -- expression 33 operands: lhs = Expression(37, Add), rhs = Counter(19) -- expression 34 operands: lhs = Counter(17), rhs = Counter(18) -- expression 35 operands: lhs = Counter(6), rhs = Expression(36, Add) -- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(19) -- expression 37 operands: lhs = Counter(17), rhs = Counter(18) -- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(70, Add) -- expression 39 operands: lhs = Counter(3), rhs = Counter(4) -- expression 40 operands: lhs = Counter(5), rhs = Counter(6) +- expression 25 operands: lhs = Counter(5), rhs = Counter(6) +- expression 26 operands: lhs = Counter(5), rhs = Counter(6) +- expression 27 operands: lhs = Counter(5), rhs = Counter(6) +- expression 28 operands: lhs = Counter(5), rhs = Counter(6) +- expression 29 operands: lhs = Counter(5), rhs = Counter(6) +- expression 30 operands: lhs = Counter(7), rhs = Counter(8) +- expression 31 operands: lhs = Counter(5), rhs = Counter(6) +- expression 32 operands: lhs = Expression(50, Add), rhs = Counter(7) +- expression 33 operands: lhs = Counter(5), rhs = Counter(6) +- expression 34 operands: lhs = Counter(8), rhs = Counter(14) +- expression 35 operands: lhs = Counter(8), rhs = Expression(36, Add) +- expression 36 operands: lhs = Counter(14), rhs = Counter(15) +- expression 37 operands: lhs = Expression(50, Add), rhs = Expression(65, Add) +- expression 38 operands: lhs = Counter(5), rhs = Counter(6) +- expression 39 operands: lhs = Counter(7), rhs = Counter(8) +- expression 40 operands: lhs = Expression(50, Add), rhs = Expression(65, Add) - expression 41 operands: lhs = Counter(5), rhs = Counter(6) -- expression 42 operands: lhs = Counter(5), rhs = Counter(6) -- expression 43 operands: lhs = Counter(5), rhs = Counter(6) +- expression 42 operands: lhs = Counter(7), rhs = Counter(8) +- expression 43 operands: lhs = Expression(50, Add), rhs = Expression(65, Add) - expression 44 operands: lhs = Counter(5), rhs = Counter(6) - expression 45 operands: lhs = Counter(7), rhs = Counter(8) -- expression 46 operands: lhs = Counter(5), rhs = Counter(6) -- expression 47 operands: lhs = Expression(70, Add), rhs = Counter(7) -- expression 48 operands: lhs = Counter(5), rhs = Counter(6) -- expression 49 operands: lhs = Counter(8), rhs = Counter(14) -- expression 50 operands: lhs = Counter(8), rhs = Expression(56, Add) -- expression 51 operands: lhs = Counter(14), rhs = Counter(15) -- expression 52 operands: lhs = Expression(56, Add), rhs = Counter(16) -- expression 53 operands: lhs = Counter(14), rhs = Counter(15) -- expression 54 operands: lhs = Counter(8), rhs = Expression(55, Add) -- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(16) -- expression 56 operands: lhs = Counter(14), rhs = Counter(15) -- expression 57 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) -- expression 58 operands: lhs = Counter(5), rhs = Counter(6) -- expression 59 operands: lhs = Counter(7), rhs = Counter(8) -- expression 60 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) -- expression 61 operands: lhs = Counter(5), rhs = Counter(6) -- expression 62 operands: lhs = Counter(7), rhs = Counter(8) -- expression 63 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) -- expression 64 operands: lhs = Counter(5), rhs = Counter(6) +- expression 46 operands: lhs = Expression(50, Add), rhs = Expression(65, Add) +- expression 47 operands: lhs = Counter(5), rhs = Counter(6) +- expression 48 operands: lhs = Counter(7), rhs = Counter(8) +- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(65, Add) +- expression 50 operands: lhs = Counter(5), rhs = Counter(6) +- expression 51 operands: lhs = Counter(7), rhs = Counter(8) +- expression 52 operands: lhs = Counter(9), rhs = Counter(10) +- expression 53 operands: lhs = Counter(7), rhs = Counter(8) +- expression 54 operands: lhs = Expression(65, Add), rhs = Counter(9) +- expression 55 operands: lhs = Counter(7), rhs = Counter(8) +- expression 56 operands: lhs = Counter(10), rhs = Counter(11) +- expression 57 operands: lhs = Counter(10), rhs = Expression(63, Add) +- expression 58 operands: lhs = Counter(11), rhs = Counter(12) +- expression 59 operands: lhs = Expression(63, Add), rhs = Counter(13) +- expression 60 operands: lhs = Counter(11), rhs = Counter(12) +- expression 61 operands: lhs = Counter(10), rhs = Expression(62, Add) +- expression 62 operands: lhs = Expression(63, Add), rhs = Counter(13) +- expression 63 operands: lhs = Counter(11), rhs = Counter(12) +- expression 64 operands: lhs = Expression(65, Add), rhs = Expression(66, Add) - expression 65 operands: lhs = Counter(7), rhs = Counter(8) -- expression 66 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) -- expression 67 operands: lhs = Counter(5), rhs = Counter(6) -- expression 68 operands: lhs = Counter(7), rhs = Counter(8) -- expression 69 operands: lhs = Expression(70, Add), rhs = Expression(85, Add) -- expression 70 operands: lhs = Counter(5), rhs = Counter(6) -- expression 71 operands: lhs = Counter(7), rhs = Counter(8) -- expression 72 operands: lhs = Counter(9), rhs = Counter(10) -- expression 73 operands: lhs = Counter(7), rhs = Counter(8) -- expression 74 operands: lhs = Expression(85, Add), rhs = Counter(9) -- expression 75 operands: lhs = Counter(7), rhs = Counter(8) -- expression 76 operands: lhs = Counter(10), rhs = Counter(11) -- expression 77 operands: lhs = Counter(10), rhs = Expression(83, Add) -- expression 78 operands: lhs = Counter(11), rhs = Counter(12) -- expression 79 operands: lhs = Expression(83, Add), rhs = Counter(13) -- expression 80 operands: lhs = Counter(11), rhs = Counter(12) -- expression 81 operands: lhs = Counter(10), rhs = Expression(82, Add) -- expression 82 operands: lhs = Expression(83, Add), rhs = Counter(13) -- expression 83 operands: lhs = Counter(11), rhs = Counter(12) -- expression 84 operands: lhs = Expression(85, Add), rhs = Expression(86, Add) -- expression 85 operands: lhs = Counter(7), rhs = Counter(8) -- expression 86 operands: lhs = Counter(9), rhs = Counter(10) +- expression 66 operands: lhs = Counter(9), rhs = Counter(10) Number of file 0 mappings: 83 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22) @@ -106,16 +86,14 @@ Number of file 0 mappings: 83 = (c0 - c1) - Code(Counter(2)) at (prev + 1, 12) to (start + 0, 25) - Code(Expression(2, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (c2 - c23) + = (c2 - c20) - Code(Expression(3, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (c2 - (c23 + c24)) -- Code(Expression(8, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c23 + c24) + c25) -- Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c2 - ((c23 + c24) + c25)) + = (c2 - (c20 + c21)) +- Code(Counter(2)) at (prev + 0, 61) to (start + 2, 10) +- Code(Zero) at (prev + 2, 9) to (start + 0, 10) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 23) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 18) -- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15) +- Code(Expression(5, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - (c1 + c2)) - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 22) = (c1 + c2) @@ -129,103 +107,97 @@ Number of file 0 mappings: 83 - Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21) = (c1 + c2) - Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6) -- Code(Expression(11, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(6, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c1 + c2) - c3) - Code(Counter(4)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(12, Sub)) at (prev + 0, 29) to (start + 0, 42) - = (c4 - c20) -- Code(Expression(13, Sub)) at (prev + 0, 46) to (start + 0, 60) - = (c4 - (c20 + c21)) -- Code(Expression(18, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c20 + c21) + c22) -- Code(Expression(17, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c4 - ((c20 + c21) + c22)) +- Code(Expression(7, Sub)) at (prev + 0, 29) to (start + 0, 42) + = (c4 - c18) +- Code(Expression(8, Sub)) at (prev + 0, 46) to (start + 0, 60) + = (c4 - (c18 + c19)) +- Code(Counter(4)) at (prev + 0, 61) to (start + 2, 10) +- Code(Zero) at (prev + 2, 9) to (start + 0, 10) - Code(Counter(4)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 0, 15) +- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15) = ((c1 + c2) - (c3 + c4)) -- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12) +- Code(Expression(24, Add)) at (prev + 3, 8) to (start + 0, 12) = (c3 + c4) -- Code(Expression(39, Add)) at (prev + 1, 13) to (start + 0, 26) +- Code(Expression(24, Add)) at (prev + 1, 13) to (start + 0, 26) = (c3 + c4) -- Code(Expression(39, Add)) at (prev + 0, 29) to (start + 0, 30) +- Code(Expression(24, Add)) at (prev + 0, 29) to (start + 0, 30) = (c3 + c4) -- Code(Expression(39, Add)) at (prev + 1, 12) to (start + 0, 16) +- Code(Expression(24, Add)) at (prev + 1, 12) to (start + 0, 16) = (c3 + c4) -- Code(Expression(39, Add)) at (prev + 0, 17) to (start + 2, 10) +- Code(Expression(24, Add)) at (prev + 0, 17) to (start + 2, 10) = (c3 + c4) - Code(Zero) at (prev + 2, 9) to (start + 0, 10) -- Code(Expression(39, Add)) at (prev + 2, 12) to (start + 0, 25) +- Code(Expression(24, Add)) at (prev + 2, 12) to (start + 0, 25) = (c3 + c4) - Code(Counter(5)) at (prev + 0, 26) to (start + 2, 10) -- Code(Expression(28, Sub)) at (prev + 4, 17) to (start + 0, 30) +- Code(Expression(18, Sub)) at (prev + 4, 17) to (start + 0, 30) = ((c3 + c4) - c5) - Code(Counter(6)) at (prev + 1, 16) to (start + 0, 29) -- Code(Expression(30, Sub)) at (prev + 0, 33) to (start + 0, 46) - = (c6 - c17) -- Code(Expression(31, Sub)) at (prev + 0, 50) to (start + 0, 64) - = (c6 - (c17 + c18)) -- Code(Expression(36, Add)) at (prev + 0, 65) to (start + 2, 14) - = ((c17 + c18) + c19) -- Code(Expression(35, Sub)) at (prev + 2, 13) to (start + 0, 14) - = (c6 - ((c17 + c18) + c19)) +- Code(Expression(20, Sub)) at (prev + 0, 33) to (start + 0, 46) + = (c6 - c16) +- Code(Expression(21, Sub)) at (prev + 0, 50) to (start + 0, 64) + = (c6 - (c16 + c17)) +- Code(Counter(6)) at (prev + 0, 65) to (start + 2, 14) +- Code(Zero) at (prev + 2, 13) to (start + 0, 14) - Code(Counter(6)) at (prev + 1, 13) to (start + 0, 27) -- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 19) +- Code(Expression(23, Sub)) at (prev + 2, 13) to (start + 0, 19) = ((c3 + c4) - (c5 + c6)) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(70, Add)) at (prev + 2, 9) to (start + 0, 22) +- Code(Expression(50, Add)) at (prev + 2, 9) to (start + 0, 22) = (c5 + c6) -- Code(Expression(70, Add)) at (prev + 0, 25) to (start + 0, 26) +- Code(Expression(50, Add)) at (prev + 0, 25) to (start + 0, 26) = (c5 + c6) -- Code(Expression(70, Add)) at (prev + 1, 8) to (start + 0, 12) +- Code(Expression(50, Add)) at (prev + 1, 8) to (start + 0, 12) = (c5 + c6) -- Code(Expression(70, Add)) at (prev + 0, 13) to (start + 2, 6) +- Code(Expression(50, Add)) at (prev + 0, 13) to (start + 2, 6) = (c5 + c6) - Code(Zero) at (prev + 2, 5) to (start + 0, 6) -- Code(Expression(85, Add)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(65, Add)) at (prev + 2, 9) to (start + 0, 10) = (c7 + c8) -- Code(Expression(70, Add)) at (prev + 0, 16) to (start + 0, 29) +- Code(Expression(50, Add)) at (prev + 0, 16) to (start + 0, 29) = (c5 + c6) - Code(Counter(7)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(47, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(32, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c5 + c6) - c7) - Code(Counter(8)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(49, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(34, Sub)) at (prev + 0, 29) to (start + 0, 42) = (c8 - c14) -- Code(Expression(50, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(35, Sub)) at (prev + 0, 46) to (start + 0, 60) = (c8 - (c14 + c15)) -- Code(Expression(55, Add)) at (prev + 0, 61) to (start + 2, 10) - = ((c14 + c15) + c16) -- Code(Expression(54, Sub)) at (prev + 2, 9) to (start + 0, 10) - = (c8 - ((c14 + c15) + c16)) +- Code(Counter(8)) at (prev + 0, 61) to (start + 2, 10) +- Code(Zero) at (prev + 2, 9) to (start + 0, 10) - Code(Counter(8)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(69, Sub)) at (prev + 2, 13) to (start + 0, 32) +- Code(Expression(49, Sub)) at (prev + 2, 13) to (start + 0, 32) = ((c5 + c6) - (c7 + c8)) -- Code(Expression(69, Sub)) at (prev + 0, 35) to (start + 0, 44) +- Code(Expression(49, Sub)) at (prev + 0, 35) to (start + 0, 44) = ((c5 + c6) - (c7 + c8)) -- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 17) +- Code(Expression(49, Sub)) at (prev + 1, 9) to (start + 0, 17) = ((c5 + c6) - (c7 + c8)) -- Code(Expression(69, Sub)) at (prev + 0, 18) to (start + 0, 27) +- Code(Expression(49, Sub)) at (prev + 0, 18) to (start + 0, 27) = ((c5 + c6) - (c7 + c8)) -- Code(Expression(69, Sub)) at (prev + 1, 9) to (start + 0, 15) +- Code(Expression(49, Sub)) at (prev + 1, 9) to (start + 0, 15) = ((c5 + c6) - (c7 + c8)) -- Code(Expression(86, Add)) at (prev + 3, 9) to (start + 0, 10) +- Code(Expression(66, Add)) at (prev + 3, 9) to (start + 0, 10) = (c9 + c10) -- Code(Expression(85, Add)) at (prev + 0, 16) to (start + 0, 29) +- Code(Expression(65, Add)) at (prev + 0, 16) to (start + 0, 29) = (c7 + c8) - Code(Counter(9)) at (prev + 0, 30) to (start + 2, 6) -- Code(Expression(74, Sub)) at (prev + 2, 15) to (start + 0, 28) +- Code(Expression(54, Sub)) at (prev + 2, 15) to (start + 0, 28) = ((c7 + c8) - c9) - Code(Counter(10)) at (prev + 1, 12) to (start + 0, 25) -- Code(Expression(76, Sub)) at (prev + 0, 29) to (start + 0, 42) +- Code(Expression(56, Sub)) at (prev + 0, 29) to (start + 0, 42) = (c10 - c11) -- Code(Expression(77, Sub)) at (prev + 0, 46) to (start + 0, 60) +- Code(Expression(57, Sub)) at (prev + 0, 46) to (start + 0, 60) = (c10 - (c11 + c12)) -- Code(Expression(82, Add)) at (prev + 0, 61) to (start + 2, 10) +- Code(Expression(62, Add)) at (prev + 0, 61) to (start + 2, 10) = ((c11 + c12) + c13) -- Code(Expression(81, Sub)) at (prev + 2, 9) to (start + 0, 10) +- Code(Expression(61, Sub)) at (prev + 2, 9) to (start + 0, 10) = (c10 - ((c11 + c12) + c13)) - Code(Counter(10)) at (prev + 1, 9) to (start + 0, 23) -- Code(Expression(84, Sub)) at (prev + 2, 9) to (start + 0, 15) +- Code(Expression(64, Sub)) at (prev + 2, 9) to (start + 0, 15) = ((c7 + c8) - (c9 + c10)) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) Highest counter ID seen: c10 diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map index d1d751ff24b86..e42b5591c0fb3 100644 --- a/tests/coverage/issue-83601.cov-map +++ b/tests/coverage/issue-83601.cov-map @@ -1,30 +1,22 @@ Function name: issue_83601::main -Raw bytes (76): 0x[01, 01, 01, 05, 09, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 01, 00, 02] +Raw bytes (74): 0x[01, 01, 00, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-83601.rs -Number of expressions: 1 -- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 0 Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) - Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) -- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2) - = (c1 - c2) -Highest counter ID seen: c1 +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) +Highest counter ID seen: c0 diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index 2b643ea599ed0..e5bb1afdcc263 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -73,20 +73,20 @@ Number of file 0 mappings: 4 Highest counter ID seen: c0 Function name: issue_84561::test3 -Raw bytes (409): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 02, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 00, 0c, 09, 00, 0f, 00, 15, 09, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 00, 10, 0d, 00, 13, 00, 2e, 0d, 02, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 00, 0c, 0d, 00, 0f, 00, 15, 0d, 01, 05, 00, 0f, 0d, 04, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 00, 0f, 1d, 02, 0c, 00, 13, 21, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (409): 0x[01, 01, 0a, 01, 05, 01, 09, 01, 0d, 11, 15, 1d, 21, 19, 1d, 19, 1d, 19, 1d, 27, 25, 1d, 21, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 02, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 01, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 05, 00, 0f, 01, 04, 05, 00, 0f, 01, 04, 05, 00, 0f, 01, 04, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 04, 08, 00, 0f, 05, 01, 09, 00, 13, 02, 05, 09, 00, 13, 01, 05, 08, 00, 0f, 09, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 01, 03, 05, 00, 0f, 01, 01, 0c, 00, 13, 0d, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 11, 04, 05, 00, 0f, 11, 02, 0c, 00, 13, 15, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 19, 01, 0c, 00, 13, 1d, 01, 0d, 00, 17, 1d, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 21, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 25, 02, 05, 00, 0f, 25, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 10 -- expression 0 operands: lhs = Counter(3), rhs = Counter(4) -- expression 1 operands: lhs = Counter(3), rhs = Counter(5) -- expression 2 operands: lhs = Counter(3), rhs = Counter(6) -- expression 3 operands: lhs = Counter(7), rhs = Counter(8) -- expression 4 operands: lhs = Counter(10), rhs = Counter(11) -- expression 5 operands: lhs = Counter(9), rhs = Counter(10) -- expression 6 operands: lhs = Counter(9), rhs = Counter(10) -- expression 7 operands: lhs = Counter(9), rhs = Counter(10) -- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12) -- expression 9 operands: lhs = Counter(10), rhs = Counter(11) +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(0), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Counter(4), rhs = Counter(5) +- expression 4 operands: lhs = Counter(7), rhs = Counter(8) +- expression 5 operands: lhs = Counter(6), rhs = Counter(7) +- expression 6 operands: lhs = Counter(6), rhs = Counter(7) +- expression 7 operands: lhs = Counter(6), rhs = Counter(7) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(9) +- expression 9 operands: lhs = Counter(7), rhs = Counter(8) Number of file 0 mappings: 77 - Code(Counter(0)) at (prev + 8, 1) to (start + 0, 11) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) @@ -94,85 +94,85 @@ Number of file 0 mappings: 77 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) - Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) -- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 12) -- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) - Code(Zero) at (prev + 0, 32) to (start + 0, 48) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) - Code(Zero) at (prev + 0, 32) to (start + 0, 36) - Code(Zero) at (prev + 0, 41) to (start + 0, 48) - Code(Zero) at (prev + 0, 51) to (start + 0, 65) - Code(Zero) at (prev + 0, 75) to (start + 0, 90) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) - Code(Zero) at (prev + 5, 9) to (start + 0, 13) - Code(Zero) at (prev + 3, 9) to (start + 0, 16) - Code(Zero) at (prev + 2, 13) to (start + 0, 27) - Code(Zero) at (prev + 2, 13) to (start + 0, 28) -- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 16) -- Code(Counter(3)) at (prev + 0, 19) to (start + 0, 46) -- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 12) -- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 8) to (start + 0, 15) -- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19) - = (c3 - c4) -- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15) -- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 19) + = (c0 - c1) +- Code(Counter(0)) at (prev + 5, 8) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 19) - Code(Zero) at (prev + 3, 13) to (start + 0, 29) - Code(Expression(1, Sub)) at (prev + 3, 9) to (start + 0, 19) - = (c3 - c5) + = (c0 - c2) - Code(Zero) at (prev + 3, 13) to (start + 0, 29) -- Code(Counter(3)) at (prev + 3, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 19) -- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 19) +- Code(Counter(3)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c3 - c6) -- Code(Counter(7)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(7)) at (prev + 2, 12) to (start + 0, 19) -- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 19) + = (c0 - c3) +- Code(Counter(4)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(4)) at (prev + 2, 12) to (start + 0, 19) +- Code(Counter(5)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c7 - c8) + = (c4 - c5) - Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15) - = (c10 + c11) -- Code(Counter(9)) at (prev + 1, 12) to (start + 0, 19) -- Code(Counter(10)) at (prev + 1, 13) to (start + 0, 23) -- Code(Counter(10)) at (prev + 4, 13) to (start + 0, 19) + = (c7 + c8) +- Code(Counter(6)) at (prev + 1, 12) to (start + 0, 19) +- Code(Counter(7)) at (prev + 1, 13) to (start + 0, 23) +- Code(Counter(7)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(7, Sub)) at (prev + 2, 13) to (start + 0, 23) - = (c9 - c10) + = (c6 - c7) - Code(Expression(7, Sub)) at (prev + 1, 20) to (start + 0, 27) - = (c9 - c10) + = (c6 - c7) - Code(Zero) at (prev + 1, 21) to (start + 0, 27) - Code(Expression(7, Sub)) at (prev + 2, 21) to (start + 0, 27) - = (c9 - c10) -- Code(Counter(11)) at (prev + 4, 13) to (start + 0, 19) + = (c6 - c7) +- Code(Counter(8)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 25) - = ((c10 + c11) - c12) -- Code(Counter(12)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(12)) at (prev + 3, 9) to (start + 0, 34) + = ((c7 + c8) - c9) +- Code(Counter(9)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(9)) at (prev + 3, 9) to (start + 0, 34) - Code(Zero) at (prev + 2, 5) to (start + 0, 15) - Code(Zero) at (prev + 3, 9) to (start + 0, 44) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c12 +Highest counter ID seen: c9 diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff index f43c0cca9ad28..6f33229ce7a27 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff @@ -30,16 +30,21 @@ } bb1: { - StorageLive(_7); +- StorageLive(_7); ++ nop; _7 = ShallowInitBox(move _6, i32); _8 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); (*_8) = const 42_i32; - _3 = move _7; - StorageDead(_7); - _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_9); +- _3 = move _7; +- StorageDead(_7); +- _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- _2 = copy (*_9); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); ++ _3 = copy _7; ++ nop; ++ _9 = copy _8; ++ _2 = copy (*_8); + _1 = copy _2; + nop; drop(_3) -> [return: bb2, unwind unreachable]; diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff index 2c903b6d85349..008f3d96962f9 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff @@ -30,16 +30,21 @@ } bb1: { - StorageLive(_7); +- StorageLive(_7); ++ nop; _7 = ShallowInitBox(move _6, i32); _8 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); (*_8) = const 42_i32; - _3 = move _7; - StorageDead(_7); - _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_9); +- _3 = move _7; +- StorageDead(_7); +- _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- _2 = copy (*_9); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); ++ _3 = copy _7; ++ nop; ++ _9 = copy _8; ++ _2 = copy (*_8); + _1 = copy _2; + nop; drop(_3) -> [return: bb2, unwind: bb3]; diff --git a/tests/mir-opt/const_prop/mutable_variable.main.GVN.diff b/tests/mir-opt/const_prop/mutable_variable.main.GVN.diff index cc25b6caf90d9..009b71044bd44 100644 --- a/tests/mir-opt/const_prop/mutable_variable.main.GVN.diff +++ b/tests/mir-opt/const_prop/mutable_variable.main.GVN.diff @@ -17,7 +17,8 @@ _1 = const 42_i32; _1 = const 99_i32; StorageLive(_2); - _2 = copy _1; +- _2 = copy _1; ++ _2 = const 99_i32; _0 = const (); StorageDead(_2); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/mutable_variable.rs b/tests/mir-opt/const_prop/mutable_variable.rs index 3aa1b1bcd2181..e86048e90b990 100644 --- a/tests/mir-opt/const_prop/mutable_variable.rs +++ b/tests/mir-opt/const_prop/mutable_variable.rs @@ -7,7 +7,7 @@ fn main() { // CHECK: debug y => [[y:_.*]]; // CHECK: [[x]] = const 42_i32; // CHECK: [[x]] = const 99_i32; - // CHECK: [[y]] = copy [[x]]; + // CHECK: [[y]] = const 99_i32; let mut x = 42; x = 99; let y = x; diff --git a/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff index 3f8dc12f4ae57..5feecdbeff29f 100644 --- a/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff +++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff @@ -19,17 +19,21 @@ StorageLive(_1); _1 = const 42_u32; StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_4); _4 = const {ALLOC0: *mut u32}; _3 = copy (*_4); - _1 = move _3; - StorageDead(_3); +- _1 = move _3; +- StorageDead(_3); ++ _1 = copy _3; ++ nop; StorageDead(_4); _2 = const (); StorageDead(_2); StorageLive(_5); - _5 = copy _1; +- _5 = copy _1; ++ _5 = copy _3; _0 = const (); StorageDead(_5); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/mutable_variable_no_prop.rs b/tests/mir-opt/const_prop/mutable_variable_no_prop.rs index 66af5bf1d5d40..8f3ba8ec846da 100644 --- a/tests/mir-opt/const_prop/mutable_variable_no_prop.rs +++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.rs @@ -10,8 +10,8 @@ fn main() { // CHECK: debug y => [[y:_.*]]; // CHECK: [[x]] = const 42_u32; // CHECK: [[tmp:_.*]] = copy (*{{_.*}}); - // CHECK: [[x]] = move [[tmp]]; - // CHECK: [[y]] = copy [[x]]; + // CHECK: [[x]] = copy [[tmp]]; + // CHECK: [[y]] = copy [[tmp]]; let mut x = 42; unsafe { x = STATIC; diff --git a/tests/mir-opt/const_prop/transmute.rs b/tests/mir-opt/const_prop/transmute.rs index 892b91a5414c3..33cbefbf053f5 100644 --- a/tests/mir-opt/const_prop/transmute.rs +++ b/tests/mir-opt/const_prop/transmute.rs @@ -56,7 +56,7 @@ pub unsafe fn undef_union_as_integer() -> u32 { pub unsafe fn unreachable_direct() -> ! { // CHECK-LABEL: fn unreachable_direct( // CHECK: = const (); - // CHECK: = const () as Never (Transmute); + // CHECK: = const ZeroSized: Never; let x: Never = unsafe { transmute(()) }; match x {} } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff index 3364782022dc7..5aeb55a5a6a53 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff @@ -15,7 +15,7 @@ - _2 = (); - _1 = move _2 as Never (Transmute); + _2 = const (); -+ _1 = const () as Never (Transmute); ++ _1 = const ZeroSized: Never; unreachable; } } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff index 3364782022dc7..5aeb55a5a6a53 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff @@ -15,7 +15,7 @@ - _2 = (); - _1 = move _2 as Never (Transmute); + _2 = const (); -+ _1 = const () as Never (Transmute); ++ _1 = const ZeroSized: Never; unreachable; } } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 25ffff619e60b..be32d4676febb 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -70,7 +70,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_11); StorageLive(_12); StorageLive(_13); @@ -88,7 +89,8 @@ } bb1: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } @@ -121,8 +123,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -139,7 +142,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index b2085afb71379..26a0238518709 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -36,7 +36,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } @@ -46,8 +47,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -64,7 +66,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); @@ -74,7 +76,8 @@ } bb2: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 839b53e3b0b3b..e04e3e8483580 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -70,7 +70,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_11); StorageLive(_12); StorageLive(_13); @@ -88,7 +89,8 @@ } bb1: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } @@ -121,8 +123,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -139,7 +142,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index b2085afb71379..26a0238518709 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -36,7 +36,8 @@ bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } @@ -46,8 +47,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -64,7 +66,7 @@ StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); @@ -74,7 +76,8 @@ } bb2: { - StorageDead(_3); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff index 6baa902b6f4bd..91cf12285c540 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff @@ -51,7 +51,8 @@ StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); - StorageLive(_5); +- StorageLive(_5); ++ nop; switchInt(copy _4) -> [0: bb2, otherwise: bb1]; } @@ -99,7 +100,7 @@ StorageLive(_15); _15 = copy _3; - _0 = float_to_exponential_common_exact::(move _9, move _10, move _11, move _12, move _15) -> [return: bb5, unwind unreachable]; -+ _0 = float_to_exponential_common_exact::(copy _1, copy _2, move _11, move _12, copy _3) -> [return: bb5, unwind unreachable]; ++ _0 = float_to_exponential_common_exact::(copy _1, copy _2, copy _5, move _12, copy _3) -> [return: bb5, unwind unreachable]; } bb5: { @@ -123,7 +124,7 @@ StorageLive(_19); _19 = copy _3; - _0 = float_to_exponential_common_shortest::(move _16, move _17, move _18, move _19) -> [return: bb7, unwind unreachable]; -+ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, move _18, copy _3) -> [return: bb7, unwind unreachable]; ++ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, copy _5, copy _3) -> [return: bb7, unwind unreachable]; } bb7: { @@ -135,7 +136,8 @@ } bb8: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageDead(_6); return; diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff index 36540e038654f..e7213a8550b66 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff @@ -51,7 +51,8 @@ StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); - StorageLive(_5); +- StorageLive(_5); ++ nop; switchInt(copy _4) -> [0: bb2, otherwise: bb1]; } @@ -99,7 +100,7 @@ StorageLive(_15); _15 = copy _3; - _0 = float_to_exponential_common_exact::(move _9, move _10, move _11, move _12, move _15) -> [return: bb5, unwind continue]; -+ _0 = float_to_exponential_common_exact::(copy _1, copy _2, move _11, move _12, copy _3) -> [return: bb5, unwind continue]; ++ _0 = float_to_exponential_common_exact::(copy _1, copy _2, copy _5, move _12, copy _3) -> [return: bb5, unwind continue]; } bb5: { @@ -123,7 +124,7 @@ StorageLive(_19); _19 = copy _3; - _0 = float_to_exponential_common_shortest::(move _16, move _17, move _18, move _19) -> [return: bb7, unwind continue]; -+ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, move _18, copy _3) -> [return: bb7, unwind continue]; ++ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, copy _5, copy _3) -> [return: bb7, unwind continue]; } bb7: { @@ -135,7 +136,8 @@ } bb8: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageDead(_6); return; diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff index 41c350f3eaeb5..841cd3ce293f3 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff @@ -51,7 +51,8 @@ StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); - StorageLive(_5); +- StorageLive(_5); ++ nop; switchInt(copy _4) -> [0: bb2, otherwise: bb1]; } @@ -99,7 +100,7 @@ StorageLive(_15); _15 = copy _3; - _0 = float_to_exponential_common_exact::(move _9, move _10, move _11, move _12, move _15) -> [return: bb5, unwind unreachable]; -+ _0 = float_to_exponential_common_exact::(copy _1, copy _2, move _11, move _12, copy _3) -> [return: bb5, unwind unreachable]; ++ _0 = float_to_exponential_common_exact::(copy _1, copy _2, copy _5, move _12, copy _3) -> [return: bb5, unwind unreachable]; } bb5: { @@ -123,7 +124,7 @@ StorageLive(_19); _19 = copy _3; - _0 = float_to_exponential_common_shortest::(move _16, move _17, move _18, move _19) -> [return: bb7, unwind unreachable]; -+ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, move _18, copy _3) -> [return: bb7, unwind unreachable]; ++ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, copy _5, copy _3) -> [return: bb7, unwind unreachable]; } bb7: { @@ -135,7 +136,8 @@ } bb8: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageDead(_6); return; diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff index b839bf81eaf45..b2623255e33b3 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff @@ -51,7 +51,8 @@ StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); - StorageLive(_5); +- StorageLive(_5); ++ nop; switchInt(copy _4) -> [0: bb2, otherwise: bb1]; } @@ -99,7 +100,7 @@ StorageLive(_15); _15 = copy _3; - _0 = float_to_exponential_common_exact::(move _9, move _10, move _11, move _12, move _15) -> [return: bb5, unwind continue]; -+ _0 = float_to_exponential_common_exact::(copy _1, copy _2, move _11, move _12, copy _3) -> [return: bb5, unwind continue]; ++ _0 = float_to_exponential_common_exact::(copy _1, copy _2, copy _5, move _12, copy _3) -> [return: bb5, unwind continue]; } bb5: { @@ -123,7 +124,7 @@ StorageLive(_19); _19 = copy _3; - _0 = float_to_exponential_common_shortest::(move _16, move _17, move _18, move _19) -> [return: bb7, unwind continue]; -+ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, move _18, copy _3) -> [return: bb7, unwind continue]; ++ _0 = float_to_exponential_common_shortest::(copy _1, copy _2, copy _5, copy _3) -> [return: bb7, unwind continue]; } bb7: { @@ -135,7 +136,8 @@ } bb8: { - StorageDead(_5); +- StorageDead(_5); ++ nop; StorageDead(_4); StorageDead(_6); return; diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff index 183b4d2599f53..5fa31b443de72 100644 --- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff @@ -27,9 +27,10 @@ bb0: { - StorageLive(_2); - _2 = const core::num::::MAX as usize (IntToInt); +- StorageLive(_3); + nop; + _2 = const usize::MAX; - StorageLive(_3); ++ nop; StorageLive(_4); StorageLive(_5); - _5 = copy _2; @@ -90,13 +91,15 @@ StorageDead(_4); StorageLive(_14); _14 = copy _3; - _0 = opaque::(move _14) -> [return: bb7, unwind unreachable]; +- _0 = opaque::(move _14) -> [return: bb7, unwind unreachable]; ++ _0 = opaque::(copy _3) -> [return: bb7, unwind unreachable]; } bb7: { StorageDead(_14); - StorageDead(_3); +- StorageDead(_3); - StorageDead(_2); ++ nop; + nop; return; } diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff index 03e8aa3bd9b98..eea9dd5e7b068 100644 --- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff @@ -27,9 +27,10 @@ bb0: { - StorageLive(_2); - _2 = const core::num::::MAX as usize (IntToInt); +- StorageLive(_3); + nop; + _2 = const usize::MAX; - StorageLive(_3); ++ nop; StorageLive(_4); StorageLive(_5); - _5 = copy _2; @@ -90,13 +91,15 @@ StorageDead(_4); StorageLive(_14); _14 = copy _3; - _0 = opaque::(move _14) -> [return: bb7, unwind continue]; +- _0 = opaque::(move _14) -> [return: bb7, unwind continue]; ++ _0 = opaque::(copy _3) -> [return: bb7, unwind continue]; } bb7: { StorageDead(_14); - StorageDead(_3); +- StorageDead(_3); - StorageDead(_2); ++ nop; + nop; return; } diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff index 3cce35d34e90d..cafc9d7425145 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:620:19: 620:21}; + let mut _9: {closure@$DIR/gvn.rs:622:19: 622:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:620:19: 620:21}; + let mut _13: {closure@$DIR/gvn.rs:622:19: 622:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:620:19: 620:21}; + let _7: {closure@$DIR/gvn.rs:622:19: 622:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:620:19: 620:21}; +- _7 = {closure@$DIR/gvn.rs:622:19: 622:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff index d85aca040fe67..654a46f0fa433 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff @@ -8,10 +8,10 @@ let mut _3: fn(u8) -> u8; let _5: (); let mut _6: fn(u8) -> u8; - let mut _9: {closure@$DIR/gvn.rs:620:19: 620:21}; + let mut _9: {closure@$DIR/gvn.rs:622:19: 622:21}; let _10: (); let mut _11: fn(); - let mut _13: {closure@$DIR/gvn.rs:620:19: 620:21}; + let mut _13: {closure@$DIR/gvn.rs:622:19: 622:21}; let _14: (); let mut _15: fn(); scope 1 { @@ -19,7 +19,7 @@ let _4: fn(u8) -> u8; scope 2 { debug g => _4; - let _7: {closure@$DIR/gvn.rs:620:19: 620:21}; + let _7: {closure@$DIR/gvn.rs:622:19: 622:21}; scope 3 { debug closure => _7; let _8: fn(); @@ -62,16 +62,16 @@ StorageDead(_6); StorageDead(_5); - StorageLive(_7); -- _7 = {closure@$DIR/gvn.rs:620:19: 620:21}; +- _7 = {closure@$DIR/gvn.rs:622:19: 622:21}; - StorageLive(_8); + nop; -+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21}; ++ _7 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21}; + nop; StorageLive(_9); - _9 = copy _7; - _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _9 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21}; ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -88,8 +88,8 @@ StorageLive(_13); - _13 = copy _7; - _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); -+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:620:19: 620:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); ++ _13 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21}; ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:622:19: 622:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff index 770c673077533..ffe4a0272b4b1 100644 --- a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff @@ -18,7 +18,8 @@ bb0: { _4 = copy _1 as *const T (PtrToPtr); - _5 = PtrMetadata(copy _4); +- _5 = PtrMetadata(copy _4); ++ _5 = const (); _6 = copy _1 as *const (&A, [T]) (PtrToPtr); - _7 = PtrMetadata(copy _6); + _7 = PtrMetadata(copy _1); diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff index 770c673077533..ffe4a0272b4b1 100644 --- a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff @@ -18,7 +18,8 @@ bb0: { _4 = copy _1 as *const T (PtrToPtr); - _5 = PtrMetadata(copy _4); +- _5 = PtrMetadata(copy _4); ++ _5 = const (); _6 = copy _1 as *const (&A, [T]) (PtrToPtr); - _7 = PtrMetadata(copy _6); + _7 = PtrMetadata(copy _1); diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 6ef320c90de12..802df8e30bb1e 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -99,13 +99,14 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) { opaque((x * y) - y); opaque((x * y) - y); - // We cannot substitute through an immutable reference. + // We can substitute through an immutable reference. // CHECK: [[ref:_.*]] = &_3; - // CHECK: [[deref:_.*]] = copy (*[[ref]]); - // CHECK: [[addref:_.*]] = Add(move [[deref]], copy _1); + // CHECK: [[deref:_.*]] = copy _3; + // CHECK: [[addref:_.*]] = Add(copy _3, copy _1); // CHECK: opaque::(move [[addref]]) - // CHECK: [[deref2:_.*]] = copy (*[[ref]]); - // CHECK: [[addref2:_.*]] = Add(move [[deref2]], copy _1); + // But `_3` is not SSA so we cannot merge the values in two different blocks. + // CHECK: [[deref2:_.*]] = copy _3; + // CHECK: [[addref2:_.*]] = Add(copy _3, copy _1); // CHECK: opaque::(move [[addref2]]) let a = &z; opaque(*a + x); @@ -141,13 +142,14 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) { // We still cannot substitute again, and never with the earlier computations. // Important: `e` is not `a`! - // CHECK: [[ref2:_.*]] = &_3; - // CHECK: [[deref2:_.*]] = copy (*[[ref2]]); - // CHECK: [[addref2:_.*]] = Add(move [[deref2]], copy _1); - // CHECK: opaque::(move [[addref2]]) - // CHECK: [[deref3:_.*]] = copy (*[[ref2]]); - // CHECK: [[addref3:_.*]] = Add(move [[deref3]], copy _1); + // CHECK: [[ref3:_.*]] = &_3; + // CHECK: [[deref3:_.*]] = copy _3; + // CHECK: [[addref3:_.*]] = Add(copy _3, copy _1); // CHECK: opaque::(move [[addref3]]) + // And `_3` is not SSA so we cannot merge the values in two different blocks. + // CHECK: [[deref4:_.*]] = copy _3; + // CHECK: [[addref4:_.*]] = Add(copy _3, copy _1); + // CHECK: opaque::(move [[addref4]]) let e = &z; opaque(*e + x); opaque(*e + x); @@ -869,7 +871,7 @@ fn generic_cast_metadata(ps: *const [T], pa: *const A, // Metadata usize -> (), do not optimize. // CHECK: [[T:_.+]] = copy _1 as - // CHECK-NEXT: PtrMetadata(copy [[T]]) + // CHECK-NEXT: const (); let t1 = CastPtrToPtr::<_, *const T>(ps); let m1 = PtrMetadata(t1); diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff index e872e011542b3..28b37af60c431 100644 --- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff @@ -760,11 +760,12 @@ StorageLive(_127); StorageLive(_128); StorageLive(_129); - _129 = copy (*_126); +- _129 = copy (*_126); ++ _129 = copy _3; StorageLive(_130); _130 = copy _1; - _128 = Add(move _129, move _130); -+ _128 = Add(move _129, copy _1); ++ _128 = Add(copy _3, copy _1); StorageDead(_130); StorageDead(_129); _127 = opaque::(move _128) -> [return: bb35, unwind unreachable]; @@ -776,11 +777,12 @@ StorageLive(_131); StorageLive(_132); StorageLive(_133); - _133 = copy (*_126); +- _133 = copy (*_126); ++ _133 = copy _3; StorageLive(_134); _134 = copy _1; - _132 = Add(move _133, move _134); -+ _132 = Add(move _133, copy _1); ++ _132 = Add(copy _3, copy _1); StorageDead(_134); StorageDead(_133); _131 = opaque::(move _132) -> [return: bb36, unwind unreachable]; @@ -901,11 +903,12 @@ StorageLive(_164); StorageLive(_165); StorageLive(_166); - _166 = copy (*_163); +- _166 = copy (*_163); ++ _166 = copy _3; StorageLive(_167); _167 = copy _1; - _165 = Add(move _166, move _167); -+ _165 = Add(move _166, copy _1); ++ _165 = Add(copy _3, copy _1); StorageDead(_167); StorageDead(_166); _164 = opaque::(move _165) -> [return: bb43, unwind unreachable]; @@ -917,11 +920,12 @@ StorageLive(_168); StorageLive(_169); StorageLive(_170); - _170 = copy (*_163); +- _170 = copy (*_163); ++ _170 = copy _3; StorageLive(_171); _171 = copy _1; - _169 = Add(move _170, move _171); -+ _169 = Add(move _170, copy _1); ++ _169 = Add(copy _3, copy _1); StorageDead(_171); StorageDead(_170); _168 = opaque::(move _169) -> [return: bb44, unwind unreachable]; diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff index 3996dab27a343..356f92f1d4209 100644 --- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff @@ -760,11 +760,12 @@ StorageLive(_127); StorageLive(_128); StorageLive(_129); - _129 = copy (*_126); +- _129 = copy (*_126); ++ _129 = copy _3; StorageLive(_130); _130 = copy _1; - _128 = Add(move _129, move _130); -+ _128 = Add(move _129, copy _1); ++ _128 = Add(copy _3, copy _1); StorageDead(_130); StorageDead(_129); _127 = opaque::(move _128) -> [return: bb35, unwind continue]; @@ -776,11 +777,12 @@ StorageLive(_131); StorageLive(_132); StorageLive(_133); - _133 = copy (*_126); +- _133 = copy (*_126); ++ _133 = copy _3; StorageLive(_134); _134 = copy _1; - _132 = Add(move _133, move _134); -+ _132 = Add(move _133, copy _1); ++ _132 = Add(copy _3, copy _1); StorageDead(_134); StorageDead(_133); _131 = opaque::(move _132) -> [return: bb36, unwind continue]; @@ -901,11 +903,12 @@ StorageLive(_164); StorageLive(_165); StorageLive(_166); - _166 = copy (*_163); +- _166 = copy (*_163); ++ _166 = copy _3; StorageLive(_167); _167 = copy _1; - _165 = Add(move _166, move _167); -+ _165 = Add(move _166, copy _1); ++ _165 = Add(copy _3, copy _1); StorageDead(_167); StorageDead(_166); _164 = opaque::(move _165) -> [return: bb43, unwind continue]; @@ -917,11 +920,12 @@ StorageLive(_168); StorageLive(_169); StorageLive(_170); - _170 = copy (*_163); +- _170 = copy (*_163); ++ _170 = copy _3; StorageLive(_171); _171 = copy _1; - _169 = Add(move _170, move _171); -+ _169 = Add(move _170, copy _1); ++ _169 = Add(copy _3, copy _1); StorageDead(_171); StorageDead(_170); _168 = opaque::(move _169) -> [return: bb44, unwind continue]; diff --git a/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed.GVN.diff index dc65cccb7bd6e..4368fa5b93d50 100644 --- a/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed.GVN.diff @@ -25,24 +25,28 @@ StorageLive(_2); _2 = copy ((*_1).0: i32); ((*_1).0: i32) = const 1_i32; - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = copy ((*_1).0: i32); - _2 = move _3; - StorageDead(_3); +- _2 = move _3; +- StorageDead(_3); - StorageLive(_4); ++ _2 = copy _3; ++ nop; + nop; _4 = copy ((*_1).1: u64); - StorageLive(_5); + nop; _5 = copy ((*_1).2: [i8; 3]); StorageLive(_6); - _6 = copy _2; +- _6 = copy _2; ++ _6 = copy _3; StorageLive(_7); _7 = copy _4; StorageLive(_8); _8 = copy _5; - _0 = AllCopy { a: move _6, b: move _7, c: move _8 }; -+ _0 = AllCopy { a: move _6, b: copy _4, c: copy _5 }; ++ _0 = AllCopy { a: copy _3, b: copy _4, c: copy _5 }; StorageDead(_8); StorageDead(_7); StorageDead(_6); diff --git a/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed_2.GVN.diff index 08a4a078adcb4..4b7c2b7d7fc42 100644 --- a/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed_2.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.all_copy_use_changed_2.GVN.diff @@ -31,18 +31,22 @@ + nop; _4 = copy ((*_1).2: [i8; 3]); ((*_1).0: i32) = const 1_i32; - StorageLive(_5); +- StorageLive(_5); ++ nop; _5 = copy ((*_1).0: i32); - _2 = move _5; - StorageDead(_5); +- _2 = move _5; +- StorageDead(_5); ++ _2 = copy _5; ++ nop; StorageLive(_6); - _6 = copy _2; +- _6 = copy _2; ++ _6 = copy _5; StorageLive(_7); _7 = copy _3; StorageLive(_8); _8 = copy _4; - _0 = AllCopy { a: move _6, b: move _7, c: move _8 }; -+ _0 = AllCopy { a: move _6, b: copy _3, c: copy _4 }; ++ _0 = AllCopy { a: copy _5, b: copy _3, c: copy _4 }; StorageDead(_8); StorageDead(_7); StorageDead(_6); diff --git a/tests/mir-opt/gvn_repeat.index_place.GVN.diff b/tests/mir-opt/gvn_repeat.index_place.GVN.diff new file mode 100644 index 0000000000000..1eb7e9015cc3f --- /dev/null +++ b/tests/mir-opt/gvn_repeat.index_place.GVN.diff @@ -0,0 +1,15 @@ +- // MIR for `index_place` before GVN ++ // MIR for `index_place` after GVN + + fn index_place(_1: usize, _2: usize, _3: [i32; 5]) -> i32 { + let mut _0: i32; + let mut _4: &i32; + + bb0: { + _4 = &_3[_1]; + _1 = copy _2; + _0 = copy (*_4); + return; + } + } + diff --git a/tests/mir-opt/gvn_repeat.repeat_place.GVN.diff b/tests/mir-opt/gvn_repeat.repeat_place.GVN.diff index e490925bc119e..4cb7d3d9aee43 100644 --- a/tests/mir-opt/gvn_repeat.repeat_place.GVN.diff +++ b/tests/mir-opt/gvn_repeat.repeat_place.GVN.diff @@ -10,7 +10,8 @@ _4 = [copy (*_3); 5]; _5 = &_4[_1]; _1 = copy _2; - _0 = copy (*_5); +- _0 = copy (*_5); ++ _0 = copy (*_3); return; } } diff --git a/tests/mir-opt/gvn_repeat.rs b/tests/mir-opt/gvn_repeat.rs index bbbb2a7ccbaf5..730378d825983 100644 --- a/tests/mir-opt/gvn_repeat.rs +++ b/tests/mir-opt/gvn_repeat.rs @@ -6,12 +6,28 @@ use std::intrinsics::mir::*; +// EMIT_MIR gvn_repeat.index_place.GVN.diff +#[custom_mir(dialect = "runtime")] +pub fn index_place(mut idx1: usize, idx2: usize, array: [i32; 5]) -> i32 { + // CHECK-LABEL: fn index_place( + // CHECK: let mut [[ELEM:.*]]: &i32; + // CHECK: _0 = copy (*[[ELEM]]) + mir! { + let elem; + { + elem = &array[idx1]; + idx1 = idx2; + RET = *elem; + Return() + } + } +} + // EMIT_MIR gvn_repeat.repeat_place.GVN.diff #[custom_mir(dialect = "runtime")] pub fn repeat_place(mut idx1: usize, idx2: usize, val: &i32) -> i32 { // CHECK-LABEL: fn repeat_place( - // CHECK: let mut [[ELEM:.*]]: &i32; - // CHECK: _0 = copy (*[[ELEM]]) + // CHECK: _0 = copy (*_3) mir! { let array; let elem; @@ -29,7 +45,7 @@ pub fn repeat_place(mut idx1: usize, idx2: usize, val: &i32) -> i32 { #[custom_mir(dialect = "runtime")] pub fn repeat_local(mut idx1: usize, idx2: usize, val: i32) -> i32 { // CHECK-LABEL: fn repeat_local( - // CHECK: _0 = copy _3 + // CHECK: _0 = copy _3; mir! { let array; let elem; @@ -44,6 +60,7 @@ pub fn repeat_local(mut idx1: usize, idx2: usize, val: i32) -> i32 { } fn main() { + assert_eq!(index_place(0, 5, [0; 5]), 0); assert_eq!(repeat_place(0, 5, &0), 0); assert_eq!(repeat_local(0, 5, 0), 0); } diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff index c33e0810739f2..b37236944320b 100644 --- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff @@ -5,14 +5,13 @@ let mut _0: (); let _1: (!, !); + let mut _2: fn() -> ! {sleep}; ++ let mut _7: (); + let mut _8: (); -+ let mut _9: (); + scope 1 (inlined call_twice:: ! {sleep}>) { + debug f => _2; + let mut _3: &fn() -> ! {sleep}; + let _4: !; + let mut _5: &fn() -> ! {sleep}; -+ let mut _7: !; + scope 2 { + debug a => _4; + let _6: !; @@ -35,12 +34,12 @@ - _1 = call_twice:: ! {sleep}>(sleep) -> unwind continue; + StorageLive(_2); + _2 = sleep; -+ StorageLive(_6); + StorageLive(_4); ++ StorageLive(_6); + StorageLive(_3); + _3 = &_2; -+ StorageLive(_8); -+ _8 = const (); ++ StorageLive(_7); ++ _7 = const (); + goto -> bb1; + } + diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir index dfe618612ab96..0ebf48bac84fc 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -6,22 +6,22 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug f => _3; let mut _0: (); let mut _4: u32; - let mut _9: std::option::Option; - let mut _11: &impl Fn(u32); - let mut _12: (u32,); - let _13: (); + let mut _8: std::option::Option; + let mut _10: &impl Fn(u32); + let mut _11: (u32,); + let _12: (); scope 1 { debug ((iter: std::ops::Range).0: u32) => _4; debug ((iter: std::ops::Range).1: u32) => _2; - let _10: u32; + let _9: u32; scope 2 { - debug x => _10; + debug x => _9; } scope 4 (inlined iter::range::>::next) { scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _6: bool; - let _7: u32; - let mut _8: u32; + let mut _5: bool; + let _6: u32; + let mut _7: u32; scope 6 { scope 8 (inlined ::forward_unchecked) { scope 9 (inlined #[track_caller] core::num::::unchecked_add) { @@ -33,7 +33,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - let mut _5: u32; } } } @@ -42,25 +41,20 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb0: { - StorageLive(_4); _4 = copy _1; goto -> bb1; } bb1: { - StorageLive(_9); - StorageLive(_6); + StorageLive(_8); StorageLive(_5); - _5 = copy _4; - _6 = Lt(move _5, copy _2); - StorageDead(_5); - switchInt(move _6) -> [0: bb2, otherwise: bb4]; + _5 = Lt(copy _4, copy _2); + switchInt(move _5) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_5); + StorageDead(_8); drop(_3) -> [return: bb3, unwind unreachable]; } @@ -69,25 +63,25 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb4: { - _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_u32); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); - StorageDead(_6); - _10 = copy ((_9 as Some).0: u32); + _6 = copy _4; + StorageLive(_7); + _7 = AddUnchecked(copy _6, const 1_u32); + _4 = move _7; + StorageDead(_7); + _8 = Option::::Some(copy _6); + StorageDead(_5); + _9 = copy ((_8 as Some).0: u32); + StorageLive(_10); + _10 = &_3; StorageLive(_11); - _11 = &_3; - StorageLive(_12); - _12 = (copy _10,); - _13 = >::call(move _11, move _12) -> [return: bb5, unwind unreachable]; + _11 = (copy _9,); + _12 = >::call(move _10, move _11) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_12); StorageDead(_11); - StorageDead(_9); + StorageDead(_10); + StorageDead(_8); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir index e0fcfcaffc59a..16cf392a7e225 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -6,22 +6,22 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug f => _3; let mut _0: (); let mut _4: u32; - let mut _9: std::option::Option; - let mut _11: &impl Fn(u32); - let mut _12: (u32,); - let _13: (); + let mut _8: std::option::Option; + let mut _10: &impl Fn(u32); + let mut _11: (u32,); + let _12: (); scope 1 { debug ((iter: std::ops::Range).0: u32) => _4; debug ((iter: std::ops::Range).1: u32) => _2; - let _10: u32; + let _9: u32; scope 2 { - debug x => _10; + debug x => _9; } scope 4 (inlined iter::range::>::next) { scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _6: bool; - let _7: u32; - let mut _8: u32; + let mut _5: bool; + let _6: u32; + let mut _7: u32; scope 6 { scope 8 (inlined ::forward_unchecked) { scope 9 (inlined #[track_caller] core::num::::unchecked_add) { @@ -33,7 +33,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - let mut _5: u32; } } } @@ -42,25 +41,20 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb0: { - StorageLive(_4); _4 = copy _1; goto -> bb1; } bb1: { - StorageLive(_9); - StorageLive(_6); + StorageLive(_8); StorageLive(_5); - _5 = copy _4; - _6 = Lt(move _5, copy _2); - StorageDead(_5); - switchInt(move _6) -> [0: bb2, otherwise: bb4]; + _5 = Lt(copy _4, copy _2); + switchInt(move _5) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_5); + StorageDead(_8); drop(_3) -> [return: bb3, unwind continue]; } @@ -69,25 +63,25 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb4: { - _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_u32); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); - StorageDead(_6); - _10 = copy ((_9 as Some).0: u32); + _6 = copy _4; + StorageLive(_7); + _7 = AddUnchecked(copy _6, const 1_u32); + _4 = move _7; + StorageDead(_7); + _8 = Option::::Some(copy _6); + StorageDead(_5); + _9 = copy ((_8 as Some).0: u32); + StorageLive(_10); + _10 = &_3; StorageLive(_11); - _11 = &_3; - StorageLive(_12); - _12 = (copy _10,); - _13 = >::call(move _11, move _12) -> [return: bb5, unwind: bb6]; + _11 = (copy _9,); + _12 = >::call(move _10, move _11) -> [return: bb5, unwind: bb6]; } bb5: { - StorageDead(_12); StorageDead(_11); - StorageDead(_9); + StorageDead(_10); + StorageDead(_8); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index d389e4069d05a..2305a77a8ff55 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,30 +4,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _13: usize; - let mut _32: std::option::Option<(usize, &T)>; - let mut _35: &impl Fn(usize, &T); - let mut _36: (usize, &T); - let _37: (); + let mut _10: std::ptr::NonNull; + let mut _11: *const T; + let mut _12: usize; + let mut _31: std::option::Option<(usize, &T)>; + let mut _34: &impl Fn(usize, &T); + let mut _35: (usize, &T); + let _36: (); scope 1 { - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _12; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _10; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _11; debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - debug ((iter: Enumerate>).1: usize) => _13; - let _33: usize; - let _34: &T; + debug ((iter: Enumerate>).1: usize) => _12; + let _32: usize; + let _33: &T; scope 2 { - debug i => _33; - debug x => _34; + debug i => _32; + debug x => _33; } scope 18 (inlined > as Iterator>::next) { - let mut _27: std::option::Option<&T>; - let mut _30: (usize, bool); - let mut _31: (usize, &T); + let mut _26: std::option::Option<&T>; + let mut _29: (usize, bool); + let mut _30: (usize, &T); scope 19 { - let _29: usize; + let _28: usize; scope 24 { } } @@ -42,21 +42,21 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 25 (inlined as Try>::branch) { - let _28: &T; + let _27: &T; scope 26 { } } scope 28 (inlined as Iterator>::next) { - let _14: std::ptr::NonNull; - let _16: std::ptr::NonNull; - let mut _19: bool; - let mut _22: std::ptr::NonNull; - let mut _24: usize; - let _26: &T; + let _13: std::ptr::NonNull; + let _15: std::ptr::NonNull; + let mut _18: bool; + let mut _21: std::ptr::NonNull; + let mut _23: usize; + let _25: &T; scope 29 { - let _15: *const T; + let _14: *const T; scope 30 { - let _23: usize; + let _22: usize; scope 31 { scope 34 (inlined #[track_caller] core::num::::unchecked_sub) { scope 35 (inlined core::ub_checks::check_language_ub) { @@ -72,21 +72,21 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 38 (inlined as PartialEq>::eq) { + let mut _16: *mut T; let mut _17: *mut T; - let mut _18: *mut T; scope 39 (inlined NonNull::::as_ptr) { } scope 40 (inlined NonNull::::as_ptr) { } } scope 41 (inlined NonNull::::add) { + let mut _19: *const T; let mut _20: *const T; - let mut _21: *const T; scope 42 (inlined NonNull::::as_ptr) { } } scope 43 (inlined NonNull::::as_ref::<'_>) { - let _25: *const T; + let _24: *const T; scope 44 (inlined NonNull::::as_ptr) { } scope 45 (inlined std::ptr::mut_ptr::::cast_const) { @@ -102,7 +102,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -145,7 +144,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -166,97 +164,93 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb3: { - _10 = copy _9; - StorageDead(_9); StorageDead(_4); StorageDead(_3); + StorageLive(_10); StorageLive(_11); StorageLive(_12); - StorageLive(_13); - _11 = copy _6; - _12 = copy _10; - _13 = const 0_usize; + _10 = copy _6; + _11 = copy _9; + _12 = const 0_usize; goto -> bb4; } bb4: { - StorageLive(_32); + StorageLive(_28); StorageLive(_29); - StorageLive(_30); - StorageLive(_27); + StorageLive(_26); + StorageLive(_13); StorageLive(_14); - StorageLive(_15); + StorageLive(_22); StorageLive(_23); - StorageLive(_24); - StorageLive(_16); - StorageLive(_26); + StorageLive(_15); + StorageLive(_25); + _13 = copy _10; _14 = copy _11; - _15 = copy _12; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageLive(_19); - _16 = copy _15 as std::ptr::NonNull (Transmute); - StorageLive(_17); - _17 = copy _14 as *mut T (Transmute); StorageLive(_18); - _18 = copy _16 as *mut T (Transmute); - _19 = Eq(move _17, move _18); - StorageDead(_18); + _15 = copy _14 as std::ptr::NonNull (Transmute); + StorageLive(_16); + _16 = copy _13 as *mut T (Transmute); + StorageLive(_17); + _17 = copy _15 as *mut T (Transmute); + _18 = Eq(move _16, move _17); StorageDead(_17); - switchInt(move _19) -> [0: bb6, otherwise: bb7]; + StorageDead(_16); + switchInt(move _18) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_19); - StorageLive(_22); + StorageDead(_18); StorageLive(_21); StorageLive(_20); - _20 = copy _14 as *const T (Transmute); - _21 = Offset(move _20, const 1_usize); + StorageLive(_19); + _19 = copy _13 as *const T (Transmute); + _20 = Offset(move _19, const 1_usize); + StorageDead(_19); + _21 = NonNull:: { pointer: move _20 }; StorageDead(_20); - _22 = NonNull:: { pointer: move _21 }; + _10 = move _21; StorageDead(_21); - _11 = move _22; - StorageDead(_22); goto -> bb13; } bb7: { - StorageDead(_19); - StorageDead(_26); - StorageDead(_16); - StorageDead(_24); - StorageDead(_23); + StorageDead(_18); + StorageDead(_25); StorageDead(_15); + StorageDead(_23); + StorageDead(_22); StorageDead(_14); + StorageDead(_13); goto -> bb10; } bb8: { - _23 = copy _15 as usize (Transmute); - switchInt(copy _23) -> [0: bb9, otherwise: bb12]; + _22 = copy _14 as usize (Transmute); + switchInt(copy _22) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_26); - StorageDead(_16); - StorageDead(_24); - StorageDead(_23); + StorageDead(_25); StorageDead(_15); + StorageDead(_23); + StorageDead(_22); StorageDead(_14); + StorageDead(_13); goto -> bb10; } bb10: { - StorageDead(_27); - StorageDead(_30); + StorageDead(_26); StorageDead(_29); - StorageDead(_32); + StorageDead(_28); + StorageDead(_10); StorageDead(_11); StorageDead(_12); - StorageDead(_13); drop(_2) -> [return: bb11, unwind unreachable]; } @@ -265,51 +259,50 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb12: { - _24 = SubUnchecked(copy _23, const 1_usize); - _12 = copy _24 as *const T (Transmute); + _23 = SubUnchecked(copy _22, const 1_usize); + _11 = copy _23 as *const T (Transmute); goto -> bb13; } bb13: { - StorageLive(_25); - _25 = copy _14 as *const T (Transmute); - _26 = &(*_25); - StorageDead(_25); - _27 = Option::<&T>::Some(copy _26); - StorageDead(_26); - StorageDead(_16); + StorageLive(_24); + _24 = copy _13 as *const T (Transmute); + _25 = &(*_24); StorageDead(_24); - StorageDead(_23); + _26 = Option::<&T>::Some(copy _25); + StorageDead(_25); StorageDead(_15); + StorageDead(_23); + StorageDead(_22); StorageDead(_14); - _28 = move ((_27 as Some).0: &T); - StorageDead(_27); - _29 = copy _13; - _30 = AddWithOverflow(copy _13, const 1_usize); - assert(!move (_30.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _13, const 1_usize) -> [success: bb14, unwind unreachable]; + StorageDead(_13); + _27 = move ((_26 as Some).0: &T); + StorageDead(_26); + _28 = copy _12; + _29 = AddWithOverflow(copy _12, const 1_usize); + assert(!move (_29.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _12, const 1_usize) -> [success: bb14, unwind unreachable]; } bb14: { - _13 = move (_30.0: usize); - StorageLive(_31); - _31 = (copy _29, copy _28); - _32 = Option::<(usize, &T)>::Some(move _31); - StorageDead(_31); + _12 = move (_29.0: usize); + StorageLive(_30); + _30 = (copy _28, copy _27); + _31 = Option::<(usize, &T)>::Some(move _30); StorageDead(_30); StorageDead(_29); - _33 = copy (((_32 as Some).0: (usize, &T)).0: usize); - _34 = copy (((_32 as Some).0: (usize, &T)).1: &T); + StorageDead(_28); + _32 = copy (((_31 as Some).0: (usize, &T)).0: usize); + _33 = copy (((_31 as Some).0: (usize, &T)).1: &T); + StorageLive(_34); + _34 = &_2; StorageLive(_35); - _35 = &_2; - StorageLive(_36); - _36 = (copy _33, copy _34); - _37 = >::call(move _35, move _36) -> [return: bb15, unwind unreachable]; + _35 = copy ((_31 as Some).0: (usize, &T)); + _36 = >::call(move _34, move _35) -> [return: bb15, unwind unreachable]; } bb15: { - StorageDead(_36); StorageDead(_35); - StorageDead(_32); + StorageDead(_34); goto -> bb4; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 3b58f1d61f4bb..c441594941974 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,22 +4,22 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Enumerate>; let mut _12: std::iter::Enumerate>; - let mut _13: std::iter::Enumerate>; - let mut _14: &mut std::iter::Enumerate>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _13: &mut std::iter::Enumerate>; + let mut _14: std::option::Option<(usize, &T)>; + let mut _15: isize; + let mut _18: &impl Fn(usize, &T); + let mut _19: (usize, &T); + let _20: (); scope 1 { - debug iter => _13; - let _17: usize; - let _18: &T; + debug iter => _12; + let _16: usize; + let _17: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _16; + debug x => _17; } } scope 3 (inlined core::slice::::iter) { @@ -27,7 +27,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -62,7 +61,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -72,7 +71,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -93,35 +91,29 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_4); StorageDead(_6); StorageDead(_3); - _12 = Enumerate::> { iter: copy _11, count: const 0_usize }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Enumerate::> { iter: copy _10, count: const 0_usize }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); - _14 = &mut _13; - _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + _13 = &mut _12; + _14 = > as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -130,19 +122,18 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = copy (((_15 as Some).0: (usize, &T)).0: usize); - _18 = copy (((_15 as Some).0: (usize, &T)).1: &T); + _16 = copy (((_14 as Some).0: (usize, &T)).0: usize); + _17 = copy (((_14 as Some).0: (usize, &T)).1: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (copy _17, copy _18); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _19 = copy ((_14 as Some).0: (usize, &T)); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); StorageDead(_19); - StorageDead(_15); + StorageDead(_18); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 216e05ec5b79c..5dd14857cb9e3 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,31 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _26: std::option::Option<&T>; - let mut _28: &impl Fn(&T); - let mut _29: (&T,); - let _30: (); + let mut _10: std::ptr::NonNull; + let mut _11: *const T; + let mut _25: std::option::Option<&T>; + let mut _27: &impl Fn(&T); + let mut _28: (&T,); + let _29: (); scope 1 { - debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; + debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _10; + debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _11; debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _27: &T; + let _26: &T; scope 2 { - debug x => _27; + debug x => _26; } scope 16 (inlined as Iterator>::next) { - let _13: std::ptr::NonNull; - let _15: std::ptr::NonNull; - let mut _18: bool; - let mut _21: std::ptr::NonNull; - let mut _23: usize; - let _25: &T; + let _12: std::ptr::NonNull; + let _14: std::ptr::NonNull; + let mut _17: bool; + let mut _20: std::ptr::NonNull; + let mut _22: usize; + let _24: &T; scope 17 { - let _14: *const T; + let _13: *const T; scope 18 { - let _22: usize; + let _21: usize; scope 19 { scope 22 (inlined #[track_caller] core::num::::unchecked_sub) { scope 23 (inlined core::ub_checks::check_language_ub) { @@ -44,21 +44,21 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 26 (inlined as PartialEq>::eq) { + let mut _15: *mut T; let mut _16: *mut T; - let mut _17: *mut T; scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined NonNull::::as_ptr) { } } scope 29 (inlined NonNull::::add) { + let mut _18: *const T; let mut _19: *const T; - let mut _20: *const T; scope 30 (inlined NonNull::::as_ptr) { } } scope 31 (inlined NonNull::::as_ref::<'_>) { - let _24: *const T; + let _23: *const T; scope 32 (inlined NonNull::::as_ptr) { } scope 33 (inlined std::ptr::mut_ptr::::cast_const) { @@ -73,7 +73,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -112,7 +111,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -133,88 +131,86 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - _10 = copy _9; - StorageDead(_9); StorageDead(_4); StorageDead(_3); + StorageLive(_10); StorageLive(_11); - StorageLive(_12); - _11 = copy _6; - _12 = copy _10; + _10 = copy _6; + _11 = copy _9; goto -> bb4; } bb4: { - StorageLive(_26); + StorageLive(_25); + StorageLive(_12); StorageLive(_13); - StorageLive(_14); + StorageLive(_21); StorageLive(_22); - StorageLive(_23); - StorageLive(_15); - StorageLive(_25); + StorageLive(_14); + StorageLive(_24); + _12 = copy _10; _13 = copy _11; - _14 = copy _12; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageLive(_18); - _15 = copy _14 as std::ptr::NonNull (Transmute); - StorageLive(_16); - _16 = copy _13 as *mut T (Transmute); StorageLive(_17); - _17 = copy _15 as *mut T (Transmute); - _18 = Eq(move _16, move _17); - StorageDead(_17); + _14 = copy _13 as std::ptr::NonNull (Transmute); + StorageLive(_15); + _15 = copy _12 as *mut T (Transmute); + StorageLive(_16); + _16 = copy _14 as *mut T (Transmute); + _17 = Eq(move _15, move _16); StorageDead(_16); - switchInt(move _18) -> [0: bb6, otherwise: bb7]; + StorageDead(_15); + switchInt(move _17) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_18); - StorageLive(_21); + StorageDead(_17); StorageLive(_20); StorageLive(_19); - _19 = copy _13 as *const T (Transmute); - _20 = Offset(move _19, const 1_usize); + StorageLive(_18); + _18 = copy _12 as *const T (Transmute); + _19 = Offset(move _18, const 1_usize); + StorageDead(_18); + _20 = NonNull:: { pointer: move _19 }; StorageDead(_19); - _21 = NonNull:: { pointer: move _20 }; + _10 = move _20; StorageDead(_20); - _11 = move _21; - StorageDead(_21); goto -> bb13; } bb7: { - StorageDead(_18); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); + StorageDead(_17); + StorageDead(_24); StorageDead(_14); + StorageDead(_22); + StorageDead(_21); StorageDead(_13); + StorageDead(_12); goto -> bb10; } bb8: { - _22 = copy _14 as usize (Transmute); - switchInt(copy _22) -> [0: bb9, otherwise: bb12]; + _21 = copy _13 as usize (Transmute); + switchInt(copy _21) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); + StorageDead(_24); StorageDead(_14); + StorageDead(_22); + StorageDead(_21); StorageDead(_13); + StorageDead(_12); goto -> bb10; } bb10: { - StorageDead(_26); + StorageDead(_25); + StorageDead(_10); StorageDead(_11); - StorageDead(_12); drop(_2) -> [return: bb11, unwind unreachable]; } @@ -223,35 +219,35 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb12: { - _23 = SubUnchecked(copy _22, const 1_usize); - _12 = copy _23 as *const T (Transmute); + _22 = SubUnchecked(copy _21, const 1_usize); + _11 = copy _22 as *const T (Transmute); goto -> bb13; } bb13: { - StorageLive(_24); - _24 = copy _13 as *const T (Transmute); - _25 = &(*_24); - StorageDead(_24); - _26 = Option::<&T>::Some(copy _25); - StorageDead(_25); - StorageDead(_15); + StorageLive(_23); + _23 = copy _12 as *const T (Transmute); + _24 = &(*_23); StorageDead(_23); - StorageDead(_22); + _25 = Option::<&T>::Some(copy _24); + StorageDead(_24); StorageDead(_14); + StorageDead(_22); + StorageDead(_21); StorageDead(_13); - _27 = copy ((_26 as Some).0: &T); + StorageDead(_12); + _26 = copy ((_25 as Some).0: &T); + StorageLive(_27); + _27 = &_2; StorageLive(_28); - _28 = &_2; - StorageLive(_29); - _29 = (copy _27,); - _30 = >::call(move _28, move _29) -> [return: bb14, unwind unreachable]; + _28 = (copy _26,); + _29 = >::call(move _27, move _28) -> [return: bb14, unwind unreachable]; } bb14: { - StorageDead(_29); StorageDead(_28); - StorageDead(_26); + StorageDead(_27); + StorageDead(_25); goto -> bb4; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 001023919804a..318cf52f5cfad 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,31 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _26: std::option::Option<&T>; - let mut _28: &impl Fn(&T); - let mut _29: (&T,); - let _30: (); + let mut _10: std::ptr::NonNull; + let mut _11: *const T; + let mut _25: std::option::Option<&T>; + let mut _27: &impl Fn(&T); + let mut _28: (&T,); + let _29: (); scope 1 { - debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; + debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _10; + debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _11; debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _27: &T; + let _26: &T; scope 2 { - debug x => _27; + debug x => _26; } scope 16 (inlined as Iterator>::next) { - let _13: std::ptr::NonNull; - let _15: std::ptr::NonNull; - let mut _18: bool; - let mut _21: std::ptr::NonNull; - let mut _23: usize; - let _25: &T; + let _12: std::ptr::NonNull; + let _14: std::ptr::NonNull; + let mut _17: bool; + let mut _20: std::ptr::NonNull; + let mut _22: usize; + let _24: &T; scope 17 { - let _14: *const T; + let _13: *const T; scope 18 { - let _22: usize; + let _21: usize; scope 19 { scope 22 (inlined #[track_caller] core::num::::unchecked_sub) { scope 23 (inlined core::ub_checks::check_language_ub) { @@ -44,21 +44,21 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 26 (inlined as PartialEq>::eq) { + let mut _15: *mut T; let mut _16: *mut T; - let mut _17: *mut T; scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined NonNull::::as_ptr) { } } scope 29 (inlined NonNull::::add) { + let mut _18: *const T; let mut _19: *const T; - let mut _20: *const T; scope 30 (inlined NonNull::::as_ptr) { } } scope 31 (inlined NonNull::::as_ref::<'_>) { - let _24: *const T; + let _23: *const T; scope 32 (inlined NonNull::::as_ptr) { } scope 33 (inlined std::ptr::mut_ptr::::cast_const) { @@ -73,7 +73,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -112,7 +111,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -133,88 +131,86 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - _10 = copy _9; - StorageDead(_9); StorageDead(_4); StorageDead(_3); + StorageLive(_10); StorageLive(_11); - StorageLive(_12); - _11 = copy _6; - _12 = copy _10; + _10 = copy _6; + _11 = copy _9; goto -> bb4; } bb4: { - StorageLive(_26); + StorageLive(_25); + StorageLive(_12); StorageLive(_13); - StorageLive(_14); + StorageLive(_21); StorageLive(_22); - StorageLive(_23); - StorageLive(_15); - StorageLive(_25); + StorageLive(_14); + StorageLive(_24); + _12 = copy _10; _13 = copy _11; - _14 = copy _12; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageLive(_18); - _15 = copy _14 as std::ptr::NonNull (Transmute); - StorageLive(_16); - _16 = copy _13 as *mut T (Transmute); StorageLive(_17); - _17 = copy _15 as *mut T (Transmute); - _18 = Eq(move _16, move _17); - StorageDead(_17); + _14 = copy _13 as std::ptr::NonNull (Transmute); + StorageLive(_15); + _15 = copy _12 as *mut T (Transmute); + StorageLive(_16); + _16 = copy _14 as *mut T (Transmute); + _17 = Eq(move _15, move _16); StorageDead(_16); - switchInt(move _18) -> [0: bb6, otherwise: bb7]; + StorageDead(_15); + switchInt(move _17) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_18); - StorageLive(_21); + StorageDead(_17); StorageLive(_20); StorageLive(_19); - _19 = copy _13 as *const T (Transmute); - _20 = Offset(move _19, const 1_usize); + StorageLive(_18); + _18 = copy _12 as *const T (Transmute); + _19 = Offset(move _18, const 1_usize); + StorageDead(_18); + _20 = NonNull:: { pointer: move _19 }; StorageDead(_19); - _21 = NonNull:: { pointer: move _20 }; + _10 = move _20; StorageDead(_20); - _11 = move _21; - StorageDead(_21); goto -> bb13; } bb7: { - StorageDead(_18); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); + StorageDead(_17); + StorageDead(_24); StorageDead(_14); + StorageDead(_22); + StorageDead(_21); StorageDead(_13); + StorageDead(_12); goto -> bb10; } bb8: { - _22 = copy _14 as usize (Transmute); - switchInt(copy _22) -> [0: bb9, otherwise: bb12]; + _21 = copy _13 as usize (Transmute); + switchInt(copy _21) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); + StorageDead(_24); StorageDead(_14); + StorageDead(_22); + StorageDead(_21); StorageDead(_13); + StorageDead(_12); goto -> bb10; } bb10: { - StorageDead(_26); + StorageDead(_25); + StorageDead(_10); StorageDead(_11); - StorageDead(_12); drop(_2) -> [return: bb11, unwind continue]; } @@ -223,35 +219,35 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb12: { - _23 = SubUnchecked(copy _22, const 1_usize); - _12 = copy _23 as *const T (Transmute); + _22 = SubUnchecked(copy _21, const 1_usize); + _11 = copy _22 as *const T (Transmute); goto -> bb13; } bb13: { - StorageLive(_24); - _24 = copy _13 as *const T (Transmute); - _25 = &(*_24); - StorageDead(_24); - _26 = Option::<&T>::Some(copy _25); - StorageDead(_25); - StorageDead(_15); + StorageLive(_23); + _23 = copy _12 as *const T (Transmute); + _24 = &(*_23); StorageDead(_23); - StorageDead(_22); + _25 = Option::<&T>::Some(copy _24); + StorageDead(_24); StorageDead(_14); + StorageDead(_22); + StorageDead(_21); StorageDead(_13); - _27 = copy ((_26 as Some).0: &T); + StorageDead(_12); + _26 = copy ((_25 as Some).0: &T); + StorageLive(_27); + _27 = &_2; StorageLive(_28); - _28 = &_2; - StorageLive(_29); - _29 = (copy _27,); - _30 = >::call(move _28, move _29) -> [return: bb14, unwind: bb15]; + _28 = (copy _26,); + _29 = >::call(move _27, move _28) -> [return: bb14, unwind: bb15]; } bb14: { - StorageDead(_29); StorageDead(_28); - StorageDead(_26); + StorageDead(_27); + StorageDead(_25); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir index 41e273151eca4..8734e80c0cd6b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -6,27 +6,27 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _0: (); let mut _3: usize; let mut _4: usize; - let mut _9: std::option::Option; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _8: std::option::Option; + let mut _10: bool; + let mut _12: &impl Fn(usize, &T); + let mut _13: (usize, &T); + let _14: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; - let _10: usize; + let _9: usize; scope 2 { - debug i => _10; - let _12: &T; + debug i => _9; + let _11: &T; scope 3 { - debug x => _12; + debug x => _11; } } scope 5 (inlined iter::range::>::next) { scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _6: bool; - let _7: usize; - let mut _8: usize; + let mut _5: bool; + let _6: usize; + let mut _7: usize; scope 7 { scope 9 (inlined ::forward_unchecked) { scope 10 (inlined #[track_caller] core::num::::unchecked_add) { @@ -38,7 +38,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 8 (inlined std::cmp::impls::::lt) { - let mut _5: usize; } } } @@ -48,25 +47,20 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb0: { _3 = PtrMetadata(copy _1); - StorageLive(_4); _4 = const 0_usize; goto -> bb1; } bb1: { - StorageLive(_9); - StorageLive(_6); + StorageLive(_8); StorageLive(_5); - _5 = copy _4; - _6 = Lt(move _5, copy _3); - StorageDead(_5); - switchInt(move _6) -> [0: bb2, otherwise: bb4]; + _5 = Lt(copy _4, copy _3); + switchInt(move _5) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_5); + StorageDead(_8); drop(_2) -> [return: bb3, unwind unreachable]; } @@ -75,31 +69,31 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb4: { - _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_usize); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); - StorageDead(_6); - _10 = copy ((_9 as Some).0: usize); - _11 = Lt(copy _10, copy _3); - assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind unreachable]; + _6 = copy _4; + StorageLive(_7); + _7 = AddUnchecked(copy _6, const 1_usize); + _4 = move _7; + StorageDead(_7); + _8 = Option::::Some(copy _6); + StorageDead(_5); + _9 = copy ((_8 as Some).0: usize); + _10 = Lt(copy _9, copy _3); + assert(move _10, "index out of bounds: the length is {} but the index is {}", copy _3, copy _9) -> [success: bb5, unwind unreachable]; } bb5: { - _12 = &(*_1)[_10]; + _11 = &(*_1)[_9]; + StorageLive(_12); + _12 = &_2; StorageLive(_13); - _13 = &_2; - StorageLive(_14); - _14 = (copy _10, copy _12); - _15 = >::call(move _13, move _14) -> [return: bb6, unwind unreachable]; + _13 = (copy _9, copy _11); + _14 = >::call(move _12, move _13) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_14); StorageDead(_13); - StorageDead(_9); + StorageDead(_12); + StorageDead(_8); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index ec781c1480c74..ba38ff1baaf4f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -6,27 +6,27 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _0: (); let mut _3: usize; let mut _4: usize; - let mut _9: std::option::Option; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _8: std::option::Option; + let mut _10: bool; + let mut _12: &impl Fn(usize, &T); + let mut _13: (usize, &T); + let _14: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; - let _10: usize; + let _9: usize; scope 2 { - debug i => _10; - let _12: &T; + debug i => _9; + let _11: &T; scope 3 { - debug x => _12; + debug x => _11; } } scope 5 (inlined iter::range::>::next) { scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _6: bool; - let _7: usize; - let mut _8: usize; + let mut _5: bool; + let _6: usize; + let mut _7: usize; scope 7 { scope 9 (inlined ::forward_unchecked) { scope 10 (inlined #[track_caller] core::num::::unchecked_add) { @@ -38,7 +38,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 8 (inlined std::cmp::impls::::lt) { - let mut _5: usize; } } } @@ -48,25 +47,20 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb0: { _3 = PtrMetadata(copy _1); - StorageLive(_4); _4 = const 0_usize; goto -> bb1; } bb1: { - StorageLive(_9); - StorageLive(_6); + StorageLive(_8); StorageLive(_5); - _5 = copy _4; - _6 = Lt(move _5, copy _3); - StorageDead(_5); - switchInt(move _6) -> [0: bb2, otherwise: bb4]; + _5 = Lt(copy _4, copy _3); + switchInt(move _5) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_5); + StorageDead(_8); drop(_2) -> [return: bb3, unwind continue]; } @@ -75,31 +69,31 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb4: { - _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_usize); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); - StorageDead(_6); - _10 = copy ((_9 as Some).0: usize); - _11 = Lt(copy _10, copy _3); - assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind: bb7]; + _6 = copy _4; + StorageLive(_7); + _7 = AddUnchecked(copy _6, const 1_usize); + _4 = move _7; + StorageDead(_7); + _8 = Option::::Some(copy _6); + StorageDead(_5); + _9 = copy ((_8 as Some).0: usize); + _10 = Lt(copy _9, copy _3); + assert(move _10, "index out of bounds: the length is {} but the index is {}", copy _3, copy _9) -> [success: bb5, unwind: bb7]; } bb5: { - _12 = &(*_1)[_10]; + _11 = &(*_1)[_9]; + StorageLive(_12); + _12 = &_2; StorageLive(_13); - _13 = &_2; - StorageLive(_14); - _14 = (copy _10, copy _12); - _15 = >::call(move _13, move _14) -> [return: bb6, unwind: bb7]; + _13 = (copy _9, copy _11); + _14 = >::call(move _12, move _13) -> [return: bb6, unwind: bb7]; } bb6: { - StorageDead(_14); StorageDead(_13); - StorageDead(_9); + StorageDead(_12); + StorageDead(_8); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index b09e36223441a..7728964ca84fc 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,22 +4,22 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Rev>; let mut _12: std::iter::Rev>; - let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + let mut _13: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -27,7 +27,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -62,7 +61,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -72,7 +71,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -93,37 +91,33 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_4); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: copy _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Rev::> { iter: copy _10 }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_13); + _13 = &mut (_12.0: std::slice::Iter<'_, T>); + _14 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -132,18 +126,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = copy ((_15 as Some).0: &T); + _16 = copy ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + _18 = (copy _16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 12b54b57b8448..379b27e629f98 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,22 +4,22 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Rev>; let mut _12: std::iter::Rev>; - let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + let mut _13: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -27,7 +27,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -62,7 +61,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -72,7 +71,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: move _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -93,37 +91,33 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_4); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: copy _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Rev::> { iter: copy _10 }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_13); + _13 = &mut (_12.0: std::slice::Iter<'_, T>); + _14 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -132,18 +126,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = copy ((_15 as Some).0: &T); + _16 = copy ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _18 = (copy _16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/crashes/128094.rs b/tests/ui/mir/gvn-nonsensical-coroutine-layout.rs similarity index 53% rename from tests/crashes/128094.rs rename to tests/ui/mir/gvn-nonsensical-coroutine-layout.rs index 56d09d78bed91..f0d174cd01b0a 100644 --- a/tests/crashes/128094.rs +++ b/tests/ui/mir/gvn-nonsensical-coroutine-layout.rs @@ -1,15 +1,19 @@ -//@ known-bug: rust-lang/rust#128094 +//! Verify that we do not ICE when a coroutine body is malformed. //@ compile-flags: -Zmir-enable-passes=+GVN //@ edition: 2018 pub enum Request { TestSome(T), + //~^ ERROR cannot find type `T` in this scope [E0412] } pub async fn handle_event(event: Request) { async move { static instance: Request = Request { bar: 17 }; + //~^ ERROR expected struct, variant or union type, found enum `Request` [E0574] &instance } .await; } + +fn main() {} diff --git a/tests/ui/mir/gvn-nonsensical-coroutine-layout.stderr b/tests/ui/mir/gvn-nonsensical-coroutine-layout.stderr new file mode 100644 index 0000000000000..abc7b16ca7415 --- /dev/null +++ b/tests/ui/mir/gvn-nonsensical-coroutine-layout.stderr @@ -0,0 +1,26 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/gvn-nonsensical-coroutine-layout.rs:6:14 + | +LL | TestSome(T), + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | pub enum Request { + | +++ + +error[E0574]: expected struct, variant or union type, found enum `Request` + --> $DIR/gvn-nonsensical-coroutine-layout.rs:12:36 + | +LL | static instance: Request = Request { bar: 17 }; + | ^^^^^^^ not a struct, variant or union type + | +help: consider importing this struct instead + | +LL + use std::error::Request; + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0412, E0574. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/crashes/135128.rs b/tests/ui/mir/gvn-nonsensical-sized-str.rs similarity index 51% rename from tests/crashes/135128.rs rename to tests/ui/mir/gvn-nonsensical-sized-str.rs index c718b758dc69b..29a82f8ce2a16 100644 --- a/tests/crashes/135128.rs +++ b/tests/ui/mir/gvn-nonsensical-sized-str.rs @@ -1,13 +1,16 @@ -//@ known-bug: #135128 +//! Verify that we do not ICE when optimizing bodies with nonsensical bounds. //@ compile-flags: -Copt-level=1 //@ edition: 2021 +//@ build-pass #![feature(trivial_bounds)] async fn return_str() -> str where str: Sized, + //~^ WARN trait bound str: Sized does not depend on any type or lifetime parameters { *"Sized".to_string().into_boxed_str() } + fn main() {} diff --git a/tests/ui/mir/gvn-nonsensical-sized-str.stderr b/tests/ui/mir/gvn-nonsensical-sized-str.stderr new file mode 100644 index 0000000000000..08f0193e9f61c --- /dev/null +++ b/tests/ui/mir/gvn-nonsensical-sized-str.stderr @@ -0,0 +1,10 @@ +warning: trait bound str: Sized does not depend on any type or lifetime parameters + --> $DIR/gvn-nonsensical-sized-str.rs:10:10 + | +LL | str: Sized, + | ^^^^^ + | + = note: `#[warn(trivial_bounds)]` on by default + +warning: 1 warning emitted +