@@ -15,8 +15,7 @@ use crate::ty::layout::VariantIdx;
15
15
use crate :: ty:: print:: { FmtPrinter , Printer } ;
16
16
use crate :: ty:: subst:: { Subst , SubstsRef } ;
17
17
use crate :: ty:: {
18
- self , AdtDef , CanonicalUserTypeAnnotations , Region , Ty , TyCtxt ,
19
- UserTypeAnnotationIndex ,
18
+ self , AdtDef , CanonicalUserTypeAnnotations , List , Region , Ty , TyCtxt , UserTypeAnnotationIndex ,
20
19
} ;
21
20
22
21
use polonius_engine:: Atom ;
@@ -1712,15 +1711,17 @@ impl Debug for Statement<'_> {
1712
1711
/// A path to a value; something that can be evaluated without
1713
1712
/// changing or disturbing program state.
1714
1713
#[ derive(
1715
- Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable , HashStable ,
1714
+ Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , HashStable ,
1716
1715
) ]
1717
1716
pub struct Place < ' tcx > {
1718
1717
pub base : PlaceBase < ' tcx > ,
1719
1718
1720
1719
/// projection out of a place (access a field, deref a pointer, etc)
1721
- pub projection : Box < [ PlaceElem < ' tcx > ] > ,
1720
+ pub projection : & ' tcx List < PlaceElem < ' tcx > > ,
1722
1721
}
1723
1722
1723
+ impl < ' tcx > rustc_serialize:: UseSpecializedDecodable for Place < ' tcx > { }
1724
+
1724
1725
#[ derive(
1725
1726
Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable , HashStable ,
1726
1727
) ]
@@ -1848,50 +1849,56 @@ pub struct PlaceRef<'a, 'tcx> {
1848
1849
}
1849
1850
1850
1851
impl < ' tcx > Place < ' tcx > {
1851
- // FIXME change this back to a const when projection is a shared slice.
1852
- //
1853
- // pub const RETURN_PLACE: Place<'tcx> = Place {
1854
- // base: PlaceBase::Local(RETURN_PLACE),
1855
- // projection: &[],
1856
- // };
1852
+ // FIXME change this to a const fn by also making List::empty a const fn.
1857
1853
pub fn return_place ( ) -> Place < ' tcx > {
1858
1854
Place {
1859
1855
base : PlaceBase :: Local ( RETURN_PLACE ) ,
1860
- projection : Box :: new ( [ ] ) ,
1856
+ projection : List :: empty ( ) ,
1861
1857
}
1862
1858
}
1863
1859
1864
- pub fn field ( self , f : Field , ty : Ty < ' tcx > ) -> Place < ' tcx > {
1865
- self . elem ( ProjectionElem :: Field ( f, ty) )
1860
+ pub fn field ( self , f : Field , ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Place < ' tcx > {
1861
+ self . elem ( ProjectionElem :: Field ( f, ty) , tcx )
1866
1862
}
1867
1863
1868
- pub fn deref ( self ) -> Place < ' tcx > {
1869
- self . elem ( ProjectionElem :: Deref )
1864
+ pub fn deref ( self , tcx : TyCtxt < ' tcx > ) -> Place < ' tcx > {
1865
+ self . elem ( ProjectionElem :: Deref , tcx )
1870
1866
}
1871
1867
1872
- pub fn downcast ( self , adt_def : & ' tcx AdtDef , variant_index : VariantIdx ) -> Place < ' tcx > {
1873
- self . elem ( ProjectionElem :: Downcast (
1874
- Some ( adt_def. variants [ variant_index] . ident . name ) ,
1875
- variant_index,
1876
- ) )
1868
+ pub fn downcast (
1869
+ self ,
1870
+ adt_def : & ' tcx AdtDef ,
1871
+ variant_index : VariantIdx ,
1872
+ tcx : TyCtxt < ' tcx > ,
1873
+ ) -> Place < ' tcx > {
1874
+ self . elem (
1875
+ ProjectionElem :: Downcast (
1876
+ Some ( adt_def. variants [ variant_index] . ident . name ) ,
1877
+ variant_index,
1878
+ ) ,
1879
+ tcx,
1880
+ )
1877
1881
}
1878
1882
1879
- pub fn downcast_unnamed ( self , variant_index : VariantIdx ) -> Place < ' tcx > {
1880
- self . elem ( ProjectionElem :: Downcast ( None , variant_index) )
1883
+ pub fn downcast_unnamed ( self , variant_index : VariantIdx , tcx : TyCtxt < ' tcx > ) -> Place < ' tcx > {
1884
+ self . elem ( ProjectionElem :: Downcast ( None , variant_index) , tcx )
1881
1885
}
1882
1886
1883
- pub fn index ( self , index : Local ) -> Place < ' tcx > {
1884
- self . elem ( ProjectionElem :: Index ( index) )
1887
+ pub fn index ( self , index : Local , tcx : TyCtxt < ' tcx > ) -> Place < ' tcx > {
1888
+ self . elem ( ProjectionElem :: Index ( index) , tcx )
1885
1889
}
1886
1890
1887
- pub fn elem ( self , elem : PlaceElem < ' tcx > ) -> Place < ' tcx > {
1888
- // FIXME(spastorino): revisit this again once projection is not a Box<[T]> anymore
1889
- let mut projection = self . projection . into_vec ( ) ;
1891
+ /// This method copies `Place`'s projection, add an element and reintern it. Should not be used
1892
+ /// to build a full `Place` it's just a convenient way to grab a projection and modify it in
1893
+ /// flight.
1894
+ // FIXME: It may be a better idea to move all these methods to `PlaceBuilder`
1895
+ pub fn elem ( self , elem : PlaceElem < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Place < ' tcx > {
1896
+ let mut projection = self . projection . to_vec ( ) ;
1890
1897
projection. push ( elem) ;
1891
1898
1892
1899
Place {
1893
1900
base : self . base ,
1894
- projection : projection . into_boxed_slice ( ) ,
1901
+ projection : tcx . intern_place_elems ( & projection ) ,
1895
1902
}
1896
1903
}
1897
1904
@@ -1939,7 +1946,7 @@ impl From<Local> for Place<'_> {
1939
1946
fn from ( local : Local ) -> Self {
1940
1947
Place {
1941
1948
base : local. into ( ) ,
1942
- projection : Box :: new ( [ ] ) ,
1949
+ projection : List :: empty ( ) ,
1943
1950
}
1944
1951
}
1945
1952
}
@@ -3190,6 +3197,17 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> {
3190
3197
}
3191
3198
}
3192
3199
3200
+ impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx ty:: List < PlaceElem < ' tcx > > {
3201
+ fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3202
+ let v = self . iter ( ) . map ( |t| t. fold_with ( folder) ) . collect :: < Vec < _ > > ( ) ;
3203
+ folder. tcx ( ) . intern_place_elems ( & v)
3204
+ }
3205
+
3206
+ fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3207
+ self . iter ( ) . any ( |t| t. visit_with ( visitor) )
3208
+ }
3209
+ }
3210
+
3193
3211
impl < ' tcx > TypeFoldable < ' tcx > for Static < ' tcx > {
3194
3212
fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3195
3213
Static {
0 commit comments