about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_transform')
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs26
1 files changed, 5 insertions, 21 deletions
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index b91ae083cf5..9c5896c4e4a 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -15,22 +15,9 @@ pub struct AddRetag;
 /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic
 /// copies.  Data races are UB.)
 fn is_stable(place: PlaceRef<'_>) -> bool {
-    place.projection.iter().all(|elem| {
-        match elem {
-            // Which place this evaluates to can change with any memory write,
-            // so cannot assume this to be stable.
-            ProjectionElem::Deref => false,
-            // Array indices are interesting, but MIR building generates a *fresh*
-            // temporary for every array access, so the index cannot be changed as
-            // a side-effect.
-            ProjectionElem::Index { .. } |
-            // The rest is completely boring, they just offset by a constant.
-            ProjectionElem::Field { .. } |
-            ProjectionElem::ConstantIndex { .. } |
-            ProjectionElem::Subslice { .. } |
-            ProjectionElem::Downcast { .. } => true,
-        }
-    })
+    // Which place this evaluates to can change with any memory write,
+    // so cannot assume deref to be stable.
+    !place.has_deref()
 }
 
 /// Determine whether this type may contain a reference (or box), and thus needs retagging.
@@ -91,11 +78,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
         };
         let place_base_raw = |place: &Place<'tcx>| {
             // If this is a `Deref`, get the type of what we are deref'ing.
-            let deref_base =
-                place.projection.iter().rposition(|p| matches!(p, ProjectionElem::Deref));
-            if let Some(deref_base) = deref_base {
-                let base_proj = &place.projection[..deref_base];
-                let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty;
+            if place.has_deref() {
+                let ty = &local_decls[place.local].ty;
                 ty.is_unsafe_ptr()
             } else {
                 // Not a deref, and thus not raw.