about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbeepster4096 <19316085+beepster4096@users.noreply.github.com>2024-03-13 12:34:29 -0700
committerbeepster4096 <19316085+beepster4096@users.noreply.github.com>2024-03-13 12:34:58 -0700
commita5cb61d39ba92beb8b48d9b4dfe72ac06fa4503c (patch)
tree698c9beaed0bde9c9de4abfed4abbdf1d5b075e4
parent3cbb93223f33024db464a4df27a13c7cce870173 (diff)
downloadrust-a5cb61d39ba92beb8b48d9b4dfe72ac06fa4503c.tar.gz
rust-a5cb61d39ba92beb8b48d9b4dfe72ac06fa4503c.zip
cleanup prefixes iterator
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs27
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs89
2 files changed, 28 insertions, 88 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 0776f455efd..cec79a4a3f5 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -39,7 +39,7 @@ use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
 use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt};
 use crate::{
     borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf,
-    InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind,
+    InitializationRequiringAction, MirBorrowckCtxt, WriteKind,
 };
 
 use super::{
@@ -114,7 +114,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             self.buffer_error(err);
         } else {
             if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) {
-                if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) {
+                if used_place.is_prefix_of(*reported_place) {
                     debug!(
                         "report_use_of_moved_or_uninitialized place: error suppressed mois={:?}",
                         move_out_indices
@@ -1995,21 +1995,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         kind: Option<WriteKind>,
     ) {
         let drop_span = place_span.1;
-        let root_place =
-            self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
+        let borrowed_local = borrow.borrowed_place.local;
 
         let borrow_spans = self.retrieve_borrow_spans(borrow);
         let borrow_span = borrow_spans.var_or_use_path_span();
 
-        assert!(root_place.projection.is_empty());
-        let proper_span = self.body.local_decls[root_place.local].source_info.span;
-
-        let root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection);
+        let proper_span = self.body.local_decls[borrowed_local].source_info.span;
 
-        if self.access_place_error_reported.contains(&(
-            Place { local: root_place.local, projection: root_place_projection },
-            borrow_span,
-        )) {
+        if self.access_place_error_reported.contains(&(Place::from(borrowed_local), borrow_span)) {
             debug!(
                 "suppressing access_place error when borrow doesn't live long enough for {:?}",
                 borrow_span
@@ -2017,12 +2010,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             return;
         }
 
-        self.access_place_error_reported.insert((
-            Place { local: root_place.local, projection: root_place_projection },
-            borrow_span,
-        ));
+        self.access_place_error_reported.insert((Place::from(borrowed_local), borrow_span));
 
-        let borrowed_local = borrow.borrowed_place.local;
         if self.body.local_decls[borrowed_local].is_ref_to_thread_local() {
             let err =
                 self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
@@ -2544,9 +2533,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             };
             (format!("{local_kind}`{place_desc}`"), format!("`{place_desc}` is borrowed here"))
         } else {
-            let root_place =
-                self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
-            let local = root_place.local;
+            let local = borrow.borrowed_place.local;
             match self.body.local_kind(local) {
                 LocalKind::Arg => (
                     "function parameter".to_string(),
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index 8bb3dc88b34..8a3a089d0ee 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -1,7 +1,4 @@
-//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
-//! place are formed by stripping away fields and derefs, except that
-//! we stop when we reach the deref of a shared reference. [...] "
-//!
+//! From the NLL RFC:
 //! "Shallow prefixes are found by stripping away fields, but stop at
 //! any dereference. So: writing a path like `a` is illegal if `a.b`
 //! is borrowed. But: writing `a` is legal if `*a` is borrowed,
@@ -9,9 +6,7 @@
 
 use super::MirBorrowckCtxt;
 
-use rustc_hir as hir;
-use rustc_middle::mir::{Body, PlaceRef, ProjectionElem};
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::mir::{PlaceRef, ProjectionElem};
 
 pub trait IsPrefixOf<'tcx> {
     fn is_prefix_of(&self, other: PlaceRef<'tcx>) -> bool;
@@ -25,9 +20,7 @@ impl<'tcx> IsPrefixOf<'tcx> for PlaceRef<'tcx> {
     }
 }
 
-pub(super) struct Prefixes<'cx, 'tcx> {
-    body: &'cx Body<'tcx>,
-    tcx: TyCtxt<'tcx>,
+pub(super) struct Prefixes<'tcx> {
     kind: PrefixSet,
     next: Option<PlaceRef<'tcx>>,
 }
@@ -39,24 +32,18 @@ pub(super) enum PrefixSet {
     All,
     /// Stops at any dereference.
     Shallow,
-    /// Stops at the deref of a shared reference.
-    Supporting,
 }
 
 impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     /// Returns an iterator over the prefixes of `place`
     /// (inclusive) from longest to smallest, potentially
     /// terminating the iteration early based on `kind`.
-    pub(super) fn prefixes(
-        &self,
-        place_ref: PlaceRef<'tcx>,
-        kind: PrefixSet,
-    ) -> Prefixes<'cx, 'tcx> {
-        Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx }
+    pub(super) fn prefixes(&self, place_ref: PlaceRef<'tcx>, kind: PrefixSet) -> Prefixes<'tcx> {
+        Prefixes { next: Some(place_ref), kind }
     }
 }
 
-impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
+impl<'tcx> Iterator for Prefixes<'tcx> {
     type Item = PlaceRef<'tcx>;
     fn next(&mut self) -> Option<Self::Item> {
         let mut cursor = self.next?;
@@ -91,57 +78,23 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                             panic!("Subtype projection is not allowed before borrow check")
                         }
                         ProjectionElem::Deref => {
-                            // (handled below)
+                            match self.kind {
+                                PrefixSet::Shallow => {
+                                    // Shallow prefixes are found by stripping away
+                                    // fields, but stop at *any* dereference.
+                                    // So we can just stop the traversal now.
+                                    self.next = None;
+                                    return Some(cursor);
+                                }
+                                PrefixSet::All => {
+                                    // All prefixes: just blindly enqueue the base
+                                    // of the projection.
+                                    self.next = Some(cursor_base);
+                                    return Some(cursor);
+                                }
+                            }
                         }
                     }
-
-                    assert_eq!(elem, ProjectionElem::Deref);
-
-                    match self.kind {
-                        PrefixSet::Shallow => {
-                            // Shallow prefixes are found by stripping away
-                            // fields, but stop at *any* dereference.
-                            // So we can just stop the traversal now.
-                            self.next = None;
-                            return Some(cursor);
-                        }
-                        PrefixSet::All => {
-                            // All prefixes: just blindly enqueue the base
-                            // of the projection.
-                            self.next = Some(cursor_base);
-                            return Some(cursor);
-                        }
-                        PrefixSet::Supporting => {
-                            // Fall through!
-                        }
-                    }
-
-                    assert_eq!(self.kind, PrefixSet::Supporting);
-                    // Supporting prefixes: strip away fields and
-                    // derefs, except we stop at the deref of a shared
-                    // reference.
-
-                    let ty = cursor_base.ty(self.body, self.tcx).ty;
-                    match ty.kind() {
-                        ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => {
-                            // don't continue traversing over derefs of raw pointers or shared
-                            // borrows.
-                            self.next = None;
-                            return Some(cursor);
-                        }
-
-                        ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => {
-                            self.next = Some(cursor_base);
-                            return Some(cursor);
-                        }
-
-                        ty::Adt(..) if ty.is_box() => {
-                            self.next = Some(cursor_base);
-                            return Some(cursor);
-                        }
-
-                        _ => panic!("unknown type fed to Projection Deref."),
-                    }
                 }
             }
         }