Skip to content

Commit d0accad

Browse files
committed
Migrate from Place enum to Place struct
1 parent 5c26b52 commit d0accad

Some content is hidden

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

46 files changed

+1461
-790
lines changed

src/librustc/mir/mod.rs

Lines changed: 59 additions & 41 deletions
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

@@ -1827,7 +1827,10 @@ newtype_index! {
18271827
}
18281828

18291829
impl<'tcx> Place<'tcx> {
1830-
pub const RETURN_PLACE: Place<'tcx> = Place::Base(PlaceBase::Local(RETURN_PLACE));
1830+
pub const RETURN_PLACE: Place<'tcx> = Place {
1831+
base: PlaceBase::Local(RETURN_PLACE),
1832+
projection: None,
1833+
};
18311834

18321835
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
18331836
self.elem(ProjectionElem::Field(f, ty))
@@ -1853,7 +1856,10 @@ impl<'tcx> Place<'tcx> {
18531856
}
18541857

18551858
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
1856-
Place::Projection(Box::new(Projection { base: self, elem }))
1859+
Place {
1860+
base: self.base,
1861+
projection: Some(Box::new(Projection { base: self.projection, elem })),
1862+
}
18571863
}
18581864

18591865
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -1862,54 +1868,70 @@ impl<'tcx> Place<'tcx> {
18621868
// FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
18631869
pub fn local_or_deref_local(&self) -> Option<Local> {
18641870
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),
1871+
Place {
1872+
base: PlaceBase::Local(local),
1873+
projection: None,
1874+
} |
1875+
Place {
1876+
base: PlaceBase::Local(local),
1877+
projection: Some(box Projection {
1878+
base: None,
1879+
elem: ProjectionElem::Deref,
1880+
}),
1881+
} => Some(*local),
18701882
_ => None,
18711883
}
18721884
}
18731885

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-
18861886
/// Recursively "iterates" over place components, generating a `PlaceBase` and
18871887
/// `Projections` list and invoking `op` with a `ProjectionsIter`.
18881888
pub fn iterate<R>(
18891889
&self,
18901890
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
18911891
) -> R {
1892-
self.iterate2(&Projections::Empty, op)
1892+
Place::iterate_over(&self.base, &self.projection, op)
18931893
}
18941894

1895-
fn iterate2<R>(
1896-
&self,
1897-
next: &Projections<'_, 'tcx>,
1895+
pub fn iterate_over<R>(
1896+
place_base: &PlaceBase<'tcx>,
1897+
place_projection: &Option<Box<Projection<'tcx>>>,
18981898
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
18991899
) -> R {
1900-
match self {
1901-
Place::Projection(interior) => {
1902-
interior.base.iterate2(&Projections::List { projection: interior, next }, op)
1903-
}
1900+
fn iterate_over2<'tcx, R>(
1901+
place_base: &PlaceBase<'tcx>,
1902+
place_projection: &Option<Box<Projection<'tcx>>>,
1903+
next: &Projections<'_, 'tcx>,
1904+
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
1905+
) -> R {
1906+
match place_projection {
1907+
None => {
1908+
op(place_base, next.iter())
1909+
}
19041910

1905-
Place::Base(base) => op(base, next.iter()),
1911+
Some(interior) => {
1912+
iterate_over2(
1913+
place_base,
1914+
&interior.base,
1915+
&Projections::List {
1916+
projection: interior,
1917+
next,
1918+
},
1919+
op,
1920+
)
1921+
}
1922+
}
19061923
}
1924+
1925+
iterate_over2(place_base, place_projection, &Projections::Empty, op)
19071926
}
19081927
}
19091928

19101929
impl From<Local> for Place<'_> {
19111930
fn from(local: Local) -> Self {
1912-
Place::Base(local.into())
1931+
Place {
1932+
base: local.into(),
1933+
projection: None,
1934+
}
19131935
}
19141936
}
19151937

@@ -3155,18 +3177,14 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
31553177

31563178
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
31573179
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(),
3180+
Place {
3181+
base: self.base.clone(),
3182+
projection: self.projection.fold_with(folder),
31613183
}
31623184
}
31633185

31643186
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-
}
3187+
self.projection.visit_with(visitor)
31703188
}
31713189
}
31723190

