about summary refs log tree commit diff
diff options
context:
space:
mode:
authorouz-a <oguz.agcayazi@gmail.com>2022-05-12 00:27:06 +0300
committerouz-a <oguz.agcayazi@gmail.com>2022-07-22 17:32:50 +0300
commitc0e4230bf5596d83d61c7a4ca5b06f0490ac4dba (patch)
tree8fc6ffab0af955c639e321be1eca58c4ae31abdc
parent41419e70366962c9a878bfe673ef4df38db6f7f1 (diff)
downloadrust-c0e4230bf5596d83d61c7a4ca5b06f0490ac4dba.tar.gz
rust-c0e4230bf5596d83d61c7a4ca5b06f0490ac4dba.zip
simplify some code that depend on Deref
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs11
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs20
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs29
3 files changed, 32 insertions, 28 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 58cee0c8bb0..38e09f539de 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -435,16 +435,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             LocalRef::Place(place) => place,
             LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
             LocalRef::Operand(..) => {
-                if let Some(elem) = place_ref
-                    .projection
-                    .iter()
-                    .enumerate()
-                    .find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
-                {
-                    base = elem.0 + 1;
+                if place_ref.ret_deref().is_some() {
+                    base = 1;
                     let cg_base = self.codegen_consume(
                         bx,
-                        mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
+                        mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref },
                     );
 
                     cg_base.deref(bx.cx())
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 702cc48ff7b..2a31441ec7b 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1461,6 +1461,16 @@ impl<'tcx> Place<'tcx> {
         self.projection.iter().any(|elem| elem.is_indirect())
     }
 
+    /// If MirPhase >= Derefered and if projection contains Deref,
+    /// It's guaranteed to be in the first place
+    pub fn ret_deref(&self) -> Option<PlaceElem<'tcx>> {
+        if !self.projection.is_empty() && self.projection[0] == PlaceElem::Deref {
+            return Some(self.projection[0]);
+        } else {
+            None
+        }
+    }
+
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
     /// a single deref of a local.
     #[inline(always)]
@@ -1533,6 +1543,16 @@ impl<'tcx> PlaceRef<'tcx> {
         }
     }
 
+    /// If MirPhase >= Derefered and if projection contains Deref,
+    /// It's guaranteed to be in the first place
+    pub fn ret_deref(&self) -> Option<PlaceElem<'tcx>> {
+        if !self.projection.is_empty() && self.projection[0] == PlaceElem::Deref {
+            return Some(self.projection[0]);
+        } else {
+            None
+        }
+    }
+
     /// If this place represents a local variable like `_X` with no
     /// projections, return `Some(_X)`.
     #[inline]
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index b91ae083cf5..b0cbcff600c 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -15,22 +15,13 @@ 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,
-        }
-    })
+    if place.ret_deref().is_some() {
+        // Which place this evaluates to can change with any memory write,
+        // so cannot assume deref to be stable.
+        return false;
+    } else {
+        return true;
+    }
 }
 
 /// Determine whether this type may contain a reference (or box), and thus needs retagging.
@@ -91,10 +82,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];
+            if place.ret_deref().is_some() {
+                let base_proj = &place.projection[..0];
                 let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty;
                 ty.is_unsafe_ptr()
             } else {