@@ -21,6 +21,7 @@ use mir::interpret::{EvalErrorKind, Scalar, Value, ScalarMaybeUndef};
21
21
use mir:: visit:: MirVisitable ;
22
22
use rustc_apfloat:: ieee:: { Double , Single } ;
23
23
use rustc_apfloat:: Float ;
24
+ use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
24
25
use rustc_data_structures:: graph:: dominators:: { dominators, Dominators } ;
25
26
use rustc_data_structures:: graph:: { self , GraphPredecessors , GraphSuccessors } ;
26
27
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
@@ -39,7 +40,7 @@ use syntax::symbol::InternedString;
39
40
use syntax_pos:: { Span , DUMMY_SP } ;
40
41
use ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
41
42
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 } ;
43
44
use util:: ppaux;
44
45
45
46
pub use mir:: interpret:: AssertMessage ;
@@ -1693,8 +1694,16 @@ impl<'tcx> Debug for Statement<'tcx> {
1693
1694
1694
1695
/// A path to a value; something that can be evaluated without
1695
1696
/// 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
+
1696
1705
#[ derive( Clone , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1697
- pub enum Place < ' tcx > {
1706
+ pub enum PlaceBase < ' tcx > {
1698
1707
/// local variable
1699
1708
Local ( Local ) ,
1700
1709
@@ -1703,9 +1712,6 @@ pub enum Place<'tcx> {
1703
1712
1704
1713
/// Constant code promoted to an injected static
1705
1714
Promoted ( Box < ( Promoted , Ty < ' tcx > ) > ) ,
1706
-
1707
- /// projection out of a place (access a field, deref a pointer, etc)
1708
- Projection ( Box < PlaceProjection < ' tcx > > ) ,
1709
1715
}
1710
1716
1711
1717
/// The def-id of a static, along with its normalized type (which is
@@ -1731,7 +1737,7 @@ pub struct Projection<'tcx, B, V, T> {
1731
1737
pub elem : ProjectionElem < ' tcx , V , T > ,
1732
1738
}
1733
1739
1734
- #[ derive( Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1740
+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1735
1741
pub enum ProjectionElem < ' tcx , V , T > {
1736
1742
Deref ,
1737
1743
Field ( Field , T ) ,
@@ -1779,31 +1785,52 @@ pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
1779
1785
1780
1786
newtype_index ! ( Field { DEBUG_FORMAT = "field[{}]" } ) ;
1781
1787
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 ( )
1785
1792
}
1786
1793
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) )
1789
1801
}
1790
1802
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 )
1793
1805
}
1794
1806
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) )
1797
1817
}
1798
1818
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
+ }
1801
1828
}
1802
1829
}
1803
1830
1804
- impl < ' tcx > Debug for Place < ' tcx > {
1831
+ impl < ' tcx > Debug for PlaceBase < ' tcx > {
1805
1832
fn fmt ( & self , fmt : & mut Formatter ) -> fmt:: Result {
1806
- use self :: Place :: * ;
1833
+ use self :: PlaceBase :: * ;
1807
1834
1808
1835
match * self {
1809
1836
Local ( id) => write ! ( fmt, "{:?}" , id) ,
@@ -1814,35 +1841,6 @@ impl<'tcx> Debug for Place<'tcx> {
1814
1841
ty
1815
1842
) ,
1816
1843
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
- } ,
1846
1844
}
1847
1845
}
1848
1846
}
@@ -2760,18 +2758,36 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
2760
2758
2761
2759
impl < ' tcx > TypeFoldable < ' tcx > for Place < ' tcx > {
2762
2760
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 ) ,
2766
2764
}
2767
2765
}
2768
2766
2769
2767
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) )
2775
2791
}
2776
2792
}
2777
2793
@@ -2858,37 +2874,52 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
2858
2874
}
2859
2875
}
2860
2876
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 >
2866
2880
{
2867
2881
fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F ) -> Self {
2868
2882
use mir:: ProjectionElem :: * ;
2869
2883
2870
- let base = self . base . fold_with ( folder) ;
2871
- let elem = match self . elem {
2884
+ match * self {
2872
2885
Deref => Deref ,
2873
2886
Field ( f, ref ty) => Field ( f, ty. fold_with ( folder) ) ,
2874
2887
Index ( ref v) => Index ( v. fold_with ( folder) ) ,
2875
2888
ref elem => elem. clone ( ) ,
2876
- } ;
2877
-
2878
- Projection { base, elem }
2889
+ }
2879
2890
}
2880
2891
2881
2892
fn super_visit_with < Vs : TypeVisitor < ' tcx > > ( & self , visitor : & mut Vs ) -> bool {
2882
2893
use mir:: ProjectionElem :: * ;
2883
2894
2884
- self . base . visit_with ( visitor ) || match self . elem {
2895
+ match * self {
2885
2896
Field ( _, ref ty) => ty. visit_with ( visitor) ,
2886
2897
Index ( ref v) => v. visit_with ( visitor) ,
2887
2898
_ => false ,
2888
2899
}
2889
2900
}
2890
2901
}
2891
2902
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
+
2892
2923
impl < ' tcx > TypeFoldable < ' tcx > for Field {
2893
2924
fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , _: & mut F ) -> Self {
2894
2925
* self
0 commit comments