// Anonymous and blank PPARAMOUTs are declared as ~rNN and ~bNN Names, respectively.
Dcl []*Name
- ClosureType Ntype // closure representation type
-
// ClosureVars lists the free variables that are used within a
// function literal, but formally declared in an enclosing
// function. The variables in this slice are the closure function's
_32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms
}{
- {Func{}, 196, 344},
+ {Func{}, 188, 328},
{Name{}, 116, 208},
}
func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
xtype := p.typeExpr(expr.Type)
- ntype := p.typeExpr(expr.Type)
fn := ir.NewFunc(p.pos(expr))
fn.SetIsHiddenClosure(ir.CurFunc != nil)
fn.Nname.Defn = fn
clo := ir.NewClosureExpr(p.pos(expr), fn)
- fn.ClosureType = ntype
fn.OClosure = clo
p.funcBody(fn, expr.Body)
fn.Iota = x
}
- fn.ClosureType = typecheckNtype(fn.ClosureType)
- clo.SetType(fn.ClosureType.Type())
fn.SetClosureCalled(top&ctxCallee != 0)
// Do not typecheck fn twice, otherwise, we will end up pushing
// fn to Target.Decls multiple times, causing initLSym called twice.
// See #30709
if fn.Typecheck() == 1 {
+ clo.SetType(fn.Type())
return
}
fn.Nname.SetSym(closurename(ir.CurFunc))
ir.MarkFunc(fn.Nname)
Func(fn)
+ clo.SetType(fn.Type())
// Type check the body now, but only if we're inside a function.
// At top level (in a variable initialization: curfn==nil) we're not
// f is ONAME of the actual function.
f := clofn.Nname
-
- // Prepend params and decls.
typ := f.Type()
- typ.Params().SetFields(append(params, typ.Params().FieldSlice()...))
+
+ // Create new function type with parameters prepended, and
+ // then update type and declarations.
+ typ = types.NewSignature(typ.Pkg(), nil, append(params, typ.Params().FieldSlice()...), typ.Results().FieldSlice())
+ f.SetType(typ)
clofn.Dcl = append(decls, clofn.Dcl...)
// Rewrite call.
// because typecheck gave it the result type of the OCLOSURE
// node, but we only rewrote the ONAME node's type. Logically,
// they're the same, but the stack offsets probably changed.
- //
- // TODO(mdempsky): Reuse a single type for both.
if typ.NumResults() == 1 {
n.SetType(typ.Results().Field(0).Type)
} else {