@@ -8,6 +8,7 @@ use rustc_middle::traits::Reveal;
88use rustc_middle:: ty:: layout:: LayoutOf ;
99use rustc_middle:: ty:: print:: with_no_trimmed_paths;
1010use rustc_middle:: ty:: { self , TyCtxt } ;
11+ use rustc_span:: def_id:: LocalDefId ;
1112use rustc_span:: Span ;
1213use rustc_target:: abi:: { self , Abi } ;
1314
@@ -249,11 +250,36 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
249250 tcx. eval_to_allocation_raw ( key) . map ( |val| turn_into_const_value ( tcx, val, key) )
250251}
251252
253+ #[ instrument( skip( tcx) , level = "debug" ) ]
254+ pub fn eval_static_initializer_provider < ' tcx > (
255+ tcx : TyCtxt < ' tcx > ,
256+ def_id : LocalDefId ,
257+ ) -> :: rustc_middle:: mir:: interpret:: EvalStaticInitializerRawResult < ' tcx > {
258+ assert ! ( tcx. is_static( def_id. to_def_id( ) ) ) ;
259+
260+ let instance = ty:: Instance :: mono ( tcx, def_id. to_def_id ( ) ) ;
261+ let cid = rustc_middle:: mir:: interpret:: GlobalId { instance, promoted : None } ;
262+ let ecx = InterpCx :: new (
263+ tcx,
264+ tcx. def_span ( def_id) ,
265+ ty:: ParamEnv :: reveal_all ( ) ,
266+ // Statics (and promoteds inside statics) may access other statics, because unlike consts
267+ // they do not have to behave "as if" they were evaluated at runtime.
268+ CompileTimeInterpreter :: new ( CanAccessMutGlobal :: Yes , CheckAlignment :: Error ) ,
269+ ) ;
270+ let alloc_id = eval_in_interpreter ( ecx, cid, true ) ?. alloc_id ;
271+ let alloc = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
272+ Ok ( alloc)
273+ }
274+
252275#[ instrument( skip( tcx) , level = "debug" ) ]
253276pub fn eval_to_allocation_raw_provider < ' tcx > (
254277 tcx : TyCtxt < ' tcx > ,
255278 key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
256279) -> :: rustc_middle:: mir:: interpret:: EvalToAllocationRawResult < ' tcx > {
280+ // This shouldn't be used for statics, since statics are conceptually places,
281+ // not values -- so what we do here could break pointer identity.
282+ assert ! ( key. value. promoted. is_some( ) || !tcx. is_static( key. value. instance. def_id( ) ) ) ;
257283 // Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
258284 // opaque types. This is needed for trivial things like `size_of`, but also for using associated
259285 // types that are not specified in the opaque type.
0 commit comments