Skip to content

Commit

Permalink
Remove StaticKind::Promoted
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino authored and oli-obk committed Jan 10, 2020
1 parent 6aa4b5a commit 6f2c702
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 197 deletions.
25 changes: 5 additions & 20 deletions src/librustc/mir/mod.rs
Expand Up @@ -1687,7 +1687,7 @@ pub enum PlaceBase<'tcx> {
)]
pub struct Static<'tcx> {
pub ty: Ty<'tcx>,
pub kind: StaticKind<'tcx>,
pub kind: StaticKind,
/// The `DefId` of the item this static was declared in. For promoted values, usually, this is
/// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in.
/// However, after inlining, that might no longer be the case as inlined `Place`s are copied
Expand All @@ -1707,11 +1707,7 @@ pub struct Static<'tcx> {
RustcEncodable,
RustcDecodable
)]
pub enum StaticKind<'tcx> {
/// Promoted references consist of an id (`Promoted`) and the substs necessary to monomorphize
/// it. Usually, these substs are just the identity substs for the item. However, the inliner
/// will adjust these substs when it inlines a function based on the substs at the callsite.
Promoted(Promoted, SubstsRef<'tcx>),
pub enum StaticKind {
Static,
}

Expand Down Expand Up @@ -1949,11 +1945,6 @@ impl Debug for PlaceBase<'_> {
PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static, def_id }) => {
write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty)
}
PlaceBase::Static(box self::Static {
ty,
kind: StaticKind::Promoted(promoted, _),
def_id: _,
}) => write!(fmt, "({:?}: {:?})", promoted, ty),
}
}
}
Expand Down Expand Up @@ -3069,21 +3060,15 @@ impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> {
}
}

impl<'tcx> TypeFoldable<'tcx> for StaticKind<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
impl<'tcx> TypeFoldable<'tcx> for StaticKind {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
match self {
StaticKind::Promoted(promoted, substs) => {
StaticKind::Promoted(promoted.fold_with(folder), substs.fold_with(folder))
}
StaticKind::Static => StaticKind::Static,
}
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
match self {
StaticKind::Promoted(promoted, substs) => {
promoted.visit_with(visitor) || substs.visit_with(visitor)
}
StaticKind::Static => false,
}
}
Expand Down
32 changes: 2 additions & 30 deletions src/librustc_codegen_ssa/mir/block.rs
Expand Up @@ -10,8 +10,8 @@ use crate::traits::*;
use crate::MemFlags;

use rustc::middle::lang_items;
use rustc::mir;
use rustc::mir::interpret::PanicInfo;
use rustc::mir::{self, PlaceBase, Static, StaticKind};
use rustc::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf};
use rustc::ty::{self, Instance, Ty, TypeFoldable};
use rustc_index::vec::Idx;
Expand Down Expand Up @@ -613,35 +613,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// The shuffle array argument is usually not an explicit constant,
// but specified directly in the code. This means it gets promoted
// and we can then extract the value by evaluating the promoted.
mir::Operand::Copy(place) | mir::Operand::Move(place) => {
if let mir::PlaceRef {
base:
&PlaceBase::Static(box Static {
kind: StaticKind::Promoted(promoted, substs),
ty,
def_id,
}),
projection: &[],
} = place.as_ref()
{
let c = bx.tcx().const_eval_promoted(
Instance::new(def_id, self.monomorphize(&substs)),
promoted,
);
let (llval, ty) = self.simd_shuffle_indices(
&bx,
terminator.source_info.span,
ty,
c,
);
return OperandRef {
val: Immediate(llval),
layout: bx.layout_of(ty),
};
} else {
span_bug!(span, "shuffle indices must be constant");
}
}
mir::Operand::Copy(_place) | mir::Operand::Move(_place) => {}

