]> git.lizzy.rs Git - rust.git/commitdiff
Bail out on overly generic substitutions
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Mon, 14 Jan 2019 16:54:35 +0000 (17:54 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Tue, 22 Jan 2019 16:22:29 +0000 (17:22 +0100)
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/interpret/step.rs

index 190a381cf52a5e0d5d20fb7b4adf7b87d0fa5859..c3b71be8354daabcb1c6c1b6c0ce952876f740cd 100644 (file)
@@ -109,11 +109,7 @@ pub fn cast(
                 // 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,
index b2d3328a73fe8335885f97a520e35937c2ea0289..b2db0fea3d09a7afdb7ff1c85edebe080963e65c 100644 (file)
@@ -216,11 +216,21 @@ pub(super) fn mir(&self) -> &'mir mir::Mir<'tcx> {
         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 @@ pub(super) fn resolve(
         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 @@ pub fn load_mir(
         }
     }
 
+    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,
index b2648480f203cc9eae0b588cb155be08979ea852..8995d091aaab65132ba27971c05e7f8c04051a50 100644 (file)
@@ -508,7 +508,7 @@ pub fn eval_operand(
 
             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)?;
index 962e0b7a7420109d9a7c9e776be4137673eb6f89..f3a948a6ca3e70dbff560c86e5fa5db5f5a6a19f 100644 (file)
@@ -9,6 +9,7 @@
 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 @@ pub(super) fn eval_place_to_mplace(
             }
 
             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,
index 2de8b3c1afdf3579d95ff2959c21f4d886b9e941..f1b4e6a5055b631c3d9a9d7de5f9f2bd6fff0678 100644 (file)
@@ -248,7 +248,7 @@ fn eval_rvalue_into_place(
             }
 
             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 @@ fn eval_rvalue_into_place(
             }
 
             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)?;
             }