@@ -193,21 +193,7 @@ fn validate_and_turn_into_const<'tcx>(
193
193
let ecx = mk_eval_cx ( tcx, tcx. def_span ( key. value . instance . def_id ( ) ) , key. param_env , is_static) ;
194
194
let val = ( || {
195
195
let mplace = ecx. raw_const_to_mplace ( constant) ?;
196
-
197
- // FIXME do not validate promoteds until a decision on
198
- // https://github.com/rust-lang/rust/issues/67465 is made
199
- if cid. promoted . is_none ( ) {
200
- let mut ref_tracking = RefTracking :: new ( mplace) ;
201
- while let Some ( ( mplace, path) ) = ref_tracking. todo . pop ( ) {
202
- ecx. const_validate_operand (
203
- mplace. into ( ) ,
204
- path,
205
- & mut ref_tracking,
206
- /*may_ref_to_static*/ ecx. memory . extra . can_access_statics ,
207
- ) ?;
208
- }
209
- }
210
- // Now that we validated, turn this into a proper constant.
196
+ // Turn this into a proper constant.
211
197
// Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides
212
198
// whether they become immediates.
213
199
if is_static || cid. promoted . is_some ( ) {
@@ -221,6 +207,7 @@ fn validate_and_turn_into_const<'tcx>(
221
207
}
222
208
} ) ( ) ;
223
209
210
+ // FIXME: Can this ever be an error and not be a compiler bug or can we just ICE here?
224
211
val. map_err ( |error| {
225
212
let err = ConstEvalErr :: new ( & ecx, error, None ) ;
226
213
err. struct_error ( ecx. tcx , "it is undefined behavior to use this value" , |mut diag| {
@@ -319,7 +306,6 @@ pub fn const_eval_raw_provider<'tcx>(
319
306
320
307
let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
321
308
res. and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, & body) )
322
- . map ( |place| RawConst { alloc_id : place. ptr . assert_ptr ( ) . alloc_id , ty : place. layout . ty } )
323
309
. map_err ( |error| {
324
310
let err = ConstEvalErr :: new ( & ecx, error, None ) ;
325
311
// errors in statics are always emitted as fatal errors
@@ -397,4 +383,37 @@ pub fn const_eval_raw_provider<'tcx>(
397
383
err. report_as_error ( ecx. tcx . at ( ecx. cur_span ( ) ) , "could not evaluate constant" )
398
384
}
399
385
} )
386
+ . and_then ( |mplace| {
387
+ // Since evaluation had no errors, valiate the resulting constant:
388
+ let validation = try {
389
+ // FIXME do not validate promoteds until a decision on
390
+ // https://github.com/rust-lang/rust/issues/67465 is made
391
+ if cid. promoted . is_none ( ) {
392
+ let mut ref_tracking = RefTracking :: new ( mplace) ;
393
+ while let Some ( ( mplace, path) ) = ref_tracking. todo . pop ( ) {
394
+ ecx. const_validate_operand (
395
+ mplace. into ( ) ,
396
+ path,
397
+ & mut ref_tracking,
398
+ /*may_ref_to_static*/ ecx. memory . extra . can_access_statics ,
399
+ ) ?;
400
+ }
401
+ }
402
+ } ;
403
+ if let Err ( error) = validation {
404
+ // Validation failed, report an error
405
+ let err = ConstEvalErr :: new ( & ecx, error, None ) ;
406
+ Err ( err. struct_error (
407
+ ecx. tcx ,
408
+ "it is undefined behavior to use this value" ,
409
+ |mut diag| {
410
+ diag. note ( note_on_undefined_behavior_error ( ) ) ;
411
+ diag. emit ( ) ;
412
+ } ,
413
+ ) )
414
+ } else {
415
+ // Convert to raw constant
416
+ Ok ( RawConst { alloc_id : mplace. ptr . assert_ptr ( ) . alloc_id , ty : mplace. layout . ty } )
417
+ }
418
+ } )
400
419
}
0 commit comments