Skip to content

Commit f76ead3

Browse files
committed
Fix overflowing_literals lint with repeated negation
Fixes #158295 The `overflowing_literal` lint is, I believe, supposed to consider the literal and not the surrounding context when deciding whether to lint. This is in contrast to the `arithmetic_overflow` lint, which only considers code that executes at run time, which excludes the negation inside a literal. According to [the reference](https://doc.rust-lang.org/1.96.0/reference/expressions/operator-expr.html#r-expr.operator.int-overflow.unary-neg), a negation in front of an integer does not result in an overflow. I think of this as: a negation, and only one negation, in front of an integer, is "part of" the integer. Therefore, the `overflowing_literal` lint should consider that when linting. It should not consider the second or third negation. Therefore, this commit changes `overflowing_literals` so that it only lints on `128_i8` when there is no preceding negation at all. This is in contrast to the previous behavior, which lints on `128_i8` preceded by an even number of negations.
1 parent 95cfa9d commit f76ead3

3 files changed

Lines changed: 14 additions & 48 deletions

File tree

compiler/rustc_lint/src/types.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -567,12 +567,8 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
567567
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) {
568568
match e.kind {
569569
hir::ExprKind::Unary(hir::UnOp::Neg, expr) => {
570-
// Propagate negation, if the negation itself isn't negated
571-
if self.last_visited_negation.is_none_or(|negation| negation.negated_id != e.hir_id)
572-
{
573-
self.last_visited_negation =
574-
Some(NegationInfo { negation_span: e.span, negated_id: expr.hir_id });
575-
}
570+
self.last_visited_negation =
571+
Some(NegationInfo { negation_span: e.span, negated_id: expr.hir_id });
576572
}
577573
hir::ExprKind::Binary(binop, ref l, ref r) => {
578574
if is_comparison(binop.node) {

tests/ui/lint/lint-type-overflow3.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@ fn main() {
99
//~^ ERROR literal out of range for `i8`
1010
let x: i8 = -128;
1111
let x: i8 = --128; //~ WARN use of a double negation
12-
//~^ ERROR literal out of range for `i8`
13-
//~| ERROR this arithmetic operation will overflow
12+
//~^ ERROR this arithmetic operation will overflow
1413
let x: i8 = ---128; //~ WARN use of a double negation
1514
//~^ ERROR this arithmetic operation will overflow
1615
let x: i8 = ----128; //~ WARN use of a double negation
17-
//~^ ERROR literal out of range for `i8`
18-
//~| ERROR this arithmetic operation will overflow
16+
//~^ ERROR this arithmetic operation will overflow
1917
let x: i8 = -----128; //~ WARN use of a double negation
2018
//~^ ERROR this arithmetic operation will overflow
2119
let x: i8 = ------128; //~ WARN use of a double negation
22-
//~^ ERROR literal out of range for `i8`
23-
//~| ERROR this arithmetic operation will overflow
20+
//~^ ERROR this arithmetic operation will overflow
2421
}

tests/ui/lint/lint-type-overflow3.stderr

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | let x: i8 = -(-128);
1313
| + +
1414

1515
warning: use of a double negation
16-
--> $DIR/lint-type-overflow3.rs:14:18
16+
--> $DIR/lint-type-overflow3.rs:13:18
1717
|
1818
LL | let x: i8 = ---128;
1919
| ^^^^^
@@ -26,7 +26,7 @@ LL | let x: i8 = --(-128);
2626
| + +
2727

2828
warning: use of a double negation
29-
--> $DIR/lint-type-overflow3.rs:16:19
29+
--> $DIR/lint-type-overflow3.rs:15:19
3030
|
3131
LL | let x: i8 = ----128;
3232
| ^^^^^
@@ -39,7 +39,7 @@ LL | let x: i8 = ---(-128);
3939
| + +
4040

4141
warning: use of a double negation
42-
--> $DIR/lint-type-overflow3.rs:19:20
42+
--> $DIR/lint-type-overflow3.rs:17:20
4343
|
4444
LL | let x: i8 = -----128;
4545
| ^^^^^
@@ -52,7 +52,7 @@ LL | let x: i8 = ----(-128);
5252
| + +
5353

5454
warning: use of a double negation
55-
--> $DIR/lint-type-overflow3.rs:21:21
55+
--> $DIR/lint-type-overflow3.rs:19:21
5656
|
5757
LL | let x: i8 = ------128;
5858
| ^^^^^
@@ -77,25 +77,25 @@ LL | #![deny(overflowing_literals, arithmetic_overflow)]
7777
| ^^^^^^^^^^^^^^^^^^^
7878

7979
error: this arithmetic operation will overflow
80-
--> $DIR/lint-type-overflow3.rs:14:18
80+
--> $DIR/lint-type-overflow3.rs:13:18
8181
|
8282
LL | let x: i8 = ---128;
8383
| ^^^^^ attempt to negate `i8::MIN`, which would overflow
8484

8585
error: this arithmetic operation will overflow
86-
--> $DIR/lint-type-overflow3.rs:16:19
86+
--> $DIR/lint-type-overflow3.rs:15:19
8787
|
8888
LL | let x: i8 = ----128;
8989
| ^^^^^ attempt to negate `i8::MIN`, which would overflow
9090

9191
error: this arithmetic operation will overflow
92-
--> $DIR/lint-type-overflow3.rs:19:20
92+
--> $DIR/lint-type-overflow3.rs:17:20
9393
|
9494
LL | let x: i8 = -----128;
9595
| ^^^^^ attempt to negate `i8::MIN`, which would overflow
9696

9797
error: this arithmetic operation will overflow
98-
--> $DIR/lint-type-overflow3.rs:21:21
98+
--> $DIR/lint-type-overflow3.rs:19:21
9999
|
100100
LL | let x: i8 = ------128;
101101
| ^^^^^ attempt to negate `i8::MIN`, which would overflow
@@ -114,32 +114,5 @@ note: the lint level is defined here
114114
LL | #![deny(overflowing_literals, arithmetic_overflow)]
115115
| ^^^^^^^^^^^^^^^^^^^^
116116

117-
error: literal out of range for `i8`
118-
--> $DIR/lint-type-overflow3.rs:11:19
119-
|
120-
LL | let x: i8 = --128;
121-
| ^^^
122-
|
123-
= note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
124-
= help: consider using the type `u8` instead
125-
126-
error: literal out of range for `i8`
127-
--> $DIR/lint-type-overflow3.rs:16:21
128-
|
129-
LL | let x: i8 = ----128;
130-
| ^^^
131-
|
132-
= note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
133-
= help: consider using the type `u8` instead
134-
135-
error: literal out of range for `i8`
136-
--> $DIR/lint-type-overflow3.rs:21:23
137-
|
138-
LL | let x: i8 = ------128;
139-
| ^^^
140-
|
141-
= note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
142-
= help: consider using the type `u8` instead
143-
144-
error: aborting due to 9 previous errors; 5 warnings emitted
117+
error: aborting due to 6 previous errors; 5 warnings emitted
145118

0 commit comments

Comments
 (0)