@@ -3,8 +3,7 @@ use std::mem;
3
3
use either:: { Left , Right } ;
4
4
5
5
use rustc_hir:: def:: DefKind ;
6
- use rustc_middle:: mir:: interpret:: { ErrorHandled , InterpErrorInfo } ;
7
- use rustc_middle:: mir:: pretty:: write_allocation_bytes;
6
+ use rustc_middle:: mir:: interpret:: ErrorHandled ;
8
7
use rustc_middle:: mir:: { self , ConstAlloc , ConstValue } ;
9
8
use rustc_middle:: traits:: Reveal ;
10
9
use rustc_middle:: ty:: layout:: LayoutOf ;
@@ -19,8 +18,8 @@ use crate::errors;
19
18
use crate :: errors:: ConstEvalError ;
20
19
use crate :: interpret:: eval_nullary_intrinsic;
21
20
use crate :: interpret:: {
22
- intern_const_alloc_recursive, CtfeValidationMode , GlobalId , Immediate , InternKind , InterpCx ,
23
- InterpError , InterpResult , MPlaceTy , MemoryKind , OpTy , RefTracking , StackPopCleanup ,
21
+ intern_const_alloc_recursive, GlobalId , Immediate , InternKind , InterpCx , InterpResult ,
22
+ MPlaceTy , MemoryKind , OpTy , StackPopCleanup ,
24
23
} ;
25
24
26
25
// Returns a pointer to where the result lives
@@ -285,15 +284,22 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
285
284
let def = cid. instance . def . def_id ( ) ;
286
285
let is_static = tcx. is_static ( def) ;
287
286
288
- let mut ecx = InterpCx :: new (
287
+ let ecx = InterpCx :: new (
289
288
tcx,
290
289
tcx. def_span ( def) ,
291
290
key. param_env ,
292
291
// Statics (and promoteds inside statics) may access other statics, because unlike consts
293
292
// they do not have to behave "as if" they were evaluated at runtime.
294
293
CompileTimeInterpreter :: new ( CanAccessStatics :: from ( is_static) , CheckAlignment :: Error ) ,
295
294
) ;
295
+ eval_in_interpreter ( ecx, cid, is_static)
296
+ }
296
297
298
+ pub fn eval_in_interpreter < ' mir , ' tcx > (
299
+ mut ecx : InterpCx < ' mir , ' tcx , CompileTimeInterpreter < ' mir , ' tcx > > ,
300
+ cid : GlobalId < ' tcx > ,
301
+ is_static : bool ,
302
+ ) -> :: rustc_middle:: mir:: interpret:: EvalToAllocationRawResult < ' tcx > {
297
303
let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
298
304
match res. and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, & body) ) {
299
305
Err ( error) => {
@@ -306,7 +312,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
306
312
// If the current item has generics, we'd like to enrich the message with the
307
313
// instance and its args: to show the actual compile-time values, in addition to
308
314
// the expression, leading to the const eval error.
309
- let instance = & key . value . instance ;
315
+ let instance = & cid . instance ;
310
316
if !instance. args . is_empty ( ) {
311
317
let instance = with_no_trimmed_paths ! ( instance. to_string( ) ) ;
312
318
( "const_with_path" , instance)
@@ -331,60 +337,15 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
331
337
Ok ( mplace) => {
332
338
// Since evaluation had no errors, validate the resulting constant.
333
339
// This is a separate `try` block to provide more targeted error reporting.
334
- let validation: Result < _ , InterpErrorInfo < ' _ > > = try {
335
- let mut ref_tracking = RefTracking :: new ( mplace. clone ( ) ) ;
336
- let mut inner = false ;
337
- while let Some ( ( mplace, path) ) = ref_tracking. todo . pop ( ) {
338
- let mode = match tcx. static_mutability ( cid. instance . def_id ( ) ) {
339
- Some ( _) if cid. promoted . is_some ( ) => {
340
- // Promoteds in statics are allowed to point to statics.
341
- CtfeValidationMode :: Const { inner, allow_static_ptrs : true }
342
- }
343
- Some ( _) => CtfeValidationMode :: Regular , // a `static`
344
- None => CtfeValidationMode :: Const { inner, allow_static_ptrs : false } ,
345
- } ;
346
- ecx. const_validate_operand ( & mplace. into ( ) , path, & mut ref_tracking, mode) ?;
347
- inner = true ;
348
- }
349
- } ;
350
- let alloc_id = mplace. ptr ( ) . provenance . unwrap ( ) ;
340
+ let validation = ecx. const_validate_mplace ( & mplace, is_static, cid. promoted . is_some ( ) ) ;
351
341
352
- // Validation failed, report an error.
353
- if let Err ( error) = validation {
354
- let ( error, backtrace) = error. into_parts ( ) ;
355
- backtrace. print_backtrace ( ) ;
356
-
357
- let ub_note = matches ! ( error, InterpError :: UndefinedBehavior ( _) ) . then ( || { } ) ;
358
-
359
- let alloc = ecx. tcx . global_alloc ( alloc_id) . unwrap_memory ( ) . inner ( ) ;
360
- let mut bytes = String :: new ( ) ;
361
- if alloc. size ( ) != abi:: Size :: ZERO {
362
- bytes = "\n " . into ( ) ;
363
- // FIXME(translation) there might be pieces that are translatable.
364
- write_allocation_bytes ( * ecx. tcx , alloc, & mut bytes, " " ) . unwrap ( ) ;
365
- }
366
- let raw_bytes = errors:: RawBytesNote {
367
- size : alloc. size ( ) . bytes ( ) ,
368
- align : alloc. align . bytes ( ) ,
369
- bytes,
370
- } ;
342
+ let alloc_id = mplace. ptr ( ) . provenance . unwrap ( ) ;
371
343
372
- Err ( super :: report (
373
- * ecx. tcx ,
374
- error,
375
- None ,
376
- || super :: get_span_and_frames ( & ecx) ,
377
- move |span, frames| errors:: UndefinedBehavior {
378
- span,
379
- ub_note,
380
- frames,
381
- raw_bytes,
382
- } ,
383
- ) )
384
- } else {
344
+ validation
345
+ // Validation failed, report an error.
346
+ . map_err ( |error| ecx. const_report_error ( error, alloc_id) )
385
347
// Convert to raw constant
386
- Ok ( ConstAlloc { alloc_id, ty : mplace. layout . ty } )
387
- }
348
+ . map ( |( ) | ConstAlloc { alloc_id, ty : mplace. layout . ty } )
388
349
}
389
350
}
390
351
}
0 commit comments