Skip to content

while_let_on_iterator suggests broken fix when iterator is captured in FnMut #7249

Closed
@zgotsch

Description

@zgotsch

I have noticed a similar problem to #5844 and #6231, where Clippy suggests a for loop instead of a while let, causing an illegal move of the target iterator. In my case, it was because the iterator was borrowed by reference in an FnMut closure.

Minimal example:

fn close_over(mut f: impl FnMut()) {
    f();
    f();
}

fn main() {
    let v = vec![1, 2, 3];
    let mut it = v.into_iter();
    close_over(|| {
        while let Some(x) = it.next() {
        // for x in it {
            println!("{}", x);
        }
    });
}

Rust Playground

Clippy suggests changing the while let Some(x) = it.next() to for x in it, but we cannot move out of the mutable reference to it. The correct suggestion is probably for x in &mut it, similar to fixes in #6966, but it seems more difficult to detect a FnMut without type information, which I'm not sure Clippy has access to. I believe the suggestion for x in it is better when the iterator has been moved into the closure.

Meta

  • cargo clippy -V: clippy 0.1.52 (88f19c6d 2021-05-03)
  • rustc -Vv:
rustc 1.52.0 (88f19c6da 2021-05-03)
binary: rustc
commit-hash: 88f19c6dab716c6281af7602e30f413e809c5974
commit-date: 2021-05-03
host: x86_64-apple-darwin
release: 1.52.0
LLVM version: 12.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when appliedL-suggestionLint: Improving, adding or fixing lint suggestions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions