]> git.lizzy.rs Git - rust.git/commitdiff
move ModifiedStatic error to ConstEval errors, and generally adjust terminology from...
authorRalf Jung <post@ralfj.de>
Sat, 21 Mar 2020 18:19:10 +0000 (19:19 +0100)
committerRalf Jung <post@ralfj.de>
Tue, 24 Mar 2020 07:27:45 +0000 (08:27 +0100)
src/librustc/mir/interpret/error.rs
src/librustc/ty/context.rs
src/librustc_mir/const_eval/error.rs
src/librustc_mir/const_eval/machine.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/intern.rs
src/librustc_mir/interpret/machine.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/place.rs
src/librustc_mir/transform/const_prop.rs

index 8f06b9a69bd15abebdb7bb2599beaa42e743b079..f7871952452128b4dc78b173bf1fad043893a7dd 100644 (file)
@@ -453,9 +453,6 @@ pub enum UnsupportedOpInfo {
     ReadForeignStatic(DefId),
     /// Could not find MIR for a function.
     NoMirFor(DefId),
-    /// Modified a static during const-eval.
-    /// FIXME: move this to `ConstEvalErrKind` through a machine hook.
-    ModifiedStatic,
     /// Encountered a pointer where we needed raw bytes.
     ReadPointerAsBytes,
     /// Encountered raw bytes where we needed a pointer.
@@ -471,12 +468,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 write!(f, "tried to read from foreign (extern) static {:?}", did)
             }
             NoMirFor(did) => write!(f, "could not load MIR for {:?}", did),
-            ModifiedStatic => write!(
-                f,
-                "tried to modify a static's initial value from another static's \
-                    initializer"
-            ),
-
             ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes",),
             ReadBytesAsPointer => write!(f, "unable to turn bytes into a pointer"),
         }
index 75842fd554941fb8d4d5be581a75d6a1a7bd7f6b..1dc2f2a6f248b00ade6dd45ff2d9e49a66da59e1 100644 (file)
@@ -984,6 +984,7 @@ pub struct GlobalCtxt<'tcx> {
     /// Stores the value of constants (and deduplicates the actual memory)
     allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,
 
+    /// Stores memory for globals (statics/consts).
     pub alloc_map: Lock<interpret::AllocMap<'tcx>>,
 
     layout_interner: ShardedHashMap<&'tcx LayoutDetails, ()>,
index dc23eba643e3e17a7c365206dbc7cae99ca63811..fd46340f03ad6beb7e049d907ccb17782f9d66f0 100644 (file)
@@ -12,6 +12,7 @@
 pub enum ConstEvalErrKind {
     NeedsRfc(String),
     ConstAccessesStatic,
+    ModifiedGlobal,
     AssertFailure(AssertKind<u64>),
     Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
 }
@@ -33,6 +34,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                 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"
+            ),
             AssertFailure(ref msg) => write!(f, "{:?}", msg),
             Panic { msg, line, col, file } => {
                 write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col)
index ab88a92ea7bc210bae9d1cd76f9bd61d7a4a9e8a..65dca16e739f5d8365c5128d141bc715524003f3 100644 (file)
@@ -8,8 +8,8 @@
 use rustc_data_structures::fx::FxHashMap;
 
 use rustc::mir::AssertMessage;
-use rustc_span::source_map::Span;
 use rustc_span::symbol::Symbol;
+use rustc_span::{def_id::DefId, Span};
 
 use crate::interpret::{
     self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy,
@@ -167,7 +167,7 @@ fn may_leak(self) -> bool {
 }
 
 impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
-    type MemoryKinds = !;
+    type MemoryKind = !;
     type PointerTag = ();
     type ExtraFnVal = !;
 
@@ -177,7 +177,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
 
     type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
 
-    const STATIC_KIND: Option<!> = None; // no copying of statics allowed
+    const GLOBAL_KIND: Option<!> = None; // no copying of globals allowed
 
     // We do not check for alignment to avoid having to carry an `Align`
     // in `ConstValue::ByRef`.
@@ -317,7 +317,7 @@ fn init_allocation_extra<'b>(
     }
 
     #[inline(always)]
