about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbeepster4096 <19316085+beepster4096@users.noreply.github.com>2025-08-26 01:12:20 -0700
committerbeepster4096 <19316085+beepster4096@users.noreply.github.com>2025-09-18 19:55:40 -0700
commit7ce81d145359aa230f8fc2d7de12650091508329 (patch)
tree1c8b51794d6c3ed2bbfa5e9bef44071c3d407d4e /compiler
parent0c0c58b8e453f552ebd7f3a1545acdd109de028c (diff)
downloadrust-7ce81d145359aa230f8fc2d7de12650091508329.tar.gz
rust-7ce81d145359aa230f8fc2d7de12650091508329.zip
deref related cleanups in ref_prop
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs33
1 files changed, 13 insertions, 20 deletions
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
index 6f61215cee2..b9d6e74ecae 100644
--- a/compiler/rustc_mir_transform/src/ref_prop.rs
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -195,10 +195,10 @@ fn compute_replacement<'tcx>(
     //   including DEF. This violates the DEF dominates USE condition, and so is impossible.
     let is_constant_place = |place: Place<'_>| {
         // We only allow `Deref` as the first projection, to avoid surprises.
-        if place.projection.first() == Some(&PlaceElem::Deref) {
+        if let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() {
             // `place == (*some_local).xxx`, it is constant only if `some_local` is constant.
             // We approximate constness using SSAness.
-            ssa.is_ssa(place.local) && place.projection[1..].iter().all(PlaceElem::is_stable_offset)
+            ssa.is_ssa(place.local) && rest.iter().all(PlaceElem::is_stable_offset)
         } else {
             storage_live.has_single_storage(place.local)
                 && place.projection[..].iter().all(PlaceElem::is_stable_offset)
@@ -206,7 +206,7 @@ fn compute_replacement<'tcx>(
     };
 
     let mut can_perform_opt = |target: Place<'tcx>, loc: Location| {
-        if target.projection.first() == Some(&PlaceElem::Deref) {
+        if target.is_indirect_first_projection() {
             // We are creating a reborrow. As `place.local` is a reference, removing the storage
             // statements should not make it much harder for LLVM to optimize.
             storage_to_remove.insert(target.local);
@@ -266,7 +266,7 @@ fn compute_replacement<'tcx>(
             Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
                 let mut place = *place;
                 // Try to see through `place` in order to collapse reborrow chains.
-                if place.projection.first() == Some(&PlaceElem::Deref)
+                if let Some((&PlaceElem::Deref, rest)) = place.projection.split_first()
                     && let Value::Pointer(target, inner_needs_unique) = targets[place.local]
                     // Only see through immutable reference and pointers, as we do not know yet if
                     // mutable references are fully replaced.
@@ -274,7 +274,7 @@ fn compute_replacement<'tcx>(
                     // Only collapse chain if the pointee is definitely live.
                     && can_perform_opt(target, location)
                 {
-                    place = target.project_deeper(&place.projection[1..], tcx);
+                    place = target.project_deeper(rest, tcx);
                 }
                 assert_ne!(place.local, local);
                 if is_constant_place(place) {
@@ -323,7 +323,7 @@ fn compute_replacement<'tcx>(
                 return;
             }
 
-            if place.projection.first() != Some(&PlaceElem::Deref) {
+            if !place.is_indirect_first_projection() {
                 // This is not a dereference, nothing to do.
                 return;
             }
@@ -392,20 +392,15 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
     }
 
     fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) {
-        // If the debuginfo is a pointer to another place:
-        // - if it's a reborrow, see through it;
-        // - if it's a direct borrow, increase `debuginfo.references`.
+        // If the debuginfo is a pointer to another place
+        // and it's a reborrow: see through it
         while let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
             && place.projection.is_empty()
             && let Value::Pointer(target, _) = self.targets[place.local]
-            && target.projection.iter().all(|p| p.can_use_in_debuginfo())
+            && let &[PlaceElem::Deref] = &target.projection[..]
         {
-            if let Some((&PlaceElem::Deref, rest)) = target.projection.split_last() {
-                *place = Place::from(target.local).project_deeper(rest, self.tcx);
-                self.any_replacement = true;
-            } else {
-                break;
-            }
+            *place = Place::from(target.local);
+            self.any_replacement = true;
         }
 
         // Simplify eventual projections left inside `debuginfo`.
@@ -414,9 +409,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
 
     fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
         loop {
-            if place.projection.first() != Some(&PlaceElem::Deref) {
-                return;
-            }
+            let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() else { return };
 
             let Value::Pointer(target, _) = self.targets[place.local] else { return };
 
@@ -432,7 +425,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
                 return;
             }
 
-            *place = target.project_deeper(&place.projection[1..], self.tcx);
+            *place = target.project_deeper(rest, self.tcx);
             self.any_replacement = true;
         }
     }