@@ -193,21 +193,7 @@ fn validate_and_turn_into_const<'tcx>(
193193 let ecx = mk_eval_cx ( tcx, tcx. def_span ( key. value . instance . def_id ( ) ) , key. param_env , is_static) ;
194194 let val = ( || {
195195 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.
211197 // Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides
212198 // whether they become immediates.
213199 if is_static || cid. promoted . is_some ( ) {
@@ -221,6 +207,7 @@ fn validate_and_turn_into_const<'tcx>(
221207 }
222208 } ) ( ) ;
223209
210+ // FIXME: Can this ever be an error and not be a compiler bug or can we just ICE here?
224211 val. map_err ( |error| {
225212 let err = ConstEvalErr :: new ( & ecx, error, None ) ;
226213 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>(
319306
320307 let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
321308 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 } )
323309 . map_err ( |error| {
324310 let err = ConstEvalErr :: new ( & ecx, error, None ) ;
325311 // errors in statics are always emitted as fatal errors
@@ -397,4 +383,37 @@ pub fn const_eval_raw_provider<'tcx>(
397383 err. report_as_error ( ecx. tcx . at ( ecx. cur_span ( ) ) , "could not evaluate constant" )
398384 }
399385 } )
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+ } )
400419}
0 commit comments