@@ -298,90 +298,44 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
298
298
tcx. def_span ( def. did ) ,
299
299
key. param_env ,
300
300
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.
301
303
MemoryExtra { can_access_statics : is_static } ,
302
304
) ;
303
305
304
306
let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
305
307
match res. and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, & body) ) {
306
308
Err ( error) => {
307
309
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 )
378
315
} 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) )
381
334
}
382
335
}
383
336
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.
385
339
let validation = try {
386
340
let mut ref_tracking = RefTracking :: new ( mplace) ;
387
341
let mut inner = false ;
@@ -399,7 +353,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
399
353
}
400
354
} ;
401
355
if let Err ( error) = validation {
402
- // Validation failed, report an error
356
+ // Validation failed, report an error. This is always a hard error.
403
357
let err = ConstEvalErr :: new ( & ecx, error, None ) ;
404
358
Err ( err. struct_error (
405
359
ecx. tcx ,
0 commit comments