rust-lang / rust-lang/rust-clippy
`needless_collect`: false positive when collecting `std::thread::JoinHandle` or similar elements
Nobody has claimed this yet.
- 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
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 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