1
0
mirror of https://github.com/golang/go synced 2024-11-25 09:57:57 -07:00

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 <taking@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
Robert Griesemer 2024-09-04 17:15:57 -07:00 committed by Gopher Robot
parent 829d1b346f
commit a17356cd23
4 changed files with 60 additions and 46 deletions

View File

@ -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, "<function literal>", 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
}

View File

@ -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, "<function literal>", 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

View File

@ -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, "<function literal>", 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
}

View File

@ -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, "<function literal>", 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