diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index ee59d9eea426..b8be02bcba46 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -363,7 +363,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { if alloc.kind != kind { return Err(EvalError::DeallocatedWrongMemoryKind(alloc.kind, kind)); } - if !alloc.locks.is_empty() { + if alloc.locks.values().any(|locks| !locks.is_empty()) { return Err(EvalError::DeallocatedLockedMemory); } if let Some((size, align)) = size_and_align { @@ -524,7 +524,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { /// Acquire the lock for the given lifetime pub(crate) fn acquire_lock(&mut self, ptr: MemoryPointer, len: u64, region: Option, kind: AccessKind) -> EvalResult<'tcx> { - trace!("Acquiring {:?} lock at {:?}, size {}", kind, ptr, len); + trace!("Acquiring {:?} lock at {:?}, size {} for region {:?}", kind, ptr, len, region); if len == 0 { return Ok(()); } @@ -536,9 +536,9 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { Ok(()) } - /// Release a lock prematurely + /// Release a write lock prematurely pub(crate) fn release_lock_until(&mut self, ptr: MemoryPointer, len: u64, release_until: Option) -> EvalResult<'tcx> { - // TODO: More tracing. + trace!("Releasing write lock at {:?}, size {} until {:?}", ptr, len, release_until); // Make sure there are no read locks and no *other* write locks here if let Err(_) = self.check_locks(ptr, len, AccessKind::Write) { return Err(EvalError::InvalidMemoryLockRelease { ptr, len }); @@ -565,7 +565,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { } pub(crate) fn locks_lifetime_ended(&mut self, ending_region: Option) { - // TODO: More tracing. + trace!("Releasing locks that expire at {:?}", ending_region); let cur_frame = self.cur_frame; let has_ended = |lock: &LockInfo| -> bool { if lock.lifetime.frame != cur_frame { diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index f148a096128a..4f7eb8eb6cc1 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -7,8 +7,9 @@ use rustc::hir; use rustc::mir::visit::{Visitor, LvalueContext}; use rustc::mir; use rustc::traits::Reveal; +use rustc::ty; use rustc::ty::layout::Layout; -use rustc::ty::{subst, self}; +use rustc::ty::subst::{Subst, Substs}; use error::{EvalResult, EvalError}; use eval_context::{EvalContext, StackPopCleanup}; @@ -133,12 +134,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { // Validity checks. Validate(ref op, ref lvalues) => { for operand in lvalues { + // We need to monomorphize ty *without* erasing lifetimes + let ty = operand.ty.subst(self.tcx, self.substs()); + // TODO: do we have to self.tcx.normalize_associated_type(&{ty}) ? That however seems to erase lifetimes. let lvalue = self.eval_lvalue(&operand.lval)?; - self.validate(lvalue, operand.ty, ValidationCtx::new(*op))?; + self.validate(lvalue, ty, ValidationCtx::new(*op))?; } } - - // Just a borrowck thing EndRegion(ce) => { self.memory.locks_lifetime_ended(Some(ce)); } @@ -180,7 +182,7 @@ impl<'a, 'b, 'tcx> ConstantExtractor<'a, 'b, 'tcx> { fn global_item( &mut self, def_id: DefId, - substs: &'tcx subst::Substs<'tcx>, + substs: &'tcx Substs<'tcx>, span: Span, mutability: Mutability, ) {