@@ -2,7 +2,6 @@ use either::{Left, Right};
22
33use rustc_hir:: def:: DefKind ;
44use rustc_middle:: mir:: interpret:: { AllocId , ErrorHandled , InterpErrorInfo } ;
5- use rustc_middle:: mir:: pretty:: write_allocation_bytes;
65use rustc_middle:: mir:: { self , ConstAlloc , ConstValue } ;
76use rustc_middle:: traits:: Reveal ;
87use rustc_middle:: ty:: layout:: LayoutOf ;
@@ -18,8 +17,9 @@ use crate::errors;
1817use crate :: errors:: ConstEvalError ;
1918use crate :: interpret:: eval_nullary_intrinsic;
2019use crate :: interpret:: {
21- intern_const_alloc_recursive, CtfeValidationMode , GlobalId , Immediate , InternKind , InterpCx ,
22- InterpError , InterpResult , MPlaceTy , MemoryKind , OpTy , RefTracking , StackPopCleanup ,
20+ create_static_alloc, intern_const_alloc_recursive, take_static_root_alloc, CtfeValidationMode ,
21+ GlobalId , Immediate , InternKind , InterpCx , InterpError , InterpResult , MPlaceTy , MemoryKind ,
22+ OpTy , RefTracking , StackPopCleanup ,
2323} ;
2424
2525// Returns a pointer to where the result lives
@@ -47,7 +47,21 @@ fn eval_body_using_ecx<'mir, 'tcx>(
4747 ) ;
4848 let layout = ecx. layout_of ( body. bound_return_ty ( ) . instantiate ( tcx, cid. instance . args ) ) ?;
4949 assert ! ( layout. is_sized( ) ) ;
50- let ret = ecx. allocate ( layout, MemoryKind :: Stack ) ?;
50+
51+ let intern_kind = if cid. promoted . is_some ( ) {
52+ InternKind :: Promoted
53+ } else {
54+ match tcx. static_mutability ( cid. instance . def_id ( ) ) {
55+ Some ( m) => InternKind :: Static ( m) ,
56+ None => InternKind :: Constant ,
57+ }
58+ } ;
59+
60+ let ret = if let InternKind :: Static ( _) = intern_kind {
61+ create_static_alloc ( ecx, cid. instance . def_id ( ) , layout) ?
62+ } else {
63+ ecx. allocate ( layout, MemoryKind :: Stack ) ?
64+ } ;
5165
5266 trace ! (
5367 "eval_body_using_ecx: pushing stack frame for global: {}{}" ,
@@ -67,14 +81,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
6781 while ecx. step ( ) ? { }
6882
6983 // Intern the result
70- let intern_kind = if cid. promoted . is_some ( ) {
71- InternKind :: Promoted
72- } else {
73- match tcx. static_mutability ( cid. instance . def_id ( ) ) {
74- Some ( m) => InternKind :: Static ( m) ,
75- None => InternKind :: Constant ,
76- }
77- } ;
7884 intern_const_alloc_recursive ( ecx, intern_kind, & ret) ?;
7985
8086 Ok ( ret)
@@ -259,16 +265,17 @@ pub fn eval_static_initializer_provider<'tcx>(
259265
260266 let instance = ty:: Instance :: mono ( tcx, def_id. to_def_id ( ) ) ;
261267 let cid = rustc_middle:: mir:: interpret:: GlobalId { instance, promoted : None } ;
262- let ecx = InterpCx :: new (
268+ let mut ecx = InterpCx :: new (
263269 tcx,
264270 tcx. def_span ( def_id) ,
265271 ty:: ParamEnv :: reveal_all ( ) ,
266272 // Statics (and promoteds inside statics) may access other statics, because unlike consts
267273 // they do not have to behave "as if" they were evaluated at runtime.
268274 CompileTimeInterpreter :: new ( CanAccessMutGlobal :: Yes , CheckAlignment :: Error ) ,
269275 ) ;
270- let alloc_id = eval_in_interpreter ( ecx, cid, true ) ?. alloc_id ;
271- let alloc = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
276+ let alloc_id = eval_in_interpreter ( & mut ecx, cid, true ) ?. alloc_id ;
277+ let alloc = take_static_root_alloc ( & mut ecx, alloc_id) ;
278+ let alloc = tcx. mk_const_alloc ( alloc) ;
272279 Ok ( alloc)
273280}
274281
@@ -299,7 +306,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
299306 let def = cid. instance . def . def_id ( ) ;
300307 let is_static = tcx. is_static ( def) ;
301308
302- let ecx = InterpCx :: new (
309+ let mut ecx = InterpCx :: new (
303310 tcx,
304311 tcx. def_span ( def) ,
305312 key. param_env ,
@@ -309,19 +316,19 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
309316 // so we have to reject reading mutable global memory.
310317 CompileTimeInterpreter :: new ( CanAccessMutGlobal :: from ( is_static) , CheckAlignment :: Error ) ,
311318 ) ;
312- eval_in_interpreter ( ecx, cid, is_static)
319+ eval_in_interpreter ( & mut ecx, cid, is_static)
313320}
314321
315322pub fn eval_in_interpreter < ' mir , ' tcx > (
316- mut ecx : InterpCx < ' mir , ' tcx , CompileTimeInterpreter < ' mir , ' tcx > > ,
323+ ecx : & mut InterpCx < ' mir , ' tcx , CompileTimeInterpreter < ' mir , ' tcx > > ,
317324 cid : GlobalId < ' tcx > ,
318325 is_static : bool ,
319326) -> :: rustc_middle:: mir:: interpret:: EvalToAllocationRawResult < ' tcx > {
320327 // `is_static` just means "in static", it could still be a promoted!
321328 debug_assert_eq ! ( is_static, ecx. tcx. static_mutability( cid. instance. def_id( ) ) . is_some( ) ) ;
322329
323330 let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
324- match res. and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, body) ) {
331+ match res. and_then ( |body| eval_body_using_ecx ( ecx, cid, body) ) {
325332 Err ( error) => {
326333 let ( error, backtrace) = error. into_parts ( ) ;
327334 backtrace. print_backtrace ( ) ;
@@ -356,8 +363,11 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
356363 }
357364 Ok ( mplace) => {
358365 // Since evaluation had no errors, validate the resulting constant.
359- // This is a separate `try` block to provide more targeted error reporting.
366+
367+ // Temporarily allow access to the static_root_alloc_id for the purpose of validation.
368+ let static_root_alloc_id = ecx. machine . static_root_alloc_id . take ( ) ;
360369 let validation = const_validate_mplace ( & ecx, & mplace, cid) ;
370+ ecx. machine . static_root_alloc_id = static_root_alloc_id;
361371
362372 let alloc_id = mplace. ptr ( ) . provenance . unwrap ( ) . alloc_id ( ) ;
363373
@@ -409,15 +419,9 @@ pub fn const_report_error<'mir, 'tcx>(
409419
410420 let ub_note = matches ! ( error, InterpError :: UndefinedBehavior ( _) ) . then ( || { } ) ;
411421
412- let alloc = ecx. tcx . global_alloc ( alloc_id) . unwrap_memory ( ) . inner ( ) ;
413- let mut bytes = String :: new ( ) ;
414- if alloc. size ( ) != abi:: Size :: ZERO {
415- bytes = "\n " . into ( ) ;
416- // FIXME(translation) there might be pieces that are translatable.
417- write_allocation_bytes ( * ecx. tcx , alloc, & mut bytes, " " ) . unwrap ( ) ;
418- }
419- let raw_bytes =
420- errors:: RawBytesNote { size : alloc. size ( ) . bytes ( ) , align : alloc. align . bytes ( ) , bytes } ;
422+ let bytes = ecx. print_alloc_bytes_for_diagnostics ( alloc_id) ;
423+ let ( size, align, _) = ecx. get_alloc_info ( alloc_id) ;
424+ let raw_bytes = errors:: RawBytesNote { size : size. bytes ( ) , align : align. bytes ( ) , bytes } ;
421425
422426 crate :: const_eval:: report (
423427 * ecx. tcx ,
0 commit comments