What it does
This suggestion builds upon #17400 (comment)
We should detect match or if statements that check the .len() of a slice and subsequently index into it, suggesting a rewrite to use slice patterns.
Advantage
- Destructuring assigns meaning to the elements (e.g.,
[_, second, _, _]) instead of requiring the reader to parse and track raw integer indices across a block of code.
- removes panic sites by guaranteeing the check, though I suspect that llvm can optimsie this away. Needs a double check if llvm can do this in all cases though.
-> so a stylistic lint I think.
Drawbacks
None that I can think off.
Example
// Bad
fn foo(slice: &[u8]) -> u8 {
match slice.len() {
3 => slice[0] + slice[1] + slice[2],
4 => slice[1],
_ => 42,
}
}
Could be written as:
// Good
fn foo(slice: &[u8]) -> u8 {
match slice.len() {
[a, b, c] => a + b + c,
[_, b, _, _] => b,
_ => 42,
}
}
Comparison with existing lints
clippy::len_zero targets len == 0
clippy::get_first targets len == 1
- not sure why
clippy::get_last does not exist
clippy::get_last_with_len targets x.get(x.len() - 1)
rustc::unconditional_panic targets bad indexings
clippy::missing_asserts_for_indexing targets indexing without len checks
Additional Context
At first, this should be done with these additional constraints:
- slices with copy-able T (given that derfs might be seen as ugly)
- operation inside does not require mut
- up to index 5 (since adding something like 25 here might be fairly ugly).
- Also goes for match-or patterns.
Allow such a rewrite again, only if sum(idx for idx in match_or) <= 5, due to complexity.
- if the whole match is not actually
.first(), .last(), 0 or impossible (no rustc::unconditional_panic)
What it does
This suggestion builds upon #17400 (comment)
We should detect
matchorifstatements that check the.len()of a slice and subsequently index into it, suggesting a rewrite to use slice patterns.Advantage
[_, second, _, _]) instead of requiring the reader to parse and track raw integer indices across a block of code.-> so a
stylisticlint I think.Drawbacks
None that I can think off.
Example
Could be written as:
Comparison with existing lints
clippy::len_zerotargets len == 0clippy::get_firsttargets len == 1clippy::get_lastdoes not existclippy::get_last_with_lentargetsx.get(x.len() - 1)rustc::unconditional_panictargets bad indexingsclippy::missing_asserts_for_indexingtargets indexing without len checksAdditional Context
At first, this should be done with these additional constraints:
Allow such a rewrite again, only if
sum(idx for idx in match_or) <= 5, due to complexity..first(),.last(),0or impossible (norustc::unconditional_panic)