@@ -8,6 +8,7 @@ use rustc_middle::traits::Reveal;
8
8
use rustc_middle:: ty:: layout:: LayoutOf ;
9
9
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
10
10
use rustc_middle:: ty:: { self , TyCtxt } ;
11
+ use rustc_span:: def_id:: LocalDefId ;
11
12
use rustc_span:: Span ;
12
13
use rustc_target:: abi:: { self , Abi } ;
13
14
@@ -249,11 +250,36 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
249
250
tcx. eval_to_allocation_raw ( key) . map ( |val| turn_into_const_value ( tcx, val, key) )
250
251
}
251
252
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
+
252
275
#[ instrument( skip( tcx) , level = "debug" ) ]
253
276
pub fn eval_to_allocation_raw_provider < ' tcx > (
254
277
tcx : TyCtxt < ' tcx > ,
255
278
key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
256
279
) -> :: 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( ) ) ) ;
257
283
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
258
284
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
259
285
// types that are not specified in the opaque type.
0 commit comments