Skip to content

Commit b9ad9b7

Browse files
committed
Auto merge of #112693 - ericmarkmartin:use-more-placeref, r=spastorino
Use PlaceRef abstractions more often Associated issue: #80647 r? `@spastorino`
2 parents 2a15bda + c07c10d commit b9ad9b7

File tree

10 files changed

+40
-93
lines changed

10 files changed

+40
-93
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
123123
item_msg = access_place_desc;
124124
debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref());
125125
debug_assert!(is_closure_or_generator(
126-
Place::ty_from(
127-
the_place_err.local,
128-
the_place_err.projection,
129-
self.body,
130-
self.infcx.tcx
131-
)
132-
.ty
126+
the_place_err.ty(self.body, self.infcx.tcx).ty
133127
));
134128

135129
reason = if self.is_upvar_field_projection(access_place.as_ref()).is_some() {

compiler/rustc_borrowck/src/place_ext.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,9 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
4646
}
4747
}
4848

49-
for (i, elem) in self.projection.iter().enumerate() {
50-
let proj_base = &self.projection[..i];
51-
49+
for (i, (proj_base, elem)) in self.iter_projections().enumerate() {
5250
if elem == ProjectionElem::Deref {
53-
let ty = Place::ty_from(self.local, proj_base, body, tcx).ty;
51+
let ty = proj_base.ty(body, tcx).ty;
5452
match ty.kind() {
5553
ty::Ref(_, _, hir::Mutability::Not) if i == 0 => {
5654
// For references to thread-local statics, we do need

compiler/rustc_borrowck/src/places_conflict.rs

+7-20
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,11 @@ fn place_components_conflict<'tcx>(
137137
}
138138

139139
// loop invariant: borrow_c is always either equal to access_c or disjoint from it.
140-
for (i, (borrow_c, &access_c)) in
141-
iter::zip(borrow_place.projection, access_place.projection).enumerate()
140+
for ((borrow_place, borrow_c), &access_c) in
141+
iter::zip(borrow_place.iter_projections(), access_place.projection)
142142
{
143143
debug!(?borrow_c, ?access_c);
144144

145-
let borrow_proj_base = &borrow_place.projection[..i];
146-
147145
// Borrow and access path both have more components.
148146
//
149147
// Examples:
@@ -156,15 +154,7 @@ fn place_components_conflict<'tcx>(
156154
// check whether the components being borrowed vs
157155
// accessed are disjoint (as in the second example,
158156
// but not the first).
159-
match place_projection_conflict(
160-
tcx,
161-
body,
162-
borrow_local,
163-
borrow_proj_base,
164-
borrow_c,
165-
access_c,
166-
bias,
167-
) {
157+
match place_projection_conflict(tcx, body, borrow_place, borrow_c, access_c, bias) {
168158
Overlap::Arbitrary => {
169159
// We have encountered different fields of potentially
170160
// the same union - the borrow now partially overlaps.
@@ -195,8 +185,7 @@ fn place_components_conflict<'tcx>(
195185
}
196186

197187
if borrow_place.projection.len() > access_place.projection.len() {
198-
for (i, elem) in borrow_place.projection[access_place.projection.len()..].iter().enumerate()
199-
{
188+
for (base, elem) in borrow_place.iter_projections().skip(access_place.projection.len()) {
200189
// Borrow path is longer than the access path. Examples:
201190
//
202191
// - borrow of `a.b.c`, access to `a.b`
@@ -205,8 +194,7 @@ fn place_components_conflict<'tcx>(
205194
// our place. This is a conflict if that is a part our
206195
// access cares about.
207196

208-
let proj_base = &borrow_place.projection[..access_place.projection.len() + i];
209-
let base_ty = Place::ty_from(borrow_local, proj_base, body, tcx).ty;
197+
let base_ty = base.ty(body, tcx).ty;
210198

211199
match (elem, &base_ty.kind(), access) {
212200
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
@@ -310,8 +298,7 @@ fn place_base_conflict(l1: Local, l2: Local) -> Overlap {
310298
fn place_projection_conflict<'tcx>(
311299
tcx: TyCtxt<'tcx>,
312300
body: &Body<'tcx>,
313-
pi1_local: Local,
314-
pi1_proj_base: &[PlaceElem<'tcx>],
301+
pi1: PlaceRef<'tcx>,
315302
pi1_elem: PlaceElem<'tcx>,
316303
pi2_elem: PlaceElem<'tcx>,
317304
bias: PlaceConflictBias,
@@ -333,7 +320,7 @@ fn place_projection_conflict<'tcx>(
333320
debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD");
334321
Overlap::EqualOrDisjoint
335322
} else {
336-
let ty = Place::ty_from(pi1_local, pi1_proj_base, body, tcx).ty;
323+
let ty = pi1.ty(body, tcx).ty;
337324
if ty.is_union() {
338325
// Different fields of a union, we are basically stuck.
339326
debug!("place_element_conflict: STUCK-UNION");

compiler/rustc_borrowck/src/type_check/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -2502,7 +2502,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25022502
location, borrow_region, borrowed_place
25032503
);
25042504

2505-
let mut cursor = borrowed_place.projection.as_ref();
25062505
let tcx = self.infcx.tcx;
25072506
let field = path_utils::is_upvar_field_projection(
25082507
tcx,
@@ -2516,14 +2515,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25162515
ConstraintCategory::Boring
25172516
};
25182517

2519-
while let [proj_base @ .., elem] = cursor {
2520-
cursor = proj_base;
2521-
2518+
for (base, elem) in borrowed_place.as_ref().iter_projections().rev() {
25222519
debug!("add_reborrow_constraint - iteration {:?}", elem);
25232520

25242521
match elem {
25252522
ProjectionElem::Deref => {
2526-
let base_ty = Place::ty_from(borrowed_place.local, proj_base, body, tcx).ty;
2523+
let base_ty = base.ty(body, tcx).ty;
25272524

25282525
debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
25292526
match base_ty.kind() {

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -612,30 +612,28 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
612612
}
613613
fn visit_projection_elem(
614614
&mut self,
615-
place_local: Local,
616-
proj_base: &[PlaceElem<'tcx>],
615+
place_ref: PlaceRef<'tcx>,
617616
elem: PlaceElem<'tcx>,
618617
context: PlaceContext,
619618
location: Location,
620619
) {
621620
trace!(
622-
"visit_projection_elem: place_local={:?} proj_base={:?} elem={:?} \
621+
"visit_projection_elem: place_ref={:?} elem={:?} \
623622
context={:?} location={:?}",
624-
place_local,
625-
proj_base,
623+
place_ref,
626624
elem,
627625
context,
628626
location,
629627
);
630628

631-
self.super_projection_elem(place_local, proj_base, elem, context, location);
629+
self.super_projection_elem(place_ref, elem, context, location);
632630

633631
match elem {
634632
ProjectionElem::Deref => {
635-
let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
633+
let base_ty = place_ref.ty(self.body, self.tcx).ty;
636634
if base_ty.is_unsafe_ptr() {
637-
if proj_base.is_empty() {
638-
let decl = &self.body.local_decls[place_local];
635+
if place_ref.projection.is_empty() {
636+
let decl = &self.body.local_decls[place_ref.local];
639637
if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() {
640638
let span = decl.source_info.span;
641639
self.check_static(def_id, span);

compiler/rustc_const_eval/src/transform/validate.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
318318

319319
fn visit_projection_elem(
320320
&mut self,
321-
local: Local,
322-
proj_base: &[PlaceElem<'tcx>],
321+
place_ref: PlaceRef<'tcx>,
323322
elem: PlaceElem<'tcx>,
324323
context: PlaceContext,
325324
location: Location,
@@ -334,7 +333,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
334333
ProjectionElem::Deref
335334
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::PostCleanup) =>
336335
{
337-
let base_ty = Place::ty_from(local, proj_base, &self.body.local_decls, self.tcx).ty;
336+
let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty;
338337

339338
if base_ty.is_box() {
340339
self.fail(
@@ -344,8 +343,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
344343
}
345344
}
346345
ProjectionElem::Field(f, ty) => {
347-
let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
348-
let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
346+
let parent_ty = place_ref.ty(&self.body.local_decls, self.tcx);
349347
let fail_out_of_bounds = |this: &Self, location| {
350348
this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
351349
};
@@ -355,7 +353,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
355353
location,
356354
format!(
357355
"Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`",
358-
parent, f, ty, f_ty
356+
place_ref, f, ty, f_ty
359357
)
360358
)
361359
}
@@ -434,7 +432,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
434432
}
435433
_ => {}
436434
}
437-
self.super_projection_elem(local, proj_base, elem, context, location);
435+
self.super_projection_elem(place_ref, elem, context, location);
438436
}
439437

440438
fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) {

compiler/rustc_middle/src/mir/visit.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1133,13 +1133,12 @@ macro_rules! visit_place_fns {
11331133

11341134
fn visit_projection_elem(
11351135
&mut self,
1136-
local: Local,
1137-
proj_base: &[PlaceElem<'tcx>],
1136+
place_ref: PlaceRef<'tcx>,
11381137
elem: PlaceElem<'tcx>,
11391138
context: PlaceContext,
11401139
location: Location,
11411140
) {
1142-
self.super_projection_elem(local, proj_base, elem, context, location);
1141+
self.super_projection_elem(place_ref, elem, context, location);
11431142
}
11441143

11451144
fn super_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
@@ -1168,15 +1167,13 @@ macro_rules! visit_place_fns {
11681167
location: Location,
11691168
) {
11701169
for (base, elem) in place_ref.iter_projections().rev() {
1171-
let base_proj = base.projection;
1172-
self.visit_projection_elem(place_ref.local, base_proj, elem, context, location);
1170+
self.visit_projection_elem(base, elem, context, location);
11731171
}
11741172
}
11751173

11761174
fn super_projection_elem(
11771175
&mut self,
1178-
_local: Local,
1179-
_proj_base: &[PlaceElem<'tcx>],
1176+
_place_ref: PlaceRef<'tcx>,
11801177
elem: PlaceElem<'tcx>,
11811178
_context: PlaceContext,
11821179
location: Location,

compiler/rustc_mir_build/src/build/expr/as_place.rs

+4-15
Original file line numberDiff line numberDiff line change
@@ -677,21 +677,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
677677
// check that we just did stays valid. Since we can't assign to
678678
// unsized values, we only need to ensure that none of the
679679
// pointers in the base place are modified.
680-
for (idx, elem) in base_place.projection.iter().enumerate().rev() {
680+
for (base_place, elem) in base_place.iter_projections().rev() {
681681
match elem {
682682
ProjectionElem::Deref => {
683-
let fake_borrow_deref_ty = Place::ty_from(
684-
base_place.local,
685-
&base_place.projection[..idx],
686-
&self.local_decls,
687-
tcx,
688-
)
689-
.ty;
683+
let fake_borrow_deref_ty = base_place.ty(&self.local_decls, tcx).ty;
690684
let fake_borrow_ty =
691685
tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
692686
let fake_borrow_temp =
693687
self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span));
694-
let projection = tcx.mk_place_elems(&base_place.projection[..idx]);
688+
let projection = tcx.mk_place_elems(&base_place.projection);
695689
self.cfg.push_assign(
696690
block,
697691
source_info,
@@ -705,12 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
705699
fake_borrow_temps.push(fake_borrow_temp);
706700
}
707701
ProjectionElem::Index(_) => {
708-
let index_ty = Place::ty_from(
709-
base_place.local,
710-
&base_place.projection[..idx],
711-
&self.local_decls,
712-
tcx,
713-
);
702+
let index_ty = base_place.ty(&self.local_decls, tcx);
714703
match index_ty.ty.kind() {
715704
// The previous index expression has already
716705
// done any index expressions needed here.

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+5-14
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
113113
// from `*(u.f: &_)` isn't allowed.
114114
let mut union_path = None;
115115

116-
for (i, elem) in place.projection.iter().enumerate() {
117-
let proj_base = &place.projection[..i];
116+
for (place_ref, elem) in place.as_ref().iter_projections() {
118117
let body = self.builder.body;
119118
let tcx = self.builder.tcx;
120-
let place_ty = Place::ty_from(place.local, proj_base, body, tcx).ty;
119+
let place_ty = place_ref.ty(body, tcx).ty;
120+
121121
match place_ty.kind() {
122122
ty::Ref(..) | ty::RawPtr(..) => {
123-
let proj = &place.projection[..i + 1];
124123
return Err(MoveError::cannot_move_out_of(
125124
self.loc,
126-
BorrowedContent {
127-
target_place: Place {
128-
local: place.local,
129-
projection: tcx.mk_place_elems(proj),
130-
},
131-
},
125+
BorrowedContent { target_place: place_ref.project_deeper(&[elem], tcx) },
132126
));
133127
}
134128
ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
@@ -163,10 +157,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
163157
};
164158

165159
if union_path.is_none() {
166-
base = self.add_move_path(base, elem, |tcx| Place {
167-
local: place.local,
168-
projection: tcx.mk_place_elems(&place.projection[..i + 1]),
169-
});
160+
base = self.add_move_path(base, elem, |tcx| place_ref.project_deeper(&[elem], tcx));
170161
}
171162
}
172163

compiler/rustc_mir_transform/src/inline.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -839,15 +839,13 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
839839
/// to normalization failure.
840840
fn visit_projection_elem(
841841
&mut self,
842-
local: Local,
843-
proj_base: &[PlaceElem<'tcx>],
842+
place_ref: PlaceRef<'tcx>,
844843
elem: PlaceElem<'tcx>,
845844
context: PlaceContext,
846845
location: Location,
847846
) {
848847
if let ProjectionElem::Field(f, ty) = elem {
849-
let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
850-
let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx);
848+
let parent_ty = place_ref.ty(&self.callee_body.local_decls, self.tcx);
851849
let check_equal = |this: &mut Self, f_ty| {
852850
if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
853851
trace!(?ty, ?f_ty);
@@ -926,7 +924,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
926924
}
927925
}
928926

929-
self.super_projection_elem(local, proj_base, elem, context, location);
927+
self.super_projection_elem(place_ref, elem, context, location);
930928
}
931929
}
932930

0 commit comments

Comments
 (0)