Skip to content

Commit 1301422

Browse files
committed
Auto merge of #60913 - spastorino:place2_4, r=oli-obk
Place 2.0 change from enum to struct r? @oli-obk
2 parents 95b1fe5 + a8ceeeb commit 1301422

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1735
-989
lines changed

src/librustc/mir/mod.rs

+101-40
Original file line numberDiff line numberDiff line change
@@ -1718,11 +1718,11 @@ impl<'tcx> Debug for Statement<'tcx> {
17181718
#[derive(
17191719
Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable,
17201720
)]
1721-
pub enum Place<'tcx> {
1722-
Base(PlaceBase<'tcx>),
1721+
pub struct Place<'tcx> {
1722+
pub base: PlaceBase<'tcx>,
17231723

17241724
/// projection out of a place (access a field, deref a pointer, etc)
1725-
Projection(Box<Projection<'tcx>>),
1725+
pub projection: Option<Box<Projection<'tcx>>>,
17261726
}
17271727

17281728
#[derive(
@@ -1761,7 +1761,7 @@ impl_stable_hash_for!(struct Static<'tcx> {
17611761
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable,
17621762
)]
17631763
pub struct Projection<'tcx> {
1764-
pub base: Place<'tcx>,
1764+
pub base: Option<Box<Projection<'tcx>>>,
17651765
pub elem: PlaceElem<'tcx>,
17661766
}
17671767

@@ -1826,8 +1826,17 @@ newtype_index! {
18261826
}
18271827
}
18281828

1829+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1830+
pub struct PlaceRef<'a, 'tcx> {
1831+
pub base: &'a PlaceBase<'tcx>,
1832+
pub projection: &'a Option<Box<Projection<'tcx>>>,
1833+
}
1834+
18291835
impl<'tcx> Place<'tcx> {
1830-
pub const RETURN_PLACE: Place<'tcx> = Place::Base(PlaceBase::Local(RETURN_PLACE));
1836+
pub const RETURN_PLACE: Place<'tcx> = Place {
1837+
base: PlaceBase::Local(RETURN_PLACE),
1838+
projection: None,
1839+
};
18311840

18321841
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
18331842
self.elem(ProjectionElem::Field(f, ty))
@@ -1853,7 +1862,10 @@ impl<'tcx> Place<'tcx> {
18531862
}
18541863

18551864
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
1856-
Place::Projection(Box::new(Projection { base: self, elem }))
1865+
Place {
1866+
base: self.base,
1867+
projection: Some(Box::new(Projection { base: self.projection, elem })),
1868+
}
18571869
}
18581870

