//fmt.Printf("Inlining func %v with closure into %v\n", subst.fn, ir.FuncName(ir.CurFunc))
- outerfunc := subst.newclofn
- if outerfunc == nil {
- outerfunc = ir.CurFunc
- }
-
oldfn := n.Func
- newfn := ir.NewClosureFunc(oldfn.Pos(), outerfunc)
+ newfn := ir.NewClosureFunc(oldfn.Pos(), true)
// Ntype can be nil for -G=3 mode.
if oldfn.Nname.Ntype != nil {
return pkg.Lookup(fmt.Sprintf("%s.%s%d", outer, prefix, *gen))
}
-// NewClosureFunc creates a new Func to represent a function literal
-// within outerfn.
-func NewClosureFunc(pos src.XPos, outerfn *Func) *Func {
+// NewClosureFunc creates a new Func to represent a function literal.
+// If hidden is true, then the closure is marked hidden (i.e., as a
+// function literal contained within another function, rather than a
+// package-scope variable initialization expression).
+func NewClosureFunc(pos src.XPos, hidden bool) *Func {
fn := NewFunc(pos)
- fn.SetIsHiddenClosure(outerfn != nil)
+ fn.SetIsHiddenClosure(hidden)
fn.Nname = NewNameAt(pos, BlankNode.Sym())
fn.Nname.Func = fn
// NameClosure generates a unique for the given function literal,
// which must have appeared within outerfn.
func NameClosure(clo *ClosureExpr, outerfn *Func) {
- name := clo.Func.Nname
+ fn := clo.Func
+ if fn.IsHiddenClosure() != (outerfn != nil) {
+ base.FatalfAt(clo.Pos(), "closure naming inconsistency: hidden %v, but outer %v", fn.IsHiddenClosure(), outerfn)
+ }
+
+ name := fn.Nname
if !IsBlank(name) {
base.FatalfAt(clo.Pos(), "closure already named: %v", name)
}
}
func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
- fn := ir.NewClosureFunc(g.pos(expr), ir.CurFunc)
+ fn := ir.NewClosureFunc(g.pos(expr), ir.CurFunc != nil)
ir.NameClosure(fn.OClosure, ir.CurFunc)
typ := g.typ(typ2)
}
func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
- fn := ir.NewClosureFunc(p.pos(expr), ir.CurFunc)
+ fn := ir.NewClosureFunc(p.pos(expr), ir.CurFunc != nil)
fn.Nname.Ntype = p.typeExpr(expr.Type)
p.funcBody(fn, expr.Body)
// }
// Make a new internal function.
- fn := ir.NewClosureFunc(pos, outer)
+ fn := ir.NewClosureFunc(pos, outer != nil)
ir.NameClosure(fn.OClosure, outer)
// This is the dictionary we want to use.
// Need to duplicate x.Func.Nname, x.Func.Dcl, x.Func.ClosureVars, and
// x.Func.Body.
oldfn := x.Func
- newfn := ir.NewClosureFunc(oldfn.Pos(), subst.newf)
+ newfn := ir.NewClosureFunc(oldfn.Pos(), subst.newf != nil)
ir.NameClosure(newfn.OClosure, subst.newf)
newfn.SetClosureCalled(oldfn.ClosureCalled())
// All the remaining code below is similar to (*noder).funcLit(), but
// with Dcls and ClosureVars lists already set up
- fn := ir.NewClosureFunc(pos, r.curfn)
+ fn := ir.NewClosureFunc(pos, true)
fn.Nname.SetType(typ)
cvars := make([]*ir.Name, r.int64())
}
// Create a new no-argument function that we'll hand off to defer.
- outerfn := ir.CurFunc
-
- fn := ir.NewClosureFunc(base.Pos, outerfn)
+ fn := ir.NewClosureFunc(base.Pos, true)
fn.Nname.SetType(types.NewSignature(types.LocalPkg, nil, nil, nil, nil))
fn.SetWrapper(true)
// Finalize body, register function on the main decls list.
fn.Body = []ir.Node{newcall}
- ir.FinishCaptureNames(n.Pos(), outerfn, fn)
+ ir.FinishCaptureNames(n.Pos(), ir.CurFunc, fn)
// Create closure expr
clo := typecheck.Expr(fn.OClosure).(*ir.ClosureExpr)