diff --git a/src/librustc_mir/const_eval/error.rs b/src/librustc_mir/const_eval/error.rs index fd46340f03ad6..aa30f43df9350 100644 --- a/src/librustc_mir/const_eval/error.rs +++ b/src/librustc_mir/const_eval/error.rs @@ -34,11 +34,9 @@ impl fmt::Display for ConstEvalErrKind { write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg) } ConstAccessesStatic => write!(f, "constant accesses static"), - ModifiedGlobal => write!( - f, - "modifying a static's initial value from another static's \ - initializer" - ), + ModifiedGlobal => { + write!(f, "modifying a static's initial value from another static's initializer") + } AssertFailure(ref msg) => write!(f, "{:?}", msg), Panic { msg, line, col, file } => { write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col) diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index ff91ddec946cb..8f4501cc3fb69 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -358,6 +358,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter { } else if is_write { Err(ConstEvalErrKind::ModifiedGlobal.into()) } else if memory_extra.can_access_statics || def_id.is_none() { + // `def_id.is_none()` indicates this is not a static, but a const or so. Ok(()) } else { Err(ConstEvalErrKind::ConstAccessesStatic.into()) diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index b820b11e9460d..cc87c2916862b 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -209,6 +209,7 @@ pub trait Machine<'mir, 'tcx>: Sized { } /// Called before a global allocation is accessed. + /// `def_id` is `Some` if this is the "lazy" allocation of a static. #[inline] fn before_access_global( _memory_extra: &Self::MemoryExtra, diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 87db44a96e7b3..110f2ffd9d78c 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -416,7 +416,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { let alloc = tcx.alloc_map.lock().get(id); let (alloc, def_id) = match alloc { - Some(GlobalAlloc::Memory(mem)) => (mem, None), + Some(GlobalAlloc::Memory(mem)) => { + // Memory of a constant or promoted or anonymous memory referenced by a static. + (mem, None) + } Some(GlobalAlloc::Function(..)) => throw_ub!(DerefFunctionPointer(id)), None => throw_ub!(PointerUseAfterFree(id)), Some(GlobalAlloc::Static(def_id)) => { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 17b8f3de75138..ef2d5404541b9 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -274,7 +274,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { _memory_extra: &(), _alloc_id: AllocId, allocation: &Allocation, - _def_id: Option, + def_id: Option, is_write: bool, ) -> InterpResult<'tcx> { if is_write { @@ -282,7 +282,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { } // If the static allocation is mutable or if it has relocations (it may be legal to mutate // the memory behind that in the future), then we can't const prop it. - if allocation.mutability == Mutability::Mut || allocation.relocations().len() > 0 { + // FIXME: we only check statics here (that have a `DefId`), not other mutable allocations. + // Why that? + if def_id.is_some() + && (allocation.mutability == Mutability::Mut || allocation.relocations().len() > 0) + { throw_machine_stop_str!("can't eval mutable statics in ConstProp"); }