mir::Operand::Constant(constant) => {
let c = self.eval_mir_constant(constant);
Expand Down
35 changes: 1 addition & 34 deletions src/librustc_codegen_ssa/mir/place.rs
Expand Up @@ -9,7 +9,7 @@ use crate::MemFlags;
use rustc::mir;
use rustc::mir::tcx::PlaceTy;
use rustc::ty::layout::{self, Align, HasTyCtxt, LayoutOf, TyLayout, VariantIdx};
use rustc::ty::{self, Instance, Ty};
use rustc::ty::{self, Ty};

#[derive(Copy, Clone, Debug)]
pub struct PlaceRef<'tcx, V> {
Expand Down Expand Up @@ -437,39 +437,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::PlaceRef {
base:
mir::PlaceBase::Static(box mir::Static {
ty,
kind: mir::StaticKind::Promoted(promoted, substs),
def_id,
}),
projection: [],
} => {
let instance = Instance::new(*def_id, self.monomorphize(substs));
let layout = cx.layout_of(self.monomorphize(&ty));
match bx.tcx().const_eval_promoted(instance, *promoted) {
Ok(val) => match val.val {
ty::ConstKind::Value(mir::interpret::ConstValue::ByRef {
alloc,
offset,
}) => bx.cx().from_const_alloc(layout, alloc, offset),
_ => bug!("promoteds should have an allocation: {:?}", val),
},
Err(_) => {
// This is unreachable as long as runtime
// and compile-time agree perfectly.
// With floats that won't always be true,
// so we generate a (safe) abort.
bx.abort();
// We still have to return a place but it doesn't matter,
// this code is unreachable.
let llval =
bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout)));
PlaceRef::new_sized(llval, layout)
}
}
}
mir::PlaceRef {
base:
mir::PlaceBase::Static(box mir::Static {
Expand Down
6 changes: 0 additions & 6 deletions src/librustc_mir/borrow_check/diagnostics/mod.rs
Expand Up @@ -172,12 +172,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => {
self.append_local_to_string(*local, buf)?;
}
PlaceRef {
base: PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }),
projection: [],
} => {
buf.push_str("promoted");
}
PlaceRef {
base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }),
projection: [],
Expand Down
10 changes: 0 additions & 10 deletions src/librustc_mir/borrow_check/mod.rs
Expand Up @@ -2196,16 +2196,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}),
}
}
// The rules for promotion are made by `qualify_consts`, there wouldn't even be a
// `Place::Promoted` if the promotion weren't 100% legal. So we just forward this
PlaceRef {
base: PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }),
projection: [],
} => Ok(RootPlace {
place_base: place.base,
place_projection: place.projection,
is_local_mutation_allowed,
}),
PlaceRef {
base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }),
projection: [],
Expand Down
24 changes: 1 addition & 23 deletions src/librustc_mir/borrow_check/places_conflict.rs
Expand Up @@ -310,7 +310,7 @@ fn place_components_conflict<'tcx>(
// between `elem1` and `elem2`.
fn place_base_conflict<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
_param_env: ty::ParamEnv<'tcx>,
elem1: &PlaceBase<'tcx>,
elem2: &PlaceBase<'tcx>,
) -> Overlap {
Expand Down Expand Up @@ -341,28 +341,6 @@ fn place_base_conflict<'tcx>(
Overlap::EqualOrDisjoint
}
}
(StaticKind::Promoted(promoted_1, _), StaticKind::Promoted(promoted_2, _)) => {
if promoted_1 == promoted_2 {
if let ty::Array(_, len) = s1.ty.kind {
if let Some(0) = len.try_eval_usize(tcx, param_env) {
// Ignore conflicts with promoted [T; 0].
debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
return Overlap::Disjoint;
}
}
// the same promoted - base case, equal
debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED");
Overlap::EqualOrDisjoint
} else {
// different promoteds - base case, disjoint
debug!("place_element_conflict: DISJOINT-PROMOTED");
Overlap::Disjoint
}
}
(_, _) => {
debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED");
Overlap::Disjoint
}
}
}
(PlaceBase::Local(_), PlaceBase::Static(_))
Expand Down
59 changes: 20 additions & 39 deletions src/librustc_mir/borrow_check/type_check/mod.rs
Expand Up @@ -488,15 +488,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
};
};
match kind {
StaticKind::Promoted(promoted, _) => {
if !self.errors_reported {
let promoted_body_cache = self.promoted[*promoted];
self.sanitize_promoted(promoted_body_cache, location);

let promoted_ty = promoted_body_cache.return_ty();
check_err(self, place, promoted_ty, san_ty);
}
}
StaticKind::Static => {
let ty = self.tcx().type_of(*def_id);
let ty = self.cx.normalize(ty, location);
Expand All @@ -510,38 +501,28 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {

if place.projection.is_empty() {
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let is_promoted = match place.as_ref() {
PlaceRef {
base: &PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }),
projection: &[],
} => true,
_ => false,
let tcx = self.tcx();
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().copy_trait().unwrap(),
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
};

if !is_promoted {
let tcx = self.tcx();
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().copy_trait().unwrap(),
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
};

// To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`,
// rather than using the `is_copy_modulo_regions`
// test. This is important because
// `is_copy_modulo_regions` ignores the resulting region
// obligations and assumes they pass. This can result in
// bounds from `Copy` impls being unsoundly ignored (e.g.,
// #29149). Note that we decide to use `Copy` before knowing
// whether the bounds fully apply: in effect, the rule is
// that if a value of some type could implement `Copy`, then
// it must.
self.cx.prove_trait_ref(
trait_ref,
location.to_locations(),
ConstraintCategory::CopyBound,
);
}
// To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`,
// rather than using the `is_copy_modulo_regions`
// test. This is important because
// `is_copy_modulo_regions` ignores the resulting region
// obligations and assumes they pass. This can result in
// bounds from `Copy` impls being unsoundly ignored (e.g.,
// #29149). Note that we decide to use `Copy` before knowing
// whether the bounds fully apply: in effect, the rule is
// that if a value of some type could implement `Copy`, then
// it must.
self.cx.prove_trait_ref(
trait_ref,
location.to_locations(),
ConstraintCategory::CopyBound,
);
}
}

