@@ -166,6 +166,16 @@ pub struct Body<'tcx> {
166166
167167 /// A span representing this MIR, for error reporting.
168168 pub span : Span ,
169+
170+ /// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because
171+ /// we'd statically know that no thing with interior mutability will ever be available to the
172+ /// user without some serious unsafe code. Now this means that our promoted is actually
173+ /// &[(SOME_CELL, 42)] and the MIR using it will do the &promoted[i].1 projection because the
174+ /// index may be a runtime value. Such a promoted value is illegal because it has reachable
175+ /// interior mutability. This flag just makes this situation very obvious where the previous
176+ /// implementation without the flag hid this situation silently.
177+ /// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components.
178+ pub ignore_interior_mut_in_const_validation : bool ,
169179}
170180
171181impl < ' tcx > Body < ' tcx > {
@@ -202,6 +212,7 @@ impl<'tcx> Body<'tcx> {
202212 spread_arg : None ,
203213 var_debug_info,
204214 span,
215+ ignore_interior_mut_in_const_validation : false ,
205216 control_flow_destroyed,
206217 }
207218 }
@@ -1642,68 +1653,16 @@ impl Debug for Statement<'_> {
16421653
16431654/// A path to a value; something that can be evaluated without
16441655/// changing or disturbing program state.
1645- #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , HashStable ) ]
1656+ #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , HashStable ) ]
16461657pub struct Place < ' tcx > {
1647- pub base : PlaceBase < ' tcx > ,
1658+ pub local : Local ,
16481659
16491660 /// projection out of a place (access a field, deref a pointer, etc)
16501661 pub projection : & ' tcx List < PlaceElem < ' tcx > > ,
16511662}
16521663
16531664impl < ' tcx > rustc_serialize:: UseSpecializedDecodable for Place < ' tcx > { }
16541665
1655- #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable , HashStable ) ]
1656- pub enum PlaceBase < ' tcx > {
1657- /// local variable
1658- Local ( Local ) ,
1659-
1660- /// static or static mut variable
1661- Static ( Box < Static < ' tcx > > ) ,
1662- }
1663-
1664- /// We store the normalized type to avoid requiring normalization when reading MIR
1665- #[ derive(
1666- Clone ,
1667- Debug ,
1668- PartialEq ,
1669- Eq ,
1670- PartialOrd ,
1671- Ord ,
1672- Hash ,
1673- RustcEncodable ,
1674- RustcDecodable ,
1675- HashStable
1676- ) ]
1677- pub struct Static < ' tcx > {
1678- pub ty : Ty < ' tcx > ,
1679- pub kind : StaticKind < ' tcx > ,
1680- /// The `DefId` of the item this static was declared in. For promoted values, usually, this is
1681- /// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in.
1682- /// However, after inlining, that might no longer be the case as inlined `Place`s are copied
1683- /// into the calling frame.
1684- pub def_id : DefId ,
1685- }
1686-
1687- #[ derive(
1688- Clone ,
1689- Debug ,
1690- PartialEq ,
1691- Eq ,
1692- PartialOrd ,
1693- Ord ,
1694- Hash ,
1695- HashStable ,
1696- RustcEncodable ,
1697- RustcDecodable
1698- ) ]
1699- pub enum StaticKind < ' tcx > {
1700- /// Promoted references consist of an id (`Promoted`) and the substs necessary to monomorphize
1701- /// it. Usually, these substs are just the identity substs for the item. However, the inliner
1702- /// will adjust these substs when it inlines a function based on the substs at the callsite.
1703- Promoted ( Promoted , SubstsRef < ' tcx > ) ,
1704- Static ,
1705- }
1706-
17071666#[ derive( Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
17081667#[ derive( RustcEncodable , RustcDecodable , HashStable ) ]
17091668pub enum ProjectionElem < V , T > {
@@ -1791,14 +1750,14 @@ rustc_index::newtype_index! {
17911750
17921751#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
17931752pub struct PlaceRef < ' a , ' tcx > {
1794- pub base : & ' a PlaceBase < ' tcx > ,
1753+ pub local : & ' a Local ,
17951754 pub projection : & ' a [ PlaceElem < ' tcx > ] ,
17961755}
17971756
17981757impl < ' tcx > Place < ' tcx > {
17991758 // FIXME change this to a const fn by also making List::empty a const fn.
18001759 pub fn return_place ( ) -> Place < ' tcx > {
1801- Place { base : PlaceBase :: Local ( RETURN_PLACE ) , projection : List :: empty ( ) }
1760+ Place { local : RETURN_PLACE , projection : List :: empty ( ) }
18021761 }
18031762
18041763 /// Returns `true` if this `Place` contains a `Deref` projection.
@@ -1815,10 +1774,8 @@ impl<'tcx> Place<'tcx> {
18151774 // FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
18161775 pub fn local_or_deref_local ( & self ) -> Option < Local > {
18171776 match self . as_ref ( ) {
1818- PlaceRef { base : & PlaceBase :: Local ( local) , projection : & [ ] }
1819- | PlaceRef { base : & PlaceBase :: Local ( local) , projection : & [ ProjectionElem :: Deref ] } => {
1820- Some ( local)
1821- }
1777+ PlaceRef { local, projection : & [ ] }
1778+ | PlaceRef { local, projection : & [ ProjectionElem :: Deref ] } => Some ( * local) ,
18221779 _ => None ,
18231780 }
18241781 }
@@ -1830,19 +1787,13 @@ impl<'tcx> Place<'tcx> {
18301787 }
18311788
18321789 pub fn as_ref ( & self ) -> PlaceRef < ' _ , ' tcx > {
1833- PlaceRef { base : & self . base , projection : & self . projection }
1790+ PlaceRef { local : & self . local , projection : & self . projection }
18341791 }
18351792}
18361793
18371794impl From < Local > for Place < ' _ > {
18381795 fn from ( local : Local ) -> Self {
1839- Place { base : local. into ( ) , projection : List :: empty ( ) }
1840- }
1841- }
1842-
1843- impl From < Local > for PlaceBase < ' _ > {
1844- fn from ( local : Local ) -> Self {
1845- PlaceBase :: Local ( local)
1796+ Place { local, projection : List :: empty ( ) }
18461797 }
18471798}
18481799
@@ -1853,10 +1804,8 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
18531804 // FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
18541805 pub fn local_or_deref_local ( & self ) -> Option < Local > {
18551806 match self {
1856- PlaceRef { base : PlaceBase :: Local ( local) , projection : [ ] }
1857- | PlaceRef { base : PlaceBase :: Local ( local) , projection : [ ProjectionElem :: Deref ] } => {
1858- Some ( * local)
1859- }
1807+ PlaceRef { local, projection : [ ] }
1808+ | PlaceRef { local, projection : [ ProjectionElem :: Deref ] } => Some ( * * local) ,
18601809 _ => None ,
18611810 }
18621811 }
@@ -1865,7 +1814,7 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
18651814 /// projections, return `Some(_X)`.
18661815 pub fn as_local ( & self ) -> Option < Local > {
18671816 match self {
1868- PlaceRef { base : PlaceBase :: Local ( l ) , projection : [ ] } => Some ( * l ) ,
1817+ PlaceRef { local , projection : [ ] } => Some ( * * local ) ,
18691818 _ => None ,
18701819 }
18711820 }
@@ -1887,7 +1836,7 @@ impl Debug for Place<'_> {
18871836 }
18881837 }
18891838
1890- write ! ( fmt, "{:?}" , self . base ) ?;
1839+ write ! ( fmt, "{:?}" , self . local ) ?;
18911840
18921841 for elem in self . projection . iter ( ) {
18931842 match elem {
@@ -1931,22 +1880,6 @@ impl Debug for Place<'_> {
19311880 }
19321881}
19331882
1934- impl Debug for PlaceBase < ' _ > {
1935- fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
1936- match * self {
1937- PlaceBase :: Local ( id) => write ! ( fmt, "{:?}" , id) ,
1938- PlaceBase :: Static ( box self :: Static { ty, kind : StaticKind :: Static , def_id } ) => {
1939- write ! ( fmt, "({}: {:?})" , ty:: tls:: with( |tcx| tcx. def_path_str( def_id) ) , ty)
1940- }
1941- PlaceBase :: Static ( box self :: Static {
1942- ty,
1943- kind : StaticKind :: Promoted ( promoted, _) ,
1944- def_id : _,
1945- } ) => write ! ( fmt, "({:?}: {:?})" , promoted, ty) ,
1946- }
1947- }
1948- }
1949-
19501883///////////////////////////////////////////////////////////////////////////
19511884// Scopes
19521885
@@ -3007,27 +2940,11 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
30072940
30082941impl < ' tcx > TypeFoldable < ' tcx > for Place < ' tcx > {
30092942 fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3010- Place { base : self . base . fold_with ( folder) , projection : self . projection . fold_with ( folder) }
3011- }
3012-
3013- fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3014- self . base . visit_with ( visitor) || self . projection . visit_with ( visitor)
3015- }
3016- }
3017-
3018- impl < ' tcx > TypeFoldable < ' tcx > for PlaceBase < ' tcx > {
3019- fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3020- match self {
3021- PlaceBase :: Local ( local) => PlaceBase :: Local ( local. fold_with ( folder) ) ,
3022- PlaceBase :: Static ( static_) => PlaceBase :: Static ( static_. fold_with ( folder) ) ,
3023- }
2943+ Place { local : self . local . fold_with ( folder) , projection : self . projection . fold_with ( folder) }
30242944 }
30252945
30262946 fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3027- match self {
3028- PlaceBase :: Local ( local) => local. visit_with ( visitor) ,
3029- PlaceBase :: Static ( static_) => ( * * static_) . visit_with ( visitor) ,
3030- }
2947+ self . local . visit_with ( visitor) || self . projection . visit_with ( visitor)
30312948 }
30322949}
30332950
@@ -3042,42 +2959,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
30422959 }
30432960}
30442961
3045- impl < ' tcx > TypeFoldable < ' tcx > for Static < ' tcx > {
3046- fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3047- Static {
3048- ty : self . ty . fold_with ( folder) ,
3049- kind : self . kind . fold_with ( folder) ,
3050- def_id : self . def_id ,
3051- }
3052- }
3053-
3054- fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3055- let Static { ty, kind, def_id : _ } = self ;
3056-
3057- ty. visit_with ( visitor) || kind. visit_with ( visitor)
3058- }
3059- }
3060-
3061- impl < ' tcx > TypeFoldable < ' tcx > for StaticKind < ' tcx > {
3062- fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3063- match self {
3064- StaticKind :: Promoted ( promoted, substs) => {
3065- StaticKind :: Promoted ( promoted. fold_with ( folder) , substs. fold_with ( folder) )
3066- }
3067- StaticKind :: Static => StaticKind :: Static ,
3068- }
3069- }
3070-
3071- fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3072- match self {
3073- StaticKind :: Promoted ( promoted, substs) => {
3074- promoted. visit_with ( visitor) || substs. visit_with ( visitor)
3075- }
3076- StaticKind :: Static => false ,
3077- }
3078- }
3079- }
3080-
30812962impl < ' tcx > TypeFoldable < ' tcx > for Rvalue < ' tcx > {
30822963 fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
30832964 use crate :: mir:: Rvalue :: * ;
0 commit comments