rust-lang / rust-lang/rust-clippy

`needless_collect`: false positive when collecting `std::thread::JoinHandle` or similar elements

Open
#7,207 4 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive L-nursery
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Lint name: needless_collect

I tried this code:

fn main() {
    let threads = (1..5).map(|n| std::thread::spawn(move || n * n)).collect::<Vec<_>>();
    threads.into_iter().for_each(|thread| println!("{}", thread.join().unwrap()));
}
I expected to see this happen:

In my opinion, no warning should be emitted here because, in almost all cases, the user wants for the threads to run in parallel and "fixing" the lint would make them run sequentially. Unfortunately, I'm not sure how feasible it would be to fix those false positives in the general case. It's somewhat subjective when "collecting" is valid for parallelism. The obvious cases from the standard library are when collecting std::thread::JoinHandle or std::process::Child elements. However, the same could be true for other crates (e.g. crossbeam::thread::ScopedJoinHandle).

Instead, this happened:

Running cargo clippy, I get the following warning:

warning: avoid using `collect()` when not needed
 --> src/main.rs:2:5
  |
2 | /     let threads = (1..5).map(|n| std::thread::spawn(move || n * n)).collect::<Vec<_>>();
3 | |     threads.into_iter().for_each(|thread| println!("{}", thread.join().unwrap()));
  | |____^
  |
  = note: `#[warn(clippy::needless_collect)]` on by default
help: use the original Iterator instead of collecting it and then producing a new one
  |
2 |     
3 |     (1..5).map(|n| std::thread::spawn(move || n * n)).for_each(|thread| println!("{}", thread.join().unwrap()));
  |

warning: 1 warning emitted

Note that using a type hint (i.e. let threads: Vec<_>) instead of turbofish syntax doesn't produce the warning with clippy 0.1.52 because of an inconsistency bug. However, that bug has been fixed in clippy 0.1.54, which emits the warning in both cases. See issue #7194.

Meta
  • cargo clippy -V: clippy 0.1.52 (9bc8c42b 2021-05-09)
    (Note that I get the same result on the Rust Playground with clippy 0.1.54)
  • rustc -Vv:
rustc 1.52.1 (9bc8c42bb 2021-05-09)
binary: rustc
commit-hash: 9bc8c42bb2f19e745a63f3445f1ac248fb015e53
commit-date: 2021-05-09
host: x86_64-apple-darwin
release: 1.52.1
LLVM version: 12.0.0

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.

Research direction

Start by reproducing the needless_collect warning with the std::thread::JoinHandle example using cargo clippy. Trace the lint's handling of collected iterator elements, then ensure the warning or suggested fix does not remove intentional parallelism while preserving the lint for genuinely unnecessary collections; add coverage for the reported case if the relevant test location is found.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.