Skip to content

Basic while loops => for loops #15046

Open
@leonardo-m

Description

@leonardo-m

What it does

In the wild I've seen people explain Rust using while loops where a basic for loop suffices (https://mmhaskell.com/blog/2025/6/9/spatial-reasoning-with-zigzag-patterns ). So I think Clippy could suggest to use a for loop in such basic cases.

Advantage

For such basic cases a for loop seems the best solution in Rust.

Drawbacks

If this lint suggests to replace while loops with a step different from 1, it risks introducing code that's slower (see rust-lang/rust#141360 ). So I suggest to avoid suggesting this replacement if the step is a run-time value (until that performance problem gets sorted out).

Example

#![warn(clippy::all)]
#![warn(clippy::nursery)]
#![warn(clippy::pedantic)]

const fn foo1(a: usize, b: usize) -> usize {
    let mut tot = 0;
    let mut i = a;
    while i < b {
        tot += i;
        i += 1;
    }
    tot
}

const fn foo3(a: usize, b: usize, step: usize) -> usize {
    let mut tot = 0;
    let mut i = a;
    while i < b {
        tot += i;
        i += step;
    }
    tot
}

fn main() {
    dbg!(foo1(2, 20)); // 189
    dbg!(foo3(2, 20, 3)); // 57
}

Could be written as:

fn foo2(a: usize, b: usize) -> usize {
    let mut tot = 0;
    for i in a .. b {
        tot += i;
    }
    tot
}

fn foo4(a: usize, b: usize, step: usize) -> usize {
    let mut tot = 0;
    for i in (a .. b).step_by(step) {
        tot += i;
    }
    tot
}

fn main() {
    dbg!(foo2(2, 20)); // 189
    dbg!(foo4(2, 20, 3)); // 57
}

The case foo4 coud be better left as in the foo2 code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions