aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-08-22 13:34:22 -0700
committerDan Scales <danscales@google.com>2021-08-23 16:57:27 +0000
commitf457ecc7f096c7e6b225003b583b989384ef0fcb (patch)
tree5462a743116a6264ae55e5b64b63ed71c2a987b5
parentf1d8ea1da3ef814ea57b545fc967865640a868ab (diff)
downloadgo-f457ecc7f096c7e6b225003b583b989384ef0fcb.tar.gz
go-f457ecc7f096c7e6b225003b583b989384ef0fcb.zip
cmd/compile: fixing 15.go for -G=3
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>
-rw-r--r--src/cmd/compile/internal/noder/decl.go6
-rw-r--r--src/cmd/compile/internal/noder/stencil.go8
-rw-r--r--test/run.go3
3 files changed, 15 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/noder/decl.go b/src/cmd/compile/internal/noder/decl.go
index cec31d87b7..6b55ce1453 100644
--- a/src/cmd/compile/internal/noder/decl.go
+++ b/src/cmd/compile/internal/noder/decl.go
@@ -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)
}
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index 19b8f63c4b..e8eee5290e 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -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
diff --git a/test/run.go b/test/run.go
index 22e94b767c..3759059c95 100644
--- a/test/run.go
+++ b/test/run.go
@@ -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(