From db2978a73cc4ab71c8839e70d12bc87d5279e632 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 14 Jan 2019 17:54:35 +0100 Subject: [PATCH] Bail out on overly generic substitutions --- src/librustc_mir/interpret/cast.rs | 6 +--- src/librustc_mir/interpret/eval_context.rs | 42 ++++++++++++++++------ src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/place.rs | 5 +-- src/librustc_mir/interpret/step.rs | 4 +-- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 190a381cf52a..c3b71be8354d 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -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, diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b2d3328a73fe..b2db0fea3d09 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -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>( + &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 + 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 + Subst<'tcx>>( &self, t: T, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b2648480f203..8995d091aaab 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -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)?; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 962e0b7a7420..f3a948a6ca3e 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -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, diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 2de8b3c1afdf..f1b4e6a5055b 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -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)?; }