about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/invalidation.rs4
-rw-r--r--compiler/rustc_borrowck/src/lib.rs17
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/resolver.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs11
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs14
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs16
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs1
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs1
-rw-r--r--compiler/rustc_middle/src/mir/type_visitable.rs4
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs7
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs30
-rw-r--r--compiler/rustc_mir_dataflow/src/un_derefer.rs36
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs13
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs1
-rw-r--r--compiler/rustc_mir_transform/src/deref_separator.rs3
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs36
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/separate_const_switch.rs2
-rw-r--r--src/test/mir-opt/derefer_complex_case.main.Derefer.diff10
-rw-r--r--src/test/mir-opt/derefer_inline_test.main.Derefer.diff20
-rw-r--r--src/test/mir-opt/derefer_terminator_test.main.Derefer.diff14
-rw-r--r--src/test/mir-opt/derefer_test.main.Derefer.diff12
-rw-r--r--src/test/mir-opt/derefer_test_multiple.main.Derefer.diff20
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff26
-rw-r--r--src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff26
-rw-r--r--src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff2
-rw-r--r--src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir4
-rw-r--r--src/test/mir-opt/inline/inline_generator.main.Inline.diff6
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir2
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs1
41 files changed, 274 insertions, 103 deletions
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs
index 721fd3e1c0f..ec521b1cf0a 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/invalidation.rs
@@ -289,6 +289,10 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
             | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
                 self.consume_operand(location, operand)
             }
