Skip to content

Commit 06a43e4

Browse files
committed
cmd/compile: fix case for structural types where we should be looking at typeparams
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 <[email protected]> Run-TryBot: Dan Scales <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 0907d57 commit 06a43e4

File tree

5 files changed

+45
-8
lines changed

5 files changed

+45
-8
lines changed

src/cmd/compile/internal/noder/stencil.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,11 @@ func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMe
641641
// over any pointer)
642642
recvType := nameNode.Type().Recv().Type
643643
recvType = deref(recvType)
644+
if recvType.IsFullyInstantiated() {
645+
// Get the type of the base generic type, so we get
646+
// its original typeparams.
647+
recvType = recvType.OrigSym().Def.(*ir.Name).Type()
648+
}
644649
tparams = recvType.RParams()
645650
} else {
646651
fields := nameNode.Type().TParams().Fields().Slice()
@@ -657,11 +662,9 @@ func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMe
657662
s1 := make([]*types.Type, len(shapes))
658663
for i, t := range shapes {
659664
var tparam *types.Type
660-
if tparams[i].Kind() == types.TTYPEPARAM {
661-
// Shapes are grouped differently for structural types, so we
662-
// pass the type param to Shapify(), so we can distinguish.
663-
tparam = tparams[i]
664-
}
665+
// Shapes are grouped differently for structural types, so we
666+
// pass the type param to Shapify(), so we can distinguish.
667+
tparam = tparams[i]
665668
if !t.IsShape() {
666669
s1[i] = typecheck.Shapify(t, i, tparam)
667670
} else {

src/cmd/compile/internal/typecheck/subr.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1432,9 +1432,9 @@ func genericTypeName(sym *types.Sym) string {
14321432
// For now, we only consider two types to have the same shape, if they have exactly
14331433
// the same underlying type or they are both pointer types.
14341434
//
1435-
// tparam is the associated typeparam. If there is a structural type for
1436-
// the associated type param (not common), then a pointer type t is mapped to its
1437-
// underlying type, rather than being merged with other pointers.
1435+
// tparam is the associated typeparam - it must be TTYPEPARAM type. If there is a
1436+
// structural type for the associated type param (not common), then a pointer type t
1437+
// is mapped to its underlying type, rather than being merged with other pointers.
14381438
//
14391439
// Shape types are also distinguished by the index of the type in a type param/arg
14401440
// list. We need to do this so we can distinguish and substitute properly for two

test/typeparam/issue51367.dir/a.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package a
6+
7+
type A[T any] struct{}
8+
9+
func (_ A[T]) Method() {}
10+
11+
func DoSomething[P any]() {
12+
a := A[*byte]{}
13+
a.Method()
14+
}

test/typeparam/issue51367.dir/main.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"a"
9+
)
10+
11+
func main() {
12+
a.DoSomething[byte]()
13+
}

test/typeparam/issue51367.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rundir -G=3
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package ignored

0 commit comments

Comments
 (0)