@@ -298,90 +298,44 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
298298 tcx. def_span ( def. did ) ,
299299 key. param_env ,
300300 CompileTimeInterpreter :: new ( tcx. sess . const_eval_limit ( ) ) ,
301+ // Statics (and promoteds inside statics) may access other statics, because unlike consts
302+ // they do not have to behave "as if" they were evaluated at runtime.
301303 MemoryExtra { can_access_statics : is_static } ,
302304 ) ;
303305
304306 let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
305307 match res. and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, & body) ) {
306308 Err ( error) => {
307309 let err = ConstEvalErr :: new ( & ecx, error, None ) ;
308- // errors in statics are always emitted as fatal errors
309- if is_static {
310- // Ensure that if the above error was either `TooGeneric` or `Reported`
311- // an error must be reported.
312- let v = err. report_as_error (
313- ecx. tcx . at ( ecx. cur_span ( ) ) ,
314- "could not evaluate static initializer" ,
315- ) ;
316-
317- // If this is `Reveal:All`, then we need to make sure an error is reported but if
318- // this is `Reveal::UserFacing`, then it's expected that we could get a
319- // `TooGeneric` error. When we fall back to `Reveal::All`, then it will either
320- // succeed or we'll report this error then.
321- if key. param_env . reveal ( ) == Reveal :: All {
322- tcx. sess . delay_span_bug (
323- err. span ,
324- & format ! ( "static eval failure did not emit an error: {:#?}" , v) ,
325- ) ;
326- }
327-
328- Err ( v)
329- } else if let Some ( def) = def. as_local ( ) {
330- // constant defined in this crate, we can figure out a lint level!
331- match tcx. def_kind ( def. did . to_def_id ( ) ) {
332- // constants never produce a hard error at the definition site. Anything else is
333- // a backwards compatibility hazard (and will break old versions of winapi for
334- // sure)
335- //
336- // note that validation may still cause a hard error on this very same constant,
337- // because any code that existed before validation could not have failed
338- // validation thus preventing such a hard error from being a backwards
339- // compatibility hazard
340- DefKind :: Const | DefKind :: AssocConst => {
341- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) ;
342- Err ( err. report_as_lint (
343- tcx. at ( tcx. def_span ( def. did ) ) ,
344- "any use of this value will cause an error" ,
345- hir_id,
346- Some ( err. span ) ,
347- ) )
348- }
349- // promoting runtime code is only allowed to error if it references broken
350- // constants any other kind of error will be reported to the user as a
351- // deny-by-default lint
352- _ => {
353- if let Some ( p) = cid. promoted {
354- let span = tcx. promoted_mir_opt_const_arg ( def. to_global ( ) ) [ p] . span ;
355- if let err_inval ! ( ReferencedConstant ) = err. error {
356- Err ( err. report_as_error (
357- tcx. at ( span) ,
358- "evaluation of constant expression failed" ,
359- ) )
360- } else {
361- Err ( err. report_as_lint (
362- tcx. at ( span) ,
363- "reaching this expression at runtime will panic or abort" ,
364- tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) ,
365- Some ( err. span ) ,
366- ) )
367- }
368- // anything else (array lengths, enum initializers, constant patterns) are
369- // reported as hard errors
370- } else {
371- Err ( err. report_as_error (
372- ecx. tcx . at ( ecx. cur_span ( ) ) ,
373- "evaluation of constant value failed" ,
374- ) )
375- }
376- }
377- }
310+ // Some CTFE errors raise just a lint, not a hard error; see
311+ // <https://github.com/rust-lang/rust/issues/71800>.
312+ let emit_as_lint = if let Some ( def) = def. as_local ( ) {
313+ // (Associated) consts only emit a lint, since they might be unused.
314+ matches ! ( tcx. def_kind( def. did. to_def_id( ) ) , DefKind :: Const | DefKind :: AssocConst )
378315 } else {
379- // use of broken constant from other crate
380- Err ( err. report_as_error ( ecx. tcx . at ( ecx. cur_span ( ) ) , "could not evaluate constant" ) )
316+ // use of broken constant from other crate: always an error
317+ false
318+ } ;
319+ if emit_as_lint {
320+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def. as_local ( ) . unwrap ( ) . did ) ;
321+ Err ( err. report_as_lint (
322+ tcx. at ( tcx. def_span ( def. did ) ) ,
323+ "any use of this value will cause an error" ,
324+ hir_id,
325+ Some ( err. span ) ,
326+ ) )
327+ } else {
328+ let msg = if is_static {
329+ "could not evaluate static initializer"
330+ } else {
331+ "evaluation of constant value failed"
332+ } ;
333+ Err ( err. report_as_error ( ecx. tcx . at ( ecx. cur_span ( ) ) , msg) )
381334 }
382335 }
383336 Ok ( mplace) => {
384- // Since evaluation had no errors, valiate the resulting constant:
337+ // Since evaluation had no errors, validate the resulting constant.
338+ // This is a separate `try` block to provide more targeted error reporting.
385339 let validation = try {
386340 let mut ref_tracking = RefTracking :: new ( mplace) ;
387341 let mut inner = false ;
@@ -399,7 +353,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
399353 }
400354 } ;
401355 if let Err ( error) = validation {
402- // Validation failed, report an error
356+ // Validation failed, report an error. This is always a hard error.
403357 let err = ConstEvalErr :: new ( & ecx, error, None ) ;
404358 Err ( err. struct_error (
405359 ecx. tcx ,
0 commit comments