Expand Down
19 changes: 3 additions & 16 deletions src/librustc_mir/interpret/place.rs
Expand Up @@ -15,9 +15,9 @@ use rustc::ty::{self, Ty};
use rustc_macros::HashStable;

use super::{
AllocId, AllocMap, Allocation, AllocationExtra, GlobalId, ImmTy, Immediate, InterpCx,
InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic,
RawConst, Scalar, ScalarMaybeUndef,
AllocId, AllocMap, Allocation, AllocationExtra, ImmTy, Immediate, InterpCx, InterpResult,
LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic, RawConst, Scalar,
ScalarMaybeUndef,
};

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
Expand Down Expand Up @@ -628,19 +628,6 @@ where
use rustc::mir::StaticKind;

Ok(match place_static.kind {
StaticKind::Promoted(promoted, promoted_substs) => {
let substs = self.subst_from_frame_and_normalize_erasing_regions(promoted_substs);
let instance = ty::Instance::new(place_static.def_id, substs);

// Even after getting `substs` from the frame, this instance may still be
// polymorphic because `ConstProp` will try to promote polymorphic MIR.
if instance.needs_subst() {
throw_inval!(TooGeneric);
}

self.const_eval_raw(GlobalId { instance, promoted: Some(promoted) })?
}

StaticKind::Static => {
let ty = place_static.ty;
assert!(!ty.needs_subst());
Expand Down
17 changes: 1 addition & 16 deletions src/librustc_mir/monomorphize/collector.rs
Expand Up @@ -186,7 +186,7 @@ use rustc::mir::{self, Location, PlaceBase, Static, StaticKind};
use rustc::session::config::EntryFnType;
use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc::ty::print::obsolete::DefPathBasedNames;
use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
Expand Down Expand Up @@ -656,21 +656,6 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
self.output.push(MonoItem::Static(*def_id));
}
}
PlaceBase::Static(box Static {
kind: StaticKind::Promoted(promoted, substs),
def_id,
..
}) => {
let instance = Instance::new(*def_id, substs.subst(self.tcx, self.param_substs));
match self.tcx.const_eval_promoted(instance, *promoted) {
Ok(val) => collect_const(self.tcx, val, substs, self.output),
Err(ErrorHandled::Reported) => {}
Err(ErrorHandled::TooGeneric) => {
let span = self.tcx.promoted_mir(*def_id)[*promoted].span;
span_bug!(span, "collection encountered polymorphic constant")
}
}
}
PlaceBase::Local(_) => {
// Locals have no relevance for collector.
}
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_mir/transform/check_unsafety.rs
Expand Up @@ -194,9 +194,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
PlaceBase::Local(..) => {
// Locals are safe.
}
PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => {
bug!("unsafety checking should happen before promotion");
}
PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => {
bug!("StaticKind::Static should not exist");
}
Expand Down

0 comments on commit 6f2c702

Please sign in to comment.