From 7bc723572c43695e36d74c20c3c2a374a172f98a Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Aug 2025 02:09:20 -0700 Subject: [PATCH 1/6] remove DerefTemp and CopyFromDeref from runtime mir --- compiler/rustc_borrowck/src/lib.rs | 20 +------ .../src/polonius/legacy/loan_invalidations.rs | 7 +-- compiler/rustc_codegen_cranelift/src/base.rs | 6 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 4 +- .../src/check_consts/qualifs.rs | 2 +- .../rustc_const_eval/src/interpret/step.rs | 5 +- compiler/rustc_middle/src/mir/mod.rs | 6 +- compiler/rustc_middle/src/mir/syntax.rs | 8 ++- compiler/rustc_mir_transform/src/copy_prop.rs | 9 +-- .../src/dataflow_const_prop.rs | 11 +--- compiler/rustc_mir_transform/src/dest_prop.rs | 5 +- .../src/erase_deref_temps.rs | 41 ++++++++++++++ compiler/rustc_mir_transform/src/gvn.rs | 7 +-- .../rustc_mir_transform/src/jump_threading.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 2 + compiler/rustc_mir_transform/src/ref_prop.rs | 3 +- .../src/shim/async_destructor_ctor.rs | 8 +-- compiler/rustc_mir_transform/src/ssa.rs | 4 +- compiler/rustc_mir_transform/src/validate.rs | 55 ++++++++++++++++--- 19 files changed, 122 insertions(+), 82 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/erase_deref_temps.rs diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index d76d6a04e6e03..7900f1b0cd877 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1473,24 +1473,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { self.consume_operand(location, (operand, span), state) } - &Rvalue::CopyForDeref(place) => { - self.access_place( - location, - (place, span), - (Deep, Read(ReadKind::Copy)), - LocalMutationIsAllowed::No, - state, - ); - - // Finally, check if path was already moved. - self.check_if_path_or_subpath_is_moved( - location, - InitializationRequiringAction::Use, - (place.as_ref(), span), - state, - ); - } - &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => { let af = match *rvalue { Rvalue::Len(..) => Some(ArtificialField::ArrayLength), @@ -1553,6 +1535,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { Rvalue::WrapUnsafeBinder(op, _) => { self.consume_operand(location, (op, span), state); } + + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in borrowck"), } } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 99dd0b2dd4664..7d9c90ef9a04b 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -301,11 +301,6 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) | Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand), - &Rvalue::CopyForDeref(place) => { - let op = &Operand::Copy(place); - self.consume_operand(location, op); - } - &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => { let af = match rvalue { Rvalue::Len(..) => Some(ArtificialField::ArrayLength), @@ -336,6 +331,8 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { Rvalue::WrapUnsafeBinder(op, _) => { self.consume_operand(location, op); } + + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in borrowck"), } } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index bc0a0f034b236..b50315a0f2c3f 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -601,11 +601,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let val = codegen_operand(fx, operand); lval.write_cvalue(fx, val); } - Rvalue::CopyForDeref(place) => { - let cplace = codegen_place(fx, place); - let val = cplace.to_cvalue(fx); - lval.write_cvalue(fx, val) - } Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { let place = codegen_place(fx, place); let ref_ = place.place_ref(fx, lval.layout()); @@ -935,6 +930,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); } + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), } } StatementKind::StorageLive(_) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 8a67b8d6e5f13..29c344fa6d9d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -494,9 +494,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ref) } - mir::Rvalue::CopyForDeref(place) => { - self.codegen_operand(bx, &mir::Operand::Copy(place)) - } mir::Rvalue::RawPtr(kind, place) => { let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { Ty::new_ptr(tcx, ty, kind.to_mutbl_lossy()) @@ -740,6 +737,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.cx().layout_of(binder_ty); OperandRef { val: operand.val, layout } } + mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), } } diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index faf41f1658b70..1fcb13a076572 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -236,7 +236,7 @@ where in_place::(cx, in_local, place.as_ref()) } - Rvalue::CopyForDeref(place) => in_place::(cx, in_local, place.as_ref()), + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), Rvalue::Use(operand) | Rvalue::Repeat(operand, _) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 76e470b69dce3..cb25b04975913 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -185,10 +185,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.copy_op(&op, &dest)?; } - CopyForDeref(place) => { - let op = self.eval_place_to_op(place, Some(dest.layout))?; - self.copy_op(&op, &dest)?; - } + CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), BinaryOp(bin_op, box (ref left, ref right)) => { let layout = util::binop_left_homogeneous(bin_op).then_some(dest.layout); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c55c7fc6002c7..38a3478f563e7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1109,7 +1109,11 @@ pub enum LocalInfo<'tcx> { /// A temporary created during evaluating `if` predicate, possibly for pattern matching for `let`s, /// and subject to Edition 2024 temporary lifetime rules IfThenRescopeTemp { if_then: HirId }, - /// A temporary created during the pass `Derefer` to avoid it's retagging + /// A temporary created during the pass `Derefer` treated as a transparent alias + /// for the place its copied from by analysis passes such as `AddRetag` and `ElaborateDrops`. + /// + /// It may only be written to by a `CopyForDeref` and otherwise only accessed through a deref. + /// In runtime MIR, it is replaced with a normal `Boring` local. DerefTemp, /// A temporary created for borrow checking. FakeBorrow, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 6039a03aa29de..446da1a51138f 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -130,7 +130,9 @@ pub enum RuntimePhase { /// * [`TerminatorKind::Yield`] /// * [`TerminatorKind::CoroutineDrop`] /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` + /// * [`Rvalue::CopyForDeref`] /// * [`PlaceElem::OpaqueCast`] + /// * [`LocalInfo::DerefTemp`](super::LocalInfo::DerefTemp) /// /// And the following variants are allowed: /// * [`StatementKind::Retag`] @@ -1485,11 +1487,13 @@ pub enum Rvalue<'tcx> { /// A CopyForDeref is equivalent to a read from a place at the /// codegen level, but is treated specially by drop elaboration. When such a read happens, it /// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator) - /// that the only use of the returned value is a deref operation, immediately - /// followed by one or more projections. Drop elaboration treats this rvalue as if the + /// that the returned value is written into a `DerefTemp` local and that its only use is a deref operation, + /// immediately followed by one or more projections. Drop elaboration treats this rvalue as if the /// read never happened and just projects further. This allows simplifying various MIR /// optimizations and codegen backends that previously had to handle deref operations anywhere /// in a place. + /// + /// Disallowed in runtime MIR and is replaced by normal copies. CopyForDeref(Place<'tcx>), /// Wraps a value in an unsafe binder. diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index cddeefca68174..e3b47611e7413 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -74,9 +74,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> DenseBitSet { let mut fully_moved = DenseBitSet::new_filled(body.local_decls.len()); for (_, rvalue, _) in ssa.assignments(body) { - let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) - | Rvalue::CopyForDeref(place)) = rvalue - else { + let Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) = rvalue else { continue; }; @@ -85,7 +83,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> DenseBitSet { continue; } - if let Rvalue::Use(Operand::Copy(_)) | Rvalue::CopyForDeref(_) = rvalue { + if let Rvalue::Use(Operand::Copy(_)) = rvalue { fully_moved.remove(rhs); } } @@ -146,8 +144,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { // Do not leave tautological assignments around. if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind - && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = - *rhs + && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) = *rhs && lhs == rhs { stmt.make_nop(); diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index fe53de31f7583..e17c7e3ca015b 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -309,12 +309,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { self.assign_operand(state, target, operand); } } - Rvalue::CopyForDeref(rhs) => { - state.flood(target.as_ref(), &self.map); - if let Some(target) = self.map.find(target.as_ref()) { - self.assign_operand(state, target, &Operand::Copy(*rhs)); - } - } + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), Rvalue::Aggregate(kind, operands) => { // If we assign `target = Enum::Variant#0(operand)`, // we must make sure that all `target as Variant#i` are `Top`. @@ -492,9 +487,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } Rvalue::Discriminant(place) => state.get_discr(place.as_ref(), &self.map), Rvalue::Use(operand) => return self.handle_operand(operand, state), - Rvalue::CopyForDeref(place) => { - return self.handle_operand(&Operand::Copy(*place), state); - } + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), Rvalue::Ref(..) | Rvalue::RawPtr(..) => { // We don't track such places. return ValueOrPlace::TOP; diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 4c94a6c524e00..445ac595d79de 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -317,8 +317,7 @@ impl<'tcx> MutVisitor<'tcx> for Merger<'tcx> { match &statement.kind { StatementKind::Assign(box (dest, rvalue)) => { match rvalue { - Rvalue::CopyForDeref(place) - | Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => { + Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => { // These might've been turned into self-assignments by the replacement // (this includes the original statement we wanted to eliminate). if dest == place { @@ -751,7 +750,7 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { if let StatementKind::Assign(box ( lhs, - Rvalue::CopyForDeref(rhs) | Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), + Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), )) = &statement.kind { let Some((src, dest)) = places_to_candidate_pair(*lhs, *rhs, self.body) else { diff --git a/compiler/rustc_mir_transform/src/erase_deref_temps.rs b/compiler/rustc_mir_transform/src/erase_deref_temps.rs new file mode 100644 index 0000000000000..ee0c7715c3cb5 --- /dev/null +++ b/compiler/rustc_mir_transform/src/erase_deref_temps.rs @@ -0,0 +1,41 @@ +//! This pass converts all `DerefTemp` locals into normal temporaries +//! and turns their `CopyForDeref` rvalues into normal copies. + +use rustc_middle::mir::visit::MutVisitor; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +struct EraseDerefTempsVisitor<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> MutVisitor<'tcx> for EraseDerefTempsVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, _: Location) { + if let &mut Rvalue::CopyForDeref(place) = rvalue { + *rvalue = Rvalue::Use(Operand::Copy(place)) + } + } + + fn visit_local_decl(&mut self, _: Local, local_decl: &mut LocalDecl<'tcx>) { + if local_decl.is_deref_temp() { + let info = local_decl.local_info.as_mut().unwrap_crate_local(); + **info = LocalInfo::Boring; + } + } +} + +pub(super) struct EraseDerefTemps; + +impl<'tcx> crate::MirPass<'tcx> for EraseDerefTemps { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + EraseDerefTempsVisitor { tcx }.visit_body_preserves_cfg(body); + } + + fn is_required(&self) -> bool { + true + } +} diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 952da2cdf7253..fe4ae5ee6ab6f 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -831,12 +831,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let value = match *rvalue { // Forward values. Rvalue::Use(ref mut operand) => return self.simplify_operand(operand, location), - Rvalue::CopyForDeref(place) => { - let mut operand = Operand::Copy(place); - let val = self.simplify_operand(&mut operand, location); - *rvalue = Rvalue::Use(operand); - return val; - } // Roots. Rvalue::Repeat(ref mut op, amount) => { @@ -879,6 +873,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // Unsupported values. Rvalue::ThreadLocalRef(..) | Rvalue::ShallowInitBox(..) => return None, + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), }; let ty = rvalue.ty(self.local_decls, self.tcx); Some(self.insert(ty, value)) diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index f9e642e28ebd7..61363d9489ecf 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -455,7 +455,6 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { match rhs { Rvalue::Use(operand) => self.process_operand(bb, lhs, operand, state), // Transfer the conditions on the copy rhs. - Rvalue::CopyForDeref(rhs) => self.process_operand(bb, lhs, &Operand::Copy(*rhs), state), Rvalue::Discriminant(rhs) => { let Some(rhs) = self.map.find_discr(rhs.as_ref()) else { return }; state.insert_place_idx(rhs, lhs, &self.map); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 08f25276cecc1..1f75dc9343971 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -137,6 +137,7 @@ declare_passes! { mod dest_prop : DestinationPropagation; pub mod dump_mir : Marker; mod early_otherwise_branch : EarlyOtherwiseBranch; + mod erase_deref_temps : EraseDerefTemps; mod elaborate_box_derefs : ElaborateBoxDerefs; mod elaborate_drops : ElaborateDrops; mod function_item_references : FunctionItemReferences; @@ -615,6 +616,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // `AddRetag` needs to run after `ElaborateDrops` but before `ElaborateBoxDerefs`. // Otherwise it should run fairly late, but before optimizations begin. &add_retag::AddRetag, + &erase_deref_temps::EraseDerefTemps, &elaborate_box_derefs::ElaborateBoxDerefs, &coroutine::StateTransform, &Lint(known_panics_lint::KnownPanicsLint), diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index d1c2d6b508f2f..9826b263c31b9 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -214,8 +214,7 @@ fn compute_replacement<'tcx>( // This is a copy, just use the value we have in store for the previous one. // As we are visiting in `assignment_order`, ie. reverse postorder, `rhs` should // have been visited before. - Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) - | Rvalue::CopyForDeref(place) => { + Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => { if let Some(rhs) = place.as_local() && ssa.is_ssa(rhs) { diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 18d09473c191e..a0f1260cd986d 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -240,7 +240,7 @@ fn build_adrop_for_coroutine_shim<'tcx>( source_info, StatementKind::Assign(Box::new(( Place::from(proxy_ref_local), - Rvalue::CopyForDeref(proxy_ref_place), + Rvalue::Use(Operand::Copy(proxy_ref_place)), ))), ), ); @@ -261,7 +261,7 @@ fn build_adrop_for_coroutine_shim<'tcx>( source_info, StatementKind::Assign(Box::new(( Place::from(cor_ptr_local), - Rvalue::CopyForDeref(impl_ptr_place), + Rvalue::Use(Operand::Copy(impl_ptr_place)), ))), ), ); @@ -334,7 +334,7 @@ fn build_adrop_for_adrop_shim<'tcx>( source_info, StatementKind::Assign(Box::new(( Place::from(proxy_ref_local), - Rvalue::CopyForDeref(proxy_ref_place), + Rvalue::Use(Operand::Copy(proxy_ref_place)), ))), )); @@ -350,7 +350,7 @@ fn build_adrop_for_adrop_shim<'tcx>( source_info, StatementKind::Assign(Box::new(( Place::from(cor_ptr_local), - Rvalue::CopyForDeref(impl_ptr_place), + Rvalue::Use(Operand::Copy(impl_ptr_place)), ))), )); } diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index cd9a7f4a39dfe..3902eeac9b65a 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -295,9 +295,7 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len()); for (local, rvalue, _) in ssa.assignments(body) { - let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) - | Rvalue::CopyForDeref(place)) = rvalue - else { + let Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) = rvalue else { continue; }; diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 99e4782e4700c..aeefd9b401b22 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -9,7 +9,7 @@ use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::mir::coverage::CoverageKind; -use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -922,6 +922,20 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } + if let ClearCrossCrate::Set(box LocalInfo::DerefTemp) = + self.body.local_decls[place.local].local_info + && !place.is_indirect_first_projection() + { + if cntxt != PlaceContext::MutatingUse(MutatingUseContext::Store) + || place.as_local().is_none() + { + self.fail( + location, + format!("`DerefTemp` locals must only be dereferenced or directly assigned to"), + ); + } + } + self.super_place(place, cntxt, location); } @@ -934,7 +948,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { }; } match rvalue { - Rvalue::Use(_) | Rvalue::CopyForDeref(_) => {} + Rvalue::Use(_) => {} + Rvalue::CopyForDeref(_) => { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { + self.fail(location, "`CopyForDeref` should have been removed in runtime MIR"); + } + } Rvalue::Aggregate(kind, fields) => match **kind { AggregateKind::Tuple => {} AggregateKind::Array(dest) => { @@ -1432,13 +1451,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ), ); } - if let Rvalue::CopyForDeref(place) = rvalue { - if place.ty(&self.body.local_decls, self.tcx).ty.builtin_deref(true).is_none() { - self.fail( - location, - "`CopyForDeref` should only be used for dereferenceable types", - ) - } + + if let Some(local) = dest.as_local() + && let ClearCrossCrate::Set(box LocalInfo::DerefTemp) = + self.body.local_decls[local].local_info + && !matches!(rvalue, Rvalue::CopyForDeref(_)) + { + self.fail(location, "assignment to a `DerefTemp` must use `CopyForDeref`") } } StatementKind::AscribeUserType(..) => { @@ -1610,4 +1629,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.super_terminator(terminator, location); } + + fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { + if let ClearCrossCrate::Set(box LocalInfo::DerefTemp) = local_decl.local_info { + if self.body.phase >= MirPhase::Runtime(RuntimePhase::Initial) { + self.fail( + START_BLOCK.start_location(), + "`DerefTemp` should have been removed in runtime MIR", + ); + } else if local_decl.ty.builtin_deref(true).is_none() { + self.fail( + START_BLOCK.start_location(), + "`DerefTemp` should only be used for dereferenceable types", + ) + } + } + + self.super_local_decl(local, local_decl); + } } From 7e17cf1adf653c241ba96152595b82c48ebc206a Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Aug 2025 14:59:08 -0700 Subject: [PATCH 2/6] trivial test blessings --- .../struct.main.DataflowConstProp.32bit.diff | 16 ++++++------ .../struct.main.DataflowConstProp.64bit.diff | 16 ++++++------ ...ch_68867.try_sum.EarlyOtherwiseBranch.diff | 26 +++++++++---------- ...ness.no_downcast.EarlyOtherwiseBranch.diff | 2 +- .../gvn_copy_aggregate.all_copy_2.GVN.diff | 7 +++-- ....run2-{closure#0}.Inline.panic-unwind.diff | 22 ++++++++-------- ...f_nested_borrows.src.GVN.panic-unwind.diff | 6 ++--- ...g-pre-optimizations.after.panic-unwind.mir | 2 +- ...mes.foo.ScalarReplacementOfAggregates.diff | 8 +++--- 9 files changed, 51 insertions(+), 54 deletions(-) diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff index 3ea49265cee33..132dfd3d8178a 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff @@ -112,16 +112,16 @@ StorageDead(_10); StorageLive(_14); _14 = const {ALLOC0: &&SmallStruct}; - _31 = deref_copy (*_14); + _31 = copy (*_14); StorageLive(_11); - _32 = deref_copy (*_14); + _32 = copy (*_14); - _11 = copy ((*_32).0: f32); + _11 = const 9f32; StorageLive(_12); - _33 = deref_copy (*_14); + _33 = copy (*_14); _12 = copy ((*_33).1: std::option::Option); StorageLive(_13); - _34 = deref_copy (*_14); + _34 = copy (*_14); _13 = copy ((*_34).2: &[f32]); StorageDead(_14); StorageLive(_15); @@ -149,16 +149,16 @@ StorageDead(_22); StorageLive(_26); _26 = const {ALLOC1: &&BigStruct}; - _35 = deref_copy (*_26); + _35 = copy (*_26); StorageLive(_23); - _36 = deref_copy (*_26); + _36 = copy (*_26); - _23 = copy ((*_36).0: f32); + _23 = const 82f32; StorageLive(_24); - _37 = deref_copy (*_26); + _37 = copy (*_26); _24 = copy ((*_37).1: std::option::Option); StorageLive(_25); - _38 = deref_copy (*_26); + _38 = copy (*_26); _25 = copy ((*_38).2: &[f32]); StorageDead(_26); StorageLive(_27); diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff index 78a0944975c86..0f3e6f0cb17f7 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff @@ -112,16 +112,16 @@ StorageDead(_10); StorageLive(_14); _14 = const {ALLOC0: &&SmallStruct}; - _31 = deref_copy (*_14); + _31 = copy (*_14); StorageLive(_11); - _32 = deref_copy (*_14); + _32 = copy (*_14); - _11 = copy ((*_32).0: f32); + _11 = const 9f32; StorageLive(_12); - _33 = deref_copy (*_14); + _33 = copy (*_14); _12 = copy ((*_33).1: std::option::Option); StorageLive(_13); - _34 = deref_copy (*_14); + _34 = copy (*_14); _13 = copy ((*_34).2: &[f32]); StorageDead(_14); StorageLive(_15); @@ -149,16 +149,16 @@ StorageDead(_22); StorageLive(_26); _26 = const {ALLOC1: &&BigStruct}; - _35 = deref_copy (*_26); + _35 = copy (*_26); StorageLive(_23); - _36 = deref_copy (*_26); + _36 = copy (*_26); - _23 = copy ((*_36).0: f32); + _23 = const 82f32; StorageLive(_24); - _37 = deref_copy (*_26); + _37 = copy (*_26); _24 = copy ((*_37).1: std::option::Option); StorageLive(_25); - _38 = deref_copy (*_26); + _38 = copy (*_26); _25 = copy ((*_38).2: &[f32]); StorageDead(_26); StorageLive(_27); diff --git a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index fec318c1ab492..c8b516c14987b 100644 --- a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -76,7 +76,7 @@ _4 = (move _5, move _6); StorageDead(_6); StorageDead(_5); - _34 = deref_copy (_4.0: &ViewportPercentageLength); + _34 = copy (_4.0: &ViewportPercentageLength); _11 = discriminant((*_34)); switchInt(move _11) -> [0: bb2, 1: bb3, 2: bb4, 3: bb5, otherwise: bb12]; } @@ -92,35 +92,35 @@ } bb2: { - _35 = deref_copy (_4.1: &ViewportPercentageLength); + _35 = copy (_4.1: &ViewportPercentageLength); _7 = discriminant((*_35)); switchInt(move _7) -> [0: bb9, otherwise: bb1]; } bb3: { - _36 = deref_copy (_4.1: &ViewportPercentageLength); + _36 = copy (_4.1: &ViewportPercentageLength); _8 = discriminant((*_36)); switchInt(move _8) -> [1: bb8, otherwise: bb1]; } bb4: { - _37 = deref_copy (_4.1: &ViewportPercentageLength); + _37 = copy (_4.1: &ViewportPercentageLength); _9 = discriminant((*_37)); switchInt(move _9) -> [2: bb7, otherwise: bb1]; } bb5: { - _38 = deref_copy (_4.1: &ViewportPercentageLength); + _38 = copy (_4.1: &ViewportPercentageLength); _10 = discriminant((*_38)); switchInt(move _10) -> [3: bb6, otherwise: bb1]; } bb6: { StorageLive(_27); - _39 = deref_copy (_4.0: &ViewportPercentageLength); + _39 = copy (_4.0: &ViewportPercentageLength); _27 = copy (((*_39) as Vmax).0: f32); StorageLive(_28); - _40 = deref_copy (_4.1: &ViewportPercentageLength); + _40 = copy (_4.1: &ViewportPercentageLength); _28 = copy (((*_40) as Vmax).0: f32); StorageLive(_29); StorageLive(_30); @@ -139,10 +139,10 @@ bb7: { StorageLive(_22); - _41 = deref_copy (_4.0: &ViewportPercentageLength); + _41 = copy (_4.0: &ViewportPercentageLength); _22 = copy (((*_41) as Vmin).0: f32); StorageLive(_23); - _42 = deref_copy (_4.1: &ViewportPercentageLength); + _42 = copy (_4.1: &ViewportPercentageLength); _23 = copy (((*_42) as Vmin).0: f32); StorageLive(_24); StorageLive(_25); @@ -161,10 +161,10 @@ bb8: { StorageLive(_17); - _43 = deref_copy (_4.0: &ViewportPercentageLength); + _43 = copy (_4.0: &ViewportPercentageLength); _17 = copy (((*_43) as Vh).0: f32); StorageLive(_18); - _44 = deref_copy (_4.1: &ViewportPercentageLength); + _44 = copy (_4.1: &ViewportPercentageLength); _18 = copy (((*_44) as Vh).0: f32); StorageLive(_19); StorageLive(_20); @@ -183,10 +183,10 @@ bb9: { StorageLive(_12); - _45 = deref_copy (_4.0: &ViewportPercentageLength); + _45 = copy (_4.0: &ViewportPercentageLength); _12 = copy (((*_45) as Vw).0: f32); StorageLive(_13); - _46 = deref_copy (_4.1: &ViewportPercentageLength); + _46 = copy (_4.1: &ViewportPercentageLength); _13 = copy (((*_46) as Vw).0: f32); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff index 6a4c947b8826e..ab81f0a67e4eb 100644 --- a/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -16,7 +16,7 @@ } bb1: { - _4 = deref_copy (((*_1) as Some).0: &E<'_>); + _4 = copy (((*_1) as Some).0: &E<'_>); _2 = discriminant((*_4)); switchInt(move _2) -> [1: bb2, 0: bb3, otherwise: bb5]; } diff --git a/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff index 452d8a9332036..eed8cb7d62e70 100644 --- a/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff @@ -25,15 +25,14 @@ bb0: { - StorageLive(_2); -- _8 = deref_copy (*_1); + nop; -+ _8 = copy (*_1); + _8 = copy (*_1); _2 = copy ((*_8).0: i32); - StorageLive(_3); -- _9 = deref_copy (*_1); +- _9 = copy (*_1); - _3 = copy ((*_9).1: u64); - StorageLive(_4); -- _10 = deref_copy (*_1); +- _10 = copy (*_1); - _4 = copy ((*_10).2: [i8; 3]); + nop; + _9 = copy _8; diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 8b027e988b8e8..fc53dce3b7838 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -129,7 +129,7 @@ StorageLive(_8); _8 = move _4; StorageLive(_9); - _10 = deref_copy (_1.1: &mut std::task::Context<'_>); + _10 = copy (_1.1: &mut std::task::Context<'_>); _9 = &mut (*_10); - _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5]; + StorageLive(_11); @@ -150,7 +150,7 @@ + StorageLive(_40); + StorageLive(_41); + StorageLive(_42); -+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _33 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _32 = discriminant((*_33)); + switchInt(move _32) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7]; } @@ -204,8 +204,8 @@ - return; + bb5: { + _31 = move _9; -+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _34 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _35 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>); + StorageLive(_12); + StorageLive(_13); @@ -218,7 +218,7 @@ + StorageDead(_14); + _12 = move _13; + StorageDead(_13); -+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _36 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + (((*_36) as variant#3).1: std::future::Ready<()>) = move _12; + goto -> bb6; } @@ -231,7 +231,7 @@ + StorageLive(_19); + StorageLive(_20); + StorageLive(_21); -+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _37 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>); + _20 = &mut (*_21); + _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 }; @@ -285,7 +285,7 @@ + StorageDead(_12); + StorageDead(_28); + StorageDead(_29); -+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _38 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_38)) = 3; + goto -> bb4; + } @@ -300,13 +300,13 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _39 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12]; + } + + bb10: { + _7 = Poll::<()>::Ready(move _30); -+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _40 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_40)) = 1; + goto -> bb4; + } @@ -319,12 +319,12 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _41 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { -+ _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _42 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_42)) = 2; + goto -> bb2; + } diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff index d81bfa9310bc1..9ce17342a445c 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff @@ -16,17 +16,15 @@ bb0: { - StorageLive(_2); -- _6 = deref_copy (*_1); + nop; -+ _6 = copy (*_1); + _6 = copy (*_1); _2 = copy (*_6); _3 = unknown() -> [return: bb1, unwind continue]; } bb1: { StorageLive(_4); -- _7 = deref_copy (*_1); -+ _7 = copy (*_1); + _7 = copy (*_1); _4 = copy (*_7); StorageLive(_5); _5 = copy _2; diff --git a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir index da005d552e2bf..4861abead2f32 100644 --- a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir +++ b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -8,7 +8,7 @@ fn box_to_raw_mut(_1: &mut Box) -> *mut i32 { bb0: { Retag([fn entry] _1); - _2 = deref_copy (*_1); + _2 = copy (*_1); _3 = copy ((_2.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); _0 = &raw mut (*_3); Retag([raw] _0); diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 0d5fcf9ef1432..056dc4c42c11f 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -117,8 +117,8 @@ StorageLive(_15); StorageLive(_16); StorageLive(_17); -- _26 = deref_copy (_12.0: &std::boxed::Box); -+ _26 = deref_copy _34; +- _26 = copy (_12.0: &std::boxed::Box); ++ _26 = copy _34; _17 = &(*_26); _16 = core::fmt::rt::Argument::<'_>::new_display::>(move _17) -> [return: bb3, unwind unreachable]; } @@ -127,8 +127,8 @@ StorageDead(_17); StorageLive(_18); StorageLive(_19); -- _27 = deref_copy (_12.1: &u32); -+ _27 = deref_copy _35; +- _27 = copy (_12.1: &u32); ++ _27 = copy _35; _19 = &(*_27); _18 = core::fmt::rt::Argument::<'_>::new_display::(move _19) -> [return: bb4, unwind unreachable]; } From 6e5b3ec79e14177df522ac32910cbbb4ee98ea24 Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Aug 2025 15:08:08 -0700 Subject: [PATCH 3/6] slightly less trivial blessings some optimization is behaving slightly differently on box derefs after this change, but the difference is irrelevant --- ...g_operand.test.GVN.32bit.panic-unwind.diff | 29 +++++++++---------- ...g_operand.test.GVN.64bit.panic-unwind.diff | 29 +++++++++---------- ...ic_rust_call.call.Inline.panic-unwind.diff | 10 +++---- ...nline_box_fn.call.Inline.panic-unwind.diff | 10 +++---- ...67_inline_as_ref_as_mut.b.Inline.after.mir | 10 +++---- ...67_inline_as_ref_as_mut.d.Inline.after.mir | 10 +++---- 6 files changed, 48 insertions(+), 50 deletions(-) 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..88754cb02776c 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 @@ -8,14 +8,14 @@ let _3: std::boxed::Box<()>; let mut _6: *const (); let mut _8: *const [()]; - let mut _9: std::boxed::Box<()>; - let mut _10: *const (); - let mut _11: usize; + let mut _9: *const (); + let mut _10: usize; + let mut _11: std::ptr::NonNull<()>; scope 1 { debug vp_ctx => _1; let _4: *const (); scope 2 { - debug slf => _10; + debug slf => _9; let _5: *const [()]; scope 3 { debug bytes => _5; @@ -45,26 +45,25 @@ _1 = copy _2; StorageDead(_2); StorageLive(_4); -- _9 = deref_copy _3; -+ _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); - _4 = copy _10; + _11 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>); + _9 = copy _11 as *const () (Transmute); + _4 = copy _9; - StorageLive(_5); + nop; StorageLive(_6); - _6 = copy _4; -+ _6 = copy _10; - StorageLive(_11); - _11 = const 1_usize; -- _5 = *const [()] from (copy _6, copy _11); -+ _5 = *const [()] from (copy _10, const 1_usize); - StorageDead(_11); ++ _6 = copy _9; + StorageLive(_10); + _10 = const 1_usize; +- _5 = *const [()] from (copy _6, copy _10); ++ _5 = *const [()] from (copy _9, const 1_usize); + StorageDead(_10); StorageDead(_6); StorageLive(_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 _11 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..88754cb02776c 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 @@ -8,14 +8,14 @@ let _3: std::boxed::Box<()>; let mut _6: *const (); let mut _8: *const [()]; - let mut _9: std::boxed::Box<()>; - let mut _10: *const (); - let mut _11: usize; + let mut _9: *const (); + let mut _10: usize; + let mut _11: std::ptr::NonNull<()>; scope 1 { debug vp_ctx => _1; let _4: *const (); scope 2 { - debug slf => _10; + debug slf => _9; let _5: *const [()]; scope 3 { debug bytes => _5; @@ -45,26 +45,25 @@ _1 = copy _2; StorageDead(_2); StorageLive(_4); -- _9 = deref_copy _3; -+ _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); - _4 = copy _10; + _11 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>); + _9 = copy _11 as *const () (Transmute); + _4 = copy _9; - StorageLive(_5); + nop; StorageLive(_6); - _6 = copy _4; -+ _6 = copy _10; - StorageLive(_11); - _11 = const 1_usize; -- _5 = *const [()] from (copy _6, copy _11); -+ _5 = *const [()] from (copy _10, const 1_usize); - StorageDead(_11); ++ _6 = copy _9; + StorageLive(_10); + _10 = const 1_usize; +- _5 = *const [()] from (copy _6, copy _10); ++ _5 = *const [()] from (copy _9, const 1_usize); + StorageDead(_10); StorageDead(_6); StorageLive(_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 _11 as *mut () (Transmute); StorageDead(_8); StorageDead(_7); - StorageDead(_5); diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff index 21b20329d4fa9..50136ae8766b2 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff @@ -9,8 +9,8 @@ let mut _4: I; + scope 1 (inlined > as FnMut>::call_mut) { + let mut _5: &mut dyn std::ops::FnMut; -+ let mut _6: std::boxed::Box>; -+ let mut _7: *const dyn std::ops::FnMut; ++ let mut _6: *const dyn std::ops::FnMut; ++ let mut _7: std::ptr::NonNull>; + } bb0: { @@ -22,9 +22,9 @@ + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); -+ _6 = copy (*_3); -+ _7 = copy ((_6.0: std::ptr::Unique>).0: std::ptr::NonNull>) as *const dyn std::ops::FnMut (Transmute); -+ _5 = &mut (*_7); ++ _7 = copy (((*_3).0: std::ptr::Unique>).0: std::ptr::NonNull>); ++ _6 = copy _7 as *const dyn std::ops::FnMut (Transmute); ++ _5 = &mut (*_6); + _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2]; } diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff index 3a4a528e879fb..3b18052616e2f 100644 --- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff @@ -9,8 +9,8 @@ let mut _4: (i32,); + scope 1 (inlined as Fn<(i32,)>>::call) { + let mut _5: &dyn std::ops::Fn(i32); -+ let mut _6: std::boxed::Box; -+ let mut _7: *const dyn std::ops::Fn(i32); ++ let mut _6: *const dyn std::ops::Fn(i32); ++ let mut _7: std::ptr::NonNull; + } bb0: { @@ -23,9 +23,9 @@ + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); -+ _6 = copy (*_3); -+ _7 = copy ((_6.0: std::ptr::Unique).0: std::ptr::NonNull) as *const dyn std::ops::Fn(i32) (Transmute); -+ _5 = &(*_7); ++ _7 = copy (((*_3).0: std::ptr::Unique).0: std::ptr::NonNull); ++ _6 = copy _7 as *const dyn std::ops::Fn(i32) (Transmute); ++ _5 = &(*_6); + _2 = >::call(move _5, move _4) -> [return: bb4, unwind: bb2]; } diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 103475b608cee..688e6967c2f85 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -8,8 +8,8 @@ fn b(_1: &mut Box) -> &mut T { let mut _4: &mut std::boxed::Box; scope 1 (inlined as AsMut>::as_mut) { debug self => _4; - let mut _5: std::boxed::Box; - let mut _6: *const T; + let mut _5: *const T; + let mut _6: std::ptr::NonNull; } bb0: { @@ -19,9 +19,9 @@ fn b(_1: &mut Box) -> &mut T { _4 = copy _1; StorageLive(_5); StorageLive(_6); - _5 = copy (*_4); - _6 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const T (Transmute); - _3 = &mut (*_6); + _6 = copy (((*_4).0: std::ptr::Unique).0: std::ptr::NonNull); + _5 = copy _6 as *const T (Transmute); + _3 = &mut (*_5); StorageDead(_6); StorageDead(_5); _2 = copy _3; diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index babb26808cece..663741c62fb84 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -7,8 +7,8 @@ fn d(_1: &Box) -> &T { let mut _3: &std::boxed::Box; scope 1 (inlined as AsRef>::as_ref) { debug self => _3; - let mut _4: std::boxed::Box; - let mut _5: *const T; + let mut _4: *const T; + let mut _5: std::ptr::NonNull; } bb0: { @@ -17,9 +17,9 @@ fn d(_1: &Box) -> &T { _3 = copy _1; StorageLive(_4); StorageLive(_5); - _4 = copy (*_3); - _5 = copy ((_4.0: std::ptr::Unique).0: std::ptr::NonNull) as *const T (Transmute); - _2 = &(*_5); + _5 = copy (((*_3).0: std::ptr::Unique).0: std::ptr::NonNull); + _4 = copy _5 as *const T (Transmute); + _2 = &(*_4); StorageDead(_5); StorageDead(_4); _0 = copy _2; From 6d7ddab979c852edb2a07a29349dcdb823031662 Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Aug 2025 16:34:04 -0700 Subject: [PATCH 4/6] erase coroutine shim dereftemps --- compiler/rustc_mir_transform/src/coroutine.rs | 8 +++---- .../src/deref_separator.rs | 24 +++++++++++++++---- .../src/elaborate_drops.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 4 ++-- compiler/rustc_mir_transform/src/shim.rs | 10 ++++---- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 761d5461a996f..306239c26700f 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1622,19 +1622,19 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { let mut drop_shim = create_coroutine_drop_shim_async(tcx, &transform, body, drop_clean, can_unwind); // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, &mut drop_shim); + deref_finder(tcx, &mut drop_shim, false); body.coroutine.as_mut().unwrap().coroutine_drop_async = Some(drop_shim); } else { // If coroutine has no async drops, generating sync drop shim let mut drop_shim = create_coroutine_drop_shim(tcx, &transform, coroutine_ty, body, drop_clean); // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, &mut drop_shim); + deref_finder(tcx, &mut drop_shim, false); body.coroutine.as_mut().unwrap().coroutine_drop = Some(drop_shim); // For coroutine with sync drop, generating async proxy for `future_drop_poll` call let mut proxy_shim = create_coroutine_drop_shim_proxy_async(tcx, body); - deref_finder(tcx, &mut proxy_shim); + deref_finder(tcx, &mut proxy_shim, false); body.coroutine.as_mut().unwrap().coroutine_drop_proxy_async = Some(proxy_shim); } @@ -1642,7 +1642,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform { create_coroutine_resume_function(tcx, transform, body, can_return, can_unwind); // Run derefer to fix Derefs that are not in the first place - deref_finder(tcx, body); + deref_finder(tcx, body, false); } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs index bc914ea656415..1f380302804b9 100644 --- a/compiler/rustc_mir_transform/src/deref_separator.rs +++ b/compiler/rustc_mir_transform/src/deref_separator.rs @@ -11,6 +11,7 @@ struct DerefChecker<'a, 'tcx> { tcx: TyCtxt<'tcx>, patcher: MirPatch<'tcx>, local_decls: &'a LocalDecls<'tcx>, + add_deref_metadata: bool, } impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> { @@ -39,7 +40,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> { let temp = self.patcher.new_local_with_info( ty, self.local_decls[p_ref.local].source_info.span, - LocalInfo::DerefTemp, + if self.add_deref_metadata { + LocalInfo::DerefTemp + } else { + LocalInfo::Boring + }, ); // We are adding current p_ref's projections to our @@ -50,7 +55,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> { self.patcher.add_assign( loc, Place::from(temp), - Rvalue::CopyForDeref(deref_place), + if self.add_deref_metadata { + Rvalue::CopyForDeref(deref_place) + } else { + Rvalue::Use(Operand::Copy(deref_place)) + }, ); place_local = temp; last_len = p_ref.projection.len(); @@ -67,9 +76,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DerefChecker<'a, 'tcx> { } } -pub(super) fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +pub(super) fn deref_finder<'tcx>( + tcx: TyCtxt<'tcx>, + body: &mut Body<'tcx>, + add_deref_metadata: bool, +) { let patch = MirPatch::new(body); - let mut checker = DerefChecker { tcx, patcher: patch, local_decls: &body.local_decls }; + let mut checker = + DerefChecker { tcx, patcher: patch, local_decls: &body.local_decls, add_deref_metadata }; for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { checker.visit_basic_block_data(bb, data); @@ -80,7 +94,7 @@ pub(super) fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { impl<'tcx> crate::MirPass<'tcx> for Derefer { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - deref_finder(tcx, body); + deref_finder(tcx, body, true); } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 58dff4514a04d..c4ad29d663010 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -87,7 +87,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops { .elaborate() }; elaborate_patch.apply(body); - deref_finder(tcx, body); + deref_finder(tcx, body, true); } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 3d49eb4e8ef75..d9931142d964a 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -64,7 +64,7 @@ impl<'tcx> crate::MirPass<'tcx> for Inline { if inline::>(tcx, body) { debug!("running simplify cfg on {:?}", body.source); simplify_cfg(tcx, body); - deref_finder(tcx, body); + deref_finder(tcx, body, false); } } @@ -100,7 +100,7 @@ impl<'tcx> crate::MirPass<'tcx> for ForceInline { if inline::>(tcx, body) { debug!("running simplify cfg on {:?}", body.source); simplify_cfg(tcx, body); - deref_finder(tcx, body); + deref_finder(tcx, body, false); } } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index c687036f544dc..1bd948a4992d2 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -17,12 +17,13 @@ use rustc_span::source_map::{Spanned, dummy_spanned}; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; +use crate::deref_separator::deref_finder; use crate::elaborate_drop::{DropElaborator, DropFlagMode, DropStyle, Unwind, elaborate_drop}; use crate::patch::MirPatch; use crate::{ - abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator, inline, - instsimplify, mentioned_items, pass_manager as pm, remove_noop_landing_pads, - run_optimization_passes, simplify, + abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, inline, instsimplify, + mentioned_items, pass_manager as pm, remove_noop_landing_pads, run_optimization_passes, + simplify, }; mod async_destructor_ctor; @@ -222,6 +223,8 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< }; debug!("make_shim({:?}) = untransformed {:?}", instance, result); + deref_finder(tcx, &mut result, false); + // We don't validate MIR here because the shims may generate code that's // only valid in a `PostAnalysis` param-env. However, since we do initial // validation with the MirBuilt phase, which uses a user-facing param-env. @@ -232,7 +235,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< &[ &mentioned_items::MentionedItems, &add_moves_for_packed_drops::AddMovesForPackedDrops, - &deref_separator::Derefer, &remove_noop_landing_pads::RemoveNoopLandingPads, &simplify::SimplifyCfg::MakeShim, &instsimplify::InstSimplify::BeforeInline, From 5d490e987c4136357bf400f3e5ea9ef29ec6fa2d Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Wed, 13 Aug 2025 18:02:24 -0700 Subject: [PATCH 5/6] remove copyforderef from custom_mir it did not create DerefTemp locals when used, so it was never actually correct. --- .../src/builder/custom/parse/instruction.rs | 1 - compiler/rustc_span/src/symbol.rs | 1 - library/core/src/intrinsics/mir.rs | 3 +-- .../projections.copy_for_deref.built.after.mir | 12 ------------ tests/mir-opt/building/custom/projections.rs | 16 ---------------- 5 files changed, 1 insertion(+), 32 deletions(-) delete mode 100644 tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index 9825b947fe09a..e30097f71f35e 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -249,7 +249,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { }, @call(mir_len, args) => Ok(Rvalue::Len(self.parse_place(args[0])?)), @call(mir_ptr_metadata, args) => Ok(Rvalue::UnaryOp(UnOp::PtrMetadata, self.parse_operand(args[0])?)), - @call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)), ExprKind::Borrow { borrow_kind, arg } => Ok( Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?) ), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index acbed7a9eed81..763aee6e5f446 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1389,7 +1389,6 @@ symbols! { mir_cast_ptr_to_ptr, mir_cast_transmute, mir_checked, - mir_copy_for_deref, mir_debuginfo, mir_deinit, mir_discriminant, diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 55dcf7cd47e97..ac933561e9eef 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -233,7 +233,7 @@ //! //! - Operands implicitly convert to `Use` rvalues. //! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue. -//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions. +//! - [`Discriminant`] and [`Len`] have associated functions. //! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc. //! - The binary operation `Offset` can be created via [`Offset`]. //! - Checked binary operations are represented by wrapping the associated binop in [`Checked`]. @@ -406,7 +406,6 @@ define!( "mir_ptr_metadata", fn PtrMetadata(place: *const P) ->

::Metadata ); -define!("mir_copy_for_deref", fn CopyForDeref(place: T) -> T); define!("mir_retag", fn Retag(place: T)); define!("mir_move", fn Move(place: T) -> T); define!("mir_static", fn Static(s: T) -> &'static T); diff --git a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir deleted file mode 100644 index b28e96f10eae7..0000000000000 --- a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir +++ /dev/null @@ -1,12 +0,0 @@ -// MIR for `copy_for_deref` after built - -fn copy_for_deref(_1: (&i32, i32)) -> i32 { - let mut _0: i32; - let mut _2: &i32; - - bb0: { - _2 = deref_copy (_1.0: &i32); - _0 = copy (*_2); - return; - } -} diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs index 0250b9b84b621..e59eebd9952d7 100644 --- a/tests/mir-opt/building/custom/projections.rs +++ b/tests/mir-opt/building/custom/projections.rs @@ -79,19 +79,6 @@ fn simple_index(a: [i32; 10], b: &[i32]) -> i32 { } } -// EMIT_MIR projections.copy_for_deref.built.after.mir -#[custom_mir(dialect = "runtime", phase = "initial")] -fn copy_for_deref(x: (&i32, i32)) -> i32 { - mir! { - let temp: &i32; - { - temp = CopyForDeref(x.0); - RET = *temp; - Return() - } - } -} - fn main() { assert_eq!(unions(U { a: 5 }), 5); assert_eq!(tuples((5, 6)), (5, 6)); @@ -103,7 +90,4 @@ fn main() { assert_eq!(o, Some(10)); assert_eq!(simple_index([0; 10], &[0; 10]), 0); - - let one = 1; - assert_eq!(copy_for_deref((&one, one)), 1); } From bfc73ec624c029a61f856a356a40ec77f3609718 Mon Sep 17 00:00:00 2001 From: beepster4096 <19316085+beepster4096@users.noreply.github.com> Date: Sun, 17 Aug 2025 14:30:27 -0700 Subject: [PATCH 6/6] remove some deref_finder uses elaborate drops and inline don't seem to actually need it --- compiler/rustc_mir_transform/src/elaborate_drops.rs | 2 -- compiler/rustc_mir_transform/src/inline.rs | 3 --- 2 files changed, 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index c4ad29d663010..833a671de1d7d 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -14,7 +14,6 @@ use rustc_mir_dataflow::{ use rustc_span::Span; use tracing::{debug, instrument}; -use crate::deref_separator::deref_finder; use crate::elaborate_drop::{DropElaborator, DropFlagMode, DropStyle, Unwind, elaborate_drop}; use crate::patch::MirPatch; @@ -87,7 +86,6 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops { .elaborate() }; elaborate_patch.apply(body); - deref_finder(tcx, body, true); } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index d9931142d964a..2d603aa82bb0e 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -20,7 +20,6 @@ use rustc_span::source_map::Spanned; use tracing::{debug, instrument, trace, trace_span}; use crate::cost_checker::{CostChecker, is_call_like}; -use crate::deref_separator::deref_finder; use crate::simplify::simplify_cfg; use crate::validate::validate_types; use crate::{check_inline, util}; @@ -64,7 +63,6 @@ impl<'tcx> crate::MirPass<'tcx> for Inline { if inline::>(tcx, body) { debug!("running simplify cfg on {:?}", body.source); simplify_cfg(tcx, body); - deref_finder(tcx, body, false); } } @@ -100,7 +98,6 @@ impl<'tcx> crate::MirPass<'tcx> for ForceInline { if inline::>(tcx, body) { debug!("running simplify cfg on {:?}", body.source); simplify_cfg(tcx, body); - deref_finder(tcx, body, false); } } }