The variables on the lhs of a short variable declaration are
only in scope after the variable declaration. Specifically,
function literals on the rhs of a short variable declaration
must not see newly declared variables on the lhs.
This used to work and this bug was likely introduced with
https://go-review.googlesource.com/c/go/+/83397 for go1.11.
Luckily this is just an oversight and the fix is trivial:
Simply use the mechanism for delayed type-checkin of function
literals introduced in the before-mentioned change here as well.
Fixes #24026.
Change-Id: I74ce3a0d05c5a2a42ce4b27601645964f906e82d
Reviewed-on: https://go-review.googlesource.com/96177
Reviewed-by: Alan Donovan <adonovan@google.com>
}
func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
+ top := len(check.delayed)
scope := check.scope
// collect lhs variables
check.initVars(lhsVars, rhs, token.NoPos)
+ // process function literals in rhs expressions before scope changes
+ check.processDelayed(top)
+
// declare new variables
if len(newVars) > 0 {
// spec: "The scope of a constant or variable identifier declared inside
_ = T{t}
_ = P{f: p}
}
+
+// Test that we don't declare lhs variables in short variable
+// declarations before we type-check function literals on the
+// rhs.
+func issue24026() {
+ f := func() int { f(0) /* must refer to outer f */; return 0 }
+ _ = f
+
+ _ = func() {
+ f := func() { _ = f() /* must refer to outer f */ }
+ _ = f
+ }
+
+ // b and c must not be visible inside function literal
+ a := 0
+ a, b, c := func() (int, int, int) {
+ return a, b /* ERROR undeclared */ , c /* ERROR undeclared */
+ }()
+ _, _ = b, c
+}
+
+func f(int) {} // for issue24026