Skip to content

Commit 5245803

Browse files
committed
Auto merge of #60441 - vext01:try-to-kill-projection-params, r=oli-obk
Make place projections concrete. **I'm not sure if we want this. I'm raising the PR for discussion** Whilst doing some work on our Rust fork, I noticed the following: Once upon a time (commit 9bd35c0) there were two kinds of projection: one for places, and one for constants. It therefore made sense to share the `Projection` struct for both. Although the different use-cases used different concrete types, sharing was made possible by type-parameterisation of `Projection`. Since then, however, the usage of projections in constants has disappeared, meaning that (forgetting lifetimes for a moment) the parameterised type is only every instantiated under one guise. So it may as well be a concrete type. Right? What do people think? This is entirely untested, although it does check. If we *don't* want this, then we should at least update the incorrect comment against `Projection`. Thanks
2 parents dec4c52 + 123a456 commit 5245803

File tree

10 files changed

+55
-67
lines changed

10 files changed

+55
-67
lines changed

src/librustc/mir/mod.rs

+32-44
Original file line numberDiff line numberDiff line change
@@ -1914,7 +1914,7 @@ pub enum Place<'tcx> {
19141914
Base(PlaceBase<'tcx>),
19151915

19161916
/// projection out of a place (access a field, deref a pointer, etc)
1917-
Projection(Box<PlaceProjection<'tcx>>),
1917+
Projection(Box<Projection<'tcx>>),
19181918
}
19191919

19201920
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
@@ -1944,16 +1944,13 @@ impl_stable_hash_for!(struct Static<'tcx> {
19441944
kind
19451945
});
19461946

1947-
/// The `Projection` data structure defines things of the form `B.x`
1948-
/// or `*B` or `B[index]`. Note that it is parameterized because it is
1949-
/// shared between `Constant` and `Place`. See the aliases
1950-
/// `PlaceProjection` etc below.
1947+
/// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`.
19511948
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
19521949
Hash, RustcEncodable, RustcDecodable, HashStable)]
1953-
pub struct Projection<B, V, T> {
1954-
pub base: B,
1955-
pub elem: ProjectionElem<V, T>,
1956-
}
1950+
pub struct Projection<'tcx> {
1951+
pub base: Place<'tcx>,
1952+
pub elem: PlaceElem<'tcx>,
1953+
}
19571954

19581955
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
19591956
Hash, RustcEncodable, RustcDecodable, HashStable)]
@@ -1996,10 +1993,6 @@ pub enum ProjectionElem<V, T> {
19961993
Downcast(Option<Symbol>, VariantIdx),
19971994
}
19981995

1999-
/// Alias for projections as they appear in places, where the base is a place
2000-
/// and the index is a local.
2001-
pub type PlaceProjection<'tcx> = Projection<Place<'tcx>, Local, Ty<'tcx>>;
2002-
20031996
/// Alias for projections as they appear in places, where the base is a place
20041997
/// and the index is a local.
20051998
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
@@ -2045,7 +2038,7 @@ impl<'tcx> Place<'tcx> {
20452038
}
20462039

20472040
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
2048-
Place::Projection(Box::new(PlaceProjection { base: self, elem }))
2041+
Place::Projection(Box::new(Projection { base: self, elem }))
20492042
}
20502043

20512044
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -2076,22 +2069,22 @@ impl<'tcx> Place<'tcx> {
20762069
}
20772070

20782071
/// Recursively "iterates" over place components, generating a `PlaceBase` and
2079-
/// `PlaceProjections` list and invoking `op` with a `PlaceProjectionsIter`.
2072+
/// `Projections` list and invoking `op` with a `ProjectionsIter`.
20802073
pub fn iterate<R>(
20812074
&self,
2082-
op: impl FnOnce(&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>) -> R,
2075+
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
20832076
) -> R {
2084-
self.iterate2(&PlaceProjections::Empty, op)
2077+
self.iterate2(&Projections::Empty, op)
20852078
}
20862079

