Handle statics in Subst::subst() by implementing TypeFoldable
This commit is contained in:
parent
e63b992030
commit
84556502e6
3 changed files with 56 additions and 28 deletions
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 } => {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue