@@ -22,6 +22,9 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
2222 ecx : & ' rt mut CompileTimeEvalContext < ' mir , ' tcx > ,
2323 /// Previously encountered safe references.
2424 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 > ,
2528 /// The root node of the value that we're looking at. This field is never mutated and only used
2629 /// for sanity assertions that will ICE when `const_qualif` screws up.
2730 mode : InternMode ,
@@ -31,9 +34,6 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
3134 /// despite the nested mutable reference!
3235 /// The field gets updated when an `UnsafeCell` is encountered.
3336 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 > ,
3737}
3838
3939#[ derive( Copy , Clone , Debug , PartialEq , Hash , Eq ) ]
@@ -59,7 +59,7 @@ struct IsStaticOrFn;
5959/// `immutable` things might become mutable if `ty` is not frozen.
6060fn intern_shallow < ' rt , ' mir , ' tcx > (
6161 ecx : & ' rt mut CompileTimeEvalContext < ' mir , ' tcx > ,
62- leftover_relocations : & ' rt mut FxHashSet < AllocId > ,
62+ leftover_allocations : & ' rt mut FxHashSet < AllocId > ,
6363 mode : InternMode ,
6464 alloc_id : AllocId ,
6565 mutability : Mutability ,
@@ -120,7 +120,7 @@ fn intern_shallow<'rt, 'mir, 'tcx>(
120120 } ;
121121 // link the alloc id to the actual allocation
122122 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) ) ;
124124 tcx. alloc_map . lock ( ) . set_alloc_id_memory ( alloc_id, alloc) ;
125125 Ok ( None )
126126}
@@ -134,7 +134,7 @@ impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
134134 ) -> InterpResult < ' tcx , Option < IsStaticOrFn > > {
135135 intern_shallow (
136136 self . ecx ,
137- self . leftover_relocations ,
137+ self . leftover_allocations ,
138138 self . mode ,
139139 alloc_id,
140140 mutability,
@@ -276,14 +276,18 @@ pub fn intern_const_alloc_recursive(
276276 Some ( hir:: Mutability :: MutMutable ) => ( Mutability :: Mutable , InternMode :: Static ) ,
277277 } ;
278278
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.
280284 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 ( ) ;
282286
283287 // start with the outermost allocation
284288 intern_shallow (
285289 ecx,
286- leftover_relocations ,
290+ leftover_allocations ,
287291 base_intern_mode,
288292 ret. ptr . to_ptr ( ) ?. alloc_id ,
289293 base_mutability,
@@ -295,7 +299,7 @@ pub fn intern_const_alloc_recursive(
295299 ref_tracking : & mut ref_tracking,
296300 ecx,
297301 mode,
298- leftover_relocations ,
302+ leftover_allocations ,
299303 mutability,
300304 } . visit_value ( mplace) ;
301305 if let Err ( error) = interned {
@@ -318,11 +322,12 @@ pub fn intern_const_alloc_recursive(
318322 // Intern the rest of the allocations as mutable. These might be inside unions, padding, raw
319323 // pointers, ... So we can't intern them according to their type rules
320324
321- let mut todo: Vec < _ > = leftover_relocations . iter ( ) . cloned ( ) . collect ( ) ;
325+ let mut todo: Vec < _ > = leftover_allocations . iter ( ) . cloned ( ) . collect ( ) ;
322326 while let Some ( alloc_id) = todo. pop ( ) {
323327 if let Some ( ( _, mut alloc) ) = ecx. memory_mut ( ) . alloc_map . remove ( & alloc_id) {
324328 // 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.
326331 if base_intern_mode != InternMode :: Static {
327332 // If it's not a static, it *must* be immutable.
328333 // We cannot have mutable memory inside a constant.
@@ -331,7 +336,7 @@ pub fn intern_const_alloc_recursive(
331336 let alloc = tcx. intern_const_alloc ( alloc) ;
332337 tcx. alloc_map . lock ( ) . set_alloc_id_memory ( alloc_id, alloc) ;
333338 for & ( _, ( ( ) , reloc) ) in alloc. relocations ( ) . iter ( ) {
334- if leftover_relocations . insert ( reloc) {
339+ if leftover_allocations . insert ( reloc) {
335340 todo. push ( reloc) ;
336341 }
337342 }
0 commit comments