20872080
fn iterate2<R>(
20882081
&self,
2089-
next: &PlaceProjections<'_, 'tcx>,
2090-
op: impl FnOnce(&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>) -> R,
2082+
next: &Projections<'_, 'tcx>,
2083+
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
20912084
) -> R {
20922085
match self {
20932086
Place::Projection(interior) => interior.base.iterate2(
2094-
&PlaceProjections::List {
2087+
&Projections::List {
20952088
projection: interior,
20962089
next,
20972090
},
@@ -2111,26 +2104,26 @@ impl<'tcx> Place<'tcx> {
21112104
/// N.B., this particular impl strategy is not the most obvious. It was
21122105
/// chosen because it makes a measurable difference to NLL
21132106
/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
2114-
pub enum PlaceProjections<'p, 'tcx: 'p> {
2107+
pub enum Projections<'p, 'tcx: 'p> {
21152108
Empty,
21162109

21172110
List {
2118-
projection: &'p PlaceProjection<'tcx>,
2119-
next: &'p PlaceProjections<'p, 'tcx>,
2111+
projection: &'p Projection<'tcx>,
2112+
next: &'p Projections<'p, 'tcx>,
21202113
}
21212114
}
21222115

2123-
impl<'p, 'tcx> PlaceProjections<'p, 'tcx> {
2124-
fn iter(&self) -> PlaceProjectionsIter<'_, 'tcx> {
2125-
PlaceProjectionsIter { value: self }
2116+
impl<'p, 'tcx> Projections<'p, 'tcx> {
2117+
fn iter(&self) -> ProjectionsIter<'_, 'tcx> {
2118+
ProjectionsIter { value: self }
21262119
}
21272120
}
21282121

2129-
impl<'p, 'tcx> IntoIterator for &'p PlaceProjections<'p, 'tcx> {
2130-
type Item = &'p PlaceProjection<'tcx>;
2131-
type IntoIter = PlaceProjectionsIter<'p, 'tcx>;
2122+
impl<'p, 'tcx> IntoIterator for &'p Projections<'p, 'tcx> {
2123+
type Item = &'p Projection<'tcx>;
2124+
type IntoIter = ProjectionsIter<'p, 'tcx>;
21322125

2133-
/// Converts a list of `PlaceProjection` components into an iterator;
2126+
/// Converts a list of `Projection` components into an iterator;
21342127
/// this iterator yields up a never-ending stream of `Option<&Place>`.
21352128
/// These begin with the "innermost" projection and then with each
21362129
/// projection therefrom. So given a place like `a.b.c` it would
@@ -2144,21 +2137,21 @@ impl<'p, 'tcx> IntoIterator for &'p PlaceProjections<'p, 'tcx> {
21442137
}
21452138
}
21462139

2147-
/// Iterator over components; see `PlaceProjections::iter` for more
2140+
/// Iterator over components; see `Projections::iter` for more
21482141
/// information.
21492142
///
21502143
/// N.B., this is not a *true* Rust iterator -- the code above just
21512144
/// manually invokes `next`. This is because we (sometimes) want to
21522145
/// keep executing even after `None` has been returned.
2153-
pub struct PlaceProjectionsIter<'p, 'tcx: 'p> {
2154-
pub value: &'p PlaceProjections<'p, 'tcx>,
2146+
pub struct ProjectionsIter<'p, 'tcx: 'p> {
2147+
pub value: &'p Projections<'p, 'tcx>,
21552148
}
21562149

2157-
impl<'p, 'tcx> Iterator for PlaceProjectionsIter<'p, 'tcx> {
2158-
type Item = &'p PlaceProjection<'tcx>;
2150+
impl<'p, 'tcx> Iterator for ProjectionsIter<'p, 'tcx> {
2151+
type Item = &'p Projection<'tcx>;
21592152

21602153
fn next(&mut self) -> Option<Self::Item> {
2161-
if let &PlaceProjections::List { projection, next } = self.value {
2154+
if let &Projections::List { projection, next } = self.value {
21622155
self.value = next;
21632156
Some(projection)
21642157
} else {
@@ -2167,7 +2160,7 @@ impl<'p, 'tcx> Iterator for PlaceProjectionsIter<'p, 'tcx> {
21672160
}
21682161
}
21692162

2170-
impl<'p, 'tcx> FusedIterator for PlaceProjectionsIter<'p, 'tcx> {}
2163+
impl<'p, 'tcx> FusedIterator for ProjectionsIter<'p, 'tcx> {}
21712164

21722165
impl<'tcx> Debug for Place<'tcx> {
21732166
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
@@ -2758,7 +2751,7 @@ impl<'tcx> UserTypeProjections {
27582751
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
27592752
pub struct UserTypeProjection {
27602753
pub base: UserTypeAnnotationIndex,
2761-
pub projs: Vec<ProjectionElem<(), ()>>,
2754+
pub projs: Vec<ProjectionKind>,
27622755
}
27632756

27642757
impl Copy for ProjectionKind { }
@@ -3587,12 +3580,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
35873580
}
35883581
}
35893582

3590-
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<B, V, T>
3591-
where
3592-
B: TypeFoldable<'tcx>,
3593-
V: TypeFoldable<'tcx>,
3594-
T: TypeFoldable<'tcx>,
3595-
{
3583+
impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> {
35963584
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
35973585
use crate::mir::ProjectionElem::*;
35983586

src/librustc/mir/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ macro_rules! make_mir_visitor {
152152
}
153153

154154
fn visit_projection(&mut self,
155-
place: & $($mutability)? PlaceProjection<'tcx>,
155+
place: & $($mutability)? Projection<'tcx>,
156156
context: PlaceContext,
157157
location: Location) {
158158
self.super_projection(place, context, location);
@@ -689,7 +689,7 @@ macro_rules! make_mir_visitor {
689689
}
690690

691691
fn super_projection(&mut self,
692-
proj: & $($mutability)? PlaceProjection<'tcx>,
692+
proj: & $($mutability)? Projection<'tcx>,
693693
context: PlaceContext,
694694
location: Location) {
695695
let Projection { base, elem } = proj;

src/librustc_mir/borrow_check/conflict_errors.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc::hir;
22
use rustc::hir::def_id::DefId;
33
use rustc::mir::{
44
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
5-
LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceProjection,
5+
LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection,
66
ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
77
};
88
use rustc::ty::{self, Ty};
@@ -619,7 +619,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
619619
// union being accessed and the field that was being accessed so we can check the
620620
// second borrowed place for the same union and a access to a different field.
621621
let mut current = first_borrowed_place;
622-
while let Place::Projection(box PlaceProjection { base, elem }) = current {
622+
while let Place::Projection(box Projection { base, elem }) = current {
623623
match elem {
624624
ProjectionElem::Field(field, _) if is_union(base) => {
625625
return Some((base, field));
@@ -633,7 +633,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
633633
// With the place of a union and a field access into it, we traverse the second
634634
// borrowed place and look for a access to a different field of the same union.
635635
let mut current = second_borrowed_place;
636-
while let Place::Projection(box PlaceProjection { base, elem }) = current {
636+
while let Place::Projection(box Projection { base, elem }) = current {
637637
match elem {
638638
ProjectionElem::Field(field, _) if {
639639
is_union(base) && field != target_field && base == target_base
@@ -1495,7 +1495,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14951495
Place::Base(PlaceBase::Static(_)) => {
14961496
StorageDeadOrDrop::LocalStorageDead
14971497
}
1498-
Place::Projection(box PlaceProjection { base, elem }) => {
1498+
Place::Projection(box Projection { base, elem }) => {
14991499
let base_access = self.classify_drop_access_kind(base);
15001500
match elem {
15011501
ProjectionElem::Deref => match base_access {

src/librustc_mir/borrow_check/move_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
352352
..
353353
} => {
354354
let try_remove_deref = match move_from {
355-
Place::Projection(box PlaceProjection {
355+
Place::Projection(box Projection {
356356
elem: ProjectionElem::Deref,
357357
..
358358
}) => true,

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2370,7 +2370,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
23702370
"add_reborrow_constraint({:?}, {:?}, {:?})",
23712371
location, borrow_region, borrowed_place
23722372
);
2373-
while let Place::Projection(box PlaceProjection { base, elem }) = borrowed_place {
2373+
while let Place::Projection(box Projection { base, elem }) = borrowed_place {
23742374
debug!("add_reborrow_constraint - iteration {:?}", borrowed_place);
23752375

23762376
match *elem {

src/librustc_mir/borrow_check/places_conflict.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::borrow_check::Overlap;
33
use crate::borrow_check::{Deep, Shallow, AccessDepth};
44
use rustc::hir;
55
use rustc::mir::{
6-
BorrowKind, Mir, Place, PlaceBase, PlaceProjection, ProjectionElem, PlaceProjectionsIter,
6+
BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, ProjectionsIter,
77
StaticKind
88
};
99
use rustc::ty::{self, TyCtxt};
@@ -86,9 +86,9 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
8686
fn place_components_conflict<'gcx, 'tcx>(
8787
tcx: TyCtxt<'_, 'gcx, 'tcx>,
8888
mir: &Mir<'tcx>,
89-
borrow_projections: (&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>),
89+
borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
9090
borrow_kind: BorrowKind,
91-
access_projections: (&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>),
91+
access_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
9292
access: AccessDepth,
9393
bias: PlaceConflictBias,
9494
) -> bool {
@@ -368,8 +368,8 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
368368
fn place_projection_conflict<'a, 'gcx: 'tcx, 'tcx>(
369369
tcx: TyCtxt<'a, 'gcx, 'tcx>,
370370
mir: &Mir<'tcx>,
371-
pi1: &PlaceProjection<'tcx>,
372-
pi2: &PlaceProjection<'tcx>,
371+
pi1: &Projection<'tcx>,
372+
pi2: &Projection<'tcx>,
373373
bias: PlaceConflictBias,
374374
) -> Overlap {
375375
match (&pi1.elem, &pi2.elem) {

src/librustc_mir/dataflow/drop_flag_effects.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
1010
path: MovePathIndex,
1111
mut cond: F)
1212
-> Option<MovePathIndex>
13-
where F: FnMut(&mir::PlaceProjection<'tcx>) -> bool
13+
where F: FnMut(&mir::Projection<'tcx>) -> bool
1414
{
1515
let mut next_child = move_data.move_paths[path].first_child;
1616
while let Some(child_index) = next_child {

src/librustc_mir/dataflow/move_paths/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
114114

115115
fn move_path_for_projection(&mut self,
116116
place: &Place<'tcx>,
117-
proj: &PlaceProjection<'tcx>)
117+
proj: &Projection<'tcx>)
118118
-> Result<MovePathIndex, MoveError<'tcx>>
119119
{
120120
let base = self.move_path_for(&proj.base)?;

src/librustc_mir/transform/qualify_consts.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ trait Qualif {
161161

162162
fn in_projection_structurally(
163163
cx: &ConstCx<'_, 'tcx>,
164-
proj: &PlaceProjection<'tcx>,
164+
proj: &Projection<'tcx>,
165165
) -> bool {
166166
let base_qualif = Self::in_place(cx, &proj.base);
167167
let qualif = base_qualif && Self::mask_for_ty(
@@ -181,7 +181,7 @@ trait Qualif {
181181
}
182182
}
183183

184-
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
184+
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool {
185185
Self::in_projection_structurally(cx, proj)
186186
}
187187

@@ -387,7 +387,7 @@ impl Qualif for IsNotPromotable {
387387
}
388388
}
389389

390-
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
390+
fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool {
391391
match proj.elem {
392392
ProjectionElem::Deref |
393393
ProjectionElem::Downcast(..) => return true,

src/librustc_mir/transform/uniform_array_move_out.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
8989
fn uniform(&mut self,
9090
location: Location,
9191
dst_place: &Place<'tcx>,
92-
proj: &PlaceProjection<'tcx>,
92+
proj: &Projection<'tcx>,
9393
item_ty: &'tcx ty::TyS<'tcx>,
9494
size: u32) {
9595
match proj.elem {
@@ -103,7 +103,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
103103
Place::Base(PlaceBase::Local(temp)),
104104
Rvalue::Use(
105105
Operand::Move(
106-
Place::Projection(box PlaceProjection{
106+
Place::Projection(box Projection{
107107
base: proj.base.clone(),
108108
elem: ProjectionElem::ConstantIndex{
109109
offset: i,
@@ -133,7 +133,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
133133
dst_place.clone(),
134134
Rvalue::Use(
135135
Operand::Move(
136-
Place::Projection(box PlaceProjection{
136+
Place::Projection(box Projection{
137137
base: proj.base.clone(),
138138
elem: ProjectionElem::ConstantIndex{
139139
offset: size - offset,
@@ -246,7 +246,7 @@ impl RestoreSubsliceArrayMoveOut {
246246
dst_place.clone(),
247247
Rvalue::Use(
248248
Operand::Move(
249-
Place::Projection(box PlaceProjection{
249+
Place::Projection(box Projection{
250250
base: opt_src_place.unwrap().clone(),
251251
elem: ProjectionElem::Subslice{
252252
from: min, to: size - max - 1}}))));
@@ -261,7 +261,7 @@ impl RestoreSubsliceArrayMoveOut {
261261
let statement = &block.statements[location.statement_index];
262262
if let StatementKind::Assign(
263263
Place::Base(PlaceBase::Local(_)),
264-
box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
264+
box Rvalue::Use(Operand::Move(Place::Projection(box Projection{
265265
ref base, elem: ProjectionElem::ConstantIndex{
266266
offset, min_length: _, from_end: false}})))) = statement.kind {
267267
return Some((offset, base))

0 commit comments

Comments
 (0)