diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go index f0030efedc..cb0fe3bc3a 100644 --- a/src/go/types/assignments.go +++ b/src/go/types/assignments.go @@ -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 diff --git a/src/go/types/testdata/issues.src b/src/go/types/testdata/issues.src index 8729555e17..a346ab169a 100644 --- a/src/go/types/testdata/issues.src +++ b/src/go/types/testdata/issues.src @@ -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