Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clean up some const error reporting around promoteds #81333

Merged
merged 1 commit into from
Jan 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
102 changes: 28 additions & 74 deletions compiler/rustc_mir/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,90 +298,44 @@ 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 },
);

let res = ecx.load_mir(cid.instance.def, cid.promoted);
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
// <https://github.com/rust-lang/rust/issues/71800>.
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;
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/associated-consts/defaults-not-assumed-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(<u8 as Tr>::A, 254);
Expand Down
10 changes: 3 additions & 7 deletions src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/const-eval-query-stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
8 changes: 3 additions & 5 deletions src/test/ui/consts/const-eval/const-eval-query-stack.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
20 changes: 6 additions & 14 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
Original file line number Diff line number Diff line change
@@ -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);
| ^^^^^^^^^^^-^^^^^
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
| |
| 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
|
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/issue-43197.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/issue-43197.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/issue-44578.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ impl Foo for u16 {

fn main() {
println!("{}", <Bar<u16, u8> as Foo>::AMT);
//~^ ERROR evaluation of constant expression failed [E0080]
//~^ ERROR evaluation of constant value failed [E0080]
}
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/issue-44578.stderr
Original file line number Diff line number Diff line change
@@ -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!("{}", <Bar<u16, u8> as Foo>::AMT);
Expand Down
8 changes: 3 additions & 5 deletions src/test/ui/consts/const-eval/issue-50814-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 | &<A<T> as Foo<T>>::BAR
| ^---------------------
| |
| referenced constant has errors
| ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors

error: aborting due to 2 previous errors

Expand Down
8 changes: 3 additions & 5 deletions src/test/ui/consts/const-eval/issue-50814.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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::<U8,U8>::MAX
| ^-----------------
| |
| referenced constant has errors
| ^^^^^^^^^^^^^^^^^ referenced constant has errors

error: aborting due to 2 previous errors

Expand Down
10 changes: 3 additions & 7 deletions src/test/ui/consts/const_unsafe_unreachable_ub.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 2 additions & 5 deletions src/test/ui/consts/issue-55878.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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::<T>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| 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
Expand Down