Skip to content

intrange ignores traditional for loop semantics #48

@rockdaboot

Description

@rockdaboot

Describe the bug
intrange suggests to translate

for i := 0; i < foo.Len(); i++

into

for i := range foo.Len()

The latter for range construct only calls foo.Len() once while the former traditional for loop call foo.Len() before every loop iteration. This leads to different results when foo is amended inside the loop so that foo.Len() returns a different result.

We can even construct simpler cases where a ranged-over variable is changed inside the loop body, demonstrated at https://go.dev/play/p/kn0YdueGxaj .

Expected behavior
Especially with larger code bases, automatic transformation to range loops with e.g. golangci-lint --fix becomes dangerous for the above mentioned type of loops. Hundreds or thousands of occurrences need to be manually reviewed.

I'd suggest to have a config/switch like "safe-only" and/or "unsafe".
Consider "safe-only" to trigger intrange output only on ranged-over constants and ranged-over variables that are either not writable or that can be proved to be not mutated during loop iterations (mind of global variables).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions