@@ -31,7 +31,7 @@ use super::{
31
31
} ;
32
32
use crate :: const_eval;
33
33
use crate :: const_eval:: DummyMachine ;
34
- use crate :: errors:: NestedStaticInThreadLocal ;
34
+ use crate :: errors:: { ConstHeapPtrInFinal , NestedStaticInThreadLocal } ;
35
35
36
36
pub trait CompileTimeMachine < ' tcx , T > = Machine <
37
37
' tcx ,
@@ -55,14 +55,36 @@ impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> {
55
55
}
56
56
}
57
57
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
+
58
80
/// Intern an allocation. Returns `Err` if the allocation does not exist in the local memory.
59
81
///
60
82
/// `mutability` can be used to force immutable interning: if it is `Mutability::Not`, the
61
83
/// allocation is interned immutably; if it is `Mutability::Mut`, then the allocation *must be*
62
84
/// already mutable (as a sanity check).
63
85
///
64
86
/// 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 > > (
66
88
ecx : & mut InterpCx < ' tcx , M > ,
67
89
alloc_id : AllocId ,
68
90
mutability : Mutability ,
@@ -71,9 +93,22 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
71
93
trace ! ( "intern_shallow {:?}" , alloc_id) ;
72
94
// remove allocation
73
95
// 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 {
75
97
return Err ( ( ) ) ;
76
98
} ;
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
+
77
112
// Set allocation mutability as appropriate. This is used by LLVM to put things into
78
113
// read-only memory, and also by Miri when evaluating other globals that
79
114
// access this one.
@@ -99,7 +134,7 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
99
134
} else {
100
135
ecx. tcx . set_alloc_id_memory ( alloc_id, alloc) ;
101
136
}
102
- Ok ( alloc. 0 . 0 . provenance ( ) . ptrs ( ) . iter ( ) . map ( |& ( _, prov) | prov) )
137
+ Ok ( alloc. inner ( ) . provenance ( ) . ptrs ( ) . iter ( ) . map ( |& ( _, prov) | prov) )
103
138
}
104
139
105
140
/// 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
321
356
322
357
/// Intern `ret`. This function assumes that `ret` references no other allocation.
323
358
#[ 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 > > (
325
360
ecx : & mut InterpCx < ' tcx , M > ,
326
361
alloc_id : AllocId ,
327
362
) -> InterpResult < ' tcx , ( ) > {
0 commit comments