From 3f8a497bf09d393e9c544dd9aa8cfa642f776760 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 13 Jul 2017 23:42:18 -0700 Subject: [PATCH] we need to normalize associated types also deep in the hierarchy (89) --- src/librustc_mir/interpret/step.rs | 14 ++------------ src/librustc_mir/interpret/terminator/mod.rs | 2 +- src/librustc_mir/interpret/validation.rs | 15 +++++++++++++-- 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::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 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'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 @@ fn eval_fn_call_inner( 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 @@ fn validate_ptr(&mut self, val: Value, pointee_ty: Ty<'tcx>, vctx: ValidationCtx } /// 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 -- 2.44.0