Skip to content

Commit 1389494

Browse files
committed
Auto merge of #67000 - spastorino:remove-promoted-from-place, r=oli-obk
Promote references to constants instead of statics r? @oli-obk
2 parents bfd0487 + e51eccd commit 1389494

File tree

100 files changed

+1116
-1593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+1116
-1593
lines changed

src/librustc/mir/interpret/queries.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,16 @@ impl<'tcx> TyCtxt<'tcx> {
3636
param_env: ty::ParamEnv<'tcx>,
3737
def_id: DefId,
3838
substs: SubstsRef<'tcx>,
39+
promoted: Option<mir::Promoted>,
3940
span: Option<Span>,
4041
) -> ConstEvalResult<'tcx> {
4142
let instance = ty::Instance::resolve(self, param_env, def_id, substs);
4243
if let Some(instance) = instance {
43-
self.const_eval_instance(param_env, instance, span)
44+
if let Some(promoted) = promoted {
45+
self.const_eval_promoted(param_env, instance, promoted)
46+
} else {
47+
self.const_eval_instance(param_env, instance, span)
48+
}
4449
} else {
4550
Err(ErrorHandled::TooGeneric)
4651
}
@@ -63,11 +68,11 @@ impl<'tcx> TyCtxt<'tcx> {
6368
/// Evaluate a promoted constant.
6469
pub fn const_eval_promoted(
6570
self,
71+
param_env: ty::ParamEnv<'tcx>,
6672
instance: ty::Instance<'tcx>,
6773
promoted: mir::Promoted,
6874
) -> ConstEvalResult<'tcx> {
6975
let cid = GlobalId { instance, promoted: Some(promoted) };
70-
let param_env = ty::ParamEnv::reveal_all();
7176
self.const_eval_validated(param_env.and(cid))
7277
}
7378
}

src/librustc/mir/mod.rs

+25-144
Original file line numberDiff line numberDiff line change
@@ -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

171181
impl<'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)]
16461657
pub 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

16531664
impl<'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)]
17091668
pub enum ProjectionElem<V, T> {
@@ -1791,14 +1750,14 @@ rustc_index::newtype_index! {
17911750

17921751
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
17931752
pub struct PlaceRef<'a, 'tcx> {
1794-
pub base: &'a PlaceBase<'tcx>,
1753+
pub local: &'a Local,
17951754
pub projection: &'a [PlaceElem<'tcx>],
17961755
}
17971756

17981757
impl<'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

18371794
impl 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

30082941
impl<'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-
30812962
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
30822963
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
30832964
use crate::mir::Rvalue::*;

src/librustc/mir/tcx.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'tcx> PlaceTy<'tcx> {
114114

115115
impl<'tcx> Place<'tcx> {
116116
pub fn ty_from<D>(
117-
base: &PlaceBase<'tcx>,
117+
local: &Local,
118118
projection: &[PlaceElem<'tcx>],
119119
local_decls: &D,
120120
tcx: TyCtxt<'tcx>,
@@ -124,26 +124,16 @@ impl<'tcx> Place<'tcx> {
124124
{
125125
projection
126126
.iter()
127-
.fold(base.ty(local_decls), |place_ty, elem| place_ty.projection_ty(tcx, elem))
127+
.fold(PlaceTy::from_ty(local_decls.local_decls()[*local].ty), |place_ty, elem| {
128+
place_ty.projection_ty(tcx, elem)
129+
})
128130
}
129131

130132
pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
131133
where
132134
D: HasLocalDecls<'tcx>,
133135
{
134-
Place::ty_from(&self.base, &self.projection, local_decls, tcx)
135-
}
136-
}
137-
138-
impl<'tcx> PlaceBase<'tcx> {
139-
pub fn ty<D>(&self, local_decls: &D) -> PlaceTy<'tcx>
140-
where
141-
D: HasLocalDecls<'tcx>,
142-
{
143-
match self {
144-
PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty),
145-
PlaceBase::Static(data) => PlaceTy::from_ty(data.ty),
146-
}
136+
Place::ty_from(&self.local, &self.projection, local_decls, tcx)
147137
}
148138
}
149139

0 commit comments

Comments
 (0)