Handle statics in Subst::subst() by implementing TypeFoldable

This commit is contained in:
Wesley Wiser 2019-08-16 20:31:28 -04:00
parent e63b992030
commit 84556502e6
3 changed files with 56 additions and 28 deletions

View file

@ -1729,7 +1729,7 @@ pub enum PlaceBase<'tcx> {
}
/// We store the normalized type to avoid requiring normalization when reading MIR
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct Static<'tcx> {
pub ty: Ty<'tcx>,
pub kind: StaticKind<'tcx>,
@ -1737,7 +1737,7 @@ pub struct Static<'tcx> {
}
#[derive(
Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable,
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable,
)]
pub enum StaticKind<'tcx> {
Promoted(Promoted, SubstsRef<'tcx>),
@ -3221,13 +3221,63 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
Place {
base: self.base.clone(),
base: self.base.fold_with(folder),
projection: self.projection.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.projection.visit_with(visitor)
self.base.visit_with(visitor) || self.projection.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
match self {
PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)),
PlaceBase::Static(static_) => PlaceBase::Static(static_.fold_with(folder)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match self {
PlaceBase::Local(local) => local.visit_with(visitor),
PlaceBase::Static(static_) => (**static_).visit_with(visitor),
}
}
}
impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
Static {
ty: self.ty.fold_with(folder),
kind: self.kind.fold_with(folder),
def_id: self.def_id,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
let Static { ty, kind, def_id: _ } = self;
ty.visit_with(visitor) || kind.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for StaticKind<'tcx> {
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 {
match self {
StaticKind::Promoted(promoted, substs) =>
promoted.visit_with(visitor) || substs.visit_with(visitor),
StaticKind::Static => { false }
}
}
}

View file

@ -1,5 +1,4 @@
use rustc::ty::{self, Instance, Ty};
use rustc::ty::subst::Subst;
use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt};
use rustc::mir;
use rustc::mir::tcx::PlaceTy;
@ -461,18 +460,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
projection: None,
} => {
let param_env = ty::ParamEnv::reveal_all();
let instance = Instance::new(*def_id, substs.subst(bx.tcx(), self.instance.substs));
debug!("instance: {:?}", instance);
let instance = Instance::new(*def_id, self.monomorphize(substs));
let cid = mir::interpret::GlobalId {
instance: instance,
promoted: Some(*promoted),
};
let mono_ty = tcx.subst_and_normalize_erasing_regions(
instance.substs,
param_env,
ty,
);
let layout = cx.layout_of(mono_ty);
let layout = cx.layout_of(self.monomorphize(&ty));
match bx.tcx().const_eval(param_env.and(cid)) {
Ok(val) => match val.val {
mir::interpret::ConstValue::ByRef { alloc, offset } => {

View file

@ -479,12 +479,10 @@ impl Inliner<'tcx> {
args: &args,
local_map,
scope_map,
callsite,
destination: dest,
return_block,
cleanup_block: cleanup,
in_cleanup_block: false,
tcx: self.tcx,
};
@ -639,12 +637,10 @@ struct Integrator<'a, 'tcx> {
args: &'a [Local],
local_map: IndexVec<Local, Local>,
scope_map: IndexVec<SourceScope, SourceScope>,
callsite: CallSite<'tcx>,
destination: Place<'tcx>,
return_block: BasicBlock,
cleanup_block: Option<BasicBlock>,
in_cleanup_block: bool,
tcx: TyCtxt<'tcx>,
}
impl<'a, 'tcx> Integrator<'a, 'tcx> {
@ -693,17 +689,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
// Return pointer; update the place itself
*place = self.destination.clone();
},
Place {
base: PlaceBase::Static(box Static {
kind: StaticKind::Promoted(_, substs),
..
}),
projection: None,
} => {
let adjusted_substs = substs.subst(self.tcx, self.callsite.substs);
debug!("replacing substs {:?} with {:?}", substs, adjusted_substs);
*substs = adjusted_substs;
},
_ => self.super_place(place, _ctxt, _location)
}
}