mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
cmd/compile: always remove receiver type from instantiated method values
If a type T has a method foo, then var t T var i interface{} = t.foo The type of foo is a method type, but the type of t.foo should be a standard function type. Make sure we always do that conversion. Fixes #47775 Change-Id: I464ec792196b050aba1914e070a4ede34bfd0bfa Reviewed-on: https://go-review.googlesource.com/c/go/+/343881 Trust: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
8486ced8b0
commit
3081f817da
6 changed files with 72 additions and 5 deletions
|
@ -578,11 +578,7 @@ func transformDot(n *ir.SelectorExpr, isCall bool) ir.Node {
|
|||
|
||||
if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && !isCall {
|
||||
n.SetOp(ir.OMETHVALUE)
|
||||
if len(n.X.Type().RParams()) > 0 || n.X.Type().IsPtr() && len(n.X.Type().Elem().RParams()) > 0 {
|
||||
// TODO: MethodValueWrapper needed for generics?
|
||||
// Or did we successfully desugar all that at stencil time?
|
||||
return n
|
||||
}
|
||||
// This converts a method type to a function type. See issue 47775.
|
||||
n.SetType(typecheck.NewMethodType(n.Type(), nil))
|
||||
}
|
||||
return n
|
||||
|
|
|
@ -479,6 +479,12 @@ func autotmpname(n int) string {
|
|||
// f is method type, with receiver.
|
||||
// return function type, receiver as first argument (or not).
|
||||
func NewMethodType(sig *types.Type, recv *types.Type) *types.Type {
|
||||
if sig.HasTParam() {
|
||||
base.Fatalf("NewMethodType with type parameters in signature %+v", sig)
|
||||
}
|
||||
if recv != nil && recv.HasTParam() {
|
||||
base.Fatalf("NewMethodType with type parameters in receiver %+v", recv)
|
||||
}
|
||||
nrecvs := 0
|
||||
if recv != nil {
|
||||
nrecvs++
|
||||
|
|
19
test/typeparam/issue47775.dir/b.go
Normal file
19
test/typeparam/issue47775.dir/b.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
// 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 b
|
||||
|
||||
type C[T any] struct {
|
||||
}
|
||||
|
||||
func (c *C[T]) reset() {
|
||||
}
|
||||
|
||||
func New[T any]() {
|
||||
c := &C[T]{}
|
||||
z(c.reset)
|
||||
}
|
||||
|
||||
func z(interface{}) {
|
||||
}
|
11
test/typeparam/issue47775.dir/main.go
Normal file
11
test/typeparam/issue47775.dir/main.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
// 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 "b"
|
||||
|
||||
func main() {
|
||||
b.New[int]()
|
||||
}
|
7
test/typeparam/issue47775.go
Normal file
7
test/typeparam/issue47775.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
// rundir -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 ignored
|
28
test/typeparam/issue47775b.go
Normal file
28
test/typeparam/issue47775b.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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
|
||||
|
||||
type C[T any] struct {
|
||||
}
|
||||
|
||||
func (c *C[T]) reset() {
|
||||
}
|
||||
|
||||
func New[T any]() {
|
||||
c := &C[T]{}
|
||||
i = c.reset
|
||||
z(c.reset)
|
||||
}
|
||||
|
||||
var i interface{}
|
||||
|
||||
func z(interface{}) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
New[int]()
|
||||
}
|
Loading…
Reference in a new issue