// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::Closure(def_id, substs) => {
- let substs = self.tcx.subst_and_normalize_erasing_regions(
- self.substs(),
- ty::ParamEnv::reveal_all(),
- &substs,
- );
+ let substs = self.subst_and_normalize_erasing_regions(substs)?;
let instance = ty::Instance::resolve_closure(
*self.tcx,
def_id,
self.frame().mir
}
- pub fn substs(&self) -> &'tcx Substs<'tcx> {
- if let Some(frame) = self.stack.last() {
- frame.instance.substs
- } else {
- Substs::empty()
+ pub(super) fn subst_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>(
+ &self,
+ substs: T,
+ ) -> EvalResult<'tcx, T> {
+ match self.stack.last() {
+ Some(frame) => Ok(self.tcx.subst_and_normalize_erasing_regions(
+ frame.instance.substs,
+ self.param_env,
+ &substs,
+ )),
+ None => if substs.needs_subst() {
+ err!(TooGeneric).into()
+ } else {
+ Ok(substs)
+ },
}
}
substs: &'tcx Substs<'tcx>
) -> EvalResult<'tcx, ty::Instance<'tcx>> {
trace!("resolve: {:?}, {:#?}", def_id, substs);
- trace!("substs: {:#?}", self.substs());
trace!("param_env: {:#?}", self.param_env);
- let substs = self.tcx.subst_and_normalize_erasing_regions(
- self.substs(),
- self.param_env,
- &substs,
- );
+ let substs = self.subst_and_normalize_erasing_regions(substs)?;
+ trace!("substs: {:#?}", substs);
ty::Instance::resolve(
*self.tcx,
self.param_env,
}
}
+ pub fn monomorphize_in_frame<T: TypeFoldable<'tcx> + Subst<'tcx>>(
+ &self,
+ t: T,
+ ) -> EvalResult<'tcx, T> {
+ match self.stack.last() {
+ Some(frame) => Ok(self.monomorphize(t, frame.instance.substs)),
+ None => if t.needs_subst() {
+ err!(TooGeneric).into()
+ } else {
+ Ok(t)
+ },
+ }
+ }
+
pub fn monomorphize<T: TypeFoldable<'tcx> + Subst<'tcx>>(
&self,
t: T,
Constant(ref constant) => {
let layout = from_known_layout(layout, || {
- let ty = self.monomorphize(mir_op.ty(self.mir(), *self.tcx), self.substs());
+ let ty = self.monomorphize_in_frame(mir_op.ty(self.mir(), *self.tcx))?;
self.layout_of(ty)
})?;
let op = self.const_value_to_op(*constant.literal)?;
use rustc::mir;
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx};
+use rustc::ty::TypeFoldable;
use super::{
GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic,
}
Static(ref static_) => {
- let ty = self.monomorphize(static_.ty, self.substs());
- let layout = self.layout_of(ty)?;
+ assert!(!static_.ty.needs_subst());
+ let layout = self.layout_of(static_.ty)?;
let instance = ty::Instance::mono(*self.tcx, static_.def_id);
let cid = GlobalId {
instance,
}
NullaryOp(mir::NullOp::SizeOf, ty) => {
- let ty = self.monomorphize(ty, self.substs());
+ let ty = self.monomorphize_in_frame(ty)?;
let layout = self.layout_of(ty)?;
assert!(!layout.is_unsized(),
"SizeOf nullary MIR operator called for unsized type");
}
Cast(kind, ref operand, cast_ty) => {
- debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest.layout.ty);
+ debug_assert_eq!(self.monomorphize_in_frame(cast_ty)?, dest.layout.ty);
let src = self.eval_operand(operand, None)?;
self.cast(src, kind, dest)?;
}