@@ -31,7 +31,7 @@ use super::{
3131} ;
3232use crate :: const_eval;
3333use crate :: const_eval:: DummyMachine ;
34- use crate :: errors:: NestedStaticInThreadLocal ;
34+ use crate :: errors:: { ConstHeapPtrInFinal , NestedStaticInThreadLocal } ;
3535
3636pub trait CompileTimeMachine < ' tcx , T > = Machine <
3737 ' tcx ,
@@ -55,14 +55,36 @@ impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> {
5555 }
5656}
5757
58+ pub enum DisallowInternReason {
59+ ConstHeap ,
60+ }
61+
62+ pub trait CanIntern {
63+ fn disallows_intern ( & self ) -> Option < DisallowInternReason > ;
64+ }
65+
66+ impl CanIntern for const_eval:: MemoryKind {
67+ fn disallows_intern ( & self ) -> Option < DisallowInternReason > {
68+ match self {
69+ const_eval:: MemoryKind :: Heap => Some ( DisallowInternReason :: ConstHeap ) ,
70+ }
71+ }
72+ }
73+
74+ impl CanIntern for ! {
75+ fn disallows_intern ( & self ) -> Option < DisallowInternReason > {
76+ * self
77+ }
78+ }
79+
5880/// Intern an allocation. Returns `Err` if the allocation does not exist in the local memory.
5981///
6082/// `mutability` can be used to force immutable interning: if it is `Mutability::Not`, the
6183/// allocation is interned immutably; if it is `Mutability::Mut`, then the allocation *must be*
6284/// already mutable (as a sanity check).
6385///
6486/// Returns an iterator over all relocations referred to by this allocation.
65- fn intern_shallow < ' tcx , T , M : CompileTimeMachine < ' tcx , T > > (
87+ fn intern_shallow < ' tcx , T : CanIntern , M : CompileTimeMachine < ' tcx , T > > (
6688 ecx : & mut InterpCx < ' tcx , M > ,
6789 alloc_id : AllocId ,
6890 mutability : Mutability ,
@@ -71,9 +93,22 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
7193 trace ! ( "intern_shallow {:?}" , alloc_id) ;
7294 // remove allocation
7395 // FIXME(#120456) - is `swap_remove` correct?
74- let Some ( ( _kind , mut alloc) ) = ecx. memory . alloc_map . swap_remove ( & alloc_id) else {
96+ let Some ( ( kind , mut alloc) ) = ecx. memory . alloc_map . swap_remove ( & alloc_id) else {
7597 return Err ( ( ) ) ;
7698 } ;
99+
100+ match kind {
101+ MemoryKind :: Machine ( x) if let Some ( reason) = x. disallows_intern ( ) => match reason {
102+ // attempting to intern a `const_allocate`d pointer that was not made global via
103+ // `const_make_global`. We emit an error here but don't return an `Err` as if we
104+ // did the caller assumes we found a dangling pointer.
105+ DisallowInternReason :: ConstHeap => {
106+ ecx. tcx . dcx ( ) . emit_err ( ConstHeapPtrInFinal { span : ecx. tcx . span } ) ;
107+ }
108+ } ,
109+ MemoryKind :: Machine ( _) | MemoryKind :: Stack | MemoryKind :: CallerLocation => { }
110+ }
111+
77112 // Set allocation mutability as appropriate. This is used by LLVM to put things into
78113 // read-only memory, and also by Miri when evaluating other globals that
79114 // access this one.
@@ -99,7 +134,7 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
99134 } else {
100135 ecx. tcx . set_alloc_id_memory ( alloc_id, alloc) ;
101136 }
102- Ok ( alloc. 0 . 0 . provenance ( ) . ptrs ( ) . iter ( ) . map ( |& ( _, prov) | prov) )
137+ Ok ( alloc. inner ( ) . provenance ( ) . ptrs ( ) . iter ( ) . map ( |& ( _, prov) | prov) )
103138}
104139
105140/// Creates a new `DefId` and feeds all the right queries to make this `DefId`
@@ -321,7 +356,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
321356
322357/// Intern `ret`. This function assumes that `ret` references no other allocation.
323358#[ instrument( level = "debug" , skip( ecx) ) ]
324- pub fn intern_const_alloc_for_constprop < ' tcx , T , M : CompileTimeMachine < ' tcx , T > > (
359+ pub fn intern_const_alloc_for_constprop < ' tcx , T : CanIntern , M : CompileTimeMachine < ' tcx , T > > (
325360 ecx : & mut InterpCx < ' tcx , M > ,
326361 alloc_id : AllocId ,
327362) -> InterpResult < ' tcx , ( ) > {
0 commit comments