Skip to content

Commit 9032734

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 ec418d8 commit 9032734

3 files changed

Lines changed: 7 additions & 41 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: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ fn main() {
55
//~^ ERROR literal out of range for `i8`
66
let x: i8 = -128;
77
let x: i8 = --128; //~ WARN use of a double negation
8-
//~^ ERROR literal out of range for `i8`
98
let x: i8 = ---128; //~ WARN use of a double negation
109
let x: i8 = ----128; //~ WARN use of a double negation
11-
//~^ ERROR literal out of range for `i8`
1210
let x: i8 = -----128; //~ WARN use of a double negation
1311
let x: i8 = ------128; //~ WARN use of a double negation
14-
//~^ ERROR literal out of range for `i8`
1512
}

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

Lines changed: 5 additions & 32 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:9:18
16+
--> $DIR/lint-type-overflow3.rs:8: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:10:19
29+
--> $DIR/lint-type-overflow3.rs:9: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:12:20
42+
--> $DIR/lint-type-overflow3.rs:10: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:13:21
55+
--> $DIR/lint-type-overflow3.rs:11:21
5656
|
5757
LL | let x: i8 = ------128;
5858
| ^^^^^
@@ -78,32 +78,5 @@ note: the lint level is defined here
7878
LL | #![deny(overflowing_literals)]
7979
| ^^^^^^^^^^^^^^^^^^^^
8080

81-
error: literal out of range for `i8`
82-
--> $DIR/lint-type-overflow3.rs:7:19
83-
|
84-
LL | let x: i8 = --128;
85-
| ^^^
86-
|
87-
= note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
88-
= help: consider using the type `u8` instead
89-
90-
error: literal out of range for `i8`
91-
--> $DIR/lint-type-overflow3.rs:10:21
92-
|
93-
LL | let x: i8 = ----128;
94-
| ^^^
95-
|
96-
= note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
97-
= help: consider using the type `u8` instead
98-
99-
error: literal out of range for `i8`
100-
--> $DIR/lint-type-overflow3.rs:13:23
101-
|
102-
LL | let x: i8 = ------128;
103-
| ^^^
104-
|
105-
= note: the literal `128` does not fit into the type `i8` whose range is `-128..=127`
106-
= help: consider using the type `u8` instead
107-
108-
error: aborting due to 4 previous errors; 5 warnings emitted
81+
error: aborting due to 1 previous error; 5 warnings emitted
10982

0 commit comments

Comments
 (0)