@@ -15,8 +15,7 @@ use crate::ty::layout::VariantIdx;
1515use crate :: ty:: print:: { FmtPrinter , Printer } ;
1616use crate :: ty:: subst:: { Subst , SubstsRef } ;
1717use crate :: ty:: {
18- self , AdtDef , CanonicalUserTypeAnnotations , Region , Ty , TyCtxt ,
19- UserTypeAnnotationIndex ,
18+ self , AdtDef , CanonicalUserTypeAnnotations , List , Region , Ty , TyCtxt , UserTypeAnnotationIndex ,
2019} ;
2120
2221use polonius_engine:: Atom ;
@@ -1712,15 +1711,17 @@ impl Debug for Statement<'_> {
17121711/// A path to a value; something that can be evaluated without
17131712/// changing or disturbing program state.
17141713#[ derive(
1715- Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable , HashStable ,
1714+ Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , HashStable ,
17161715) ]
17171716pub struct Place < ' tcx > {
17181717 pub base : PlaceBase < ' tcx > ,
17191718
17201719 /// 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 > > ,
17221721}
17231722
1723+ impl < ' tcx > rustc_serialize:: UseSpecializedDecodable for Place < ' tcx > { }
1724+
17241725#[ derive(
17251726 Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable , HashStable ,
17261727) ]
@@ -1848,50 +1849,56 @@ pub struct PlaceRef<'a, 'tcx> {
18481849}
18491850
18501851impl < ' 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.
18571853 pub fn return_place ( ) -> Place < ' tcx > {
18581854 Place {
18591855 base : PlaceBase :: Local ( RETURN_PLACE ) ,
1860- projection : Box :: new ( [ ] ) ,
1856+ projection : List :: empty ( ) ,
18611857 }
18621858 }
18631859
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 )
18661862 }
18671863
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 )
18701866 }
18711867
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+ )
18771881 }
18781882
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 )
18811885 }
18821886
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 )
18851889 }
18861890
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 ( ) ;
18901897 projection. push ( elem) ;
18911898
18921899 Place {
18931900 base : self . base ,
1894- projection : projection . into_boxed_slice ( ) ,
1901+ projection : tcx . intern_place_elems ( & projection ) ,
18951902 }
18961903 }
18971904
@@ -1939,7 +1946,7 @@ impl From<Local> for Place<'_> {
19391946 fn from ( local : Local ) -> Self {
19401947 Place {
19411948 base : local. into ( ) ,
1942- projection : Box :: new ( [ ] ) ,
1949+ projection : List :: empty ( ) ,
19431950 }
19441951 }
19451952}
@@ -3190,6 +3197,17 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> {
31903197 }
31913198}
31923199
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+
31933211impl < ' tcx > TypeFoldable < ' tcx > for Static < ' tcx > {
31943212 fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
31953213 Static {
0 commit comments