Skip to content

Commit

Permalink
fix case where loopvar is redefined with an explicit i := i define (p…
Browse files Browse the repository at this point in the history
…re 1.22 fix for loopvar) with the same name as the original. all the other tests were using a new variable name, so we missed this case.
  • Loading branch information
rcoreilly committed Jul 19, 2024
1 parent 2e59c8a commit baba132
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
18 changes: 18 additions & 0 deletions _test/closure19.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func main() {
foos := []func(){}

for i := 0; i < 3; i++ {
i := i
foos = append(foos, func() { println(i) })
}
foos[0]()
foos[1]()
foos[2]()
}

// Output:
// 0
// 1
// 2
18 changes: 18 additions & 0 deletions _test/closure20.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

func main() {
foos := []func(){}

for i := range 3 {
i := i
foos = append(foos, func() { println(i) })
}
foos[0]()
foos[1]()
foos[2]()
}

// Output:
// 0
// 1
// 2
16 changes: 16 additions & 0 deletions interp/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,22 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
return
}
if sc.global || sc.isRedeclared(dest) {
if n.anc != nil && n.anc.anc != nil && (n.anc.anc.kind == forStmt7 || n.anc.anc.kind == rangeStmt) {
// check for redefine of for loop variables, which are now auto-defined in go1.22
init := n.anc.anc.child[0]
var fi *node // for ident
if n.anc.anc.kind == forStmt7 {
if init.kind == defineStmt && len(init.child) >= 2 && init.child[0].kind == identExpr {
fi = init.child[0]
}
} else { // range
fi = init
}
if fi != nil && dest.ident == fi.ident {
n.gen = nop
break
}
}
// Do not overload existing symbols (defined in GTA) in global scope.
sym, _, _ = sc.lookup(dest.ident)
}
Expand Down

0 comments on commit baba132

Please sign in to comment.