diff options
author | Keith Randall <khr@golang.org> | 2021-08-20 16:15:53 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2021-08-23 19:27:46 +0000 |
commit | 3081f817da8c194982596ddddf5d3ec321c859af (patch) | |
tree | 75122cd8b260c224a9d35a5d0e474a3e5a11a149 /src | |
parent | 8486ced8b09f4425bfd85e09b021dc78f93aea08 (diff) | |
download | go-3081f817da8c194982596ddddf5d3ec321c859af.tar.gz go-3081f817da8c194982596ddddf5d3ec321c859af.zip |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/compile/internal/noder/transform.go | 6 | ||||
-rw-r--r-- | src/cmd/compile/internal/typecheck/dcl.go | 6 |
2 files changed, 7 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go index e1eeb8e739..140bb33234 100644 --- a/src/cmd/compile/internal/noder/transform.go +++ b/src/cmd/compile/internal/noder/transform.go @@ -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 diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go index 11e20f0f07..472d8d2b8a 100644 --- a/src/cmd/compile/internal/typecheck/dcl.go +++ b/src/cmd/compile/internal/typecheck/dcl.go @@ -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++ |