@@ -2,7 +2,6 @@ use either::{Left, Right};
2
2
3
3
use rustc_hir:: def:: DefKind ;
4
4
use rustc_middle:: mir:: interpret:: { AllocId , ErrorHandled , InterpErrorInfo } ;
5
- use rustc_middle:: mir:: pretty:: write_allocation_bytes;
6
5
use rustc_middle:: mir:: { self , ConstAlloc , ConstValue } ;
7
6
use rustc_middle:: traits:: Reveal ;
8
7
use rustc_middle:: ty:: layout:: LayoutOf ;
@@ -18,8 +17,9 @@ use crate::errors;
18
17
use crate :: errors:: ConstEvalError ;
19
18
use crate :: interpret:: eval_nullary_intrinsic;
20
19
use 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 ,
23
23
} ;
24
24
25
25
// Returns a pointer to where the result lives
@@ -47,7 +47,21 @@ fn eval_body_using_ecx<'mir, 'tcx>(
47
47
) ;
48
48
let layout = ecx. layout_of ( body. bound_return_ty ( ) . instantiate ( tcx, cid. instance . args ) ) ?;
49
49
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
+ } ;
51
65
52
66
trace ! (
53
67
"eval_body_using_ecx: pushing stack frame for global: {}{}" ,
@@ -67,14 +81,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
67
81
while ecx. step ( ) ? { }
68
82
69
83
// 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
- } ;
78
84
intern_const_alloc_recursive ( ecx, intern_kind, & ret) ?;
79
85
80
86
Ok ( ret)
@@ -259,16 +265,17 @@ pub fn eval_static_initializer_provider<'tcx>(
259
265
260
266
let instance = ty:: Instance :: mono ( tcx, def_id. to_def_id ( ) ) ;
261
267
let cid = rustc_middle:: mir:: interpret:: GlobalId { instance, promoted : None } ;
262
- let ecx = InterpCx :: new (
268
+ let mut ecx = InterpCx :: new (
263
269
tcx,
264
270
tcx. def_span ( def_id) ,
265
271
ty:: ParamEnv :: reveal_all ( ) ,
266
272
// Statics (and promoteds inside statics) may access other statics, because unlike consts
267
273
// they do not have to behave "as if" they were evaluated at runtime.
268
274
CompileTimeInterpreter :: new ( CanAccessMutGlobal :: Yes , CheckAlignment :: Error ) ,
269
275
) ;
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) ;
272
279
Ok ( alloc)
273
280
}
274
281
@@ -299,7 +306,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
299
306
let def = cid. instance . def . def_id ( ) ;
300
307
let is_static = tcx. is_static ( def) ;
301
308
302
- let ecx = InterpCx :: new (
309
+ let mut ecx = InterpCx :: new (
303
310
tcx,
304
311
tcx. def_span ( def) ,
305
312
key. param_env ,
@@ -309,19 +316,19 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
309
316
// so we have to reject reading mutable global memory.
310
317
CompileTimeInterpreter :: new ( CanAccessMutGlobal :: from ( is_static) , CheckAlignment :: Error ) ,
311
318
) ;
312
- eval_in_interpreter ( ecx, cid, is_static)
319
+ eval_in_interpreter ( & mut ecx, cid, is_static)
313
320
}
314
321
315
322
pub fn eval_in_interpreter < ' mir , ' tcx > (
316
- mut ecx : InterpCx < ' mir , ' tcx , CompileTimeInterpreter < ' mir , ' tcx > > ,
323
+ ecx : & mut InterpCx < ' mir , ' tcx , CompileTimeInterpreter < ' mir , ' tcx > > ,
317
324
cid : GlobalId < ' tcx > ,
318
325
is_static : bool ,
319
326
) -> :: rustc_middle:: mir:: interpret:: EvalToAllocationRawResult < ' tcx > {
320
327
// `is_static` just means "in static", it could still be a promoted!
321
328
debug_assert_eq ! ( is_static, ecx. tcx. static_mutability( cid. instance. def_id( ) ) . is_some( ) ) ;
322
329
323
330
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) ) {
325
332
Err ( error) => {
326
333
let ( error, backtrace) = error. into_parts ( ) ;
327
334
backtrace. print_backtrace ( ) ;
@@ -356,8 +363,11 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
356
363
}
357
364
Ok ( mplace) => {
358
365
// 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 ( ) ;
360
369
let validation = const_validate_mplace ( & ecx, & mplace, cid) ;
370
+ ecx. machine . static_root_alloc_id = static_root_alloc_id;
361
371
362
372
let alloc_id = mplace. ptr ( ) . provenance . unwrap ( ) . alloc_id ( ) ;
363
373
@@ -409,15 +419,9 @@ pub fn const_report_error<'mir, 'tcx>(
409
419
410
420
let ub_note = matches ! ( error, InterpError :: UndefinedBehavior ( _) ) . then ( || { } ) ;
411
421
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 } ;
421
425
422
426
crate :: const_eval:: report (
423
427
* ecx. tcx ,
0 commit comments