rust-lang / rust-lang/rust-clippy
Warn about arithmetic before type cast/conversion
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
What it does
It is easy mistake to do arithmetics before type conversion (or cast) instead of the other way around as probably intended.
E.g. when parsing data where length field is u16 and internally in Rust code we want to use usize.
fn main() {
let value: u16 = std::hint::black_box(0xFFFF); // black box is to fool compiler in this example
// this line is wrong and can lead to integer overflow:
let sum: usize = usize::from(value + 2); // or: (value + 2) as usize
println!("{sum}");
}
This code can lead to unexpected results since value + 2 is arithmetics on u16 instead of usize. It's also quite difficult to spot in code review.
The correct code should be:
let sum: usize = usize::from(value) + 2;
This issue can be found with arithmetic_side_effects if enabled, but that lint is really noisy. I think this is special case of arithmetic side effects.
Advantage
The recommended code (type conversion before arithmetics) produces expected results while incorrect code (arithmetics before type conversion) can hide a bug for long time and cause difficult to debug bug in release builds.
And if overflow is really wanted then there is .overflowing_add() function for that already and making it really obvious.
Drawbacks
No response
Example
let parsed_value: u16 = parse_something();
let length: usize = usize::from(parsed_value + 2);
or
let parsed_value: u16 = parse_something();
let length: usize = (parsed_value + 2) as usize;
Could be written as:
let parsed_value: u16 = parse_something();
let length: usize = usize::from(parsed_value) + 2;
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing arithmetic_side_effects lint, which the issue identifies as related but too noisy. Use the Rust examples in the issue to define the conversion-before-arithmetic cases and determine how the proposed lint should distinguish intentional overflow. Done means an agreed lint scope and implementation with coverage for the shown u16 to usize patterns.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100