rust-lang / rust-lang/rust-clippy
False positive in `needless_collect` with borrowing error
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Summary
Inlining an iterator to a later call site whilst the iterator is accessed causes a compile error and potentially different program behaviour.
Lint Name
needless_collect
Reproducer
I tried this code:
fn main() {
let prefix = 1;
let mut children = [1, 2, 3, 4].into_iter();
let prefix: Vec<_> = children.by_ref().take(prefix).collect();
let suffix: Vec<_> = children.collect();
let dummy = 0;
let items = prefix
.into_iter()
.chain(std::iter::once(dummy))
.chain(suffix);
println!("{:?}", items.collect::<Vec<_>>())
}
I saw this happen:
warning: avoid using `collect()` when not needed
--> src/main.rs:6:57
|
6 | let prefix: Vec<_> = children.by_ref().take(prefix).collect();
| ^^^^^^^
...
11 | let items = prefix
| _________________-
12 | | .into_iter()
| |____________________- the iterator could be used here instead
|
= note: `#[warn(clippy::needless_collect)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
help: use the original Iterator instead of collecting it and then producing a new one
|
6 ~
7 | let suffix: Vec<_> = children.collect();
...
10 |
11 ~ let items = children.by_ref().take(prefix)
|
I expected to see this happen:
No warning, applying the lint causes a compile error and further fixing the error causes the program's logic to change:
the fixed code would be:
fn main() {
let prefix = 1;
let mut children = [1, 2, 3, 4].into_iter();
let suffix: Vec<_> = children.by_ref().collect();
let dummy = 0;
let items = children.by_ref().take(prefix)
.chain(std::iter::once(dummy))
.chain(suffix);
println!("{:?}", items.collect::<Vec<_>>())
}
and prints:
[0, 1, 2, 3, 4]
but the original program would print:
[1, 0, 2, 3, 4]
Version
rustc 1.64.0-nightly (f8588549c 2022-07-18)
binary: rustc
commit-hash: f8588549c3c3d45c32b404210cada01e2a45def3
commit-date: 2022-07-18
host: x86_64-apple-darwin
release: 1.64.0-nightly
LLVM version: 14.0.6
Additional Labels
@rustbot label +I-suggestion-causes-error
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 with the needless_collect lint entry point and run the Rust reproducer from the issue. Trace why the suggestion moves collection across the borrowed iterator, then add regression coverage showing that no warning is emitted and the original program behavior is preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100