Code
#![allow(arithmetic_overflow)]
pub fn zero() {
// lint
let _ = 128_i8;
}
pub fn one() {
// no lint
let _ = -128_i8;
}
pub fn two() {
// lint
let _ = -(-128_i8);
}
pub fn three() {
// no lint
let _ = -(-(-128_i8));
}
Current output
error: literal out of range for `i8`
--> src/lib.rs:5:13
|
5 | let _ = 128_i8;
| ^^^^^^
|
= note: the literal `128_i8` does not fit into the type `i8` whose range is `-128..=127`
= help: consider using the type `u8` instead
= note: `#[deny(overflowing_literals)]` on by default
error: literal out of range for `i8`
--> src/lib.rs:15:16
|
15 | let _ = -(-128_i8);
| ^^^^^^
|
= note: the literal `128_i8` does not fit into the type `i8` whose range is `-128..=127`
= help: consider using the type `u8` instead
Desired output
error: literal out of range for `i8`
--> src/lib.rs:5:13
|
5 | let _ = 128_i8;
| ^^^^^^
|
= note: the literal `128_i8` does not fit into the type `i8` whose range is `-128..=127`
= help: consider using the type `u8` instead
= note: `#[deny(overflowing_literals)]` on by default
Rationale and extra context
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, 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, I think that overflowing_literals should only lint on 128_i8 when there is no preceding negation at all. This is in contrast to the current behavior, which lints on 128_i8 preceded by an even number of negations.
Other cases
Rust Version
Reproducible on the playground with version 1.98.0-nightly (2026-06-22 4429659e4745016bd3f2)
Anything else?
No response
Code
Current output
Desired output
Rationale and extra context
The
overflowing_literallint is, I believe, supposed to consider the literal and not the surrounding context when deciding whether to lint. This is in contrast to thearithmetic_overflowlint, which only considers code that executes at run time, which excludes the negation inside a literal.According to the reference, 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_literallint should consider that when linting. It should not consider the second or third negation.Therefore, I think that
overflowing_literalsshould only lint on128_i8when there is no preceding negation at all. This is in contrast to the current behavior, which lints on128_i8preceded by an even number of negations.Other cases
Rust Version
Anything else?
No response