Skip to content

convert_for_loop_with_for_each does not take control flow in account #11111

Description

@masklinn

This assist apparently does not notice when it's being invoked on a for loop with control flow, given:

fn main() {
    for i in 0..10 {
        if i % 2 == 0 {
            continue;
        } else if i % 3 == 0 {
            break;
        } else {
            return;
        }
    }
}

Triggering the assist generates:

fn main() {
    (0..10).for_each(|i| {
        if i % 2 == 0 {
            continue;
        } else if i % 3 == 0 {
            break;
        } else {
            return;
        }
    });
}

Which is rather non-functional.

As first resolution, the assist should probably not trigger / show up if there's any control flow going through the loop (possibly any control flow at all for simplicity? e.g. nested loops would make the analysis more difficult).

A second pass could be an ancillary version of the assist which replaces the loop by try_for_each instead, though that only works if the loop is being manipulated by continue or break. If there's a return inside the loop it should probably not be convertible at all, as (AFAIK) Rust doesn't have non-local returns.
rust-analyzer version: (eg. output of "Rust Analyzer: Show RA Version" command)

> rust-analyzer --version
rust-analyzer 0add6e95e 2021-12-23 dev

rustc version: (eg. output of rustc -V)

> rustc --version
rustc 1.57.0 (f1edd0429 2021-11-29)

/cc @mattyhall @Veykril

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-assistsC-bugCategory: bugS-actionableSomeone could pick this issue up and work on it right now

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions