@@ -166,6 +166,16 @@ pub struct Body<'tcx> {
166
166
167
167
/// A span representing this MIR, for error reporting.
168
168
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 ,
169
179
}
170
180
171
181
impl < ' tcx > Body < ' tcx > {
@@ -202,6 +212,7 @@ impl<'tcx> Body<'tcx> {
202
212
spread_arg : None ,
203
213
var_debug_info,
204
214
span,
215
+ ignore_interior_mut_in_const_validation : false ,
205
216
control_flow_destroyed,
206
217
}
207
218
}
@@ -1642,68 +1653,16 @@ impl Debug for Statement<'_> {
1642
1653
1643
1654
/// A path to a value; something that can be evaluated without
1644
1655
/// 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 ) ]
1646
1657
pub struct Place < ' tcx > {
1647
- pub base : PlaceBase < ' tcx > ,
1658
+ pub local : Local ,
1648
1659
1649
1660
/// projection out of a place (access a field, deref a pointer, etc)
1650
1661
pub projection : & ' tcx List < PlaceElem < ' tcx > > ,
1651
1662
}
1652
1663
1653
1664
impl < ' tcx > rustc_serialize:: UseSpecializedDecodable for Place < ' tcx > { }
1654
1665
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
-
1707
1666
#[ derive( Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
1708
1667
#[ derive( RustcEncodable , RustcDecodable , HashStable ) ]
1709
1668
pub enum ProjectionElem < V , T > {
@@ -1791,14 +1750,14 @@ rustc_index::newtype_index! {
1791
1750
1792
1751
#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
1793
1752
pub struct PlaceRef < ' a , ' tcx > {
1794
- pub base : & ' a PlaceBase < ' tcx > ,
1753
+ pub local : & ' a Local ,
1795
1754
pub projection : & ' a [ PlaceElem < ' tcx > ] ,
1796
1755
}
1797
1756
1798
1757
impl < ' tcx > Place < ' tcx > {
1799
1758
// FIXME change this to a const fn by also making List::empty a const fn.
1800
1759
pub fn return_place ( ) -> Place < ' tcx > {
1801
- Place { base : PlaceBase :: Local ( RETURN_PLACE ) , projection : List :: empty ( ) }
1760
+ Place { local : RETURN_PLACE , projection : List :: empty ( ) }
1802
1761
}
1803
1762
1804
1763
/// Returns `true` if this `Place` contains a `Deref` projection.
@@ -1815,10 +1774,8 @@ impl<'tcx> Place<'tcx> {
1815
1774
// FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
1816
1775
pub fn local_or_deref_local ( & self ) -> Option < Local > {
1817
1776
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) ,
1822
1779
_ => None ,
1823
1780
}
1824
1781
}
@@ -1830,19 +1787,13 @@ impl<'tcx> Place<'tcx> {
1830
1787
}
1831
1788
1832
1789
pub fn as_ref ( & self ) -> PlaceRef < ' _ , ' tcx > {
1833
- PlaceRef { base : & self . base , projection : & self . projection }
1790
+ PlaceRef { local : & self . local , projection : & self . projection }
1834
1791
}
1835
1792
}
1836
1793
1837
1794
impl From < Local > for Place < ' _ > {
1838
1795
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 ( ) }
1846
1797
}
1847
1798
}
1848
1799
@@ -1853,10 +1804,8 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
1853
1804
// FIXME: can we safely swap the semantics of `fn base_local` below in here instead?
1854
1805
pub fn local_or_deref_local ( & self ) -> Option < Local > {
1855
1806
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) ,
1860
1809
_ => None ,
1861
1810
}
1862
1811
}
@@ -1865,7 +1814,7 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
1865
1814
/// projections, return `Some(_X)`.
1866
1815
pub fn as_local ( & self ) -> Option < Local > {
1867
1816
match self {
1868
- PlaceRef { base : PlaceBase :: Local ( l ) , projection : [ ] } => Some ( * l ) ,
1817
+ PlaceRef { local , projection : [ ] } => Some ( * * local ) ,
1869
1818
_ => None ,
1870
1819
}
1871
1820
}
@@ -1887,7 +1836,7 @@ impl Debug for Place<'_> {
1887
1836
}
1888
1837
}
1889
1838
1890
- write ! ( fmt, "{:?}" , self . base ) ?;
1839
+ write ! ( fmt, "{:?}" , self . local ) ?;
1891
1840
1892
1841
for elem in self . projection . iter ( ) {
1893
1842
match elem {
@@ -1931,22 +1880,6 @@ impl Debug for Place<'_> {
1931
1880
}
1932
1881
}
1933
1882
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
-
1950
1883
///////////////////////////////////////////////////////////////////////////
1951
1884
// Scopes
1952
1885
@@ -3007,27 +2940,11 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
3007
2940
3008
2941
impl < ' tcx > TypeFoldable < ' tcx > for Place < ' tcx > {
3009
2942
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) }
3024
2944
}
3025
2945
3026
2946
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)
3031
2948
}
3032
2949
}
3033
2950
@@ -3042,42 +2959,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
3042
2959
}
3043
2960
}
3044
2961
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
-
3081
2962
impl < ' tcx > TypeFoldable < ' tcx > for Rvalue < ' tcx > {
3082
2963
fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
3083
2964
use crate :: mir:: Rvalue :: * ;
0 commit comments