Skip to content

x/tools/gopls/internal/analysis/modernize: range over int rule doesn't consider potential slice appends #73022

Duplicate of#72917
@jakebailey

Description

@jakebailey

Go version

go version go1.24.1 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/jabaile/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/jabaile/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4045231923=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/jabaile/work/TypeScript-go/go.mod'
GOMODCACHE='/home/jabaile/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/jabaile/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/jabaile/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I have an insertion ordered map implementation; a subset of it is:

// OrderedMap is an insertion ordered map.
type OrderedMap[K comparable, V any] struct {
	keys []K
	mp   map[K]V
}

// ...

// Keys returns an iterator over the keys in the map.
// A slice of the keys can be obtained by calling `slices.Collect`.
func (m *OrderedMap[K, V]) Keys() iter.Seq[K] {
	return func(yield func(K) bool) {
		if m == nil {
			return
		}

		// We use a for loop here to ensure we enumerate new items added during iteration.
		for i := 0; i < len(m.keys); i++ {
			if !yield(m.keys[i]) {
				break
			}
		}
	}
}

The loop here is explicitly a plain for loop such that the len is reevaluated each iteration, so that adding new entries to the map still yield them.

What did you see happen?

Modernizer reports that the plain for loop could be turned into an int range loop:

.../internal/collections/ordered_map.go:116:7: for loop can be modernized using range over int
.../internal/collections/ordered_map.go:134:7: for loop can be modernized using range over int
.../internal/collections/ordered_map.go:151:7: for loop can be modernized using range over int

What did you expect to see?

Potentially no suggestion of a range over int, since iterating over a mutable slice has differing behavior. However, this case is certainly rare, most people don't do this.

(Mainly I'm worried for the potential future where modernizers are run by go vet or similar and thus cannot be ignored.)

Activity

added
ToolsThis label describes issues relating to any tools in the x/tools repository.
goplsIssues related to the Go language server, gopls.
on Mar 24, 2025
added this to the Unreleased milestone on Mar 24, 2025
added
ToolProposalIssues describing a requested change to a Go tool or command-line program.
on Mar 24, 2025
jakebailey

jakebailey commented on Mar 24, 2025

@jakebailey
ContributorAuthor

Dang, sorry, I tried to find the dupe beforehand!

adonovan

adonovan commented on Mar 25, 2025

@adonovan
Member

No worries, thanks for reporting it--I'd rather have two reports than none.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ToolProposalIssues describing a requested change to a Go tool or command-line program.ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jakebailey@adonovan@gopherbot@gabyhelp

        Issue actions

          x/tools/gopls/internal/analysis/modernize: range over int rule doesn't consider potential slice appends · Issue #73022 · golang/go