@@ -22,6 +22,9 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
22
22
ecx : & ' rt mut CompileTimeEvalContext < ' mir , ' tcx > ,
23
23
/// Previously encountered safe references.
24
24
ref_tracking : & ' rt mut RefTracking < ( MPlaceTy < ' tcx > , Mutability , InternMode ) > ,
25
+ /// A list of all encountered allocations. After type-based interning, we traverse this list to
26
+ /// also intern allocations that are only referenced by a raw pointer or inside a union.
27
+ leftover_allocations : & ' rt mut FxHashSet < AllocId > ,
25
28
/// The root node of the value that we're looking at. This field is never mutated and only used
26
29
/// for sanity assertions that will ICE when `const_qualif` screws up.
27
30
mode : InternMode ,
@@ -31,9 +34,6 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
31
34
/// despite the nested mutable reference!
32
35
/// The field gets updated when an `UnsafeCell` is encountered.
33
36
mutability : Mutability ,
34
- /// A list of all encountered relocations. After type-based interning, we traverse this list to
35
- /// also intern allocations that are only referenced by a raw pointer or inside a union.
36
- leftover_relocations : & ' rt mut FxHashSet < AllocId > ,
37
37
}
38
38
39
39
#[ derive( Copy , Clone , Debug , PartialEq , Hash , Eq ) ]
@@ -59,7 +59,7 @@ struct IsStaticOrFn;
59
59
/// `immutable` things might become mutable if `ty` is not frozen.
60
60
fn intern_shallow < ' rt , ' mir , ' tcx > (
61
61
ecx : & ' rt mut CompileTimeEvalContext < ' mir , ' tcx > ,
62
- leftover_relocations : & ' rt mut FxHashSet < AllocId > ,
62
+ leftover_allocations : & ' rt mut FxHashSet < AllocId > ,
63
63
mode : InternMode ,
64
64
alloc_id : AllocId ,
65
65
mutability : Mutability ,
@@ -120,7 +120,7 @@ fn intern_shallow<'rt, 'mir, 'tcx>(
120
120
} ;
121
121
// link the alloc id to the actual allocation
122
122
let alloc = tcx. intern_const_alloc ( alloc) ;
123
- leftover_relocations . extend ( alloc. relocations ( ) . iter ( ) . map ( |& ( _, ( ( ) , reloc) ) | reloc) ) ;
123
+ leftover_allocations . extend ( alloc. relocations ( ) . iter ( ) . map ( |& ( _, ( ( ) , reloc) ) | reloc) ) ;
124
124
tcx. alloc_map . lock ( ) . set_alloc_id_memory ( alloc_id, alloc) ;
125
125
Ok ( None )
126
126
}
@@ -134,7 +134,7 @@ impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
134
134
) -> InterpResult < ' tcx , Option < IsStaticOrFn > > {
135
135
intern_shallow (
136
136
self . ecx ,
137
- self . leftover_relocations ,
137
+ self . leftover_allocations ,
138
138
self . mode ,
139
139
alloc_id,
140
140
mutability,
@@ -276,14 +276,18 @@ pub fn intern_const_alloc_recursive(
276
276
Some ( hir:: Mutability :: MutMutable ) => ( Mutability :: Mutable , InternMode :: Static ) ,
277
277
} ;
278
278
279
- // type based interning
279
+ // Type based interning.
280
+ // `ref_tracking` tracks typed references we have seen and still need to crawl for
281
+ // more typed information inside them.
282
+ // `leftover_allocations` collects *all* allocations we see, because some might not
283
+ // be available in a typed way. They get interned at the end.
280
284
let mut ref_tracking = RefTracking :: new ( ( ret, base_mutability, base_intern_mode) ) ;
281
- let leftover_relocations = & mut FxHashSet :: default ( ) ;
285
+ let leftover_allocations = & mut FxHashSet :: default ( ) ;
282
286
283
287
// start with the outermost allocation
284
288
intern_shallow (
285
289
ecx,
286
- leftover_relocations ,
290
+ leftover_allocations ,
287
291
base_intern_mode,
288
292
ret. ptr . to_ptr ( ) ?. alloc_id ,
289
293
base_mutability,
@@ -295,7 +299,7 @@ pub fn intern_const_alloc_recursive(
295
299
ref_tracking : & mut ref_tracking,
296
300
ecx,
297
301
mode,
298
- leftover_relocations ,
302
+ leftover_allocations ,
299
303
mutability,
300
304
} . visit_value ( mplace) ;
301
305
if let Err ( error) = interned {
@@ -318,11 +322,12 @@ pub fn intern_const_alloc_recursive(
318
322
// Intern the rest of the allocations as mutable. These might be inside unions, padding, raw
319
323
// pointers, ... So we can't intern them according to their type rules
320
324
321
- let mut todo: Vec < _ > = leftover_relocations . iter ( ) . cloned ( ) . collect ( ) ;
325
+ let mut todo: Vec < _ > = leftover_allocations . iter ( ) . cloned ( ) . collect ( ) ;
322
326
while let Some ( alloc_id) = todo. pop ( ) {
323
327
if let Some ( ( _, mut alloc) ) = ecx. memory_mut ( ) . alloc_map . remove ( & alloc_id) {
324
328
// We can't call the `intern_shallow` method here, as its logic is tailored to safe
325
- // references. So we hand-roll the interning logic here again.
329
+ // references and a `leftover_allocations` set (where we only have a todo-list here).
330
+ // So we hand-roll the interning logic here again.
326
331
if base_intern_mode != InternMode :: Static {
327
332
// If it's not a static, it *must* be immutable.
328
333
// We cannot have mutable memory inside a constant.
@@ -331,7 +336,7 @@ pub fn intern_const_alloc_recursive(
331
336
let alloc = tcx. intern_const_alloc ( alloc) ;
332
337
tcx. alloc_map . lock ( ) . set_alloc_id_memory ( alloc_id, alloc) ;
333
338
for & ( _, ( ( ) , reloc) ) in alloc. relocations ( ) . iter ( ) {
334
- if leftover_relocations . insert ( reloc) {
339
+ if leftover_allocations . insert ( reloc) {
335
340
todo. push ( reloc) ;
336
341
}
337
342
}
0 commit comments