mirror of
https://github.com/golang/go
synced 2024-11-14 09:00:21 -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:
parent
7113d3a512
commit
2465ae6459
@ -279,6 +279,7 @@ func (check *Checker) assignVars(lhs, rhs []ast.Expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
|
func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
|
||||||
|
top := len(check.delayed)
|
||||||
scope := check.scope
|
scope := check.scope
|
||||||
|
|
||||||
// collect lhs variables
|
// collect lhs variables
|
||||||
@ -319,6 +320,9 @@ func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
|
|||||||
|
|
||||||
check.initVars(lhsVars, rhs, token.NoPos)
|
check.initVars(lhsVars, rhs, token.NoPos)
|
||||||
|
|
||||||
|
// process function literals in rhs expressions before scope changes
|
||||||
|
check.processDelayed(top)
|
||||||
|
|
||||||
// declare new variables
|
// declare new variables
|
||||||
if len(newVars) > 0 {
|
if len(newVars) > 0 {
|
||||||
// spec: "The scope of a constant or variable identifier declared inside
|
// spec: "The scope of a constant or variable identifier declared inside
|
||||||
|
22
src/go/types/testdata/issues.src
vendored
22
src/go/types/testdata/issues.src
vendored
@ -207,3 +207,25 @@ func issue20358() {
|
|||||||
_ = T{t}
|
_ = T{t}
|
||||||
_ = P{f: p}
|
_ = 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
|
||||||
|
Loading…
Reference in New Issue
Block a user