+            Rvalue::CopyForDeref(ref place) => {
+                let op = &Operand::Copy(*place);
+                self.consume_operand(location, op);
+            }
 
             Rvalue::Len(place) | Rvalue::Discriminant(place) => {
                 let af = match *rvalue {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 2ed35062da1..e6142cab5c2 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1236,6 +1236,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
                 self.consume_operand(location, (operand, span), flow_state)
             }
+            Rvalue::CopyForDeref(place) => {
+                self.access_place(
+                    location,
+                    (place, span),
+                    (Deep, Read(ReadKind::Copy)),
+                    LocalMutationIsAllowed::No,
+                    flow_state,
+                );
+
+                // Finally, check if path was already moved.
+                self.check_if_path_or_subpath_is_moved(
+                    location,
+                    InitializationRequiringAction::Use,
+                    (place.as_ref(), span),
+                    flow_state,
+                );
+            }
 
             Rvalue::Len(place) | Rvalue::Discriminant(place) => {
                 let af = match *rvalue {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index d71a4983a92..cf2140097e6 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2269,6 +2269,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => {
                 self.check_operand(operand, location);
             }
+            Rvalue::CopyForDeref(place) => {
+                let op = &Operand::Copy(*place);
+                self.check_operand(op, location);
+            }
 
             Rvalue::BinaryOp(_, box (left, right))
             | Rvalue::CheckedBinaryOp(_, box (left, right)) => {
@@ -2299,6 +2303,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::BinaryOp(..)
             | Rvalue::CheckedBinaryOp(..)
             | Rvalue::NullaryOp(..)
+            | Rvalue::CopyForDeref(..)
             | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..) => None,
 
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index f71d749df62..63cd4d6de4c 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -503,6 +503,11 @@ fn codegen_stmt<'tcx>(
                     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::AddressOf(_, place) => {
                     let place = codegen_place(fx, place);
                     let ref_ = place.place_ref(fx, lval.layout());
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 55ab8b08d4a..26b9fbf4428 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -8,6 +8,7 @@ use crate::traits::*;
 use crate::MemFlags;
 
 use rustc_middle::mir;
+use rustc_middle::mir::Operand;
 use rustc_middle::ty::cast::{CastTy, IntTy};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
@@ -344,6 +345,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_place_to_pointer(bx, place, mk_ref)
             }
 
+            mir::Rvalue::CopyForDeref(place) => {
+                let operand = self.codegen_operand(&mut bx, &Operand::Copy(place));
+                (bx, operand)
+            }
             mir::Rvalue::AddressOf(mutability, place) => {
                 let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
                     tcx.mk_ptr(ty::TypeAndMut { ty, mutbl: mutability })
@@ -698,6 +703,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool {
         match *rvalue {
             mir::Rvalue::Ref(..) |
+            mir::Rvalue::CopyForDeref(..) |
             mir::Rvalue::AddressOf(..) |
             mir::Rvalue::Len(..) |
             mir::Rvalue::Cast(..) | // (*)
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 240910c08b2..fea158a9fe4 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -172,6 +172,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.copy_op(&op, &dest, /*allow_transmute*/ false)?;
             }
 
+            CopyForDeref(ref place) => {
+                let op = self.eval_place_to_op(*place, Some(dest.layout))?;
+                self.copy_op(&op, &dest, /* allow_transmute*/ false)?;
+            }
+
             BinaryOp(bin_op, box (ref left, ref right)) => {
                 let layout = binop_left_homogeneous(bin_op).then_some(dest.layout);
                 let left = self.read_immediate(&self.eval_operand(left, layout)?)?;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 3dcd96df33c..39fabd17c52 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -446,6 +446,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             Rvalue::ThreadLocalRef(_) => self.check_op(ops::ThreadLocalAccess),
 
             Rvalue::Use(_)
+            | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Len(_)
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 0aa7b117b89..9941afe5a12 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -260,6 +260,8 @@ where
             in_place::<Q, _>(cx, in_local, place.as_ref())
         }
 
+        Rvalue::CopyForDeref(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
+
         Rvalue::Use(operand)
         | Rvalue::Repeat(operand, _)
         | Rvalue::UnaryOp(_, operand)
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
index fd7febc17a3..60c1e495029 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
@@ -199,6 +199,7 @@ where
             mir::Rvalue::Cast(..)
             | mir::Rvalue::ShallowInitBox(..)
             | mir::Rvalue::Use(..)
+            | mir::Rvalue::CopyForDeref(..)
             | mir::Rvalue::ThreadLocalRef(..)
             | mir::Rvalue::Repeat(..)
             | mir::Rvalue::Len(..)
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 12527a9b2ae..ed4d8c95d1e 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -494,6 +494,10 @@ impl<'tcx> Validator<'_, 'tcx> {
             Rvalue::Use(operand) | Rvalue::Repeat(operand, _) => {
                 self.validate_operand(operand)?;
             }
+            Rvalue::CopyForDeref(place) => {
+                let op = &Operand::Copy(*place);
+                self.validate_operand(op)?
+            }
 
             Rvalue::Discriminant(place) | Rvalue::Len(place) => {
                 self.validate_place(place.as_ref())?
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index d3bf6b49f12..cd2b8be0acd 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -382,7 +382,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             };
         }
         match rvalue {
-            Rvalue::Use(_) => {}
+            Rvalue::Use(_) | Rvalue::CopyForDeref(_) => {}
             Rvalue::Aggregate(agg_kind, _) => {
                 let disallowed = match **agg_kind {
                     AggregateKind::Array(..) => false,
@@ -592,6 +592,15 @@ 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_some()
+                    {
+                        self.fail(
+                            location,
+                            "`CopyForDeref` should only be used for dereferenceable types",
+                        )
+                    }
+                }
                 // FIXME(JakobDegen): Check this for all rvalues, not just this one.
                 if let Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) = rvalue {
                     // The sides of an assignment must not alias. Currently this just checks whether
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 26314e3fe8e..333a88ba520 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -61,7 +61,7 @@ mod syntax;
 pub use syntax::*;
 mod switch_sources;
 pub mod tcx;
-mod terminator;
+pub mod terminator;
 pub use terminator::*;
 
 pub mod traversal;
@@ -925,6 +925,15 @@ impl<'tcx> LocalDecl<'tcx> {
         }
     }
 
+    /// Returns `true` if this is a DerefTemp
+    pub fn is_deref_temp(&self) -> bool {
+        match self.local_info {
+            Some(box LocalInfo::DerefTemp) => return true,
+            _ => (),
+        }
+        return false;
+    }
+
     /// Returns `true` is the local is from a compiler desugaring, e.g.,
     /// `__next` from a `for` loop.
     #[inline]
@@ -1795,6 +1804,7 @@ impl<'tcx> Rvalue<'tcx> {
             Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
 
             Rvalue::Use(_)
+            | Rvalue::CopyForDeref(_)
             | Rvalue::Repeat(_, _)
             | Rvalue::Ref(_, _, _)
             | Rvalue::ThreadLocalRef(_)
@@ -1889,6 +1899,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                 write!(fmt, "&{}{}{:?}", region, kind_str, place)
             }
 
+            CopyForDeref(ref place) => write!(fmt, "deref_copy {:#?}", place),
+
             AddressOf(mutability, ref place) => {
                 let kind_str = match mutability {
                     Mutability::Mut => "mut",
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 45fc5f24a60..510316c778b 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -52,6 +52,8 @@ pub enum MirPhase {
     /// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir`
     /// query.
     ConstsPromoted = 2,
+    /// After this projections may only contain deref projections as the first element.
+    Derefered = 3,
     /// Beginning with this phase, the following variants are disallowed:
     /// * [`TerminatorKind::DropAndReplace`]
     /// * [`TerminatorKind::FalseUnwind`]
@@ -66,9 +68,7 @@ pub enum MirPhase {
     /// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop`
     /// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands
     /// are allowed for non-`Copy` types.
-    DropsLowered = 3,
-    /// After this projections may only contain deref projections as the first element.
-    Derefered = 4,
+    DropsLowered = 4,
     /// Beginning with this phase, the following variant is disallowed:
     /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
     ///
@@ -1051,6 +1051,16 @@ pub enum Rvalue<'tcx> {
     /// initialized but its content as uninitialized. Like other pointer casts, this in general
     /// affects alias analysis.
     ShallowInitBox(Operand<'tcx>, Ty<'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
+    /// 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.
+    CopyForDeref(Place<'tcx>),
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index c99faf80187..fd3359ea80f 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -211,6 +211,7 @@ impl<'tcx> Rvalue<'tcx> {
                 }
             },
             Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty),
+            Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index 3c9850a9eb3..82a6b0c506f 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -122,6 +122,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
             Ref(region, bk, place) => {
                 Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
             }
+            CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?),
             AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
             Len(place) => Len(place.try_fold_with(folder)?),
             Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),
diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs
index d52ae5fac67..6a0801cb0dd 100644
--- a/compiler/rustc_middle/src/mir/type_visitable.rs
+++ b/compiler/rustc_middle/src/mir/type_visitable.rs
@@ -78,6 +78,10 @@ impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> {
         use crate::mir::Rvalue::*;
         match *self {
             Use(ref op) => op.visit_with(visitor),
+            CopyForDeref(ref place) => {
+                let op = &Operand::Copy(*place);
+                op.visit_with(visitor)
+            }
             Repeat(ref op, _) => op.visit_with(visitor),
             ThreadLocalRef(did) => did.visit_with(visitor),
             Ref(region, _, ref place) => {
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index d1477f9e2ae..1cfda71baf8 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -711,6 +711,13 @@ macro_rules! make_mir_visitor {
                         };
                         self.visit_place(path, ctx, location);
                     }
+                    Rvalue::CopyForDeref(place) => {
+                        self.visit_place(
+                            place,
+                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
+                            location
+                        );
+                    }
 
                     Rvalue::AddressOf(m, path) => {
                         let ctx = match m {
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 627fe3f7f57..0f8e86d1d66 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -102,7 +102,8 @@ where
             | mir::Rvalue::NullaryOp(..)
             | mir::Rvalue::UnaryOp(..)
             | mir::Rvalue::Discriminant(..)
-            | mir::Rvalue::Aggregate(..) => {}
+            | mir::Rvalue::Aggregate(..)
+            | mir::Rvalue::CopyForDeref(..) => {}
         }
     }
 
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index e4c130f0807..5793a286bd0 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -38,6 +38,7 @@ pub mod impls;
 pub mod move_paths;
 pub mod rustc_peek;
 pub mod storage;
+pub mod un_derefer;
 
 pub(crate) mod indexes {
     pub(crate) use super::move_paths::MovePathIndex;
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index b08cb50f77a..19aa71d7bc7 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -1,3 +1,4 @@
+use crate::un_derefer::UnDerefer;
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir::tcx::RvalueInitializationState;
 use rustc_middle::mir::*;
@@ -19,6 +20,7 @@ struct MoveDataBuilder<'a, 'tcx> {
     param_env: ty::ParamEnv<'tcx>,
     data: MoveData<'tcx>,
     errors: Vec<(Place<'tcx>, MoveError<'tcx>)>,
+    un_derefer: UnDerefer<'tcx>,
 }
 
 impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
@@ -32,6 +34,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             tcx,
             param_env,
             errors: Vec::new(),
+            un_derefer: UnDerefer { tcx: tcx, derefer_sidetable: Default::default() },
             data: MoveData {
                 moves: IndexVec::new(),
                 loc_map: LocationMap::new(body),
@@ -94,6 +97,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     ///
     /// Maybe we should have separate "borrowck" and "moveck" modes.
     fn move_path_for(&mut self, place: Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
+        if let Some(new_place) = self.builder.un_derefer.derefer(place.as_ref(), self.builder.body)
+        {
+            return self.move_path_for(new_place);
+        }
+
         debug!("lookup({:?})", place);
         let mut base = self.builder.data.rev_lookup.locals[place.local];
 
@@ -276,6 +284,12 @@ struct Gatherer<'b, 'a, 'tcx> {
 impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
         match &stmt.kind {
+            StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
+                assert!(place.projection.is_empty());
+                if self.builder.body.local_decls[place.local].is_deref_temp() {
+                    self.builder.un_derefer.derefer_sidetable.insert(place.local, *reffed);
+                }
+            }
             StatementKind::Assign(box (place, rval)) => {
                 self.create_move_path(*place);
                 if let RvalueInitializationState::Shallow = rval.initialization_state() {
@@ -294,7 +308,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             }
             StatementKind::StorageLive(_) => {}
             StatementKind::StorageDead(local) => {
-                self.gather_move(Place::from(*local));
+                // DerefTemp locals (results of CopyForDeref) don't actually move anything.
+                if !self.builder.un_derefer.derefer_sidetable.contains_key(&local) {
+                    self.gather_move(Place::from(*local));
+                }
             }
             StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) => {
                 span_bug!(
@@ -328,6 +345,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     self.gather_operand(operand);
                 }
             }
+            Rvalue::CopyForDeref(..) => unreachable!(),
             Rvalue::Ref(..)
             | Rvalue::AddressOf(..)
             | Rvalue::Discriminant(..)
@@ -439,6 +457,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
     fn gather_move(&mut self, place: Place<'tcx>) {
         debug!("gather_move({:?}, {:?})", self.loc, place);
+        if let Some(new_place) = self.builder.un_derefer.derefer(place.as_ref(), self.builder.body)
+        {
+            self.gather_move(new_place);
+            return;
+        }
 
         if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] =
             **place.projection
@@ -494,6 +517,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
         debug!("gather_init({:?}, {:?})", self.loc, place);
 
+        if let Some(new_place) = self.builder.un_derefer.derefer(place, self.builder.body) {
+            self.gather_init(new_place.as_ref(), kind);
+            return;
+        }
+
         let mut place = place;
 
         // Check if we are assigning into a field of a union, if so, lookup the place
diff --git a/compiler/rustc_mir_dataflow/src/un_derefer.rs b/compiler/rustc_mir_dataflow/src/un_derefer.rs
new file mode 100644
index 00000000000..ec2e516f7ac
--- /dev/null
+++ b/compiler/rustc_mir_dataflow/src/un_derefer.rs
@@ -0,0 +1,36 @@
+use rustc_data_structures::stable_map::FxHashMap;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+
+/// Used for reverting changes made by `DerefSeparator`
+pub struct UnDerefer<'tcx> {
+    pub tcx: TyCtxt<'tcx>,
+    pub derefer_sidetable: FxHashMap<Local, Place<'tcx>>,
+}
+
+impl<'tcx> UnDerefer<'tcx> {
+    pub fn derefer(&self, place: PlaceRef<'tcx>, body: &Body<'tcx>) -> Option<Place<'tcx>> {
+        let reffed = self.derefer_sidetable.get(&place.local)?;
+
+        let new_place = reffed.project_deeper(place.projection, self.tcx);
+        if body.local_decls[new_place.local].is_deref_temp() {
+            return self.derefer(new_place.as_ref(), body);
+        }
+        Some(new_place)
+    }
+
+    pub fn ref_finder(&mut self, body: &Body<'tcx>) {
+        for (_bb, data) in body.basic_blocks().iter_enumerated() {
+            for stmt in data.statements.iter() {
+                match stmt.kind {
+                    StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
+                        if body.local_decls[place.local].is_deref_temp() {
+                            self.derefer_sidetable.insert(place.local, reffed);
+                        }
+                    }
+                    _ => (),
+                }
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index 5d15f03491d..13ec1e7bb72 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -70,17 +70,6 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
     }
 }
 
-/// Determines whether or not this LocalDecl is temp, if not it needs retagging.
-fn is_not_temp<'tcx>(local_decl: &LocalDecl<'tcx>) -> bool {
-    if let Some(local_info) = &local_decl.local_info {
-        match local_info.as_ref() {
-            LocalInfo::DerefTemp => return false,
-            _ => (),
-        };
-    }
-    return true;
-}
-
 impl<'tcx> MirPass<'tcx> for AddRetag {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.opts.debugging_opts.mir_emit_retag
@@ -98,7 +87,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
             // a temporary and retag on that.
             is_stable(place.as_ref())
                 && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
-                && is_not_temp(&local_decls[place.local])
+                && !local_decls[place.local].is_deref_temp()
         };
         let place_base_raw = |place: &Place<'tcx>| {
             // If this is a `Deref`, get the type of what we are deref'ing.
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index fb5423dd157..acd9e605353 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -621,6 +621,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             // There's no other checking to do at this time.
             Rvalue::Aggregate(..)
             | Rvalue::Use(..)
+            | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
             | Rvalue::Len(..)
             | Rvalue::Cast(..)
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 09a5cb8280f..49db140c474 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -693,6 +693,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             // There's no other checking to do at this time.
             Rvalue::Aggregate(..)
             | Rvalue::Use(..)
+            | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
             | Rvalue::Len(..)
             | Rvalue::Cast(..)
diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs
index bfb3ad1be27..a00bb16f7ac 100644
--- a/compiler/rustc_mir_transform/src/deref_separator.rs
+++ b/compiler/rustc_mir_transform/src/deref_separator.rs
@@ -35,6 +35,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
                     last_deref_idx = idx;
                 }
             }
+
             for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
                 if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref {
                     let ty = p_ref.ty(&self.local_decls, self.tcx).ty;
@@ -54,7 +55,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
                     self.patcher.add_assign(
                         loc,
                         Place::from(temp),
-                        Rvalue::Use(Operand::Move(deref_place)),
+                        Rvalue::CopyForDeref(deref_place),
                     );
                     place_local = temp;
                     last_len = p_ref.projection.len();
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index e0e27c53f18..71ab6dee1b6 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -1,3 +1,4 @@
+use crate::deref_separator::deref_finder;
 use crate::MirPass;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::bit_set::BitSet;
@@ -9,6 +10,7 @@ use rustc_mir_dataflow::elaborate_drops::{DropElaborator, DropFlagMode, DropStyl
 use rustc_mir_dataflow::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
 use rustc_mir_dataflow::on_lookup_result_bits;
+use rustc_mir_dataflow::un_derefer::UnDerefer;
 use rustc_mir_dataflow::MoveDataParamEnv;
 use rustc_mir_dataflow::{on_all_children_bits, on_all_drop_children_bits};
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -26,6 +28,8 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);
 
+        let mut un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: Default::default() };
+        un_derefer.ref_finder(body);
         let def_id = body.source.def_id();
         let param_env = tcx.param_env_reveal_all_normalized(def_id);
         let move_data = match MoveData::gather_moves(body, tcx, param_env) {
@@ -41,7 +45,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
         let elaborate_patch = {
             let body = &*body;
             let env = MoveDataParamEnv { move_data, param_env };
-            let dead_unwinds = find_dead_unwinds(tcx, body, &env);
+            let dead_unwinds = find_dead_unwinds(tcx, body, &env, &un_derefer);
 
             let inits = MaybeInitializedPlaces::new(tcx, body, &env)
                 .into_engine(tcx, body)
@@ -65,10 +69,12 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
                 init_data: InitializationData { inits, uninits },
                 drop_flags: Default::default(),
                 patch: MirPatch::new(body),
+                un_derefer: un_derefer,
             }
             .elaborate()
         };
         elaborate_patch.apply(body);
+        deref_finder(tcx, body);
     }
 }
 
@@ -79,6 +85,7 @@ fn find_dead_unwinds<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     env: &MoveDataParamEnv<'tcx>,
+    und: &UnDerefer<'tcx>,
 ) -> BitSet<BasicBlock> {
     debug!("find_dead_unwinds({:?})", body.span);
     // We only need to do this pass once, because unwind edges can only
@@ -92,7 +99,9 @@ fn find_dead_unwinds<'tcx>(
     for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
         let place = match bb_data.terminator().kind {
             TerminatorKind::Drop { ref place, unwind: Some(_), .. }
-            | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => place,
+            | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => {
+                und.derefer(place.as_ref(), body).unwrap_or(*place)
+            }
             _ => continue,
         };
 
@@ -256,6 +265,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
     init_data: InitializationData<'a, 'tcx>,
     drop_flags: FxHashMap<MovePathIndex, Local>,
     patch: MirPatch<'tcx>,
+    un_derefer: UnDerefer<'tcx>,
 }
 
 impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
@@ -298,7 +308,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
             let terminator = data.terminator();
             let place = match terminator.kind {
                 TerminatorKind::Drop { ref place, .. }
-                | TerminatorKind::DropAndReplace { ref place, .. } => place,
+                | TerminatorKind::DropAndReplace { ref place, .. } => {
+                    self.un_derefer.derefer(place.as_ref(), self.body).unwrap_or(*place)
+                }
                 _ => continue,
             };
 
@@ -312,12 +324,17 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                 LookupResult::Parent(None) => continue,
                 LookupResult::Parent(Some(parent)) => {
                     let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent);
+
+                    if self.body.local_decls[place.local].is_deref_temp() {
+                        continue;
+                    }
+
                     if maybe_dead {
                         self.tcx.sess.delay_span_bug(
                             terminator.source_info.span,
                             &format!(
                                 "drop of untracked, uninitialized value {:?}, place {:?} ({:?})",
-                                bb, place, path,
+                                bb, place, path
                             ),
                         );
                     }
@@ -348,7 +365,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
             let resume_block = self.patch.resume_block();
             match terminator.kind {
-                TerminatorKind::Drop { place, target, unwind } => {
+                TerminatorKind::Drop { mut place, target, unwind } => {
+                    if let Some(new_place) = self.un_derefer.derefer(place.as_ref(), self.body) {
+                        place = new_place;
+                    }
+
                     self.init_data.seek_before(loc);
                     match self.move_data().rev_lookup.find(place.as_ref()) {
                         LookupResult::Exact(path) => elaborate_drop(
@@ -372,9 +393,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                         }
                     }
                 }
-                TerminatorKind::DropAndReplace { place, ref value, target, unwind } => {
+                TerminatorKind::DropAndReplace { mut place, ref value, target, unwind } => {
                     assert!(!data.is_cleanup);
 
+                    if let Some(new_place) = self.un_derefer.derefer(place.as_ref(), self.body) {
+                        place = new_place;
+                    }
                     self.elaborate_replace(loc, place, value, target, unwind);
                 }
                 _ => continue,
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 0887775aae5..9e5c22308e7 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -420,6 +420,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
         &remove_noop_landing_pads::RemoveNoopLandingPads,
         &cleanup_post_borrowck::CleanupNonCodegenStatements,
         &simplify::SimplifyCfg::new("early-opt"),
+        &deref_separator::Derefer,
         // These next passes must be executed together
         &add_call_guards::CriticalCallEdges,
         &elaborate_drops::ElaborateDrops,
@@ -432,7 +433,6 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
         &add_moves_for_packed_drops::AddMovesForPackedDrops,
         // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
         // but before optimizations begin.
-        &deref_separator::Derefer,
         &elaborate_box_derefs::ElaborateBoxDerefs,
         &add_retag::AddRetag,
         &lower_intrinsics::LowerIntrinsics,
diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs
index 194c2794aac..925eb10a1f7 100644
--- a/compiler/rustc_mir_transform/src/separate_const_switch.rs
+++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs
@@ -218,6 +218,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
                         // These rvalues move the place to track
                         Rvalue::Cast(_, Operand::Copy(place) | Operand::Move(place), _)
                         | Rvalue::Use(Operand::Copy(place) | Operand::Move(place))
+                        | Rvalue::CopyForDeref(place)
                         | Rvalue::UnaryOp(_, Operand::Copy(place) | Operand::Move(place))
                         | Rvalue::Discriminant(place) => tracked_place = place,
                     }
@@ -279,6 +280,7 @@ fn find_determining_place<'tcx>(
                     // that may be const in the predecessor
                     Rvalue::Use(Operand::Move(new) | Operand::Copy(new))
                     | Rvalue::UnaryOp(_, Operand::Copy(new) | Operand::Move(new))
+                    | Rvalue::CopyForDeref(new)
                     | Rvalue::Cast(_, Operand::Move(new) | Operand::Copy(new), _)
                     | Rvalue::Repeat(Operand::Move(new) | Operand::Copy(new), _)
                     | Rvalue::Discriminant(new)
diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
index 571efc91171..05d336be3bd 100644
--- a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff
@@ -69,7 +69,7 @@
           StorageLive(_12);                // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13
 -         _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13
 +         StorageLive(_15);                // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13
-+         _15 = move ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13
++         _15 = deref_copy ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13
 +         _12 = (*_15);                    // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13
 +         StorageDead(_15);                // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37
           StorageLive(_13);                // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37
@@ -102,10 +102,10 @@
           StorageDead(_6);                 // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40
           _5 = const ();                   // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40
           goto -> bb2;                     // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40
-      }
-  
-      bb8 (cleanup): {
-          resume;                          // scope 0 at $DIR/derefer_complex_case.rs:3:1: 5:2
++     }
++ 
++     bb8 (cleanup): {
++         resume;                          // scope 0 at $DIR/derefer_complex_case.rs:3:1: 5:2
       }
   }
   
diff --git a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
index 09cce1c1654..fe64156f42f 100644
--- a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff
@@ -8,7 +8,6 @@
       let mut _3: usize;                   // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
       let mut _4: *mut u8;                 // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
       let mut _5: std::boxed::Box<std::boxed::Box<u32>>; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
-      let mut _6: ();                      // in scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
       scope 1 {
       }
   
@@ -25,7 +24,7 @@
       bb1: {
           StorageLive(_5);                 // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
           _5 = ShallowInitBox(move _4, std::boxed::Box<u32>); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
-          (*_5) = f() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:10:9: 10:12
+          (*_5) = f() -> [return: bb2, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:10:9: 10:12
                                            // mir::Constant
                                            // + span: $DIR/derefer_inline_test.rs:10:9: 10:10
                                            // + literal: Const { ty: fn() -> Box<u32> {f}, val: Value(<ZST>) }
@@ -33,12 +32,12 @@
   
       bb2: {
           _1 = move _5;                    // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12
-          goto -> bb3;                     // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
+          drop(_5) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
       }
   
       bb3: {
           StorageDead(_5);                 // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
-          drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13
+          drop(_1) -> bb4;                 // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13
       }
   
       bb4: {
@@ -48,22 +47,15 @@
       }
   
       bb5 (cleanup): {
-          goto -> bb8;                     // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
+          drop(_1) -> bb7;                 // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13
       }
   
       bb6 (cleanup): {
-          resume;                          // scope 0 at $DIR/derefer_inline_test.rs:9:1: 11:2
+          drop(_5) -> bb7;                 // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
       }
   
       bb7 (cleanup): {
-          _6 = alloc::alloc::box_free::<Box<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::boxed::Box<u32>>), move (_5.1: std::alloc::Global)) -> bb6; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
-                                           // mir::Constant
-                                           // + span: $DIR/derefer_inline_test.rs:10:11: 10:12
-                                           // + literal: Const { ty: unsafe fn(Unique<Box<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Box<u32>, std::alloc::Global>}, val: Value(<ZST>) }
-      }
-  
-      bb8 (cleanup): {
-          goto -> bb7;                     // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12
+          resume;                          // scope 0 at $DIR/derefer_inline_test.rs:9:1: 11:2
       }
   }
   
diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
index cb110afe019..b26b3478551 100644
--- a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff
@@ -56,12 +56,12 @@
           _4 = &_5;                        // scope 2 at $DIR/derefer_terminator_test.rs:5:15: 5:22
 -         switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
 +         StorageLive(_10);                // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
-+         _10 = move (*_4);                // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
++         _10 = deref_copy (*_4);          // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
 +         StorageLive(_11);                // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
-+         _11 = move (*_10);               // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
++         _11 = deref_copy (*_10);         // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
 +         StorageDead(_10);                // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
 +         StorageLive(_12);                // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
-+         _12 = move (*_11);               // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
++         _12 = deref_copy (*_11);         // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
 +         StorageDead(_11);                // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
 +         switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22
       }
@@ -94,10 +94,10 @@
           StorageDead(_2);                 // scope 1 at $DIR/derefer_terminator_test.rs:10:1: 10:2
           StorageDead(_1);                 // scope 0 at $DIR/derefer_terminator_test.rs:10:1: 10:2
           return;                          // scope 0 at $DIR/derefer_terminator_test.rs:10:2: 10:2
-      }
-  
-      bb6 (cleanup): {
-          resume;                          // scope 0 at $DIR/derefer_terminator_test.rs:2:1: 10:2
++     }
++ 
++     bb6 (cleanup): {
++         resume;                          // scope 0 at $DIR/derefer_terminator_test.rs:2:1: 10:2
       }
   }
   
diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff
index 84476aeed7a..df76b3ebc2d 100644
--- a/src/test/mir-opt/derefer_test.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_test.main.Derefer.diff
@@ -34,13 +34,13 @@
           StorageLive(_4);                 // scope 2 at $DIR/derefer_test.rs:5:9: 5:10
 -         _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
 +         StorageLive(_6);                 // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
-+         _6 = move (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
++         _6 = deref_copy (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
 +         _4 = &mut ((*_6).0: i32);        // scope 2 at $DIR/derefer_test.rs:5:13: 5:26
 +         StorageDead(_6);                 // scope 3 at $DIR/derefer_test.rs:6:9: 6:10
           StorageLive(_5);                 // scope 3 at $DIR/derefer_test.rs:6:9: 6:10
 -         _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
 +         StorageLive(_7);                 // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
-+         _7 = move (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
++         _7 = deref_copy (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
 +         _5 = &mut ((*_7).1: i32);        // scope 3 at $DIR/derefer_test.rs:6:13: 6:26
 +         StorageDead(_7);                 // scope 0 at $DIR/derefer_test.rs:2:11: 7:2
           _0 = const ();                   // scope 0 at $DIR/derefer_test.rs:2:11: 7:2
@@ -49,10 +49,10 @@
           StorageDead(_2);                 // scope 1 at $DIR/derefer_test.rs:7:1: 7:2
           StorageDead(_1);                 // scope 0 at $DIR/derefer_test.rs:7:1: 7:2
           return;                          // scope 0 at $DIR/derefer_test.rs:7:2: 7:2
-      }
-  
-      bb1 (cleanup): {
-          resume;                          // scope 0 at $DIR/derefer_test.rs:2:1: 7:2
++     }
++ 
++     bb1 (cleanup): {
++         resume;                          // scope 0 at $DIR/derefer_test.rs:2:1: 7:2
       }
   }
   
diff --git a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
index b8e5a0c328f..044c92a2f43 100644
--- a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
+++ b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff
@@ -58,24 +58,24 @@
           StorageLive(_8);                 // scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10
 -         _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         StorageLive(_10);                // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
-+         _10 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
++         _10 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         StorageLive(_11);                // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
-+         _11 = move ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
++         _11 = deref_copy ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         StorageDead(_10);                // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         StorageLive(_12);                // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
-+         _12 = move ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
++         _12 = deref_copy ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         StorageDead(_11);                // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         _8 = &mut ((*_12).1: i32);       // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30
 +         StorageDead(_12);                // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
           StorageLive(_9);                 // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10
 -         _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         StorageLive(_13);                // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
-+         _13 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
++         _13 = deref_copy (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         StorageLive(_14);                // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
-+         _14 = move ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
++         _14 = deref_copy ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         StorageDead(_13);                // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         StorageLive(_15);                // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
-+         _15 = move ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
++         _15 = deref_copy ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         StorageDead(_14);                // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         _9 = &mut ((*_15).1: i32);       // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30
 +         StorageDead(_15);                // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2
@@ -87,10 +87,10 @@
           StorageDead(_2);                 // scope 1 at $DIR/derefer_test_multiple.rs:9:1: 9:2
           StorageDead(_1);                 // scope 0 at $DIR/derefer_test_multiple.rs:9:1: 9:2
           return;                          // scope 0 at $DIR/derefer_test_multiple.rs:9:2: 9:2
-      }
-  
-      bb1 (cleanup): {
-          resume;                          // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2
++     }
++ 
++     bb1 (cleanup): {
++         resume;                          // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2
       }
   }
   
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
index 67ce0c2aabb..988694000ee 100644
--- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
+++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff
@@ -93,7 +93,7 @@
 -         StorageDead(_5);                 // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24
           StorageLive(_34);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _34 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _11 = discriminant((*_34));      // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_34);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -101,7 +101,7 @@
   
       bb1: {
           StorageLive(_35);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _35 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _7 = discriminant((*_35));       // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_35);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -123,7 +123,7 @@
   
       bb3: {
           StorageLive(_36);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _36 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _8 = discriminant((*_36));       // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_36);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -131,7 +131,7 @@
   
       bb4: {
           StorageLive(_37);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _37 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _9 = discriminant((*_37));       // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_37);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -139,7 +139,7 @@
   
       bb5: {
           StorageLive(_38);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _38 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _10 = discriminant((*_38));      // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_38);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -149,14 +149,14 @@
 -         StorageLive(_12);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
           StorageLive(_39);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
-          _39 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
+          _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
 -         _12 = (((*_39) as Vw).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
 +         _15 = (((*_39) as Vw).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
           StorageDead(_39);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
 -         StorageLive(_13);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
           StorageLive(_40);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
-          _40 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
+          _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
 -         _13 = (((*_40) as Vw).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
 +         _16 = (((*_40) as Vw).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
           StorageDead(_40);                // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49
@@ -195,14 +195,14 @@
 -         StorageLive(_17);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
           StorageLive(_41);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
-          _41 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
+          _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
 -         _17 = (((*_41) as Vh).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
 +         _20 = (((*_41) as Vh).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
           StorageDead(_41);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
 -         StorageLive(_18);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
           StorageLive(_42);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
-          _42 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
+          _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
 -         _18 = (((*_42) as Vh).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
 +         _21 = (((*_42) as Vh).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
           StorageDead(_42);                // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49
@@ -241,14 +241,14 @@
 -         StorageLive(_22);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
           StorageLive(_43);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
-          _43 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
+          _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
 -         _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
 +         _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
           StorageDead(_43);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
 -         StorageLive(_23);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
           StorageLive(_44);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
-          _44 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
+          _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
 -         _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
 +         _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
           StorageDead(_44);                // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55
@@ -287,14 +287,14 @@
 -         StorageLive(_27);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
           StorageLive(_45);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
-          _45 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
+          _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
 -         _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
 +         _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
           StorageDead(_45);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
 -         StorageLive(_28);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
 +         nop;                             // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
           StorageLive(_46);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
-          _46 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
+          _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
 -         _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
 +         _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
           StorageDead(_46);                // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55
diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
index c2b00f915a4..1b090a33ffc 100644
--- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
+++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
@@ -79,7 +79,7 @@
           StorageDead(_6);                 // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24
           StorageDead(_5);                 // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24
           StorageLive(_34);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _34 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _11 = discriminant((*_34));      // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_34);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -87,7 +87,7 @@
   
       bb1: {
           StorageLive(_35);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _35 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _7 = discriminant((*_35));       // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_35);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -107,7 +107,7 @@
   
       bb3: {
           StorageLive(_36);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _36 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _8 = discriminant((*_36));       // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_36);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -115,7 +115,7 @@
   
       bb4: {
           StorageLive(_37);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _37 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _9 = discriminant((*_37));       // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_37);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -123,7 +123,7 @@
   
       bb5: {
           StorageLive(_38);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
-          _38 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
+          _38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           _10 = discriminant((*_38));      // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24
           StorageDead(_38);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
           switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24
@@ -132,12 +132,12 @@
       bb6: {
           StorageLive(_12);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
           StorageLive(_39);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
-          _39 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
+          _39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
           _12 = (((*_39) as Vw).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17
           StorageDead(_39);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
           StorageLive(_13);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
           StorageLive(_40);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
-          _40 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
+          _40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
           _13 = (((*_40) as Vw).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29
           StorageDead(_40);                // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49
           StorageLive(_14);                // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49
@@ -160,12 +160,12 @@
       bb7: {
           StorageLive(_17);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
           StorageLive(_41);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
-          _41 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
+          _41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
           _17 = (((*_41) as Vh).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17
           StorageDead(_41);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
           StorageLive(_18);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
           StorageLive(_42);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
-          _42 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
+          _42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
           _18 = (((*_42) as Vh).0: f32);   // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29
           StorageDead(_42);                // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49
           StorageLive(_19);                // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49
@@ -188,12 +188,12 @@
       bb8: {
           StorageLive(_22);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
           StorageLive(_43);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
-          _43 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
+          _43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
           _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19
           StorageDead(_43);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
           StorageLive(_23);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
           StorageLive(_44);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
-          _44 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
+          _44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
           _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33
           StorageDead(_44);                // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55
           StorageLive(_24);                // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55
@@ -216,12 +216,12 @@
       bb9: {
           StorageLive(_27);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
           StorageLive(_45);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
-          _45 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
+          _45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
           _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
           StorageDead(_45);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
           StorageLive(_28);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
           StorageLive(_46);                // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
-          _46 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
+          _46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
           _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
           StorageDead(_46);                // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55
           StorageLive(_29);                // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55
diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
index 982dd7a27bc..2ee73742502 100644
--- a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
+++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff
@@ -17,7 +17,7 @@
   
       bb1: {
           StorageLive(_4);                 // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
-          _4 = move (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
+          _4 = deref_copy (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
           _2 = discriminant((*_4));        // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
           StorageDead(_4);                 // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
           switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31
diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
index fc8118d475a..0e6ae6578e2 100644
--- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
@@ -46,12 +46,12 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
         _9 = move (_7.0: i32);           // scope 1 at $DIR/inline-closure-captures.rs:12:5: 12:9
         StorageLive(_10);                // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20
         StorageLive(_12);                // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20
-        _12 = move ((*_6).0: &i32);      // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20
+        _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20
         _10 = (*_12);                    // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20
         StorageDead(_12);                // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23
         StorageLive(_11);                // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23
         StorageLive(_13);                // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23
-        _13 = move ((*_6).1: &T);        // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23
+        _13 = deref_copy ((*_6).1: &T);  // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23
         _11 = (*_13);                    // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23
         StorageDead(_13);                // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24
         Deinit(_0);                      // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24
diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
index bb093c5bc09..b4f0abd1af5 100644
--- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
@@ -77,7 +77,7 @@
 +         StorageLive(_11);                // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
 +         StorageLive(_12);                // scope 0 at $DIR/inline-generator.rs:9:14: 9:46
 +         StorageLive(_13);                // scope 6 at $DIR/inline-generator.rs:15:5: 15:8
-+         _13 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:8
++         _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:8
 +         _12 = discriminant((*_13));      // scope 6 at $DIR/inline-generator.rs:15:5: 15:8
 +         StorageDead(_13);                // scope 6 at $DIR/inline-generator.rs:15:5: 15:8
 +         switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:8
@@ -125,7 +125,7 @@
 +         ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
 +         discriminant(_1) = 0;            // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
 +         StorageLive(_14);                // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
-+         _14 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
++         _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
 +         discriminant((*_14)) = 3;        // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
 +         StorageDead(_14);                // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
 +         goto -> bb1;                     // scope 0 at $DIR/inline-generator.rs:15:11: 15:39
@@ -139,7 +139,7 @@
 +         ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
 +         discriminant(_1) = 1;            // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
 +         StorageLive(_15);                // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
-+         _15 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
++         _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
 +         discriminant((*_15)) = 1;        // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
 +         StorageDead(_15);                // scope 6 at $DIR/inline-generator.rs:15:8: 15:8
 +         goto -> bb1;                     // scope 0 at $DIR/inline-generator.rs:15:8: 15:8
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
index 11a205eb415..b45dfb17bfe 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -22,7 +22,7 @@ fn b(_1: &mut Box<T>) -> &mut T {
         StorageLive(_5);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageLive(_6);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageLive(_7);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
-        _7 = move (*_4);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        _7 = deref_copy (*_4);           // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageLive(_8);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _8 = (((_7.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _6 = &mut (*_8);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
index b04a91d7c95..4e8547419ae 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -16,7 +16,7 @@ fn d(_1: &Box<T>) -> &T {
         StorageLive(_3);                 // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
         _3 = &(*_1);                     // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
         StorageLive(_4);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
-        _4 = move (*_3);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
+        _4 = deref_copy (*_3);           // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         StorageLive(_5);                 // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
         _2 = &(*_5);                     // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 498dcbb8900..f3283588c73 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -124,6 +124,7 @@ fn check_rvalue<'tcx>(
         Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
             check_place(tcx, *place, span, body)
         },
+        Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body),
         Rvalue::Repeat(operand, _)
         | Rvalue::Use(operand)
         | Rvalue::Cast(