src/librustc/mir/tcx.rs

Lines changed: 15 additions & 4 deletions
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

Lines changed: 20 additions & 17 deletions
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
}

src/librustc_codegen_ssa/mir/analyze.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
103103
location: Location) {
104104
debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue);
105105

106-
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
106+
if let mir::Place {
107+
base: mir::PlaceBase::Local(index),
108+
projection: None,
109+
} = *place {
107110
self.assign(index, location);
108111
if !self.fx.rvalue_creates_operand(rvalue) {
109112
self.not_ssa(index);
@@ -157,15 +160,15 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
157160
debug!("visit_place(place={:?}, context={:?})", place, context);
158161
let cx = self.fx.cx;
159162

160-
if let mir::Place::Projection(ref proj) = *place {
163+
if let Some(proj) = &place.projection {
161164
// Allow uses of projections that are ZSTs or from scalar fields.
162165
let is_consume = match context {
163166
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
164167
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
165168
_ => false
166169
};
167170
if is_consume {
168-
let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
171+
let base_ty = mir::Place::ty_from(&place.base, &proj.base, self.fx.mir, cx.tcx());
169172
let base_ty = self.fx.monomorphize(&base_ty);
170173

171174
// ZSTs don't require any actual memory access.
@@ -183,7 +186,15 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
183186
// Recurse with the same context, instead of `Projection`,
184187
// potentially stopping at non-operand projections,
185188
// which would trigger `not_ssa` on locals.
186-
self.visit_place(&proj.base, context, location);
189+
self.visit_place(
190+
// FIXME do not clone
191+
&mir::Place {
192+
base: place.base.clone(),
193+
projection: proj.base.clone(),
194+
},
195+
context,
196+
location,
197+
);
187198
return;
188199
}
189200
}
@@ -192,7 +203,11 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
192203
// A deref projection only reads the pointer, never needs the place.
193204
if let mir::ProjectionElem::Deref = proj.elem {
194205
return self.visit_place(
195-
&proj.base,
206+
// FIXME do not clone
207+
&mir::Place {
208+
base: place.base.clone(),
209+
projection: proj.base.clone(),
210+
},
196211
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
197212
location
198213
);

src/librustc_codegen_ssa/mir/block.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -607,18 +607,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
607607
// but specified directly in the code. This means it gets promoted
608608
// and we can then extract the value by evaluating the promoted.
609609
mir::Operand::Copy(
610-
Place::Base(
611-
PlaceBase::Static(
612-
box Static { kind: StaticKind::Promoted(promoted), ty }
613-
)
614-
)
610+
Place {
611+
base: PlaceBase::Static(box Static {
612+
kind: StaticKind::Promoted(promoted),
613+
ty,
614+
}),
615+
projection: None,
616+
}
615617
) |
616618
mir::Operand::Move(
617-
Place::Base(
618-
PlaceBase::Static(
619-
box Static { kind: StaticKind::Promoted(promoted), ty }
620-
)
621-
)
619+
Place {
620+
base: PlaceBase::Static(box Static {
621+
kind: StaticKind::Promoted(promoted),
622+
ty,
623+
}),
624+
projection: None,
625+
}
622626
) => {
623627
let param_env = ty::ParamEnv::reveal_all();
624628
let cid = mir::interpret::GlobalId {
@@ -1098,7 +1102,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10981102
if fn_ret.is_ignore() {
10991103
return ReturnDest::Nothing;
11001104
}
1101-
let dest = if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dest {
1105+
let dest = if let mir::Place {
1106+
base: mir::PlaceBase::Local(index),
1107+
projection: None,
1108+
} = *dest {
11021109
match self.locals[index] {
11031110
LocalRef::Place(dest) => dest,
11041111
LocalRef::UnsizedPlace(_) => bug!("return type must be sized"),
@@ -1153,7 +1160,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11531160
src: &mir::Operand<'tcx>,
11541161
dst: &mir::Place<'tcx>
11551162
) {
1156-
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *dst {
1163+
if let mir::Place {
1164+
base: mir::PlaceBase::Local(index),
1165+
projection: None,
1166+
} = *dst {
11571167
match self.locals[index] {
11581168
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
11591169
LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),

0 commit comments

Comments
 (0)