mirror of
https://github.com/golang/go
synced 2024-11-02 08:01:26 +00:00
cmd/compile: fix wrong instantiated type for embedded receiver
In case of embedded field, if the receiver was fully instantiated, we must use its instantiated type, instead of passing the type params of the base receiver. Fixes #47797 Fixes #48253 Change-Id: I97613e7e669a72605137e82406f7bf5fbb629378 Reviewed-on: https://go-review.googlesource.com/c/go/+/348549 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Dan Scales <danscales@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
d62866ef79
commit
2481f6e367
3 changed files with 59 additions and 15 deletions
|
@ -360,12 +360,10 @@ func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.Selecto
|
|||
n.(*ir.SelectorExpr).Selection.Nname = method
|
||||
typed(method.Type(), n)
|
||||
|
||||
// selinfo.Targs() are the types used to
|
||||
// instantiate the type of receiver
|
||||
targs2 := getTargs(selinfo)
|
||||
targs := make([]ir.Node, targs2.Len())
|
||||
xt := deref(x.Type())
|
||||
targs := make([]ir.Node, len(xt.RParams()))
|
||||
for i := range targs {
|
||||
targs[i] = ir.TypeNode(g.typ(targs2.At(i)))
|
||||
targs[i] = ir.TypeNode(xt.RParams()[i])
|
||||
}
|
||||
|
||||
// Create function instantiation with the type
|
||||
|
@ -388,16 +386,6 @@ func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.Selecto
|
|||
return n
|
||||
}
|
||||
|
||||
// getTargs gets the targs associated with the receiver of a selected method
|
||||
func getTargs(selinfo *types2.Selection) *types2.TypeList {
|
||||
r := deref2(selinfo.Recv())
|
||||
n := types2.AsNamed(r)
|
||||
if n == nil {
|
||||
base.Fatalf("Incorrect type for selinfo %v", selinfo)
|
||||
}
|
||||
return n.TypeArgs()
|
||||
}
|
||||
|
||||
func (g *irgen) exprList(expr syntax.Expr) []ir.Node {
|
||||
return g.exprs(unpackListExpr(expr))
|
||||
}
|
||||
|
|
22
test/typeparam/issue47797.go
Normal file
22
test/typeparam/issue47797.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
// compile -G=3
|
||||
|
||||
// Copyright 2021 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 p
|
||||
|
||||
type Foo[T any] struct {
|
||||
Val T
|
||||
}
|
||||
|
||||
func (f Foo[T]) Bat() {}
|
||||
|
||||
type Bar struct {
|
||||
Foo[int]
|
||||
}
|
||||
|
||||
func foo() {
|
||||
var b Bar
|
||||
b.Bat()
|
||||
}
|
34
test/typeparam/issue48253.go
Normal file
34
test/typeparam/issue48253.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// run -gcflags="-G=3"
|
||||
|
||||
// Copyright 2021 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 (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type A[T any] struct {
|
||||
B[int]
|
||||
}
|
||||
|
||||
type B[T any] struct {
|
||||
}
|
||||
|
||||
func (b B[T]) Bat() {
|
||||
t := new(T)
|
||||
if tt := reflect.TypeOf(t); tt.Kind() != reflect.Pointer || tt.Elem().Kind() != reflect.Int {
|
||||
panic("unexpected type, want: *int, got: "+tt.String())
|
||||
}
|
||||
}
|
||||
|
||||
type Foo struct {
|
||||
A[string]
|
||||
}
|
||||
func main() {
|
||||
Foo{}.A.Bat()
|
||||
Foo{}.A.B.Bat()
|
||||
Foo{}.Bat()
|
||||
}
|
Loading…
Reference in a new issue