Bail out on overly generic substitutions
This commit is contained in:
parent
a59eabbc36
commit
db2978a73c
5 changed files with 38 additions and 21 deletions
|
|
@ -109,11 +109,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||
// 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,
|
||||
|
|
|
|||
|
|
@ -216,11 +216,21 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
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)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -230,13 +240,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
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,
|
||||
|
|
@ -276,6 +282,20 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||
|
||||
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)?;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use rustc::hir;
|
|||
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,
|
||||
|
|
@ -583,8 +584,8 @@ where
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||
}
|
||||
|
||||
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");
|
||||
|
|
@ -260,7 +260,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||
}
|
||||
|
||||
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)?;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue