Remove StaticKind::Promoted
This commit is contained in:
parent
6aa4b5a760
commit
6f2c7025b8
10 changed files with 33 additions and 197 deletions
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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: [],
|
||||
|
|
|
|||
|
|
@ -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: [],
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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(_))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue