Skip to content

Commit 8a1050b

Browse files
committed
Auto merge of #119432 - gurry:117949-make-lint-run-on-promoteds, r=<try>
Make `ConstPropLint` lint run on promoteds Fixes #117949 wherein the lint didn't fire for the following promoteds: - SHL or SHR operators in a non-optimized build - any arithmetic operator in an optimized build What I have done here is simply enabled `ConstPropLint` to run on promoted bodies by removing the relevant `if` check. After this change _all_ promoted arithmetic operators will lint _in both non-optimized and optimized builds_. On the flip side programs containing the above mentioned overflowing promoteds that were accepted earlier will now be rejected. Hope that is okay from a backward compatibility standpoint. I have added tests covering all overflowing promoted & non-promoted ops for both compile-time and runtime operations and for optimized as well as non-optimized builds. I had to amend some existing tests to make them pass and had to delete a couple that were set to pass despite overflows. This PR increases the number of duplicate diagnostics emitted (because the same operator might get linted in both the promoted MIR and the main MIR). I hope that is an acceptable trade-off given that we now lint overflows much more comprehensively than earlier.
2 parents 090d5ea + ecadc52 commit 8a1050b

21 files changed

+5879
-23
lines changed

compiler/rustc_mir_transform/src/const_prop_lint.rs

-5
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
4242
return;
4343
}
4444

45-
// will be evaluated by miri and produce its errors there
46-
if body.source.promoted.is_some() {
47-
return;
48-
}
49-
5045
let def_id = body.source.def_id().expect_local();
5146
let def_kind = tcx.def_kind(def_id);
5247
let is_fn_like = def_kind.is_fn_like();

src/tools/miri/tests/pass/overflow_checks_off.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
//@compile-flags: -C overflow-checks=off
22

33
// Check that we correctly implement the intended behavior of these operators
4-
// when they are not being overflow-checked.
4+
// when they are not being overflow-checked at runtime.
55

66
// FIXME: if we call the functions in `std::ops`, we still get the panics.
77
// Miri does not implement the codegen-time hack that backs `#[rustc_inherit_overflow_checks]`.
88
// use std::ops::*;
99

