rust-clippy
rust-clippy copied to clipboard
new lint: Recommend using slice.into() to box the slice
What it does
Given a slice like
let x: &[i32] = &[1, 2, 3, 4, ..];
When users write something like
let y: Box<[i32]> = x.iter().copied().collect();
Then clippy
should propose to replace x.iter().copied().collect()
with x.into()
.
This is not only shorter and more readable but also more efficient according to my benchmarks since x.iter()
can make use of memset
.
So users should write
let y: Box<[i32]> = x.into();
instead.
I often come across this anti-pattern of boxing up a slice in codebases.
I don't know if this explodes the scope of this issue but technically we could also lint against the following usage with similar reasoning: When users write something like
let y: Box<[i32]> = x.to_vec().into_boxed_slice();
Then clippy
again should propose to replace x.to_vec().into_boxed_slice()
with x.into()
since x.to_vec().into_boxed_slice()
creates a Vec
with some capacity that fits x
but the call into_boxed_slice
does not guarantee that the former won't be shrunk which causes another memory reallocation. Whereas using x.into()
won't have this problem.
Lint Name
slice_into_boxed_slice
Category
perf
Advantage
- The replacement with
x.into()
is less verbose and likely more readable than the alternatives. - In the first example
x.into()
can make use ofmemset
under the hood which yields better performance according to my benchmarks. - In the second example
x.into()
will guarantee to only cause at most one memory allocation whereasx.to_vec().into_boxed_slice()
might perform more than that.
Drawbacks
None?
Example
Given a slice like
let x: &[i32] = &[1, 2, 3, 4, ..];
Then
let y: Box<[i32]> = x.iter().copied().collect();
And
let y: Box<[i32]> = x.to_vec().into_boxed_slice();
Could both be written as:
let y: Box<[i32]> = x.into();
@rustbot claim