diff --git a/_test/closure19.go b/_test/closure19.go new file mode 100644 index 00000000..7ad87fb5 --- /dev/null +++ b/_test/closure19.go @@ -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 diff --git a/_test/closure20.go b/_test/closure20.go new file mode 100644 index 00000000..7afb6708 --- /dev/null +++ b/_test/closure20.go @@ -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 diff --git a/interp/cfg.go b/interp/cfg.go index 227a73a2..933e2a93 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -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) }