mirror of
https://github.com/golang/go
synced 2024-11-26 18:06:55 -07:00
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 <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
0907d57abf
commit
06a43e4ab6
@ -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 {
|
||||
|
@ -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
|
||||
|
14
test/typeparam/issue51367.dir/a.go
Normal file
14
test/typeparam/issue51367.dir/a.go
Normal file
@ -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()
|
||||
}
|
13
test/typeparam/issue51367.dir/main.go
Normal file
13
test/typeparam/issue51367.dir/main.go
Normal file
@ -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]()
|
||||
}
|
7
test/typeparam/issue51367.go
Normal file
7
test/typeparam/issue51367.go
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user