about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Mark Martin <ericmarkmartin@gmail.com>2023-06-25 20:38:01 -0400
committerEric Mark Martin <ericmarkmartin@gmail.com>2023-06-25 20:38:01 -0400
commitc07c10d1e424d01e61c5900ec0700dd4c3caadb6 (patch)
tree7b57baa9e2151db389cf81f49ed03065788e3990
parent0c2c243342ec2a2427f0624fac5ac59f0ee6fbcd (diff)
downloadrust-c07c10d1e424d01e61c5900ec0700dd4c3caadb6.tar.gz
rust-c07c10d1e424d01e61c5900ec0700dd4c3caadb6.zip
use PlaceRef abstractions more consistently
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs8
-rw-r--r--compiler/rustc_borrowck/src/place_ext.rs6
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs27
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs7
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs16
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs12
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs11
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs19
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs19
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs8
10 files changed, 40 insertions, 93 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 34d466db2b4..1646bb63e15 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -123,13 +123,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     item_msg = access_place_desc;
                     debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref());
                     debug_assert!(is_closure_or_generator(
-                        Place::ty_from(
-                            the_place_err.local,
-                            the_place_err.projection,
-                            self.body,
-                            self.infcx.tcx
-                        )
-                        .ty
+                        the_place_err.ty(self.body, self.infcx.tcx).ty
                     ));
 
                     reason = if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs
index d521d0db213..3d7e8c6ebf3 100644
--- a/compiler/rustc_borrowck/src/place_ext.rs
+++ b/compiler/rustc_borrowck/src/place_ext.rs
@@ -46,11 +46,9 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
             }
         }
 
