diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 7c8f3764f2b7..16501091240f 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 a44713f221f8..3ee6bab77e05 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 7506ecdedbd8..7795bd0e126c 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