From 5daba8beecc9b748fc5c181c921f2c24050d83c1 Mon Sep 17 00:00:00 2001 From: Charles KWON OhJun Date: Wed, 27 May 2026 09:16:28 +0900 Subject: [PATCH] docs(gengo): explain why _v needs block scope in array compound-assign Co-Authored-By: Claude Opus 4.7 (1M context) --- compiler/gengo/emit_stmt.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/gengo/emit_stmt.go b/compiler/gengo/emit_stmt.go index 8252805..ef73146 100644 --- a/compiler/gengo/emit_stmt.go +++ b/compiler/gengo/emit_stmt.go @@ -461,7 +461,14 @@ func (g *Generator) emitAssign(a *ast.AssignExpr, locals localMap) { g.emitExpr(a.Right) g.emitBinaryOp(a.Op) // Stack now: [folded value]. Re-push X/index to set. - // Scope _v so multiple compound assigns in the same function don't redeclare. + // + // Wrap in { ... } so the _v binding is scoped to this snippet. + // Without the block, a function with two or more arr[i] op= rhs + // expressions emits `_v := t.Pop2()` twice in the same Go scope, + // which the Go compiler rejects with "no new variables on left + // side of :=". The other gengo sites that introduce _v (see + // gengo.go:1335, 1341 and emit_stmt.go:135) use the same block + // pattern; this branch was the lone exception. g.writeln("{ _v := t.Pop2()") g.emitExpr(idx.X) g.emitExpr(idx.Index)