1313//! but that would require relying on type information, and given how many ways Rust has to lie
1414//! about type information, we want to avoid doing that.
1515
16+ use hir:: def:: DefKind ;
1617use rustc_ast:: Mutability ;
1718use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
1819use rustc_errors:: ErrorGuaranteed ;
1920use 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 ;
2123use rustc_middle:: ty:: layout:: TyAndLayout ;
24+ use rustc_span:: def_id:: LocalDefId ;
25+ use rustc_span:: sym;
2226
2327use super :: { AllocId , Allocation , InterpCx , MPlaceTy , Machine , MemoryKind , PlaceTy } ;
2428use crate :: const_eval;
@@ -33,7 +37,7 @@ pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine<
3337 FrameExtra = ( ) ,
3438 AllocExtra = ( ) ,
3539 MemoryMap = FxIndexMap < AllocId , ( MemoryKind < T > , Allocation ) > ,
36- > ;
40+ > + const_eval : : HasStaticRootDefId ;
3741
3842/// Intern an allocation. Returns `Err` if the allocation does not exist in the local memory.
3943 ///
@@ -67,10 +71,34 @@ fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>(
6771 }
6872 // link the alloc id to the actual allocation
6973 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+ }
7179 Ok ( alloc. 0 . 0 . provenance ( ) . ptrs ( ) . iter ( ) . map ( |& ( _, prov) | prov) )
7280}
7381
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+ }
74102/// How a constant value should be interned.
75103#[ derive( Copy , Clone , Debug , PartialEq , Hash , Eq ) ]
76104pub enum InternKind {
0 commit comments