Skip to content

Commit 357bc2c

Browse files
committed
Introduce new Place in librustc/mir
1 parent 3f4f18f commit 357bc2c

File tree

4 files changed

+171
-141
lines changed

4 files changed

+171
-141
lines changed

src/librustc/ich/impls_mir.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,28 +290,38 @@ impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
290290

291291
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
292292

293-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
293+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::PlaceBase<'gcx> {
294294
fn hash_stable<W: StableHasherResult>(&self,
295295
hcx: &mut StableHashingContext<'a>,
296296
hasher: &mut StableHasher<W>) {
297297
mem::discriminant(self).hash_stable(hcx, hasher);
298298
match *self {
299-
mir::Place::Local(ref local) => {
299+
mir::PlaceBase::Local(ref local) => {
300300
local.hash_stable(hcx, hasher);
301301
}
302-
mir::Place::Static(ref statik) => {
302+
mir::PlaceBase::Static(ref statik) => {
303303
statik.hash_stable(hcx, hasher);
304304
}
305-
mir::Place::Promoted(ref promoted) => {
305+
mir::PlaceBase::Promoted(ref promoted) => {
306306
promoted.hash_stable(hcx, hasher);
307307
}
308-
mir::Place::Projection(ref place_projection) => {
309-
place_projection.hash_stable(hcx, hasher);
310-
}
311308
}
312309
}
313310
}
314311

312+
impl<'a, 'tcx> HashStable<StableHashingContext<'a>>
313+
for mir::Place<'tcx>
314+
{
315+
fn hash_stable<W: StableHasherResult>(
316+
&self,
317+
hcx: &mut StableHashingContext<'a>,
318+
hasher: &mut StableHasher<W>,
319+
) {
320+
self.base.hash_stable(hcx, hasher);
321+
self.elems.hash_stable(hcx, hasher);
322+
}
323+
}
324+
315325
impl<'a, 'gcx, B, V, T> HashStable<StableHashingContext<'a>>
316326
for mir::Projection<'gcx, B, V, T>
317327
where B: HashStable<StableHashingContext<'a>>,

src/librustc/mir/mod.rs

Lines changed: 98 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use mir::interpret::{EvalErrorKind, Scalar, Value, ScalarMaybeUndef};
2121
use mir::visit::MirVisitable;
2222
use rustc_apfloat::ieee::{Double, Single};
2323
use rustc_apfloat::Float;
24+
use rustc_data_structures::accumulate_vec::AccumulateVec;
2425
use rustc_data_structures::graph::dominators::{dominators, Dominators};
2526
use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
2627
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
@@ -39,7 +40,7 @@ use syntax::symbol::InternedString;
3940
use syntax_pos::{Span, DUMMY_SP};
4041
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
4142
use ty::subst::{Subst, Substs};
42-
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
43+
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Slice, Ty, TyCtxt};
4344
use util::ppaux;
4445

4546
pub use mir::interpret::AssertMessage;
@@ -1693,8 +1694,16 @@ impl<'tcx> Debug for Statement<'tcx> {
16931694

16941695
/// A path to a value; something that can be evaluated without
16951696
/// changing or disturbing program state.
1697+
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
1698+
pub struct Place<'tcx> {
1699+
pub base: PlaceBase<'tcx>,
1700+
pub elems: &'tcx Slice<PlaceElem<'tcx>>,
1701+
}
1702+
1703+
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<PlaceElem<'tcx>> {}
1704+
16961705
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
1697-
pub enum Place<'tcx> {
1706+
pub enum PlaceBase<'tcx> {
16981707
/// local variable
16991708
Local(Local),
17001709

@@ -1703,9 +1712,6 @@ pub enum Place<'tcx> {
17031712

17041713
/// Constant code promoted to an injected static
17051714
Promoted(Box<(Promoted, Ty<'tcx>)>),
1706-
1707-
/// projection out of a place (access a field, deref a pointer, etc)
1708-
Projection(Box<PlaceProjection<'tcx>>),
17091715
}
17101716

17111717
/// The def-id of a static, along with its normalized type (which is
@@ -1731,7 +1737,7 @@ pub struct Projection<'tcx, B, V, T> {
17311737
pub elem: ProjectionElem<'tcx, V, T>,
17321738
}
17331739

1734-
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
1740+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
17351741
pub enum ProjectionElem<'tcx, V, T> {
17361742
Deref,
17371743
Field(Field, T),
@@ -1779,31 +1785,52 @@ pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
17791785

17801786
newtype_index!(Field { DEBUG_FORMAT = "field[{}]" });
17811787

1782-
impl<'tcx> Place<'tcx> {
1783-
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
1784-
self.elem(ProjectionElem::Field(f, ty))
1788+
impl<'a, 'tcx> Place<'tcx> {
1789+
// projection lives in the last elem.
1790+
pub fn projection(&self) -> Option<&PlaceElem> {
1791+
self.elems.last()
17851792
}
17861793

1787-
pub fn deref(self) -> Place<'tcx> {
1788-
self.elem(ProjectionElem::Deref)
1794+
pub fn field(
1795+
self,
1796+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
1797+
f: Field,
1798+
ty: Ty<'tcx>,
1799+
) -> Self {
1800+
self.elem(tcx, ProjectionElem::Field(f, ty))
17891801
}
17901802

1791-
pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> {
1792-
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
1803+
pub fn deref(self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
1804+
self.elem(tcx, ProjectionElem::Deref)
17931805
}
17941806

1795-
pub fn index(self, index: Local) -> Place<'tcx> {
1796-
self.elem(ProjectionElem::Index(index))
1807+
pub fn downcast(
1808+
self,
1809+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
1810+
adt_def: &'tcx AdtDef, variant_index: usize,
1811+
) -> Self {
1812+
self.elem(tcx, ProjectionElem::Downcast(adt_def, variant_index))
1813+
}
1814+
1815+
pub fn index(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, index: Local) -> Self {
1816+
self.elem(tcx, ProjectionElem::Index(index))
17971817
}
17981818

1799-
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
1800-
Place::Projection(Box::new(PlaceProjection { base: self, elem }))
1819+
pub fn elem(
1820+
self,
1821+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
1822+
elem: PlaceElem<'tcx>,
1823+
) -> Self {
1824+
Place {
1825+
base: self.base,
1826+
elems: tcx.intern_place_elems(&[elem]),
1827+
}
18011828
}
18021829
}
18031830

1804-
impl<'tcx> Debug for Place<'tcx> {
1831+
impl<'tcx> Debug for PlaceBase<'tcx> {
18051832
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
1806-
use self::Place::*;
1833+
use self::PlaceBase::*;
18071834

18081835
match *self {
18091836
Local(id) => write!(fmt, "{:?}", id),
@@ -1814,35 +1841,6 @@ impl<'tcx> Debug for Place<'tcx> {
18141841
ty
18151842
),
18161843
Promoted(ref promoted) => write!(fmt, "({:?}: {:?})", promoted.0, promoted.1),
1817-
Projection(ref data) => match data.elem {
1818-
ProjectionElem::Downcast(ref adt_def, index) => {
1819-
write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name)
1820-
}
1821-
ProjectionElem::Deref => write!(fmt, "(*{:?})", data.base),
1822-
ProjectionElem::Field(field, ty) => {
1823-
write!(fmt, "({:?}.{:?}: {:?})", data.base, field.index(), ty)
1824-
}
1825-
ProjectionElem::Index(ref index) => write!(fmt, "{:?}[{:?}]", data.base, index),
1826-
ProjectionElem::ConstantIndex {
1827-
offset,
1828-
min_length,
1829-
from_end: false,
1830-
} => write!(fmt, "{:?}[{:?} of {:?}]", data.base, offset, min_length),
1831-
ProjectionElem::ConstantIndex {
1832-
offset,
1833-
min_length,
1834-
from_end: true,
1835-
} => write!(fmt, "{:?}[-{:?} of {:?}]", data.base, offset, min_length),
1836-
ProjectionElem::Subslice { from, to } if to == 0 => {
1837-
write!(fmt, "{:?}[{:?}:]", data.base, from)
1838-
}
1839-
ProjectionElem::Subslice { from, to } if from == 0 => {
1840-
write!(fmt, "{:?}[:-{:?}]", data.base, to)
1841-
}
1842-
ProjectionElem::Subslice { from, to } => {
1843-
write!(fmt, "{:?}[{:?}:-{:?}]", data.base, from, to)
1844-
}
1845-
},
18461844
}
18471845
}
18481846
}
@@ -2760,18 +2758,36 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
27602758

27612759
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
27622760
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
2763-
match self {
2764-
&Place::Projection(ref p) => Place::Projection(p.fold_with(folder)),
2765-
_ => self.clone(),
2761+
Place {
2762+
base: self.base.fold_with(folder),
2763+
elems: self.elems.fold_with(folder),
27662764
}
27672765
}
27682766

27692767
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
2770-
if let &Place::Projection(ref p) = self {
2771-
p.visit_with(visitor)
2772-
} else {
2773-
false
2774-
}
2768+
self.base.visit_with(visitor) ||
2769+
self.elems.visit_with(visitor)
2770+
}
2771+
}
2772+
2773+
impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> {
2774+
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
2775+
self.clone()
2776+
}
2777+
2778+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
2779+
false
2780+
}
2781+
}
2782+
2783+
impl<'tcx> TypeFoldable<'tcx> for &'tcx Slice<PlaceElem<'tcx>> {
2784+
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
2785+
let v = self.iter().map(|p| p.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
2786+
folder.tcx().intern_place_elems(&v)
2787+
}
2788+
2789+
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
2790+
self.iter().any(|p| p.visit_with(visitor))
27752791
}
27762792
}
27772793

