]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix wrong instantiated type for embedded receiver
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 8 Sep 2021 18:11:26 +0000 (01:11 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 9 Sep 2021 03:31:51 +0000 (03:31 +0000)
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>
src/cmd/compile/internal/noder/expr.go
test/typeparam/issue47797.go [new file with mode: 0644]
test/typeparam/issue48253.go [new file with mode: 0644]

index 5eeafddae2ace2f84e877c3331e62c6b6defa41e..045f028e1aa124c3dddb46a0e7a7e89ede6fb822 100644 (file)
@@ -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))
 }
diff --git a/test/typeparam/issue47797.go b/test/typeparam/issue47797.go
new file mode 100644 (file)
index 0000000..3e80d3c
--- /dev/null
@@ -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()
+}
diff --git a/test/typeparam/issue48253.go b/test/typeparam/issue48253.go
new file mode 100644 (file)
index 0000000..7bd0234
--- /dev/null
@@ -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()
+}