From 79b7420ee105b3b5478db35240151af33749e45d Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 21 Sep 2023 23:00:06 +0200 Subject: [PATCH] interp: fix issue where a var is reused instead of redefined Avoid a spurious optimisation which forces a variable to be reused instead of redefined for assignment operation. This ensures that a variable defined in a loop is re-allocated, preserving the previous instance when used by a closure for example. Fix #1594 --- _test/issue-1594.go | 17 +++++++++++++++++ interp/cfg.go | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 _test/issue-1594.go diff --git a/_test/issue-1594.go b/_test/issue-1594.go new file mode 100644 index 000000000..3bfa5f181 --- /dev/null +++ b/_test/issue-1594.go @@ -0,0 +1,17 @@ +package main + +func main() { + var fns []func() + for _, v := range []int{1, 2, 3} { + x := v*100 + v + fns = append(fns, func() { println(x) }) + } + for _, fn := range fns { + fn() + } +} + +// Output: +// 101 +// 202 +// 303 diff --git a/interp/cfg.go b/interp/cfg.go index 8bc45910e..39133a4c8 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -755,7 +755,7 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string n.gen = nop src.findex = dest.findex src.level = level - case len(n.child) < 4 && isArithmeticAction(src) && !isInterface(dest.typ): + case len(n.child) < 4 && n.kind != defineStmt && isArithmeticAction(src) && !isInterface(dest.typ): // Optimize single assignments from some arithmetic operations. src.typ = dest.typ src.findex = dest.findex