]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fixing 15.go for -G=3
authorDan Scales <danscales@google.com>
Sun, 22 Aug 2021 20:34:22 +0000 (13:34 -0700)
committerDan Scales <danscales@google.com>
Mon, 23 Aug 2021 16:57:27 +0000 (16:57 +0000)
Required two changes:

 - avoid creating a closure in the case where the actual receiver of an
   embedded method is not generic even though the base operand of the
   selector is generic. This is similar to the test suggested by wayne
   zuo - I thought it was clear in buildClosure, and easier to comment.

 - Propagate //go:nointerface to base generic methods and then to
   instantiations.

Change-Id: If30c834e4223c2639b7f7e74d44e6087aa9ccd76
Reviewed-on: https://go-review.googlesource.com/c/go/+/344251
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Wayne Zuo <wdvxdr1123@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>

src/cmd/compile/internal/noder/decl.go
src/cmd/compile/internal/noder/stencil.go
test/run.go

index cec31d87b754cdfd065cfb79b158cc66b06bc918..6b55ce1453924555bae4cc91fb3b7b8cd307c1f6 100644 (file)
@@ -104,6 +104,12 @@ func (g *irgen) funcDecl(out *ir.Nodes, decl *syntax.FuncDecl) {
                // the Fields to represent the receiver's method set.
                if recv := fn.Type().Recv(); recv != nil {
                        typ := types.ReceiverBaseType(recv.Type)
+                       if typ.OrigSym != nil {
+                               // For a generic method, we mark the methods on the
+                               // base generic type, since those are the methods
+                               // that will be stenciled.
+                               typ = typ.OrigSym.Def.Type()
+                       }
                        meth := typecheck.Lookdot1(fn, typecheck.Lookup(decl.Name.Value), typ, typ.Methods(), 0)
                        meth.SetNointerface(true)
                }
index 19b8f63c4b1c67a50cd5a4e62805887bafd58108..e8eee5290e2ff21f9b9958789236f8d7e6bd5b8c 100644 (file)
@@ -304,6 +304,11 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
                // of se.Selection, since that will be the type that actually has
                // the method.
                recv := deref(se.Selection.Type.Recv().Type)
+               if len(recv.RParams()) == 0 {
+                       // The embedded type that actually has the method is not
+                       // actually generic, so no need to build a closure.
+                       return x
+               }
                baseType := recv.OrigSym.Def.Type()
                var gf *ir.Name
                for _, m := range baseType.Methods().Slice() {
@@ -491,6 +496,9 @@ func (g *irgen) instantiateMethods() {
                baseSym := typ.OrigSym
                baseType := baseSym.Def.(*ir.Name).Type()
                for j, _ := range typ.Methods().Slice() {
+                       if baseType.Methods().Slice()[j].Nointerface() {
+                               typ.Methods().Slice()[j].SetNointerface(true)
+                       }
                        baseNname := baseType.Methods().Slice()[j].Nname.(*ir.Name)
                        // Eagerly generate the instantiations and dictionaries that implement these methods.
                        // We don't use the instantiations here, just generate them (and any
index 22e94b767cae7434406e1562a0a9f65555d8ec9a..3759059c95cf9c9f541c1b5a5e5f4609b21dd3ad 100644 (file)
@@ -2185,8 +2185,7 @@ var g3Failures = setOf(
 
        "typeparam/nested.go", // -G=3 doesn't support function-local types with generics
 
-       "typeparam/mdempsky/4.go",  // -G=3 can't export functions with labeled breaks in loops
-       "typeparam/mdempsky/15.go", // ICE in (*irgen).buildClosure
+       "typeparam/mdempsky/4.go", // -G=3 can't export functions with labeled breaks in loops
 )
 
 var unifiedFailures = setOf(