about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2017-07-13 23:42:18 -0700
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-07-25 10:30:12 +0200
commit3f8a497bf09d393e9c544dd9aa8cfa642f776760 (patch)
tree9494c9e33e9de0a59f99139c6c528eb2b0f02a72
parent769a2b5c813fc476e69ac21b13b42a2fa96f3dfe (diff)
downloadrust-3f8a497bf09d393e9c544dd9aa8cfa642f776760.tar.gz
rust-3f8a497bf09d393e9c544dd9aa8cfa642f776760.zip
we need to normalize associated types also deep in the hierarchy (89)
-rw-r--r--src/librustc_mir/interpret/step.rs14
-rw-r--r--src/librustc_mir/interpret/terminator/mod.rs2
-rw-r--r--src/librustc_mir/interpret/validation.rs15
3 files changed, 16 insertions, 15 deletions
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 7c8f3764f2b..16501091240 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -7,10 +7,9 @@ use rustc::hir;
 use rustc::mir::visit::{Visitor, LvalueContext};
 use rustc::mir;
 use rustc::traits::Reveal;
-use rustc::ty::{self, TypeFoldable};
+use rustc::ty;
 use rustc::ty::layout::Layout;
 use rustc::ty::subst::{Subst, Substs};
-use rustc::infer::TransNormalize;
 
 use error::{EvalResult, EvalError};
 use eval_context::{EvalContext, StackPopCleanup};
@@ -137,16 +136,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
             Validate(op, ref lvalues) => {
                 for operand in lvalues {
                     // We need to monomorphize ty *without* erasing lifetimes
-                    let mut ty = operand.ty.subst(self.tcx, self.substs());
-                    // This is essentially a copy of normalize_associated_type, but without erasure
-                    if ty.has_projection_types() {
-                        let param_env = ty::ParamEnv::empty(Reveal::All);
-                        ty = self.tcx.infer_ctxt().enter(move |infcx| {
-                            ty.trans_normalize(&infcx, param_env)
-                        })
-                    }
-
-                    // Now we can do validation at this type
+                    let ty = operand.ty.subst(self.tcx, self.substs());
                     let lvalue = self.eval_lvalue(&operand.lval)?;
                     self.validate(lvalue, ty, ValidationCtx::new(op))?;
                 }
diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs
index a44713f221f..3ee6bab77e0 100644
--- a/src/librustc_mir/interpret/terminator/mod.rs
+++ b/src/librustc_mir/interpret/terminator/mod.rs
@@ -467,7 +467,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
     pub fn read_discriminant_value(&self, adt_ptr: MemoryPointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
         use rustc::ty::layout::Layout::*;
         let adt_layout = self.type_layout(adt_ty)?;
-        trace!("read_discriminant_value {:#?}", adt_layout);
+        //trace!("read_discriminant_value {:#?}", adt_layout);
 
         let discr_val = match *adt_layout {
             General { discr, .. } | CEnum { discr, signed: false, .. } => {
diff --git a/src/librustc_mir/interpret/validation.rs b/src/librustc_mir/interpret/validation.rs
index 7506ecdedbd..7795bd0e126 100644
--- a/src/librustc_mir/interpret/validation.rs
+++ b/src/librustc_mir/interpret/validation.rs
@@ -1,6 +1,8 @@
 use rustc::hir::Mutability;
 use rustc::mir::{self, ValidationOp};
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, Ty, TypeFoldable};
+use rustc::traits::Reveal;
+use rustc::infer::TransNormalize;
 use rustc::middle::region::CodeExtent;
 
 use error::{EvalError, EvalResult};
@@ -55,12 +57,21 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
     }
 
     /// Validate the lvalue at the given type. If `release` is true, just do a release of all write locks
-    pub(super) fn validate(&mut self, lvalue: Lvalue<'tcx>, ty: Ty<'tcx>, mut vctx: ValidationCtx) -> EvalResult<'tcx>
+    pub(super) fn validate(&mut self, lvalue: Lvalue<'tcx>, mut ty: Ty<'tcx>, mut vctx: ValidationCtx) -> EvalResult<'tcx>
     {
         use rustc::ty::TypeVariants::*;
         use rustc::ty::RegionKind::*;
         use rustc::ty::AdtKind;
         use self::Mutability::*;
+
+        // This is essentially a copy of normalize_associated_type, but without erasure
+        if ty.has_projection_types() {
+            let param_env = ty::ParamEnv::empty(Reveal::All);
+            ty = self.tcx.infer_ctxt().enter(move |infcx| {
+                ty.trans_normalize(&infcx, param_env)
+            })
+        }
+        let ty = ty; // no more mutation
         trace!("Validating {:?} at type {}, context {:?}", lvalue, ty, vctx);
 
         // Decide whether this type *owns* the memory it covers (like integers), or whether it