@@ -2858,37 +2874,52 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
28582874
}
28592875
}
28602876

2861-
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
2862-
where
2863-
B: TypeFoldable<'tcx>,
2864-
V: TypeFoldable<'tcx>,
2865-
T: TypeFoldable<'tcx>,
2877+
impl<'tcx, V, T> TypeFoldable<'tcx> for ProjectionElem<'tcx, V, T>
2878+
where V: TypeFoldable<'tcx>,
2879+
T: TypeFoldable<'tcx>
28662880
{
28672881
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
28682882
use mir::ProjectionElem::*;
28692883

2870-
let base = self.base.fold_with(folder);
2871-
let elem = match self.elem {
2884+
match *self {
28722885
Deref => Deref,
28732886
Field(f, ref ty) => Field(f, ty.fold_with(folder)),
28742887
Index(ref v) => Index(v.fold_with(folder)),
28752888
ref elem => elem.clone(),
2876-
};
2877-
2878-
Projection { base, elem }
2889+
}
28792890
}
28802891

28812892
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
28822893
use mir::ProjectionElem::*;
28832894

2884-
self.base.visit_with(visitor) || match self.elem {
2895+
match *self {
28852896
Field(_, ref ty) => ty.visit_with(visitor),
28862897
Index(ref v) => v.visit_with(visitor),
28872898
_ => false,
28882899
}
28892900
}
28902901
}
28912902

2903+
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
2904+
where
2905+
B: TypeFoldable<'tcx>,
2906+
V: TypeFoldable<'tcx>,
2907+
T: TypeFoldable<'tcx>,
2908+
{
2909+
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
2910+
2911+
let base = self.base.fold_with(folder);
2912+
let elem = self.elem.fold_with(folder);
2913+
Projection { base, elem }
2914+
}
2915+
2916+
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
2917+
2918+
self.base.visit_with(visitor) ||
2919+
self.elem.visit_with(visitor)
2920+
}
2921+
}
2922+
28922923
impl<'tcx> TypeFoldable<'tcx> for Field {
28932924
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self {
28942925
*self

0 commit comments

Comments
 (0)