rust-lang / rust-lang/rust-clippy

new lint: Recommend using slice.into() to box the slice

Open
#9,261 1 comment 0 reactions 1 assignee View on GitHub

@HMPerson1 is already working on this.

Since Sep 18, 2022.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

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 of memset 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 whereas x.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();

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.