-    fn tag_static_base_pointer(_memory_extra: &MemoryExtra, _id: AllocId) -> Self::PointerTag {}
+    fn tag_global_base_pointer(_memory_extra: &MemoryExtra, _id: AllocId) -> Self::PointerTag {}
 
     fn box_alloc(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
@@ -345,11 +345,15 @@ fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         Ok(())
     }
 
-    fn before_access_static(
+    fn before_access_global(
         memory_extra: &MemoryExtra,
         _allocation: &Allocation,
+        def_id: Option<DefId>,
+        is_write: bool,
     ) -> InterpResult<'tcx> {
-        if memory_extra.can_access_statics {
+        if is_write {
+            Err(ConstEvalErrKind::ModifiedGlobal.into())
+        } else if memory_extra.can_access_statics || def_id.is_none() {
             Ok(())
         } else {
             Err(ConstEvalErrKind::ConstAccessesStatic.into())
index ac593d0845a7df52051836a3379cc1181d84f888..c50146f295adb67e8517934a7408f619f2732e08 100644 (file)
@@ -253,8 +253,8 @@ pub fn force_bits(
     /// This represents a *direct* access to that memory, as opposed to access
     /// through a pointer that was created by the program.
     #[inline(always)]
-    pub fn tag_static_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
-        self.memory.tag_static_base_pointer(ptr)
+    pub fn tag_global_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
+        self.memory.tag_global_base_pointer(ptr)
     }
 
     #[inline(always)]
index 90b8a4932991e2b44499c2a4105a257c4ecb1dba..b9ed69842f1a9b28beaffdedf30170b241f6b149 100644 (file)
@@ -16,7 +16,7 @@
 pub trait CompileTimeMachine<'mir, 'tcx> = Machine<
     'mir,
     'tcx,
-    MemoryKinds = !,
+    MemoryKind = !,
     PointerTag = (),
     ExtraFnVal = !,
     FrameExtra = (),
@@ -104,7 +104,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
         MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {}
     }
     // Set allocation mutability as appropriate. This is used by LLVM to put things into
-    // read-only memory, and also by Miri when evluating other constants/statics that
+    // read-only memory, and also by Miri when evaluating other globals that
     // access this one.
     if mode == InternMode::Static {
         // When `ty` is `None`, we assume no interior mutability.
index 88cb74ebf8c98bca2b1874dd578d8bd0ca7000d3..6fe70548554809297d48fd534f330bca085e175d 100644 (file)
@@ -7,7 +7,7 @@
 
 use rustc::mir;
 use rustc::ty::{self, Ty};
-use rustc_span::Span;
+use rustc_span::{def_id::DefId, Span};
 
 use super::{
     AllocId, Allocation, AllocationExtra, Frame, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
@@ -79,7 +79,7 @@ fn get_mut(&mut self, k: K) -> Option<&mut V> {
 /// and some use case dependent behaviour can instead be applied.
 pub trait Machine<'mir, 'tcx>: Sized {
     /// Additional memory kinds a machine wishes to distinguish from the builtin ones
-    type MemoryKinds: ::std::fmt::Debug + MayLeak + Eq + 'static;
+    type MemoryKind: ::std::fmt::Debug + MayLeak + Eq + 'static;
 
     /// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
     /// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
@@ -105,16 +105,17 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// Memory's allocation map
     type MemoryMap: AllocMap<
             AllocId,
-            (MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag, Self::AllocExtra>),
+            (MemoryKind<Self::MemoryKind>, Allocation<Self::PointerTag, Self::AllocExtra>),
         > + Default
         + Clone;
 
-    /// The memory kind to use for copied statics -- or None if statics should not be mutated
-    /// and thus any such attempt will cause a `ModifiedStatic` error to be raised.
+    /// The memory kind to use for copied global memory (held in `tcx`) --
+    /// or None if such memory should not be mutated and thus any such attempt will cause
+    /// a `ModifiedStatic` error to be raised.
     /// Statics are copied under two circumstances: When they are mutated, and when
-    /// `tag_allocation` or `find_foreign_static` (see below) returns an owned allocation
+    /// `tag_allocation` (see below) returns an owned allocation
     /// that is added to the memory so that the work is not done twice.
-    const STATIC_KIND: Option<Self::MemoryKinds>;
+    const GLOBAL_KIND: Option<Self::MemoryKind>;
 
     /// Whether memory accesses should be alignment-checked.
     const CHECK_ALIGN: bool;
@@ -207,11 +208,13 @@ fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx
         Ok(())
     }
 
-    /// Called before a `Static` value is accessed.
+    /// Called before a global allocation is accessed.
     #[inline]
-    fn before_access_static(
+    fn before_access_global(
         _memory_extra: &Self::MemoryExtra,
         _allocation: &Allocation,
+        _def_id: Option<DefId>,
+        _is_write: bool,
     ) -> InterpResult<'tcx> {
         Ok(())
     }
@@ -231,10 +234,10 @@ fn canonical_alloc_id(_mem: &Memory<'mir, 'tcx, Self>, id: AllocId) -> AllocId {
     /// it contains (in relocations) tagged.  The way we construct allocations is
     /// to always first construct it without extra and then add the extra.
     /// This keeps uniform code paths for handling both allocations created by CTFE
-    /// for statics, and allocations created by Miri during evaluation.
+    /// for globals, and allocations created by Miri during evaluation.
     ///
     /// `kind` is the kind of the allocation being tagged; it can be `None` when
-    /// it's a static and `STATIC_KIND` is `None`.
+    /// it's a global and `GLOBAL_KIND` is `None`.
     ///
     /// This should avoid copying if no work has to be done! If this returns an owned
     /// allocation (because a copy had to be done to add tags or metadata), machine memory will
@@ -243,20 +246,20 @@ fn canonical_alloc_id(_mem: &Memory<'mir, 'tcx, Self>, id: AllocId) -> AllocId {
     ///
     /// Also return the "base" tag to use for this allocation: the one that is used for direct
     /// accesses to this allocation. If `kind == STATIC_KIND`, this tag must be consistent
-    /// with `tag_static_base_pointer`.
+    /// with `tag_global_base_pointer`.
     fn init_allocation_extra<'b>(
         memory_extra: &Self::MemoryExtra,
         id: AllocId,
         alloc: Cow<'b, Allocation>,
-        kind: Option<MemoryKind<Self::MemoryKinds>>,
+        kind: Option<MemoryKind<Self::MemoryKind>>,
     ) -> (Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>, Self::PointerTag);
 
-    /// Return the "base" tag for the given *static* allocation: the one that is used for direct
-    /// accesses to this static/const/fn allocation. If `id` is not a static allocation,
+    /// Return the "base" tag for the given *global* allocation: the one that is used for direct
+    /// accesses to this static/const/fn allocation. If `id` is not a global allocation,
     /// this will return an unusable tag (i.e., accesses will be UB)!
     ///
     /// Expects `id` to be already canonical, if needed.
-    fn tag_static_base_pointer(memory_extra: &Self::MemoryExtra, id: AllocId) -> Self::PointerTag;
+    fn tag_global_base_pointer(memory_extra: &Self::MemoryExtra, id: AllocId) -> Self::PointerTag;
 
     /// Executes a retagging operation
     #[inline]
index 277a77af3fd56efc5d448ef179bda2c2ef173cc2..df56b3f957782b65ed76133defb13f7609a9dcff 100644 (file)
@@ -80,12 +80,12 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
     /// Allocations local to this instance of the miri engine. The kind
     /// helps ensure that the same mechanism is used for allocation and
     /// deallocation. When an allocation is not found here, it is a
-    /// static and looked up in the `tcx` for read access. Some machines may
-    /// have to mutate this map even on a read-only access to a static (because
+    /// global and looked up in the `tcx` for read access. Some machines may
+    /// have to mutate this map even on a read-only access to a global (because
     /// they do pointer provenance tracking and the allocations in `tcx` have
     /// the wrong type), so we let the machine override this type.
-    /// Either way, if the machine allows writing to a static, doing so will
-    /// create a copy of the static allocation here.
+    /// Either way, if the machine allows writing to a global, doing so will
+    /// create a copy of the global allocation here.
     // FIXME: this should not be public, but interning currently needs access to it
     pub(super) alloc_map: M::MemoryMap,
 
@@ -130,9 +130,9 @@ pub fn new(tcx: TyCtxtAt<'tcx>, extra: M::MemoryExtra) -> Self {
     /// This represents a *direct* access to that memory, as opposed to access
     /// through a pointer that was created by the program.
     #[inline]
-    pub fn tag_static_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
+    pub fn tag_global_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
         let id = M::canonical_alloc_id(self, ptr.alloc_id);
-        ptr.with_tag(M::tag_static_base_pointer(&self.extra, id))
+        ptr.with_tag(M::tag_global_base_pointer(&self.extra, id))
     }
 
     pub fn create_fn_alloc(
@@ -149,23 +149,23 @@ pub fn create_fn_alloc(
                 id
             }
         };
-        self.tag_static_base_pointer(Pointer::from(id))
+        self.tag_global_base_pointer(Pointer::from(id))
     }
 
     pub fn allocate(
         &mut self,
         size: Size,
         align: Align,
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> Pointer<M::PointerTag> {
         let alloc = Allocation::undef(size, align);
         self.allocate_with(alloc, kind)
     }
 
-    pub fn allocate_static_bytes(
+    pub fn allocate_bytes(
         &mut self,
         bytes: &[u8],
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> Pointer<M::PointerTag> {
         let alloc = Allocation::from_byte_aligned_bytes(bytes);
         self.allocate_with(alloc, kind)
@@ -174,13 +174,13 @@ pub fn allocate_static_bytes(
     pub fn allocate_with(
         &mut self,
         alloc: Allocation,
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> Pointer<M::PointerTag> {
         let id = self.tcx.alloc_map.lock().reserve();
         debug_assert_ne!(
             Some(kind),
-            M::STATIC_KIND.map(MemoryKind::Machine),
-            "dynamically allocating static memory"
+            M::GLOBAL_KIND.map(MemoryKind::Machine),
+            "dynamically allocating global memory"
         );
         let (alloc, tag) = M::init_allocation_extra(&self.extra, id, Cow::Owned(alloc), Some(kind));
         self.alloc_map.insert(id, (kind, alloc.into_owned()));
@@ -193,7 +193,7 @@ pub fn reallocate(
         old_size_and_align: Option<(Size, Align)>,
         new_size: Size,
         new_align: Align,
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
         if ptr.offset.bytes() != 0 {
             throw_ub_format!(
@@ -215,9 +215,9 @@ pub fn reallocate(
         Ok(new_ptr)
     }
 
-    /// Deallocate a local, or do nothing if that local has been made into a static
+    /// Deallocate a local, or do nothing if that local has been made into a global.
     pub fn deallocate_local(&mut self, ptr: Pointer<M::PointerTag>) -> InterpResult<'tcx> {
-        // The allocation might be already removed by static interning.
+        // The allocation might be already removed by global interning.
         // This can only really happen in the CTFE instance, not in miri.
         if self.alloc_map.contains_key(&ptr.alloc_id) {
             self.deallocate(ptr, None, MemoryKind::Stack)
@@ -230,7 +230,7 @@ pub fn deallocate(
         &mut self,
         ptr: Pointer<M::PointerTag>,
         old_size_and_align: Option<(Size, Align)>,
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> InterpResult<'tcx> {
         trace!("deallocating: {}", ptr.alloc_id);
 
@@ -244,7 +244,7 @@ pub fn deallocate(
         let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) {
             Some(alloc) => alloc,
             None => {
-                // Deallocating static memory -- always an error
+                // Deallocating global memory -- always an error
                 return Err(match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
                     Some(GlobalAlloc::Function(..)) => err_ub_format!("deallocating a function"),
                     Some(GlobalAlloc::Static(..)) | Some(GlobalAlloc::Memory(..)) => {
@@ -403,43 +403,42 @@ pub fn ptr_may_be_null(&self, ptr: Pointer<M::PointerTag>) -> bool {
 
 /// Allocation accessors
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
-    /// Helper function to obtain the global (tcx) allocation for a static.
+    /// Helper function to obtain a global (tcx) allocation.
     /// This attempts to return a reference to an existing allocation if
     /// one can be found in `tcx`. That, however, is only possible if `tcx` and
     /// this machine use the same pointer tag, so it is indirected through
     /// `M::tag_allocation`.
-    ///
-    /// Notice that every static has two `AllocId` that will resolve to the same
-    /// thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID,
-    /// and the other one is maps to `GlobalAlloc::Memory`, this is returned by
-    /// `const_eval_raw` and it is the "resolved" ID.
-    /// The resolved ID is never used by the interpreted progrma, it is hidden.
-    /// The `GlobalAlloc::Memory` branch here is still reachable though; when a static
-    /// contains a reference to memory that was created during its evaluation (i.e., not to
-    /// another static), those inner references only exist in "resolved" form.
-    ///
-    /// Assumes `id` is already canonical.
-    fn get_static_alloc(
+    fn get_global_alloc(
         memory_extra: &M::MemoryExtra,
         tcx: TyCtxtAt<'tcx>,
         id: AllocId,
+        is_write: bool,
     ) -> InterpResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
         let alloc = tcx.alloc_map.lock().get(id);
-        let alloc = match alloc {
-            Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem),
+        let (alloc, def_id) = match alloc {
+            Some(GlobalAlloc::Memory(mem)) => (mem, None),
             Some(GlobalAlloc::Function(..)) => throw_ub!(DerefFunctionPointer(id)),
             None => throw_ub!(PointerUseAfterFree(id)),
             Some(GlobalAlloc::Static(def_id)) => {
-                // We got a "lazy" static that has not been computed yet.
+                // Notice that every static has two `AllocId` that will resolve to the same
+                // thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID,
+                // and the other one is maps to `GlobalAlloc::Memory`, this is returned by
+                // `const_eval_raw` and it is the "resolved" ID.
+                // The resolved ID is never used by the interpreted progrma, it is hidden.
+                // The `GlobalAlloc::Memory` branch here is still reachable though; when a static
+                // contains a reference to memory that was created during its evaluation (i.e., not
+                // to another static), those inner references only exist in "resolved" form.
+                //
+                // Assumes `id` is already canonical.
                 if tcx.is_foreign_item(def_id) {
-                    trace!("get_static_alloc: foreign item {:?}", def_id);
+                    trace!("get_global_alloc: foreign item {:?}", def_id);
                     throw_unsup!(ReadForeignStatic(def_id))
                 }
-                trace!("get_static_alloc: Need to compute {:?}", def_id);
+                trace!("get_global_alloc: Need to compute {:?}", def_id);
                 let instance = Instance::mono(tcx.tcx, def_id);
                 let gid = GlobalId { instance, promoted: None };
-                // use the raw query here to break validation cycles. Later uses of the static
-                // will call the full query anyway
+                // Use the raw query here to break validation cycles. Later uses of the static
+                // will call the full query anyway.
                 let raw_const =
                     tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
                         // no need to report anything, the const_eval call takes care of that
@@ -454,18 +453,19 @@ fn get_static_alloc(
                 let id = raw_const.alloc_id;
                 let allocation = tcx.alloc_map.lock().unwrap_memory(id);
 
-                M::before_access_static(memory_extra, allocation)?;
-                Cow::Borrowed(allocation)
+                (allocation, Some(def_id))
             }
         };
+        M::before_access_global(memory_extra, alloc, def_id, is_write)?;
+        let alloc = Cow::Borrowed(alloc);
         // We got tcx memory. Let the machine initialize its "extra" stuff.
         let (alloc, tag) = M::init_allocation_extra(
             memory_extra,
             id, // always use the ID we got as input, not the "hidden" one.
             alloc,
-            M::STATIC_KIND.map(MemoryKind::Machine),
+            M::GLOBAL_KIND.map(MemoryKind::Machine),
         );
-        debug_assert_eq!(tag, M::tag_static_base_pointer(memory_extra, id));
+        debug_assert_eq!(tag, M::tag_global_base_pointer(memory_extra, id));
         Ok(alloc)
     }
 
@@ -478,10 +478,11 @@ pub fn get_raw(
         let id = M::canonical_alloc_id(self, id);
         // The error type of the inner closure here is somewhat funny.  We have two
         // ways of "erroring": An actual error, or because we got a reference from
-        // `get_static_alloc` that we can actually use directly without inserting anything anywhere.
+        // `get_global_alloc` that we can actually use directly without inserting anything anywhere.
         // So the error type is `InterpResult<'tcx, &Allocation<M::PointerTag>>`.
         let a = self.alloc_map.get_or(id, || {
-            let alloc = Self::get_static_alloc(&self.extra, self.tcx, id).map_err(Err)?;
+            let alloc = Self::get_global_alloc(&self.extra, self.tcx, id, /*is_write*/ false)
+                .map_err(Err)?;
             match alloc {
                 Cow::Borrowed(alloc) => {
                     // We got a ref, cheaply return that as an "error" so that the
@@ -490,8 +491,8 @@ pub fn get_raw(
                 }
                 Cow::Owned(alloc) => {
                     // Need to put it into the map and return a ref to that
-                    let kind = M::STATIC_KIND.expect(
-                        "I got an owned allocation that I have to copy but the machine does \
+                    let kind = M::GLOBAL_KIND.expect(
+                        "I got a global allocation that I have to copy but the machine does \
                             not expect that to happen",
                     );
                     Ok((MemoryKind::Machine(kind), alloc))
@@ -515,16 +516,17 @@ pub fn get_raw_mut(
         let tcx = self.tcx;
         let memory_extra = &self.extra;
         let a = self.alloc_map.get_mut_or(id, || {
-            // Need to make a copy, even if `get_static_alloc` is able
+            // Need to make a copy, even if `get_global_alloc` is able
             // to give us a cheap reference.
-            let alloc = Self::get_static_alloc(memory_extra, tcx, id)?;
+            let alloc = Self::get_global_alloc(memory_extra, tcx, id, /*is_write*/ true)?;
             if alloc.mutability == Mutability::Not {
                 throw_ub!(WriteToReadOnly(id))
             }
-            match M::STATIC_KIND {
-                Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())),
-                None => throw_unsup!(ModifiedStatic),
-            }
+            let kind = M::GLOBAL_KIND.expect(
+                "I got a global allocation that I have to copy but the machine does \
+                    not expect that to happen",
+            );
+            Ok((MemoryKind::Machine(kind), alloc.into_owned()))
         });
         // Unpack the error type manually because type inference doesn't
         // work otherwise (and we cannot help it because `impl Trait`)
@@ -553,7 +555,7 @@ pub fn get_size_and_align(
         // # Regular allocations
         // Don't use `self.get_raw` here as that will
         // a) cause cycles in case `id` refers to a static
-        // b) duplicate a static's allocation in miri
+        // b) duplicate a global's allocation in miri
         if let Some((_, alloc)) = self.alloc_map.get(id) {
             return Ok((alloc.size, alloc.align));
         }
@@ -728,7 +730,7 @@ pub fn dump_allocs(&self, mut allocs: Vec<AllocId>) {
                     );
                 }
                 Err(()) => {
-                    // static alloc?
+                    // global alloc?
                     match self.tcx.alloc_map.lock().get(id) {
                         Some(GlobalAlloc::Memory(alloc)) => {
                             self.dump_alloc_helper(
index 4c82172ae4517cb1958bdd4254c978f0e2c7381e..90fb7eb2bb3ac0cdf60f0c35b4a41c8d620dd5e9 100644 (file)
@@ -517,7 +517,7 @@ pub(super) fn eval_operands(
         layout: Option<TyLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         let tag_scalar = |scalar| match scalar {
-            Scalar::Ptr(ptr) => Scalar::Ptr(self.tag_static_base_pointer(ptr)),
+            Scalar::Ptr(ptr) => Scalar::Ptr(self.tag_global_base_pointer(ptr)),
             Scalar::Raw { data, size } => Scalar::Raw { data, size },
         };
         // Early-return cases.
@@ -547,7 +547,7 @@ pub(super) fn eval_operands(
                 let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
                 // We rely on mutability being set correctly in that allocation to prevent writes
                 // where none should happen.
-                let ptr = self.tag_static_base_pointer(Pointer::new(id, offset));
+                let ptr = self.tag_global_base_pointer(Pointer::new(id, offset));
                 Operand::Indirect(MemPlace::from_ptr(ptr, layout.align.abi))
             }
             ConstValue::Scalar(x) => Operand::Immediate(tag_scalar(x).into()),
@@ -559,7 +559,7 @@ pub(super) fn eval_operands(
                     Size::from_bytes(start as u64), // offset: `start`
                 );
                 Operand::Immediate(Immediate::new_slice(
-                    self.tag_static_base_pointer(ptr).into(),
+                    self.tag_global_base_pointer(ptr).into(),
                     (end - start) as u64, // len: `end - start`
                     self,
                 ))
index 027e33abc7bb193b19909b964eb9dea33da2c695..6cf11c071e4f7edc767faaedd9bf0a13677a71b9 100644 (file)
@@ -290,7 +290,7 @@ impl<'mir, 'tcx, Tag, M> InterpCx<'mir, 'tcx, M>
     Tag: ::std::fmt::Debug + Copy + Eq + Hash + 'static,
     M: Machine<'mir, 'tcx, PointerTag = Tag>,
     // FIXME: Working around https://github.com/rust-lang/rust/issues/24159
-    M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<Tag, M::AllocExtra>)>,
+    M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKind>, Allocation<Tag, M::AllocExtra>)>,
     M::AllocExtra: AllocationExtra<Tag>,
 {
     /// Take a value, which represents a (thin or wide) reference, and make it a place.
@@ -1015,7 +1015,7 @@ pub fn force_allocation(
     pub fn allocate(
         &mut self,
         layout: TyLayout<'tcx>,
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> MPlaceTy<'tcx, M::PointerTag> {
         let ptr = self.memory.allocate(layout.size, layout.align.abi, kind);
         MPlaceTy::from_aligned_ptr(ptr, layout)
@@ -1025,9 +1025,9 @@ pub fn allocate(
     pub fn allocate_str(
         &mut self,
         str: &str,
-        kind: MemoryKind<M::MemoryKinds>,
+        kind: MemoryKind<M::MemoryKind>,
     ) -> MPlaceTy<'tcx, M::PointerTag> {
-        let ptr = self.memory.allocate_static_bytes(str.as_bytes(), kind);
+        let ptr = self.memory.allocate_bytes(str.as_bytes(), kind);
         let meta = Scalar::from_uint(str.len() as u128, self.pointer_size());
         let mplace = MemPlace {
             ptr: ptr.into(),
@@ -1118,7 +1118,7 @@ pub fn raw_const_to_mplace(
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         // This must be an allocation in `tcx`
         assert!(self.tcx.alloc_map.lock().get(raw.alloc_id).is_some());
-        let ptr = self.tag_static_base_pointer(Pointer::from(raw.alloc_id));
+        let ptr = self.tag_global_base_pointer(Pointer::from(raw.alloc_id));
         let layout = self.layout_of(raw.ty)?;
         Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
     }
index 8899f12b15361fc5aad9ed59098661e3db0df16d..850fc15f12cf7c9bbc423c8a8af04a49a7452124 100644 (file)
@@ -25,7 +25,7 @@
 use rustc_hir::HirId;
 use rustc_index::vec::IndexVec;
 use rustc_session::lint;
-use rustc_span::Span;
+use rustc_span::{def_id::DefId, Span};
 use rustc_trait_selection::traits;
 
 use crate::const_eval::error_to_const_error;
@@ -162,7 +162,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAn
 struct ConstPropMachine;
 
 impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
-    type MemoryKinds = !;
+    type MemoryKind = !;
     type PointerTag = ();
     type ExtraFnVal = !;
 
@@ -172,7 +172,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
 
     type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
 
-    const STATIC_KIND: Option<!> = None;
+    const GLOBAL_KIND: Option<!> = None;
 
     const CHECK_ALIGN: bool = false;
 
@@ -247,7 +247,7 @@ fn init_allocation_extra<'b>(
     }
 
     #[inline(always)]
-    fn tag_static_base_pointer(_memory_extra: &(), _id: AllocId) -> Self::PointerTag {}
+    fn tag_global_base_pointer(_memory_extra: &(), _id: AllocId) -> Self::PointerTag {}
 
     fn box_alloc(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
@@ -270,14 +270,19 @@ fn access_local(
         l.access()
     }
 
-    fn before_access_static(
+    fn before_access_global(
         _memory_extra: &(),
         allocation: &Allocation<Self::PointerTag, Self::AllocExtra>,
+        _def_id: Option<DefId>,
+        is_write: bool,
     ) -> InterpResult<'tcx> {
-        // 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 is_write {
+            throw_machine_stop_str!("can't write to global");
+        }
+        // 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 {
-            throw_machine_stop_str!("can't eval mutable statics in ConstProp")
+            throw_machine_stop_str!("can't eval mutable statics in ConstProp");
         }
 
         Ok(())