about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-01-14 17:54:35 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-01-22 17:22:29 +0100
commitdb2978a73cc4ab71c8839e70d12bc87d5279e632 (patch)
treeef89e7169d2b1015c694d941125beeeee230cb5b
parenta59eabbc36d7b96bb9e42d9bc6691d28b62c4187 (diff)
downloadrust-db2978a73cc4ab71c8839e70d12bc87d5279e632.tar.gz
rust-db2978a73cc4ab71c8839e70d12bc87d5279e632.zip
Bail out on overly generic substitutions
-rw-r--r--src/librustc_mir/interpret/cast.rs6
-rw-r--r--src/librustc_mir/interpret/eval_context.rs42
-rw-r--r--src/librustc_mir/interpret/operand.rs2
-rw-r--r--src/librustc_mir/interpret/place.rs5
-rw-r--r--src/librustc_mir/interpret/step.rs4
5 files changed, 38 insertions, 21 deletions
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 190a381cf52..c3b71be8354 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 b2d3328a73f..b2db0fea3d0 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<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,
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index b2648480f20..8995d091aaa 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 962e0b7a742..f3a948a6ca3 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 2de8b3c1afd..f1b4e6a5055 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)?;
             }