[dev.typeparams] cmd/compile: refactor closure construction

typecheck.tcClosure is complicated with many code flows because all of
its callers setup the closure funcs in slightly different ways. E.g.,
it's non-obvious who's responsible for setting the underlying func's
Sym or adding it to target.Decls, or how to write new code that
constructs a closure without interfering with existing code.

This CL refactors everything to use three common functions in package
ir: NewClosureFunc (which handle creating the Func, Name, and
ClosureExpr and wiring them together), NameClosure (which generates
and assigns its unique Sym), and UseClosure (which handles adding the
Func to target.Decls).

Most IR builders can actually name the closure right away, but the
legacy noder+typecheck path may not yet know the name of the enclosing
function. In particular, for methods declared with aliased receiver
parameters, we need to wait until after typechecking top-level
declarations to know the method's true name. So they're left anonymous
until typecheck.

UseClosure does relatively little work today, but it serves as a
useful spot to check that the code setting up closures got it right.
It may also eventually serve as an optimization point for early
lifting of trivial closures, which may or may not ultimately be
beneficial.

Change-Id: I7da1e93c70d268f575b12d6aaeb2336eb910a6f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/327051
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2021-06-11 03:09:26 -07:00
parent 8f00eb0099
commit 0132b91127
10 changed files with 200 additions and 196 deletions

View file

@ -373,19 +373,13 @@ func (g *irgen) compLit(typ types2.Type, lit *syntax.CompositeLit) ir.Node {
}
func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
fn := ir.NewFunc(g.pos(expr))
fn.SetIsHiddenClosure(ir.CurFunc != nil)
fn := ir.NewClosureFunc(g.pos(expr), ir.CurFunc)
ir.NameClosure(fn.OClosure, ir.CurFunc)
fn.Nname = ir.NewNameAt(g.pos(expr), typecheck.ClosureName(ir.CurFunc))
ir.MarkFunc(fn.Nname)
typ := g.typ(typ2)
fn.Nname.Func = fn
fn.Nname.Defn = fn
typed(typ, fn.Nname)
fn.SetTypecheck(1)
fn.OClosure = ir.NewClosureExpr(g.pos(expr), fn)
typed(typ, fn.OClosure)
fn.SetTypecheck(1)
g.funcBody(fn, nil, expr.Type, expr.Body)
@ -399,9 +393,7 @@ func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
cv.SetWalkdef(1)
}
g.target.Decls = append(g.target.Decls, fn)
return fn.OClosure
return ir.UseClosure(fn.OClosure, g.target)
}
func (g *irgen) typeExpr(typ syntax.Expr) *types.Type {