]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix case for structural types where we should be looking at typeparams
authorDan Scales <danscales@google.com>
Fri, 25 Feb 2022 22:56:04 +0000 (14:56 -0800)
committerDan Scales <danscales@google.com>
Mon, 28 Feb 2022 15:58:07 +0000 (15:58 +0000)
In getInstantiation, we were not computing tparams correctly for the
case where the receiver of a method was a fully-instantiated type. This
wasn't affecting later parts of the function, since method
instantiations of fully-instantiated types were already being calculated
in an earlier path. But it did give us a non-typeparam when trying to
see if a shape was associated with a type param with a structural type.
The fix is just to get the typeparams associated with the base generic
type. Then we can eliminate a conditional check later in the code.
The tparam parameter of Shapify should always be non-nil

Fixes #51367

Change-Id: I6f95fe603886148b2dad0c581416c51373c85009
Reviewed-on: https://go-review.googlesource.com/c/go/+/388116
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/typecheck/subr.go
test/typeparam/issue51367.dir/a.go [new file with mode: 0644]
test/typeparam/issue51367.dir/main.go [new file with mode: 0644]
test/typeparam/issue51367.go [new file with mode: 0644]

index 807794dc3007bf562b0042343e7c6644eea22c53..9d17d5ffd1b61fa6e566e27fca36f5b9f10ee51d 100644 (file)
@@ -641,6 +641,11 @@ func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMe
                // over any pointer)
                recvType := nameNode.Type().Recv().Type
                recvType = deref(recvType)
+               if recvType.IsFullyInstantiated() {
+                       // Get the type of the base generic type, so we get
+                       // its original typeparams.
+                       recvType = recvType.OrigSym().Def.(*ir.Name).Type()
+               }
                tparams = recvType.RParams()
        } else {
                fields := nameNode.Type().TParams().Fields().Slice()
@@ -657,11 +662,9 @@ func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMe
        s1 := make([]*types.Type, len(shapes))
        for i, t := range shapes {
                var tparam *types.Type
-               if tparams[i].Kind() == types.TTYPEPARAM {
-                       // Shapes are grouped differently for structural types, so we
-                       // pass the type param to Shapify(), so we can distinguish.
-                       tparam = tparams[i]
-               }
+               // Shapes are grouped differently for structural types, so we
+               // pass the type param to Shapify(), so we can distinguish.
+               tparam = tparams[i]
                if !t.IsShape() {
                        s1[i] = typecheck.Shapify(t, i, tparam)
                } else {
index 9892471142086a62975ccac5de570c7c6eca652d..181066ba969e8ed6d666a6afd66d0b487a3bd653 100644 (file)
@@ -1432,9 +1432,9 @@ func genericTypeName(sym *types.Sym) string {
 // For now, we only consider two types to have the same shape, if they have exactly
 // the same underlying type or they are both pointer types.
 //
-//  tparam is the associated typeparam. If there is a structural type for
-//  the associated type param (not common), then a pointer type t is mapped to its
-//  underlying type, rather than being merged with other pointers.
+//  tparam is the associated typeparam - it must be TTYPEPARAM type. If there is a
+//  structural type for the associated type param (not common), then a pointer type t
+//  is mapped to its underlying type, rather than being merged with other pointers.
 //
 //  Shape types are also distinguished by the index of the type in a type param/arg
 //  list. We need to do this so we can distinguish and substitute properly for two
diff --git a/test/typeparam/issue51367.dir/a.go b/test/typeparam/issue51367.dir/a.go
new file mode 100644 (file)
index 0000000..be0c3b0
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2022 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.
+
+package a
+
+type A[T any] struct{}
+
+func (_ A[T]) Method() {}
+
+func DoSomething[P any]() {
+       a := A[*byte]{}
+       a.Method()
+}
diff --git a/test/typeparam/issue51367.dir/main.go b/test/typeparam/issue51367.dir/main.go
new file mode 100644 (file)
index 0000000..64273d3
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2022 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.
+
+package main
+
+import (
+       "a"
+)
+
+func main() {
+       a.DoSomething[byte]()
+}
diff --git a/test/typeparam/issue51367.go b/test/typeparam/issue51367.go
new file mode 100644 (file)
index 0000000..642f4bf
--- /dev/null
@@ -0,0 +1,7 @@
+// rundir -G=3
+
+// Copyright 2022 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.
+
+package ignored