@@ -154,6 +154,16 @@ pub struct Body<'tcx> {
154154
155155 /// A span representing this MIR, for error reporting.
156156 pub span : Span ,
157+
158+ /// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because
159+ /// we'd statically know that no thing with interior mutability will ever be available to the
160+ /// user without some serious unsafe code. Now this means that our promoted is actually
161+ /// &[(SOME_CELL, 42)] and the MIR using it will do the &promoted[i].1 projection because the
162+ /// index may be a runtime value. Such a promoted value is illegal because it has reachable
163+ /// interior mutability. This flag just makes this situation very obvious where the previous
164+ /// implementation without the flag hid this situation silently.
165+ /// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components.
166+ pub ignore_interior_mut_in_const_validation : bool ,
157167}
158168
159169impl < ' tcx > Body < ' tcx > {
@@ -190,6 +200,7 @@ impl<'tcx> Body<'tcx> {
190200 spread_arg : None ,
191201 var_debug_info,
192202 span,
203+ ignore_interior_mut_in_const_validation : false ,
193204 control_flow_destroyed,
194205 }
195206 }
@@ -1649,52 +1660,17 @@ impl Debug for Statement<'_> {
16491660/// A path to a value; something that can be evaluated without
16501661/// changing or disturbing program state.
16511662#[ derive(
1652- Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , HashStable ,
1663+ Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , HashStable ,
16531664) ]
16541665pub struct Place < ' tcx > {
1655- pub base : PlaceBase < ' tcx > ,
1666+ pub local : Local ,
16561667
16571668 /// projection out of a place (access a field, deref a pointer, etc)
16581669 pub projection : & ' tcx List < PlaceElem < ' tcx > > ,
16591670}
16601671
16611672impl < ' tcx > rustc_serialize:: UseSpecializedDecodable for Place < ' tcx > { }
16621673
1663- #[ derive(
1664- Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable , HashStable ,
1665- ) ]
1666- pub enum PlaceBase < ' tcx > {
1667- /// local variable
1668- Local ( Local ) ,
1669-
1670- /// static or static mut variable
1671- Static ( Box < Static < ' tcx > > ) ,
1672- }
1673-
1674- /// We store the normalized type to avoid requiring normalization when reading MIR
1675- #[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ,
1676- RustcEncodable , RustcDecodable , HashStable ) ]
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 , Debug , PartialEq , Eq , PartialOrd , Ord , Hash , HashStable , RustcEncodable , RustcDecodable ,
1689- ) ]
1690- pub enum StaticKind < ' tcx > {
1691- /// Promoted references consist of an id (`Promoted`) and the substs necessary to monomorphize
1692- /// it. Usually, these substs are just the identity substs for the item. However, the inliner
1693- /// will adjust these substs when it inlines a function based on the substs at the callsite.
1694- Promoted ( Promoted , SubstsRef < ' tcx > ) ,
1695- Static ,
1696- }
1697-
16981674#[ derive( Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
16991675#[ derive( RustcEncodable , RustcDecodable , HashStable ) ]
17001676pub enum ProjectionElem < V , T > {
@@ -1783,15 +1759,15 @@ rustc_index::newtype_index! {
17831759
17841760#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
17851761pub struct PlaceRef < ' a , ' tcx > {
1786- pub base : & ' a PlaceBase < ' tcx > ,
1762+ pub local : & ' a Local ,
17871763 pub projection : & ' a [ PlaceElem < ' tcx > ] ,
17881764}
17891765
17901766impl < ' tcx > Place < ' tcx > {
17911767 // FIXME change this to a const fn by also making List::empty a const fn.
17921768 pub fn return_place ( ) -> Place < ' tcx > {
17931769 Place {
1794- base : PlaceBase :: Local ( RETURN_PLACE ) ,
1770+ local : RETURN_PLACE ,
17951771 projection : List :: empty ( ) ,
17961772 }
17971773 }
@@ -1811,13 +1787,13 @@ impl<'tcx> Place<'tcx> {
18111787 pub fn local_or_deref_local ( & self ) -> Option < Local > {
18121788 match self . as_ref ( ) {
18131789 PlaceRef {
1814- base : & PlaceBase :: Local ( local) ,
1790+ local,
18151791 projection : & [ ] ,
18161792 } |
18171793 PlaceRef {
1818- base : & PlaceBase :: Local ( local) ,
1794+ local,
18191795 projection : & [ ProjectionElem :: Deref ] ,
1820- } => Some ( local) ,
1796+ } => Some ( * local) ,
18211797 _ => None ,
18221798 }
18231799 }
@@ -1830,7 +1806,7 @@ impl<'tcx> Place<'tcx> {
18301806
18311807 pub fn as_ref ( & self ) -> PlaceRef < ' _ , ' tcx > {
18321808 PlaceRef {
1833- base : & self . base ,
1809+ local : & self . local ,
18341810 projection : & self . projection ,
18351811 }
18361812 }
@@ -1839,18 +1815,12 @@ impl<'tcx> Place<'tcx> {
18391815impl From < Local > for Place < ' _ > {
18401816 fn from ( local : Local ) -> Self {
18411817 Place {
1842- base : local. into ( ) ,
1818+ local,
18431819 projection : List :: empty ( ) ,
18441820 }
18451821 }
18461822}
18471823
1848- impl From < Local > for PlaceBase < ' _ > {
1849- fn from ( local : Local ) -> Self {
1850- PlaceBase :: Local ( local)
1851- }
1852- }
1853-
18541824impl < ' a , ' tcx > PlaceRef < ' a , ' tcx > {
18551825 /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
18561826 /// a single deref of a local.
@@ -1859,13 +1829,13 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
18591829 pub fn local_or_deref_local ( & self ) -> Option < Local > {
18601830 match self {
18611831 PlaceRef {
1862- base : PlaceBase :: Local ( local) ,
1832+ local,
18631833 projection : [ ] ,
18641834 } |
18651835 PlaceRef {
1866- base : PlaceBase :: Local ( local) ,
1836+ local,
18671837 projection : [ ProjectionElem :: Deref ] ,
1868- } => Some ( * local) ,
1838+ } => Some ( * * local) ,
18691839 _ => None ,
18701840 }
18711841 }
@@ -1874,7 +1844,7 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
18741844 /// projections, return `Some(_X)`.
18751845 pub fn as_local ( & self ) -> Option < Local > {
18761846 match self {
1877- PlaceRef { base : PlaceBase :: Local ( l ) , projection : [ ] } => Some ( * l ) ,
1847+ PlaceRef { local , projection : [ ] } => Some ( * * local ) ,
18781848 _ => None ,
18791849 }
18801850 }
@@ -1896,7 +1866,7 @@ impl Debug for Place<'_> {
18961866 }
18971867 }
18981868
1899- write ! ( fmt, "{:?}" , self . base ) ?;
1869+ write ! ( fmt, "{:?}" , self . local ) ?;
19001870
19011871 for elem in self . projection . iter ( ) {
19021872 match elem {
@@ -1940,22 +1910,6 @@ impl Debug for Place<'_> {
19401910 }
19411911}
19421912
1943- impl Debug for PlaceBase < ' _ > {
1944- fn fmt ( & self , fmt : & mut Formatter < ' _ > ) -> fmt:: Result {
1945- match * self {
1946- PlaceBase :: Local ( id) => write ! ( fmt, "{:?}" , id) ,
1947- PlaceBase :: Static ( box self :: Static { ty, kind : StaticKind :: Static , def_id } ) => {
1948- write ! ( fmt, "({}: {:?})" , ty:: tls:: with( |tcx| tcx. def_path_str( def_id) ) , ty)
1949- }
1950- PlaceBase :: Static ( box self :: Static {
1951- ty, kind : StaticKind :: Promoted ( promoted, _) , def_id : _
1952- } ) => {
1953- write ! ( fmt, "({:?}: {:?})" , promoted, ty)
1954- }
1955- }
1956- }
1957- }
1958-
19591913///////////////////////////////////////////////////////////////////////////
19601914// Scopes
19611915
@@ -3019,29 +2973,13 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
30192973impl < ' tcx > TypeFoldable < ' tcx > for Place < ' tcx > {
30202974 fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
30212975 Place {
3022- base : self . base . fold_with ( folder) ,
2976+ local : self . local . fold_with ( folder) ,
30232977 projection : self . projection . fold_with ( folder) ,
30242978 }
30252979 }
30262980
30272981 fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3028- self . base . visit_with ( visitor) || self . projection . visit_with ( visitor)
3029- }
3030- }
3031-
3032- impl < ' tcx > TypeFoldable < ' tcx > for PlaceBase < ' tcx > {
3033- fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3034- match self {
3035- PlaceBase :: Local ( local) => PlaceBase :: Local ( local. fold_with ( folder) ) ,
3036- PlaceBase :: Static ( static_) => PlaceBase :: Static ( static_. fold_with ( folder) ) ,
3037- }
3038- }
3039-
3040- fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3041- match self {
3042- PlaceBase :: Local ( local) => local. visit_with ( visitor) ,
3043- PlaceBase :: Static ( static_) => ( * * static_) . visit_with ( visitor) ,
3044- }
2982+ self . local . visit_with ( visitor) || self . projection . visit_with ( visitor)
30452983 }
30462984}
30472985
@@ -3056,40 +2994,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
30562994 }
30572995}
30582996
3059- impl < ' tcx > TypeFoldable < ' tcx > for Static < ' tcx > {
3060- fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3061- Static {
3062- ty : self . ty . fold_with ( folder) ,
3063- kind : self . kind . fold_with ( folder) ,
3064- def_id : self . def_id ,
3065- }
3066- }
3067-
3068- fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3069- let Static { ty, kind, def_id : _ } = self ;
3070-
3071- ty. visit_with ( visitor) || kind. visit_with ( visitor)
3072- }
3073- }
3074-
3075- impl < ' tcx > TypeFoldable < ' tcx > for StaticKind < ' tcx > {
3076- fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3077- match self {
3078- StaticKind :: Promoted ( promoted, substs) =>
3079- StaticKind :: Promoted ( promoted. fold_with ( folder) , substs. fold_with ( folder) ) ,
3080- StaticKind :: Static => StaticKind :: Static
3081- }
3082- }
3083-
3084- fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
3085- match self {
3086- StaticKind :: Promoted ( promoted, substs) =>
3087- promoted. visit_with ( visitor) || substs. visit_with ( visitor) ,
3088- StaticKind :: Static => { false }
3089- }
3090- }
3091- }
3092-
30932997impl < ' tcx > TypeFoldable < ' tcx > for Rvalue < ' tcx > {
30942998 fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
30952999 use crate :: mir:: Rvalue :: * ;
0 commit comments