Skip to content

Commit 48f9dbf

Browse files
committed
clean up some const error reporting around promoteds
1 parent 4d0dd02 commit 48f9dbf

18 files changed

+66
-144
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,9 @@ pub(crate) fn codegen_constant<'tcx>(
134134
{
135135
Ok(const_val) => const_val,
136136
Err(_) => {
137-
if promoted.is_none() {
138-
fx.tcx
139-
.sess
140-
.span_err(constant.span, "erroneous constant encountered");
141-
}
137+
fx.tcx
138+
.sess
139+
.span_err(constant.span, "erroneous constant encountered");
142140
return crate::trap::trap_unreachable_ret_value(
143141
fx,
144142
fx.layout_of(const_.ty),

compiler/rustc_codegen_ssa/src/mir/constant.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
3030
.tcx()
3131
.const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None)
3232
.map_err(|err| {
33-
if promoted.is_none() {
34-
self.cx
35-
.tcx()
36-
.sess
37-
.span_err(constant.span, "erroneous constant encountered");
38-
}
33+
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
3934
err
4035
}),
4136
ty::ConstKind::Value(value) => Ok(value),

compiler/rustc_mir/src/const_eval/eval_queries.rs

+28-74
Original file line numberDiff line numberDiff line change
@@ -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,

src/test/ui/associated-consts/defaults-not-assumed-fail.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl Tr for u32 {
3131
fn main() {
3232
assert_eq!(<() as Tr>::A, 255);
3333
assert_eq!(<() as Tr>::B, 0); // causes the error above
34-
//~^ ERROR evaluation of constant expression failed
34+
//~^ ERROR evaluation of constant value failed
3535
//~| ERROR erroneous constant used
3636

3737
assert_eq!(<u8 as Tr>::A, 254);

src/test/ui/associated-consts/defaults-not-assumed-fail.stderr

+3-7
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,11 @@ LL | const B: u8 = Self::A + 1;
88
|
99
= note: `#[deny(const_err)]` on by default
1010

11-
error[E0080]: evaluation of constant expression failed
12-
--> $DIR/defaults-not-assumed-fail.rs:33:5
11+
error[E0080]: evaluation of constant value failed
12+
--> $DIR/defaults-not-assumed-fail.rs:33:16
1313
|
1414
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
15-
| ^^^^^^^^^^^-------------^^^^^
16-
| |
17-
| referenced constant has errors
18-
|
19-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
15+
| ^^^^^^^^^^^^^ referenced constant has errors
2016

2117
error: erroneous constant used
2218
--> $DIR/defaults-not-assumed-fail.rs:33:5

src/test/ui/consts/const-eval/conditional_array_execution.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: the lint level is defined here
1212
LL | #![warn(const_err)]
1313
| ^^^^^^^^^
1414

15-
error[E0080]: evaluation of constant expression failed
15+
error[E0080]: evaluation of constant value failed
1616
--> $DIR/conditional_array_execution.rs:11:20
1717
|
1818
LL | println!("{}", FOO);

src/test/ui/consts/const-eval/const-eval-query-stack.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ const X: i32 = 1 / 0; //~WARN any use of this value will cause an error
2121

2222
fn main() {
2323
let x: &'static i32 = &X;
24-
//~^ ERROR evaluation of constant expression failed
24+
//~^ ERROR evaluation of constant value failed
2525
println!("x={}", x);
2626
}

src/test/ui/consts/const-eval/const-eval-query-stack.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ note: the lint level is defined here
1212
LL | #[warn(const_err)]
1313
| ^^^^^^^^^
1414

15-
error[E0080]: evaluation of constant expression failed
16-
--> $DIR/const-eval-query-stack.rs:23:27
15+
error[E0080]: evaluation of constant value failed
16+
--> $DIR/const-eval-query-stack.rs:23:28
1717
|
1818
LL | let x: &'static i32 = &X;
19-
| ^-
20-
| |
21-
| referenced constant has errors
19+
| ^ referenced constant has errors
2220
query stack during panic:
2321
#0 [normalize_generic_arg_after_erasing_regions] normalizing `main::promoted[1]`
2422
#1 [optimized_mir] optimizing MIR for `main`

src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
1818

1919
fn main() {
2020
assert_eq!(Y, 4);
21-
//~^ ERROR evaluation of constant expression failed
21+
//~^ ERROR evaluation of constant value failed
2222
assert_eq!(Z, 4);
23-
//~^ ERROR evaluation of constant expression failed
23+
//~^ ERROR evaluation of constant value failed
2424
}

src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
error[E0080]: evaluation of constant expression failed
2-
--> $DIR/const_fn_ptr_fail2.rs:20:5
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/const_fn_ptr_fail2.rs:20:16
33
|
44
LL | assert_eq!(Y, 4);
5-
| ^^^^^^^^^^^-^^^^^
6-
| |
7-
| referenced constant has errors
8-
|
9-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
5+
| ^ referenced constant has errors
106

11-
error[E0080]: evaluation of constant expression failed
12-
--> $DIR/const_fn_ptr_fail2.rs:22:5
7+
error[E0080]: evaluation of constant value failed
8+
--> $DIR/const_fn_ptr_fail2.rs:22:16
139
|
1410
LL | assert_eq!(Z, 4);
15-
| ^^^^^^^^^^^-^^^^^
16-
| |
17-
| referenced constant has errors
18-
|
19-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
11+
| ^ referenced constant has errors
2012

2113
warning: skipping const checks
2214
|

src/test/ui/consts/const-eval/issue-43197.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ fn main() {
1212
const Y: u32 = foo(0 - 1);
1313
//~^ WARN any use of this value will cause
1414
println!("{} {}", X, Y);
15-
//~^ ERROR evaluation of constant expression failed
16-
//~| ERROR evaluation of constant expression failed
15+
//~^ ERROR evaluation of constant value failed
16+
//~| ERROR evaluation of constant value failed
1717
//~| WARN erroneous constant used [const_err]
1818
//~| WARN erroneous constant used [const_err]
1919
}

src/test/ui/consts/const-eval/issue-43197.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | const Y: u32 = foo(0 - 1);
2020
| |
2121
| attempt to compute `0_u32 - 1_u32`, which would overflow
2222

23-
error[E0080]: evaluation of constant expression failed
23+
error[E0080]: evaluation of constant value failed
2424
--> $DIR/issue-43197.rs:14:23
2525
|
2626
LL | println!("{} {}", X, Y);
@@ -32,7 +32,7 @@ warning: erroneous constant used
3232
LL | println!("{} {}", X, Y);
3333
| ^ referenced constant has errors
3434

35-
error[E0080]: evaluation of constant expression failed
35+
error[E0080]: evaluation of constant value failed
3636
--> $DIR/issue-43197.rs:14:26
3737
|
3838
LL | println!("{} {}", X, Y);

src/test/ui/consts/const-eval/issue-44578.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ impl Foo for u16 {
2525

2626
fn main() {
2727
println!("{}", <Bar<u16, u8> as Foo>::AMT);
28-
//~^ ERROR evaluation of constant expression failed [E0080]
28+
//~^ ERROR evaluation of constant value failed [E0080]
2929
}

src/test/ui/consts/const-eval/issue-44578.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0080]: evaluation of constant expression failed
1+
error[E0080]: evaluation of constant value failed
22
--> $DIR/issue-44578.rs:27:20
33
|
44
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);

src/test/ui/consts/const-eval/issue-50814-2.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ LL | const BAR: usize = [5, 6, 7][T::BOO];
88
|
99
= note: `#[deny(const_err)]` on by default
1010

11-
error[E0080]: evaluation of constant expression failed
12-
--> $DIR/issue-50814-2.rs:18:5
11+
error[E0080]: evaluation of constant value failed
12+
--> $DIR/issue-50814-2.rs:18:6
1313
|
1414
LL | &<A<T> as Foo<T>>::BAR
15-
| ^---------------------
16-
| |
17-
| referenced constant has errors
15+
| ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
1816

1917
error: aborting due to 2 previous errors
2018

src/test/ui/consts/const-eval/issue-50814.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ LL | const MAX: u8 = A::MAX + B::MAX;
88
|
99
= note: `#[deny(const_err)]` on by default
1010

11-
error[E0080]: evaluation of constant expression failed
12-
--> $DIR/issue-50814.rs:20:5
11+
error[E0080]: evaluation of constant value failed
12+
--> $DIR/issue-50814.rs:20:6
1313
|
1414
LL | &Sum::<U8,U8>::MAX
15-
| ^-----------------
16-
| |
17-
| referenced constant has errors
15+
| ^^^^^^^^^^^^^^^^^ referenced constant has errors
1816

1917
error: aborting due to 2 previous errors
2018

src/test/ui/consts/const_unsafe_unreachable_ub.stderr

+3-7
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,11 @@ note: the lint level is defined here
2020
LL | #[warn(const_err)]
2121
| ^^^^^^^^^
2222

23-
error[E0080]: evaluation of constant expression failed
24-
--> $DIR/const_unsafe_unreachable_ub.rs:17:3
23+
error[E0080]: evaluation of constant value failed
24+
--> $DIR/const_unsafe_unreachable_ub.rs:17:14
2525
|
2626
LL | assert_eq!(BAR, true);
27-
| ^^^^^^^^^^^---^^^^^^^^
28-
| |
29-
| referenced constant has errors
30-
|
31-
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
27+
| ^^^ referenced constant has errors
3228

3329
error: erroneous constant used
3430
--> $DIR/const_unsafe_unreachable_ub.rs:17:3

src/test/ui/consts/issue-55878.stderr

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ error[E0080]: values of the type `[u8; SIZE]` are too big for the current archit
22
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
33
|
44
LL | intrinsics::size_of::<T>()
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
| |
7-
| inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
8-
| inside `main` at $DIR/issue-55878.rs:7:26
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
96
|
107
::: $DIR/issue-55878.rs:7:26
118
|
129
LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
13-
| ----------------------------------------------
10+
| ---------------------------------------------- inside `main` at $DIR/issue-55878.rs:7:26
1411

1512
error: erroneous constant used
1613
--> $DIR/issue-55878.rs:7:26

0 commit comments

Comments
 (0)