From: Robert Griesemer Date: Thu, 5 Sep 2024 00:15:57 +0000 (-0700) Subject: go/types, types2: factor type checking of func literals and generate go/types code X-Git-Tag: go1.24rc1~982 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a17356cd23163997031b648def23d56cbb76ae9a;p=gostls13.git go/types, types2: factor type checking of func literals and generate go/types code Move the code for type checking of function literals into literals.go. In go/types, the respective code is now generated from the types2 source. Change-Id: Ic81ab3c0d3c66d99bc0f2e21d66bf9a896ef9375 Reviewed-on: https://go-review.googlesource.com/c/go/+/610996 Reviewed-by: Tim King Auto-Submit: Robert Griesemer LUCI-TryBot-Result: Go LUCI Reviewed-by: Robert Griesemer --- diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index 30fa05673c..a1e3012bcb 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -1123,29 +1123,8 @@ func (check *Checker) exprInternal(T *target, x *operand, e syntax.Expr, hint Ty check.overflow(x, opPos(x.expr)) case *syntax.FuncLit: - if sig, ok := check.typ(e.Type).(*Signature); ok { - // Set the Scope's extent to the complete "func (...) {...}" - // so that Scope.Innermost works correctly. - sig.scope.pos = e.Pos() - sig.scope.end = endPos(e) - if !check.conf.IgnoreFuncBodies && e.Body != nil { - // Anonymous functions are considered part of the - // init expression/func declaration which contains - // them: use existing package-level declaration info. - decl := check.decl // capture for use in closure below - iota := check.iota // capture for use in closure below (go.dev/issue/22345) - // Don't type-check right away because the function may - // be part of a type definition to which the function - // body refers. Instead, type-check as soon as possible, - // but before the enclosing scope contents changes (go.dev/issue/22992). - check.later(func() { - check.funcBody(decl, "", sig, e.Body, iota) - }).describef(e, "func literal") - } - x.mode = value - x.typ = sig - } else { - check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e) + check.funcLit(x, e) + if x.mode == invalid { goto Error } diff --git a/src/cmd/compile/internal/types2/literals.go b/src/cmd/compile/internal/types2/literals.go index fbb139be8f..188c920776 100644 --- a/src/cmd/compile/internal/types2/literals.go +++ b/src/cmd/compile/internal/types2/literals.go @@ -11,6 +11,34 @@ import ( . "internal/types/errors" ) +func (check *Checker) funcLit(x *operand, e *syntax.FuncLit) { + if sig, ok := check.typ(e.Type).(*Signature); ok { + // Set the Scope's extent to the complete "func (...) {...}" + // so that Scope.Innermost works correctly. + sig.scope.pos = e.Pos() + sig.scope.end = endPos(e) + if !check.conf.IgnoreFuncBodies && e.Body != nil { + // Anonymous functions are considered part of the + // init expression/func declaration which contains + // them: use existing package-level declaration info. + decl := check.decl // capture for use in closure below + iota := check.iota // capture for use in closure below (go.dev/issue/22345) + // Don't type-check right away because the function may + // be part of a type definition to which the function + // body refers. Instead, type-check as soon as possible, + // but before the enclosing scope contents changes (go.dev/issue/22992). + check.later(func() { + check.funcBody(decl, "", sig, e.Body, iota) + }).describef(e, "func literal") + } + x.mode = value + x.typ = sig + } else { + check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e) + x.mode = invalid + } +} + func (check *Checker) compositeLit(T *target, x *operand, e *syntax.CompositeLit, hint Type) { var typ, base Type var isElem bool // true if composite literal is an element of an enclosing composite literal diff --git a/src/go/types/expr.go b/src/go/types/expr.go index ebc662e966..d17464e27e 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1101,29 +1101,8 @@ func (check *Checker) exprInternal(T *target, x *operand, e ast.Expr, hint Type) check.overflow(x, e.Pos()) case *ast.FuncLit: - if sig, ok := check.typ(e.Type).(*Signature); ok { - // Set the Scope's extent to the complete "func (...) {...}" - // so that Scope.Innermost works correctly. - sig.scope.pos = e.Pos() - sig.scope.end = endPos(e) - if !check.conf.IgnoreFuncBodies && e.Body != nil { - // Anonymous functions are considered part of the - // init expression/func declaration which contains - // them: use existing package-level declaration info. - decl := check.decl // capture for use in closure below - iota := check.iota // capture for use in closure below (go.dev/issue/22345) - // Don't type-check right away because the function may - // be part of a type definition to which the function - // body refers. Instead, type-check as soon as possible, - // but before the enclosing scope contents changes (go.dev/issue/22992). - check.later(func() { - check.funcBody(decl, "", sig, e.Body, iota) - }).describef(e, "func literal") - } - x.mode = value - x.typ = sig - } else { - check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e) + check.funcLit(x, e) + if x.mode == invalid { goto Error } diff --git a/src/go/types/literals.go b/src/go/types/literals.go index a32f8ca37c..5efb0360ad 100644 --- a/src/go/types/literals.go +++ b/src/go/types/literals.go @@ -14,6 +14,34 @@ import ( . "internal/types/errors" ) +func (check *Checker) funcLit(x *operand, e *ast.FuncLit) { + if sig, ok := check.typ(e.Type).(*Signature); ok { + // Set the Scope's extent to the complete "func (...) {...}" + // so that Scope.Innermost works correctly. + sig.scope.pos = e.Pos() + sig.scope.end = endPos(e) + if !check.conf.IgnoreFuncBodies && e.Body != nil { + // Anonymous functions are considered part of the + // init expression/func declaration which contains + // them: use existing package-level declaration info. + decl := check.decl // capture for use in closure below + iota := check.iota // capture for use in closure below (go.dev/issue/22345) + // Don't type-check right away because the function may + // be part of a type definition to which the function + // body refers. Instead, type-check as soon as possible, + // but before the enclosing scope contents changes (go.dev/issue/22992). + check.later(func() { + check.funcBody(decl, "", sig, e.Body, iota) + }).describef(e, "func literal") + } + x.mode = value + x.typ = sig + } else { + check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e) + x.mode = invalid + } +} + func (check *Checker) compositeLit(T *target, x *operand, e *ast.CompositeLit, hint Type) { var typ, base Type var isElem bool // true if composite literal is an element of an enclosing composite literal