10+
11+
// Disable _compile-time_ overflow linting
12+
// so that we can test runtime overflow checks
13+
#![allow(arithmetic_overflow)]
14+
1015
fn main() {
1116
assert_eq!(-{ -0x80i8 }, -0x80);
1217

tests/ui/associated-consts/defaults-cyclic-fail.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ note: ...which requires const-evaluating + checking `Tr::B`...
2020
LL | const B: u8 = Self::A;
2121
| ^^^^^^^
2222
= note: ...which again requires simplifying constant for the type system `Tr::A`, completing the cycle
23-
note: cycle used when const-evaluating + checking `main::promoted[1]`
24-
--> $DIR/defaults-cyclic-fail.rs:16:16
23+
note: cycle used when simplifying constant for the type system `Tr::A`
24+
--> $DIR/defaults-cyclic-fail.rs:5:5
2525
|
26-
LL | assert_eq!(<() as Tr>::A, 0);
27-
| ^^^^^^^^^^^^^
26+
LL | const A: u8 = Self::B;
27+
| ^^^^^^^^^^^
2828
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
2929

3030
error: aborting due to 1 previous error

tests/ui/associated-consts/defaults-not-assumed-fail.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ note: erroneous constant encountered
1010
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
1111
| ^^^^^^^^^^^^^
1212

13+
note: erroneous constant encountered
14+
--> $DIR/defaults-not-assumed-fail.rs:33:16
15+
|
16+
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
17+
| ^^^^^^^^^^^^^
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
1321
note: erroneous constant encountered
1422
--> $DIR/defaults-not-assumed-fail.rs:33:5
1523
|

tests/ui/consts/const-eval/issue-44578.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ note: erroneous constant encountered
1010
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

13+
note: erroneous constant encountered
14+
--> $DIR/issue-44578.rs:25:20
15+
|
16+
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
1321
note: erroneous constant encountered
1422
--> $DIR/issue-44578.rs:25:20
1523
|

tests/ui/consts/const-eval/issue-50814.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct Sum<A, B>(A, B);
1414
impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A, B> {
1515
const MAX: u8 = A::MAX + B::MAX;
1616
//~^ ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
17+
//~| ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
1718
}
1819

1920
fn foo<T>(_: T) -> &'static u8 {

tests/ui/consts/const-eval/issue-50814.stderr

+19-3
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,33 @@ LL | const MAX: u8 = A::MAX + B::MAX;
55
| ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
66

77
note: erroneous constant encountered
8-
--> $DIR/issue-50814.rs:20:6
8+
--> $DIR/issue-50814.rs:21:6
99
|
1010
LL | &Sum::<U8, U8>::MAX
1111
| ^^^^^^^^^^^^^^^^^^
1212

13+
error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
14+
--> $DIR/issue-50814.rs:15:21
15+
|
16+
LL | const MAX: u8 = A::MAX + B::MAX;
17+
| ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
21+
note: erroneous constant encountered
22+
--> $DIR/issue-50814.rs:21:6
23+
|
24+
LL | &Sum::<U8, U8>::MAX
25+
| ^^^^^^^^^^^^^^^^^^
26+
|
27+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
28+
1329
note: the above error was encountered while instantiating `fn foo::<i32>`
14-
--> $DIR/issue-50814.rs:25:5
30+
--> $DIR/issue-50814.rs:26:5
1531
|
1632
LL | foo(0);
1733
| ^^^^^^
1834

19-
error: aborting due to 1 previous error
35+
error: aborting due to 2 previous errors
2036

2137
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/promotion.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ fn main() {
2525
assert_static(&["d", "e", "f"]);
2626
assert_eq!(C, 42);
2727

28-
// make sure that these do not cause trouble despite overflowing
28+
// make sure that this does not cause trouble despite overflowing
2929
assert_static(&(0-1));
30-
assert_static(&-i32::MIN);
3130

3231
// div-by-non-0 is okay
3332
assert_static(&(1/1));
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error: this arithmetic operation will overflow
2+
--> $DIR/issue-117949.rs:16:24
3+
|
4+
LL | format_args!("{}", 5 * i32::MAX);
5+
| ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
6+
|
7+
= note: `#[deny(arithmetic_overflow)]` on by default
8+
9+
error: this arithmetic operation will overflow
10+
--> $DIR/issue-117949.rs:15:24
11+
|
12+
LL | format_args!("{}", -5 - i32::MAX);
13+
| ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
14+
15+
error: this arithmetic operation will overflow
16+
--> $DIR/issue-117949.rs:14:24
17+
|
18+
LL | format_args!("{}", 1 + i32::MAX);
19+
| ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
20+
21+
error: this arithmetic operation will overflow
22+
--> $DIR/issue-117949.rs:13:24
23+
|
24+
LL | format_args!("{}", 1 >> 32);
25+
| ^^^^^^^ attempt to shift right by `32_i32`, which would overflow
26+
27+
error: this arithmetic operation will overflow
28+
--> $DIR/issue-117949.rs:12:24
29+
|
30+
LL | format_args!("{}", 1 << 32);
31+
| ^^^^^^^ attempt to shift left by `32_i32`, which would overflow
32+
33+
error: this operation will panic at runtime
34+
--> $DIR/issue-117949.rs:17:24
35+
|
36+
LL | format_args!("{}", 1 / 0);
37+
| ^^^^^ attempt to divide `1_i32` by zero
38+
|
39+
= note: `#[deny(unconditional_panic)]` on by default
40+
41+
error: this operation will panic at runtime
42+
--> $DIR/issue-117949.rs:18:24
43+
|
44+
LL | format_args!("{}", 1 % 0);
45+
| ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
46+
47+
error: this operation will panic at runtime
48+
--> $DIR/issue-117949.rs:19:24
49+
|
50+
LL | format_args!("{}", [1, 2, 3][4]);
51+
| ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
52+
53+
error: aborting due to 8 previous errors
54+

tests/ui/lint/issue-117949.opt.stderr

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error: this arithmetic operation will overflow
2+
--> $DIR/issue-117949.rs:16:24
3+
|
4+
LL | format_args!("{}", 5 * i32::MAX);
5+
| ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
6+
|
7+
= note: `#[deny(arithmetic_overflow)]` on by default
8+
9+
error: this arithmetic operation will overflow
10+
--> $DIR/issue-117949.rs:15:24
11+
|
12+
LL | format_args!("{}", -5 - i32::MAX);
13+
| ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
14+
15+
error: this arithmetic operation will overflow
16+
--> $DIR/issue-117949.rs:14:24
17+
|
18+
LL | format_args!("{}", 1 + i32::MAX);
19+
| ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
20+
21+
error: this arithmetic operation will overflow
22+
--> $DIR/issue-117949.rs:13:24
23+
|
24+
LL | format_args!("{}", 1 >> 32);
25+
| ^^^^^^^ attempt to shift right by `32_i32`, which would overflow
26+
27+
error: this arithmetic operation will overflow
28+
--> $DIR/issue-117949.rs:12:24
29+
|
30+
LL | format_args!("{}", 1 << 32);
31+
| ^^^^^^^ attempt to shift left by `32_i32`, which would overflow
32+
33+
error: this operation will panic at runtime
34+
--> $DIR/issue-117949.rs:17:24
35+
|
36+
LL | format_args!("{}", 1 / 0);
37+
| ^^^^^ attempt to divide `1_i32` by zero
38+
|
39+
= note: `#[deny(unconditional_panic)]` on by default
40+
41+
error: this operation will panic at runtime
42+
--> $DIR/issue-117949.rs:18:24
43+
|
44+
LL | format_args!("{}", 1 % 0);
45+
| ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
46+
47+
error: this operation will panic at runtime
48+
--> $DIR/issue-117949.rs:19:24
49+
|
50+
LL | format_args!("{}", [1, 2, 3][4]);
51+
| ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
52+
53+
error: aborting due to 8 previous errors
54+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error: this arithmetic operation will overflow
2+
--> $DIR/issue-117949.rs:16:24
3+
|
4+
LL | format_args!("{}", 5 * i32::MAX);
5+
| ^^^^^^^^^^^^ attempt to compute `5_i32 * i32::MAX`, which would overflow
6+
|
7+
= note: `#[deny(arithmetic_overflow)]` on by default
8+
9+
error: this arithmetic operation will overflow
10+
--> $DIR/issue-117949.rs:15:24
11+
|
12+
LL | format_args!("{}", -5 - i32::MAX);
13+
| ^^^^^^^^^^^^^ attempt to compute `-5_i32 - i32::MAX`, which would overflow
14+
15+
error: this arithmetic operation will overflow
16+
--> $DIR/issue-117949.rs:14:24
17+
|
18+
LL | format_args!("{}", 1 + i32::MAX);
19+
| ^^^^^^^^^^^^ attempt to compute `1_i32 + i32::MAX`, which would overflow
20+
21+
error: this arithmetic operation will overflow
22+
--> $DIR/issue-117949.rs:13:24
23+
|
24+
LL | format_args!("{}", 1 >> 32);
25+
| ^^^^^^^ attempt to shift right by `32_i32`, which would overflow
26+
27+
error: this arithmetic operation will overflow
28+
--> $DIR/issue-117949.rs:12:24
29+
|
30+
LL | format_args!("{}", 1 << 32);
31+
| ^^^^^^^ attempt to shift left by `32_i32`, which would overflow
32+
33+
error: this operation will panic at runtime
34+
--> $DIR/issue-117949.rs:17:24
35+
|
36+
LL | format_args!("{}", 1 / 0);
37+
| ^^^^^ attempt to divide `1_i32` by zero
38+
|
39+
= note: `#[deny(unconditional_panic)]` on by default
40+
41+
error: this operation will panic at runtime
42+
--> $DIR/issue-117949.rs:18:24
43+
|
44+
LL | format_args!("{}", 1 % 0);
45+
| ^^^^^ attempt to calculate the remainder of `1_i32` with a divisor of zero
46+
47+
error: this operation will panic at runtime
48+
--> $DIR/issue-117949.rs:19:24
49+
|
50+
LL | format_args!("{}", [1, 2, 3][4]);
51+
| ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
52+
53+
error: aborting due to 8 previous errors
54+

tests/ui/lint/issue-117949.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Regression test for issue #117949
2+
3+
// revisions: noopt opt opt_with_overflow_checks
4+
//[noopt]compile-flags: -C opt-level=0 -Z deduplicate-diagnostics=yes
5+
//[opt]compile-flags: -O
6+
//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes
7+
// build-fail
8+
// ignore-pass (test tests codegen-time behaviour)
9+
10+
11+
fn main() {
12+
format_args!("{}", 1 << 32); //~ ERROR: arithmetic operation will overflow
13+
format_args!("{}", 1 >> 32); //~ ERROR: arithmetic operation will overflow
14+
format_args!("{}", 1 + i32::MAX); //~ ERROR: arithmetic operation will overflow
15+
format_args!("{}", -5 - i32::MAX); //~ ERROR: arithmetic operation will overflow
16+
format_args!("{}", 5 * i32::MAX); //~ ERROR: arithmetic operation will overflow
17+
format_args!("{}", 1 / 0); //~ ERROR: this operation will panic at runtime
18+
format_args!("{}", 1 % 0); //~ ERROR: this operation will panic at runtime
19+
format_args!("{}", [1, 2, 3][4]); //~ ERROR: this operation will panic at runtime
20+
}

0 commit comments

Comments
 (0)