-        for (i, elem) in self.projection.iter().enumerate() {
-            let proj_base = &self.projection[..i];
-
+        for (i, (proj_base, elem)) in self.iter_projections().enumerate() {
             if elem == ProjectionElem::Deref {
-                let ty = Place::ty_from(self.local, proj_base, body, tcx).ty;
+                let ty = proj_base.ty(body, tcx).ty;
                 match ty.kind() {
                     ty::Ref(_, _, hir::Mutability::Not) if i == 0 => {
                         // For references to thread-local statics, we do need
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 25c485b814f..612406ce913 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -135,13 +135,11 @@ fn place_components_conflict<'tcx>(
     }
 
     // loop invariant: borrow_c is always either equal to access_c or disjoint from it.
-    for (i, (borrow_c, &access_c)) in
-        iter::zip(borrow_place.projection, access_place.projection).enumerate()
+    for ((borrow_place, borrow_c), &access_c) in
+        iter::zip(borrow_place.iter_projections(), access_place.projection)
     {
         debug!(?borrow_c, ?access_c);
 
-        let borrow_proj_base = &borrow_place.projection[..i];
-
         // Borrow and access path both have more components.
         //
         // Examples:
@@ -154,15 +152,7 @@ fn place_components_conflict<'tcx>(
         // check whether the components being borrowed vs
         // accessed are disjoint (as in the second example,
         // but not the first).
-        match place_projection_conflict(
-            tcx,
-            body,
-            borrow_local,
-            borrow_proj_base,
-            borrow_c,
-            access_c,
-            bias,
-        ) {
+        match place_projection_conflict(tcx, body, borrow_place, borrow_c, access_c, bias) {
             Overlap::Arbitrary => {
                 // We have encountered different fields of potentially
                 // the same union - the borrow now partially overlaps.
@@ -193,8 +183,7 @@ fn place_components_conflict<'tcx>(
     }
 
     if borrow_place.projection.len() > access_place.projection.len() {
-        for (i, elem) in borrow_place.projection[access_place.projection.len()..].iter().enumerate()
-        {
+        for (base, elem) in borrow_place.iter_projections().skip(access_place.projection.len()) {
             // Borrow path is longer than the access path. Examples:
             //
             // - borrow of `a.b.c`, access to `a.b`
@@ -203,8 +192,7 @@ fn place_components_conflict<'tcx>(
             // our place. This is a conflict if that is a part our
             // access cares about.
 
-            let proj_base = &borrow_place.projection[..access_place.projection.len() + i];
-            let base_ty = Place::ty_from(borrow_local, proj_base, body, tcx).ty;
+            let base_ty = base.ty(body, tcx).ty;
 
             match (elem, &base_ty.kind(), access) {
                 (_, _, Shallow(Some(ArtificialField::ArrayLength)))
@@ -308,8 +296,7 @@ fn place_base_conflict(l1: Local, l2: Local) -> Overlap {
 fn place_projection_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    pi1_local: Local,
-    pi1_proj_base: &[PlaceElem<'tcx>],
+    pi1: PlaceRef<'tcx>,
     pi1_elem: PlaceElem<'tcx>,
     pi2_elem: PlaceElem<'tcx>,
     bias: PlaceConflictBias,
@@ -331,7 +318,7 @@ fn place_projection_conflict<'tcx>(
                 debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD");
                 Overlap::EqualOrDisjoint
             } else {
-                let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty;
+                let ty = pi1.ty(body, tcx).ty;
                 if ty.is_union() {
                     // Different fields of a union, we are basically stuck.
                     debug!("place_element_conflict: STUCK-UNION");
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6697e1aff7d..ec9577af802 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2499,7 +2499,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             location, borrow_region, borrowed_place
         );
 
-        let mut cursor = borrowed_place.projection.as_ref();
         let tcx = self.infcx.tcx;
         let field = path_utils::is_upvar_field_projection(
             tcx,
@@ -2513,14 +2512,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             ConstraintCategory::Boring
         };
 
-        while let [proj_base @ .., elem] = cursor {
-            cursor = proj_base;
-
+        for (base, elem) in borrowed_place.as_ref().iter_projections().rev() {
             debug!("add_reborrow_constraint - iteration {:?}", elem);
 
             match elem {
                 ProjectionElem::Deref => {
-                    let base_ty = Place::ty_from(borrowed_place.local, proj_base, body, tcx).ty;
+                    let base_ty = base.ty(body, tcx).ty;
 
                     debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
                     match base_ty.kind() {
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 106cf111474..61bc24b4c61 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -617,30 +617,28 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
     }
     fn visit_projection_elem(
         &mut self,
-        place_local: Local,
-        proj_base: &[PlaceElem<'tcx>],
+        place_ref: PlaceRef<'tcx>,
         elem: PlaceElem<'tcx>,
         context: PlaceContext,
         location: Location,
     ) {
         trace!(
-            "visit_projection_elem: place_local={:?} proj_base={:?} elem={:?} \
+            "visit_projection_elem: place_ref={:?} elem={:?} \
             context={:?} location={:?}",
-            place_local,
-            proj_base,
+            place_ref,
             elem,
             context,
             location,
         );
 
-        self.super_projection_elem(place_local, proj_base, elem, context, location);
+        self.super_projection_elem(place_ref, elem, context, location);
 
         match elem {
             ProjectionElem::Deref => {
-                let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
+                let base_ty = place_ref.ty(self.body, self.tcx).ty;
                 if base_ty.is_unsafe_ptr() {
-                    if proj_base.is_empty() {
-                        let decl = &self.body.local_decls[place_local];
+                    if place_ref.projection.is_empty() {
+                        let decl = &self.body.local_decls[place_ref.local];
                         if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() {
                             let span = decl.source_info.span;
                             self.check_static(def_id, span);
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 3c350e25ba6..eda50d3a767 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -318,8 +318,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
 
     fn visit_projection_elem(
         &mut self,
-        local: Local,
-        proj_base: &[PlaceElem<'tcx>],
+        place_ref: PlaceRef<'tcx>,
         elem: PlaceElem<'tcx>,
         context: PlaceContext,
         location: Location,
@@ -334,7 +333,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             ProjectionElem::Deref
                 if self.mir_phase >= MirPhase::Runtime(RuntimePhase::PostCleanup) =>
             {
-                let base_ty = Place::ty_from(local, proj_base, &self.body.local_decls, self.tcx).ty;
+                let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty;
 
                 if base_ty.is_box() {
                     self.fail(
@@ -344,8 +343,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             ProjectionElem::Field(f, ty) => {
-                let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
-                let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
+                let parent_ty = place_ref.ty(&self.body.local_decls, self.tcx);
                 let fail_out_of_bounds = |this: &Self, location| {
                     this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
                 };
@@ -355,7 +353,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             location,
                             format!(
                                 "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`",
-                                parent, f, ty, f_ty
+                                place_ref, f, ty, f_ty
                             )
                         )
                     }
@@ -434,7 +432,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             }
             _ => {}
         }
-        self.super_projection_elem(local, proj_base, elem, context, location);
+        self.super_projection_elem(place_ref, elem, context, location);
     }
 
     fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) {
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 8d44e929afd..68f24d7eaa4 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1136,13 +1136,12 @@ macro_rules! visit_place_fns {
 
         fn visit_projection_elem(
             &mut self,
-            local: Local,
-            proj_base: &[PlaceElem<'tcx>],
+            place_ref: PlaceRef<'tcx>,
             elem: PlaceElem<'tcx>,
             context: PlaceContext,
             location: Location,
         ) {
-            self.super_projection_elem(local, proj_base, elem, context, location);
+            self.super_projection_elem(place_ref, elem, context, location);
         }
 
         fn super_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
@@ -1171,15 +1170,13 @@ macro_rules! visit_place_fns {
             location: Location,
         ) {
             for (base, elem) in place_ref.iter_projections().rev() {
-                let base_proj = base.projection;
-                self.visit_projection_elem(place_ref.local, base_proj, elem, context, location);
+                self.visit_projection_elem(base, elem, context, location);
             }
         }
 
         fn super_projection_elem(
             &mut self,
-            _local: Local,
-            _proj_base: &[PlaceElem<'tcx>],
+            _place_ref: PlaceRef<'tcx>,
             elem: PlaceElem<'tcx>,
             _context: PlaceContext,
             location: Location,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 7ec57add66b..623bef5ff2d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -677,21 +677,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // check that we just did stays valid. Since we can't assign to
             // unsized values, we only need to ensure that none of the
             // pointers in the base place are modified.
-            for (idx, elem) in base_place.projection.iter().enumerate().rev() {
+            for (base_place, elem) in base_place.iter_projections().rev() {
                 match elem {
                     ProjectionElem::Deref => {
-                        let fake_borrow_deref_ty = Place::ty_from(
-                            base_place.local,
-                            &base_place.projection[..idx],
-                            &self.local_decls,
-                            tcx,
-                        )
-                        .ty;
+                        let fake_borrow_deref_ty = base_place.ty(&self.local_decls, tcx).ty;
                         let fake_borrow_ty =
                             tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
                         let fake_borrow_temp =
                             self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span));
-                        let projection = tcx.mk_place_elems(&base_place.projection[..idx]);
+                        let projection = tcx.mk_place_elems(&base_place.projection);
                         self.cfg.push_assign(
                             block,
                             source_info,
@@ -705,12 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         fake_borrow_temps.push(fake_borrow_temp);
                     }
                     ProjectionElem::Index(_) => {
-                        let index_ty = Place::ty_from(
-                            base_place.local,
-                            &base_place.projection[..idx],
-                            &self.local_decls,
-                            tcx,
-                        );
+                        let index_ty = base_place.ty(&self.local_decls, tcx);
                         match index_ty.ty.kind() {
                             // The previous index expression has already
                             // done any index expressions needed here.
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 096bc0acfcc..7cdd3a21aca 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -113,22 +113,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
         // from `*(u.f: &_)` isn't allowed.
         let mut union_path = None;
 
-        for (i, elem) in place.projection.iter().enumerate() {
-            let proj_base = &place.projection[..i];
+        for (place_ref, elem) in place.as_ref().iter_projections() {
             let body = self.builder.body;
             let tcx = self.builder.tcx;
-            let place_ty = Place::ty_from(place.local, proj_base, body, tcx).ty;
+            let place_ty = place_ref.ty(body, tcx).ty;
+
             match place_ty.kind() {
                 ty::Ref(..) | ty::RawPtr(..) => {
-                    let proj = &place.projection[..i + 1];
                     return Err(MoveError::cannot_move_out_of(
                         self.loc,
-                        BorrowedContent {
-                            target_place: Place {
-                                local: place.local,
-                                projection: tcx.mk_place_elems(proj),
-                            },
-                        },
+                        BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
                     ));
                 }
                 ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
@@ -163,10 +157,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             };
 
             if union_path.is_none() {
-                base = self.add_move_path(base, elem, |tcx| Place {
-                    local: place.local,
-                    projection: tcx.mk_place_elems(&place.projection[..i + 1]),
-                });
+                base = self.add_move_path(base, elem, |tcx| place_ref.project_deeper(&[elem], tcx));
             }
         }
 
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index b28fed7159f..37c7a3b5880 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -839,15 +839,13 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
     /// to normalization failure.
     fn visit_projection_elem(
         &mut self,
-        local: Local,
-        proj_base: &[PlaceElem<'tcx>],
+        place_ref: PlaceRef<'tcx>,
         elem: PlaceElem<'tcx>,
         context: PlaceContext,
         location: Location,
     ) {
         if let ProjectionElem::Field(f, ty) = elem {
-            let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
-            let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx);
+            let parent_ty = place_ref.ty(&self.callee_body.local_decls, self.tcx);
             let check_equal = |this: &mut Self, f_ty| {
                 if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
                     trace!(?ty, ?f_ty);
@@ -926,7 +924,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
             }
         }
 
-        self.super_projection_elem(local, proj_base, elem, context, location);
+        self.super_projection_elem(place_ref, elem, context, location);
     }
 }