Skip to content

Commit ae8a438

Browse files
authored
Rollup merge of #85112 - RalfJung:promoted-errors, r=oli-obk
ensure failing promoteds in const/static bodies are handled correctly `const`/`static` bodies are the one case where we still promote code that might fail to evaluate. Ensure that this is handled correctly; in particular, it must not fail compilation. `src/test/ui/consts/const-eval/erroneous-const.rs` ensures that when a non-promoted fails to evaluate, we *do* show an error. r? `@oli-obk`
2 parents 7107c89 + 7a01160 commit ae8a438

8 files changed

+101
-19
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ impl<T> PrintName<T> {
1010

1111
const fn no_codegen<T>() {
1212
if false {
13+
// This bad constant is only used in dead code in a no-codegen function... and yet we still
14+
// must make sure that the build fails.
1315
let _ = PrintName::<T>::VOID; //~ERROR could not evaluate static initializer
1416
}
1517
}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ LL | #![warn(const_err, unconditional_panic)]
2727
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
2828

2929
error[E0080]: could not evaluate static initializer
30-
--> $DIR/erroneous-const.rs:13:17
30+
--> $DIR/erroneous-const.rs:15:17
3131
|
3232
LL | let _ = PrintName::<T>::VOID;
3333
| ^^^^^^^^^^^^^^^^^^^^
3434
| |
3535
| referenced constant has errors
36-
| inside `no_codegen::<i32>` at $DIR/erroneous-const.rs:13:17
36+
| inside `no_codegen::<i32>` at $DIR/erroneous-const.rs:15:17
3737
...
3838
LL | pub static FOO: () = no_codegen::<i32>();
39-
| ------------------- inside `FOO` at $DIR/erroneous-const.rs:17:22
39+
| ------------------- inside `FOO` at $DIR/erroneous-const.rs:19:22
4040

4141
error: aborting due to previous error; 2 warnings emitted
4242

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! Make sure we error on erroneous consts even if they are unused.
2+
#![warn(const_err, unconditional_panic)]
3+
4+
struct PrintName<T>(T);
5+
impl<T> PrintName<T> {
6+
const VOID: () = [()][2]; //~WARN any use of this value will cause an error
7+
//~^ WARN this operation will panic at runtime
8+
//~| WARN this was previously accepted by the compiler but is being phased out
9+
}
10+
11+
pub static FOO: () = {
12+
if false {
13+
// This bad constant is only used in dead code in a static initializer... and yet we still
14+
// must make sure that the build fails.
15+
let _ = PrintName::<i32>::VOID; //~ERROR could not evaluate static initializer
16+
}
17+
};
18+
19+
fn main() {
20+
FOO
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
warning: this operation will panic at runtime
2+
--> $DIR/erroneous-const2.rs:6:22
3+
|
4+
LL | const VOID: () = [()][2];
5+
| ^^^^^^^ index out of bounds: the length is 1 but the index is 2
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/erroneous-const2.rs:2:20
9+
|
10+
LL | #![warn(const_err, unconditional_panic)]
11+
| ^^^^^^^^^^^^^^^^^^^
12+
13+
warning: any use of this value will cause an error
14+
--> $DIR/erroneous-const2.rs:6:22
15+
|
16+
LL | const VOID: () = [()][2];
17+
| -----------------^^^^^^^-
18+
| |
19+
| index out of bounds: the length is 1 but the index is 2
20+
|
21+
note: the lint level is defined here
22+
--> $DIR/erroneous-const2.rs:2:9
23+
|
24+
LL | #![warn(const_err, unconditional_panic)]
25+
| ^^^^^^^^^
26+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
27+
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
28+
29+
error[E0080]: could not evaluate static initializer
30+
--> $DIR/erroneous-const2.rs:15:17
31+
|
32+
LL | let _ = PrintName::<i32>::VOID;
33+
| ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
34+
35+
error: aborting due to previous error; 2 warnings emitted
36+
37+
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-eval/promoted_errors.noopt.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
warning: any use of this value will cause an error
2-
--> $DIR/promoted_errors.rs:13:5
2+
--> $DIR/promoted_errors.rs:15:5
33
|
44
LL | 0 - 1
55
| ^^^^^
66
| |
77
| attempt to compute `0_u32 - 1_u32`, which would overflow
8-
| inside `overflow` at $DIR/promoted_errors.rs:13:5
9-
| inside `X` at $DIR/promoted_errors.rs:33:29
8+
| inside `overflow` at $DIR/promoted_errors.rs:15:5
9+
| inside `X` at $DIR/promoted_errors.rs:38:29
1010
...
1111
LL | / const X: () = {
1212
LL | | let _x: &'static u32 = &overflow();
@@ -18,15 +18,15 @@ LL | | };
1818
| |__-
1919
|
2020
note: the lint level is defined here
21-
--> $DIR/promoted_errors.rs:9:9
21+
--> $DIR/promoted_errors.rs:11:9
2222
|
2323
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
2424
| ^^^^^^^^^
2525
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2626
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
2727

2828
warning: any use of this value will cause an error
29-
--> $DIR/promoted_errors.rs:33:28
29+
--> $DIR/promoted_errors.rs:38:28
3030
|
3131
LL | / const X: () = {
3232
LL | | let _x: &'static u32 = &overflow();

src/test/ui/consts/const-eval/promoted_errors.opt.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
warning: any use of this value will cause an error
2-
--> $DIR/promoted_errors.rs:18:5
2+
--> $DIR/promoted_errors.rs:20:5
33
|
44
LL | 1 / 0
55
| ^^^^^
66
| |
77
| attempt to divide `1_i32` by zero
8-
| inside `div_by_zero1` at $DIR/promoted_errors.rs:18:5
9-
| inside `X` at $DIR/promoted_errors.rs:36:29
8+
| inside `div_by_zero1` at $DIR/promoted_errors.rs:20:5
9+
| inside `X` at $DIR/promoted_errors.rs:41:29
1010
...
1111
LL | / const X: () = {
1212
LL | | let _x: &'static u32 = &overflow();
@@ -18,15 +18,15 @@ LL | | };
1818
| |__-
1919
|
2020
note: the lint level is defined here
21-
--> $DIR/promoted_errors.rs:9:9
21+
--> $DIR/promoted_errors.rs:11:9
2222
|
2323
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
2424
| ^^^^^^^^^
2525
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2626
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
2727

2828
warning: any use of this value will cause an error
29-
--> $DIR/promoted_errors.rs:36:28
29+
--> $DIR/promoted_errors.rs:41:28
3030
|
3131
LL | / const X: () = {
3232
LL | | let _x: &'static u32 = &overflow();

src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
warning: any use of this value will cause an error
2-
--> $DIR/promoted_errors.rs:13:5
2+
--> $DIR/promoted_errors.rs:15:5
33
|
44
LL | 0 - 1
55
| ^^^^^
66
| |
77
| attempt to compute `0_u32 - 1_u32`, which would overflow
8-
| inside `overflow` at $DIR/promoted_errors.rs:13:5
9-
| inside `X` at $DIR/promoted_errors.rs:33:29
8+
| inside `overflow` at $DIR/promoted_errors.rs:15:5
9+
| inside `X` at $DIR/promoted_errors.rs:38:29
1010
...
1111
LL | / const X: () = {
1212
LL | | let _x: &'static u32 = &overflow();
@@ -18,15 +18,15 @@ LL | | };
1818
| |__-
1919
|
2020
note: the lint level is defined here
21-
--> $DIR/promoted_errors.rs:9:9
21+
--> $DIR/promoted_errors.rs:11:9
2222
|
2323
LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)]
2424
| ^^^^^^^^^
2525
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2626
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
2727

2828
warning: any use of this value will cause an error
29-
--> $DIR/promoted_errors.rs:33:28
29+
--> $DIR/promoted_errors.rs:38:28
3030
|
3131
LL | / const X: () = {
3232
LL | | let _x: &'static u32 = &overflow();

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

+23-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// build-pass
77
// ignore-pass (test emits codegen-time warnings and verifies that they are not errors)
88

9+
//! This test ensures that when we promote code that fails to evaluate, the build still succeeds.
10+
911
#![warn(const_err, arithmetic_overflow, unconditional_panic)]
1012

1113
// The only way to have promoteds that fail is in `const fn` called from `const`/`static`.
@@ -29,6 +31,9 @@ const fn oob() -> i32 {
2931
[1, 2, 3][4]
3032
}
3133

34+
// An unused constant containing failing promoteds.
35+
// This should work as long as `const_err` can be turned into just a warning;
36+
// once it turns into a hard error, just remove `X`.
3237
const X: () = {
3338
let _x: &'static u32 = &overflow();
3439
//[opt_with_overflow_checks,noopt]~^ WARN any use of this value will cause an error
@@ -41,4 +46,21 @@ const X: () = {
4146
let _x: &'static i32 = &oob();
4247
};
4348

44-
fn main() {}
49+
const fn mk_false() -> bool { false }
50+
51+
// An actually used constant referencing failing promoteds in dead code.
52+
// This needs to always work.
53+
const Y: () = {
54+
if mk_false() {
55+
let _x: &'static u32 = &overflow();
56+
let _x: &'static i32 = &div_by_zero1();
57+
let _x: &'static i32 = &div_by_zero2();
58+
let _x: &'static i32 = &div_by_zero3();
59+
let _x: &'static i32 = &oob();
60+
}
61+
()
62+
};
63+
64+
fn main() {
65+
let _y = Y;
66+
}

0 commit comments

Comments
 (0)