13
13
//! but that would require relying on type information, and given how many ways Rust has to lie
14
14
//! about type information, we want to avoid doing that.
15
15
16
+ use hir:: def:: DefKind ;
16
17
use rustc_ast:: Mutability ;
17
18
use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
18
19
use rustc_errors:: ErrorGuaranteed ;
19
20
use rustc_hir as hir;
20
- use rustc_middle:: mir:: interpret:: { CtfeProvenance , InterpResult } ;
21
+ use rustc_middle:: mir:: interpret:: { ConstAllocation , CtfeProvenance , InterpResult } ;
22
+ use rustc_middle:: query:: TyCtxtAt ;
21
23
use rustc_middle:: ty:: layout:: TyAndLayout ;
24
+ use rustc_span:: def_id:: LocalDefId ;
25
+ use rustc_span:: sym;
22
26
23
27
use super :: { AllocId , Allocation , InterpCx , MPlaceTy , Machine , MemoryKind , PlaceTy } ;
24
28
use crate :: const_eval;
@@ -33,7 +37,7 @@ pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine<
33
37
FrameExtra = ( ) ,
34
38
AllocExtra = ( ) ,
35
39
MemoryMap = FxIndexMap < AllocId , ( MemoryKind < T > , Allocation ) > ,
36
- > ;
40
+ > + const_eval : : HasStaticRootDefId ;
37
41
38
42
/// Intern an allocation. Returns `Err` if the allocation does not exist in the local memory.
39
43
///
@@ -67,10 +71,34 @@ fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>(
67
71
}
68
72
// link the alloc id to the actual allocation
69
73
let alloc = ecx. tcx . mk_const_alloc ( alloc) ;
70
- ecx. tcx . set_alloc_id_memory ( alloc_id, alloc) ;
74
+ if let Some ( static_id) = ecx. machine . static_def_id ( ) {
75
+ intern_as_new_static ( ecx. tcx , static_id, alloc_id, alloc) ;
76
+ } else {
77
+ ecx. tcx . set_alloc_id_memory ( alloc_id, alloc) ;
78
+ }
71
79
Ok ( alloc. 0 . 0 . provenance ( ) . ptrs ( ) . iter ( ) . map ( |& ( _, prov) | prov) )
72
80
}
73
81
82
+ /// Creates a new `DefId` and feeds all the right queries to make this `DefId`
83
+ /// appear as if it were a user -written `static ` ( though it has no HIR ) .
84
+ fn intern_as_new_static <' tcx>(
85
+ tcx: TyCtxtAt <' tcx>,
86
+ static_id: LocalDefId ,
87
+ alloc_id: AllocId ,
88
+ alloc: ConstAllocation <' tcx>,
89
+ ) {
90
+ let feed = tcx. create_def (
91
+ static_id,
92
+ sym:: nested,
93
+ DefKind :: Static { mt : alloc. 0 . mutability , nested : true } ,
94
+ ) ;
95
+ tcx. set_nested_alloc_id_static ( alloc_id, feed. def_id ( ) ) ;
96
+ feed. codegen_fn_attrs ( tcx. codegen_fn_attrs ( static_id) . clone ( ) ) ;
97
+ feed. eval_static_initializer ( Ok ( alloc) ) ;
98
+ feed. generics_of ( tcx. generics_of ( static_id) . clone ( ) ) ;
99
+ feed. def_ident_span ( tcx. def_ident_span ( static_id) ) ;
100
+ feed. explicit_predicates_of ( tcx. explicit_predicates_of ( static_id) ) ;
101
+ }
74
102
/// How a constant value should be interned.
75
103
#[ derive( Copy , Clone , Debug , PartialEq , Hash , Eq ) ]
76
104
pub enum InternKind {
0 commit comments