18591871
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -1862,54 +1874,77 @@ impl<'tcx> Place<'tcx> {
18621874
// FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
18631875
pub fn local_or_deref_local(&self) -> Option<Local> {
18641876
match self {
1865-
Place::Base(PlaceBase::Local(local))
1866-
| Place::Projection(box Projection {
1867-
base: Place::Base(PlaceBase::Local(local)),
1868-
elem: ProjectionElem::Deref,
1869-
}) => Some(*local),
1877+
Place {
1878+
base: PlaceBase::Local(local),
1879+
projection: None,
1880+
} |
1881+
Place {
1882+
base: PlaceBase::Local(local),
1883+
projection: Some(box Projection {
1884+
base: None,
1885+
elem: ProjectionElem::Deref,
1886+
}),
1887+
} => Some(*local),
18701888
_ => None,
18711889
}
18721890
}
18731891

1874-
/// Finds the innermost `Local` from this `Place`.
1875-
pub fn base_local(&self) -> Option<Local> {
1876-
let mut place = self;
1877-
loop {
1878-
match place {
1879-
Place::Projection(proj) => place = &proj.base,
1880-
Place::Base(PlaceBase::Static(_)) => return None,
1881-
Place::Base(PlaceBase::Local(local)) => return Some(*local),
1882-
}
1883-
}
1884-
}
1885-
18861892
/// Recursively "iterates" over place components, generating a `PlaceBase` and
18871893
/// `Projections` list and invoking `op` with a `ProjectionsIter`.
18881894
pub fn iterate<R>(
18891895
&self,
18901896
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
18911897
) -> R {
1892-
self.iterate2(&Projections::Empty, op)
1898+
Place::iterate_over(&self.base, &self.projection, op)
18931899
}
18941900

1895-
fn iterate2<R>(
1896-
&self,
1897-
next: &Projections<'_, 'tcx>,
1901+
pub fn iterate_over<R>(
1902+
place_base: &PlaceBase<'tcx>,
1903+
place_projection: &Option<Box<Projection<'tcx>>>,
18981904
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
18991905
) -> R {
1900-
match self {
1901-
Place::Projection(interior) => {
1902-
interior.base.iterate2(&Projections::List { projection: interior, next }, op)
1906+
fn iterate_over2<'tcx, R>(
1907+
place_base: &PlaceBase<'tcx>,
1908+
place_projection: &Option<Box<Projection<'tcx>>>,
1909+
next: &Projections<'_, 'tcx>,
1910+
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
1911+
) -> R {
1912+
match place_projection {
1913+
None => {
1914+
op(place_base, next.iter())
1915+
}
1916+
1917+
Some(interior) => {
1918+
iterate_over2(
1919+
place_base,
1920+
&interior.base,
1921+
&Projections::List {
1922+
projection: interior,
1923+
next,
1924+
},
1925+
op,
1926+
)
1927+
}
19031928
}
1929+
}
19041930

1905-
Place::Base(base) => op(base, next.iter()),
1931+
iterate_over2(place_base, place_projection, &Projections::Empty, op)
1932+
}
1933+
1934+
pub fn as_place_ref(&self) -> PlaceRef<'_, 'tcx> {
1935+
PlaceRef {
1936+
base: &self.base,
1937+
projection: &self.projection,
19061938
}
19071939
}
19081940
}
19091941

19101942
impl From<Local> for Place<'_> {
19111943
fn from(local: Local) -> Self {
1912-
Place::Base(local.into())
1944+
Place {
1945+
base: local.into(),
1946+
projection: None,
1947+
}
19131948
}
19141949
}
19151950

@@ -1919,6 +1954,36 @@ impl From<Local> for PlaceBase<'_> {
19191954
}
19201955
}
19211956

1957+
impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
1958+
pub fn iterate<R>(
1959+
&self,
1960+
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
1961+
) -> R {
1962+
Place::iterate_over(self.base, self.projection, op)
1963+
}
1964+
1965+
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
1966+
/// a single deref of a local.
1967+
//
1968+
// FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
1969+
pub fn local_or_deref_local(&self) -> Option<Local> {
1970+
match self {
1971+
PlaceRef {
1972+
base: PlaceBase::Local(local),
1973+
projection: None,
1974+
} |
1975+
PlaceRef {
1976+
base: PlaceBase::Local(local),
1977+
projection: Some(box Projection {
1978+
base: None,
1979+
elem: ProjectionElem::Deref,
1980+
}),
1981+
} => Some(*local),
1982+
_ => None,
1983+
}
1984+
}
1985+
}
1986+
19221987
/// A linked list of projections running up the stack; begins with the
19231988
/// innermost projection and extends to the outermost (e.g., `a.b.c`
19241989
/// would have the place `b` with a "next" pointer to `b.c`).
@@ -3155,18 +3220,14 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
31553220

31563221
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
31573222
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
3158-
match self {
3159-
&Place::Projection(ref p) => Place::Projection(p.fold_with(folder)),
3160-
_ => self.clone(),
3223+
Place {
3224+
base: self.base.clone(),
3225+
projection: self.projection.fold_with(folder),
31613226
}
31623227
}
31633228

