]> Cypherpunks repositories - gostls13.git/commit
cmd/compile: fix loopvar version detection with line directives
authorxieyuschen <xieyuschen@gmail.com>
Wed, 21 Jan 2026 06:57:14 +0000 (14:57 +0800)
committerKeith Randall <khr@golang.org>
Fri, 23 Jan 2026 23:40:20 +0000 (15:40 -0800)
commitb408256be720c51ff1730d7a97389a975744a312
tree61be9aaefd6c57bb80098de05b9bab68a224a576
parent27fcec4d8f3041e845762303d85d868cc3e351e8
cmd/compile: fix loopvar version detection with line directives

The Go loop variable semantics changed in Go 1.22: loop variables are now
created per-iteration instead of per-loop. The compiler decides which
semantics to use based on the Go version in go.mod.

When go.mod specifies go 1.21 and the code is built with a Go 1.22+
compiler, the per-loop(compatible behavior) semantics should be used.

However, when a line directive is present in the source file,
go.mod 1.21 and go1.22+ compiler outputs a per-iteration semantics.

For example, the file below wants output 333 but got 012.

    -- go.mod --
    module test
    go 1.21
    -- main.go --
    //line main.go:1
    func main() {
            var fns []func()
            for i := 0; i < 3; i++ {
                    fns = append(fns, func() { fmt.Print(i) })
            }
            for _, fn := range fns {
                    fn()
            }
    }

The distinctVars function uses stmt.Pos().Base() to look up the file
version in FileVersions. Base() returns the file name after line
directives are applied (e.g., "main.go" for "//line main.go:1"), not
the actual source file path. This causes the version lookup to fail
for files with line directives.

This CL fixes the bug by using stmt.Pos().FileBase() instead. FileBase()
returns the actual file path before line directives are applied, ensuring
the correct version information is retrieved from the original source file.

Fixes: #77248
Change-Id: Idacc0816d112ee393089262468a02acfe40e4b72
Reviewed-on: https://go-review.googlesource.com/c/go/+/737820
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
src/cmd/compile/internal/loopvar/loopvar_test.go
src/cmd/compile/internal/loopvar/testdata/range_esc_closure_linedir.go [new file with mode: 0644]
src/cmd/compile/internal/noder/writer.go