g.target.Inits = append(g.target.Inits, fn)
}
+ if fn.Type().HasTParam() {
+ g.topFuncIsGeneric = true
+ }
g.funcBody(fn, decl.Recv, decl.Type, decl.Body)
+ g.topFuncIsGeneric = false
if fn.Type().HasTParam() && fn.Body != nil {
// Set pointers to the dcls/body of a generic function/method in
// the Inl struct, so it is marked for export, is available for
cv.SetWalkdef(1)
}
- return ir.UseClosure(fn.OClosure, g.target)
+ if g.topFuncIsGeneric {
+ // Don't add any closure inside a generic function/method to the
+ // g.target.Decls list, even though it may not be generic itself.
+ // See issue #47514.
+ return ir.UseClosure(fn.OClosure, nil)
+ } else {
+ return ir.UseClosure(fn.OClosure, g.target)
+ }
}
func (g *irgen) typeExpr(typ syntax.Expr) *types.Type {
// dictionary syms which we need to finish, by writing out any itabconv
// entries.
dictSymsToFinalize []*delayInfo
+
+ // True when we are compiling a top-level generic function or method. Use to
+ // avoid adding closures of generic functions/methods to the target.Decls
+ // list.
+ topFuncIsGeneric bool
}
type delayInfo struct {
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that closures inside a generic function are not exported,
+// even though not themselves generic.
+
+package main
+
+func Do[T any]() {
+ _ = func() string {
+ return ""
+ }
+}
+
+func main() {
+ Do[int]()
+}