31643229
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
3165-
if let &Place::Projection(ref p) = self {
3166-
p.visit_with(visitor)
3167-
} else {
3168-
false
3169-
}
3230+
self.projection.visit_with(visitor)
31703231
}
31713232
}
31723233

src/librustc/mir/tcx.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,15 @@ BraceStructTypeFoldableImpl! {
118118
}
119119

120120
impl<'tcx> Place<'tcx> {
121-
pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
122-
where
123-
D: HasLocalDecls<'tcx>,
121+
pub fn ty_from<D>(
122+
base: &PlaceBase<'tcx>,
123+
projection: &Option<Box<Projection<'tcx>>>,
124+
local_decls: &D,
125+
tcx: TyCtxt<'tcx>
126+
) -> PlaceTy<'tcx>
127+
where D: HasLocalDecls<'tcx>
124128
{
125-
self.iterate(|place_base, place_projections| {
129+
Place::iterate_over(base, projection, |place_base, place_projections| {
126130
let mut place_ty = place_base.ty(local_decls);
127131

128132
for proj in place_projections {
@@ -132,6 +136,13 @@ impl<'tcx> Place<'tcx> {
132136
place_ty
133137
})
134138
}
139+
140+
pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
141+
where
142+
D: HasLocalDecls<'tcx>,
143+
{
144+
Place::ty_from(&self.base, &self.projection, local_decls, tcx)
145+
}
135146
}
136147

137148
impl<'tcx> PlaceBase<'tcx> {

src/librustc/mir/visit.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ macro_rules! make_mir_visitor {
159159
}
160160

161161
fn visit_projection(&mut self,
162+
place_base: & $($mutability)? PlaceBase<'tcx>,
162163
place: & $($mutability)? Projection<'tcx>,
163164
context: PlaceContext,
164165
location: Location) {
165-
self.super_projection(place, context, location);
166+
self.super_projection(place_base, place, context, location);
166167
}
167168

168169
fn visit_constant(&mut self,
@@ -676,19 +677,20 @@ macro_rules! make_mir_visitor {
676677
place: & $($mutability)? Place<'tcx>,
677678
context: PlaceContext,
678679
location: Location) {
679-
match place {
680-
Place::Base(place_base) => {
681-
self.visit_place_base(place_base, context, location);
682-
}
683-
Place::Projection(proj) => {
684-
let context = if context.is_mutating_use() {
685-
PlaceContext::MutatingUse(MutatingUseContext::Projection)
686-
} else {
687-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
688-
};
680+
let mut context = context;
681+
682+
if place.projection.is_some() {
683+
context = if context.is_mutating_use() {
684+
PlaceContext::MutatingUse(MutatingUseContext::Projection)
685+
} else {
686+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
687+
};
688+
}
689689

690-
self.visit_projection(proj, context, location);
691-
}
690+
self.visit_place_base(& $($mutability)? place.base, context, location);
691+
692+
if let Some(box proj) = & $($mutability)? place.projection {
693+
self.visit_projection(& $($mutability)? place.base, proj, context, location);
692694
}
693695
}
694696

@@ -707,13 +709,14 @@ macro_rules! make_mir_visitor {
707709
}
708710

709711
fn super_projection(&mut self,
712+
place_base: & $($mutability)? PlaceBase<'tcx>,
710713
proj: & $($mutability)? Projection<'tcx>,
711714
context: PlaceContext,
712715
location: Location) {
713-
// this is calling `super_place` in preparation for changing `Place` to be
714-
// a struct with a base and a slice of projections. `visit_place` should only ever
715-
// be called for the outermost place now.
716-
self.super_place(& $($mutability)? proj.base, context, location);
716+
if let Some(box proj_base) = & $($mutability)? proj.base {
717+
self.visit_projection(place_base, proj_base, context, location);
718+
}
719+
717720
match & $($mutability)? proj.elem {
718721
ProjectionElem::Deref => {
719722
}

0 commit comments

Comments
 (0)