1
0
mirror of https://github.com/golang/go synced 2024-11-14 08:50:22 -07:00

go/types: fix regression with short variable declarations

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>
This commit is contained in:
Robert Griesemer 2018-02-21 20:27:29 -08:00
parent 7113d3a512
commit 2465ae6459
2 changed files with 26 additions and 0 deletions

View File

@ -279,6 +279,7 @@ func (check *Checker) assignVars(lhs, rhs []ast.Expr) {
}
func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
top := len(check.delayed)
scope := check.scope
// collect lhs variables
@ -319,6 +320,9 @@ func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
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

View File

@ -207,3 +207,25 @@ func issue20358() {
_ = 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