diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index beff84fb2e2..5702832bcb6 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -134,11 +134,9 @@ pub(crate) fn codegen_constant<'tcx>( { Ok(const_val) => const_val, Err(_) => { - if promoted.is_none() { - fx.tcx - .sess - .span_err(constant.span, "erroneous constant encountered"); - } + fx.tcx + .sess + .span_err(constant.span, "erroneous constant encountered"); return crate::trap::trap_unreachable_ret_value( fx, fx.layout_of(const_.ty), diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 3a85c268e0e..b79a221a0e7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -30,12 +30,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None) .map_err(|err| { - if promoted.is_none() { - self.cx - .tcx() - .sess - .span_err(constant.span, "erroneous constant encountered"); - } + self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); err }), ty::ConstKind::Value(value) => Ok(value), diff --git a/compiler/rustc_mir/src/const_eval/eval_queries.rs b/compiler/rustc_mir/src/const_eval/eval_queries.rs index df163f65628..252f5e7ef2f 100644 --- a/compiler/rustc_mir/src/const_eval/eval_queries.rs +++ b/compiler/rustc_mir/src/const_eval/eval_queries.rs @@ -298,6 +298,8 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx.def_span(def.did), key.param_env, CompileTimeInterpreter::new(tcx.sess.const_eval_limit()), + // Statics (and promoteds inside statics) may access other statics, because unlike consts + // they do not have to behave "as if" they were evaluated at runtime. MemoryExtra { can_access_statics: is_static }, ); @@ -305,83 +307,35 @@ pub fn eval_to_allocation_raw_provider<'tcx>( match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body)) { Err(error) => { let err = ConstEvalErr::new(&ecx, error, None); - // errors in statics are always emitted as fatal errors - if is_static { - // Ensure that if the above error was either `TooGeneric` or `Reported` - // an error must be reported. - let v = err.report_as_error( - ecx.tcx.at(ecx.cur_span()), - "could not evaluate static initializer", - ); - - // If this is `Reveal:All`, then we need to make sure an error is reported but if - // this is `Reveal::UserFacing`, then it's expected that we could get a - // `TooGeneric` error. When we fall back to `Reveal::All`, then it will either - // succeed or we'll report this error then. - if key.param_env.reveal() == Reveal::All { - tcx.sess.delay_span_bug( - err.span, - &format!("static eval failure did not emit an error: {:#?}", v), - ); - } - - Err(v) - } else if let Some(def) = def.as_local() { - // constant defined in this crate, we can figure out a lint level! - match tcx.def_kind(def.did.to_def_id()) { - // constants never produce a hard error at the definition site. Anything else is - // a backwards compatibility hazard (and will break old versions of winapi for - // sure) - // - // note that validation may still cause a hard error on this very same constant, - // because any code that existed before validation could not have failed - // validation thus preventing such a hard error from being a backwards - // compatibility hazard - DefKind::Const | DefKind::AssocConst => { - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - Err(err.report_as_lint( - tcx.at(tcx.def_span(def.did)), - "any use of this value will cause an error", - hir_id, - Some(err.span), - )) - } - // promoting runtime code is only allowed to error if it references broken - // constants any other kind of error will be reported to the user as a - // deny-by-default lint - _ => { - if let Some(p) = cid.promoted { - let span = tcx.promoted_mir_opt_const_arg(def.to_global())[p].span; - if let err_inval!(ReferencedConstant) = err.error { - Err(err.report_as_error( - tcx.at(span), - "evaluation of constant expression failed", - )) - } else { - Err(err.report_as_lint( - tcx.at(span), - "reaching this expression at runtime will panic or abort", - tcx.hir().local_def_id_to_hir_id(def.did), - Some(err.span), - )) - } - // anything else (array lengths, enum initializers, constant patterns) are - // reported as hard errors - } else { - Err(err.report_as_error( - ecx.tcx.at(ecx.cur_span()), - "evaluation of constant value failed", - )) - } - } - } + // Some CTFE errors raise just a lint, not a hard error; see + // . + let emit_as_lint = if let Some(def) = def.as_local() { + // (Associated) consts only emit a lint, since they might be unused. + matches!(tcx.def_kind(def.did.to_def_id()), DefKind::Const | DefKind::AssocConst) } else { - // use of broken constant from other crate - Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), "could not evaluate constant")) + // use of broken constant from other crate: always an error + false + }; + if emit_as_lint { + let hir_id = tcx.hir().local_def_id_to_hir_id(def.as_local().unwrap().did); + Err(err.report_as_lint( + tcx.at(tcx.def_span(def.did)), + "any use of this value will cause an error", + hir_id, + Some(err.span), + )) + } else { + let msg = if is_static { + "could not evaluate static initializer" + } else { + "evaluation of constant value failed" + }; + Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), msg)) } } Ok(mplace) => { - // Since evaluation had no errors, valiate the resulting constant: + // Since evaluation had no errors, validate the resulting constant. + // This is a separate `try` block to provide more targeted error reporting. let validation = try { let mut ref_tracking = RefTracking::new(mplace); let mut inner = false; @@ -399,7 +353,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>( } }; if let Err(error) = validation { - // Validation failed, report an error + // Validation failed, report an error. This is always a hard error. let err = ConstEvalErr::new(&ecx, error, None); Err(err.struct_error( ecx.tcx, diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs index d7a48cbd63e..b0a4c7722e3 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs @@ -31,7 +31,7 @@ impl Tr for u32 { fn main() { assert_eq!(<() as Tr>::A, 255); assert_eq!(<() as Tr>::B, 0); // causes the error above - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed //~| ERROR erroneous constant used assert_eq!(::A, 254); diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr index 1497633c26a..cbaaed0508b 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -8,15 +8,11 @@ LL | const B: u8 = Self::A + 1; | = note: `#[deny(const_err)]` on by default -error[E0080]: evaluation of constant expression failed - --> $DIR/defaults-not-assumed-fail.rs:33:5 +error[E0080]: evaluation of constant value failed + --> $DIR/defaults-not-assumed-fail.rs:33:16 | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above - | ^^^^^^^^^^^-------------^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^^^^^^^^^^^ referenced constant has errors error: erroneous constant used --> $DIR/defaults-not-assumed-fail.rs:33:5 diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index 65dfbd8097e..c2adff116ef 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(const_err)] | ^^^^^^^^^ -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/conditional_array_execution.rs:11:20 | LL | println!("{}", FOO); diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.rs b/src/test/ui/consts/const-eval/const-eval-query-stack.rs index 39803c8f257..cbfeca24026 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.rs +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.rs @@ -21,6 +21,6 @@ const X: i32 = 1 / 0; //~WARN any use of this value will cause an error fn main() { let x: &'static i32 = &X; - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed println!("x={}", x); } diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 0016d301e59..3e727b84aed 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -12,13 +12,11 @@ note: the lint level is defined here LL | #[warn(const_err)] | ^^^^^^^^^ -error[E0080]: evaluation of constant expression failed - --> $DIR/const-eval-query-stack.rs:23:27 +error[E0080]: evaluation of constant value failed + --> $DIR/const-eval-query-stack.rs:23:28 | LL | let x: &'static i32 = &X; - | ^- - | | - | referenced constant has errors + | ^ referenced constant has errors query stack during panic: #0 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]` #1 [optimized_mir] optimizing MIR for `main` diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs index f67871e6142..0a2532973f4 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -18,7 +18,7 @@ const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday fn main() { assert_eq!(Y, 4); - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed assert_eq!(Z, 4); - //~^ ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index 822d4af8306..2afedf30563 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -1,22 +1,14 @@ -error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:20:5 +error[E0080]: evaluation of constant value failed + --> $DIR/const_fn_ptr_fail2.rs:20:16 | LL | assert_eq!(Y, 4); - | ^^^^^^^^^^^-^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^ referenced constant has errors -error[E0080]: evaluation of constant expression failed - --> $DIR/const_fn_ptr_fail2.rs:22:5 +error[E0080]: evaluation of constant value failed + --> $DIR/const_fn_ptr_fail2.rs:22:16 | LL | assert_eq!(Z, 4); - | ^^^^^^^^^^^-^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^ referenced constant has errors warning: skipping const checks | diff --git a/src/test/ui/consts/const-eval/issue-43197.rs b/src/test/ui/consts/const-eval/issue-43197.rs index 9109307632b..7d1d33288a9 100644 --- a/src/test/ui/consts/const-eval/issue-43197.rs +++ b/src/test/ui/consts/const-eval/issue-43197.rs @@ -12,8 +12,8 @@ fn main() { const Y: u32 = foo(0 - 1); //~^ WARN any use of this value will cause println!("{} {}", X, Y); - //~^ ERROR evaluation of constant expression failed - //~| ERROR evaluation of constant expression failed + //~^ ERROR evaluation of constant value failed + //~| ERROR evaluation of constant value failed //~| WARN erroneous constant used [const_err] //~| WARN erroneous constant used [const_err] } diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index 27e067cedbb..8c72b591416 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -20,7 +20,7 @@ LL | const Y: u32 = foo(0 - 1); | | | attempt to compute `0_u32 - 1_u32`, which would overflow -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/issue-43197.rs:14:23 | LL | println!("{} {}", X, Y); @@ -32,7 +32,7 @@ warning: erroneous constant used LL | println!("{} {}", X, Y); | ^ referenced constant has errors -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/issue-43197.rs:14:26 | LL | println!("{} {}", X, Y); diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs index f9194709dc0..79f1301a2f9 100644 --- a/src/test/ui/consts/const-eval/issue-44578.rs +++ b/src/test/ui/consts/const-eval/issue-44578.rs @@ -25,5 +25,5 @@ impl Foo for u16 { fn main() { println!("{}", as Foo>::AMT); - //~^ ERROR evaluation of constant expression failed [E0080] + //~^ ERROR evaluation of constant value failed [E0080] } diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index f4323713e68..bff9f40f82b 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -1,4 +1,4 @@ -error[E0080]: evaluation of constant expression failed +error[E0080]: evaluation of constant value failed --> $DIR/issue-44578.rs:27:20 | LL | println!("{}", as Foo>::AMT); diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index ca8885e9350..f929f500cf9 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -8,13 +8,11 @@ LL | const BAR: usize = [5, 6, 7][T::BOO]; | = note: `#[deny(const_err)]` on by default -error[E0080]: evaluation of constant expression failed - --> $DIR/issue-50814-2.rs:18:5 +error[E0080]: evaluation of constant value failed + --> $DIR/issue-50814-2.rs:18:6 | LL | & as Foo>::BAR - | ^--------------------- - | | - | referenced constant has errors + | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index 73271386276..307fb3c8c9d 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -8,13 +8,11 @@ LL | const MAX: u8 = A::MAX + B::MAX; | = note: `#[deny(const_err)]` on by default -error[E0080]: evaluation of constant expression failed - --> $DIR/issue-50814.rs:20:5 +error[E0080]: evaluation of constant value failed + --> $DIR/issue-50814.rs:20:6 | LL | &Sum::::MAX - | ^----------------- - | | - | referenced constant has errors + | ^^^^^^^^^^^^^^^^^ referenced constant has errors error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr index 31090be0908..6dddc7ff6e9 100644 --- a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr +++ b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr @@ -20,15 +20,11 @@ note: the lint level is defined here LL | #[warn(const_err)] | ^^^^^^^^^ -error[E0080]: evaluation of constant expression failed - --> $DIR/const_unsafe_unreachable_ub.rs:17:3 +error[E0080]: evaluation of constant value failed + --> $DIR/const_unsafe_unreachable_ub.rs:17:14 | LL | assert_eq!(BAR, true); - | ^^^^^^^^^^^---^^^^^^^^ - | | - | referenced constant has errors - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^ referenced constant has errors error: erroneous constant used --> $DIR/const_unsafe_unreachable_ub.rs:17:3 diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index 924910e9cb6..ede5487b65d 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -2,15 +2,12 @@ error[E0080]: values of the type `[u8; SIZE]` are too big for the current archit --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL - | inside `main` at $DIR/issue-55878.rs:7:26 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL | ::: $DIR/issue-55878.rs:7:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); - | ---------------------------------------------- + | ---------------------------------------------- inside `main` at $DIR/issue-55878.rs:7:26 error: erroneous constant used --> $DIR/issue-55878.rs:7:26