aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/signature.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-07-09 21:18:12 -0700
committerRobert Griesemer <gri@golang.org>2021-07-14 23:33:48 +0000
commit2a8087817c18314d81c4165258487cdba73ebc71 (patch)
treedeb784ee7f884be0013dbed05e26d2ce9c8aacc9 /src/cmd/compile/internal/types2/signature.go
parent95f8e64fc0ff53e4df6ba03e8dbbaf3d18695d1b (diff)
downloadgo-2a8087817c18314d81c4165258487cdba73ebc71.tar.gz
go-2a8087817c18314d81c4165258487cdba73ebc71.zip
[dev.typeparams] cmd/compile/internal/types2: cleanups around receiver type checks
Generic receiver types may be defined such that an instantiated receiver ends up being a pointer type. Disallow them as we do for non-generic receivers. Change-Id: I6612a52615a2999375c35aa1d69ab42f37d9f55d Reviewed-on: https://go-review.googlesource.com/c/go/+/333770 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/signature.go')
-rw-r--r--src/cmd/compile/internal/types2/signature.go32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/types2/signature.go b/src/cmd/compile/internal/types2/signature.go
index ab9a1c487e..fa5c3f7a9b 100644
--- a/src/cmd/compile/internal/types2/signature.go
+++ b/src/cmd/compile/internal/types2/signature.go
@@ -211,9 +211,10 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
// spec: "The receiver type must be of the form T or *T where T is a type name."
// (ignore invalid types - error was reported before)
- if t := rtyp; t != Typ[Invalid] {
+ if rtyp != Typ[Invalid] {
var err string
- if T := asNamed(t); T != nil {
+ switch T := rtyp.(type) {
+ case *Named:
// spec: "The type denoted by T is called the receiver base type; it must not
// be a pointer or interface type and it must be declared in the same package
// as the method."
@@ -224,23 +225,30 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
err = ""
}
} else {
- switch u := optype(T).(type) {
- case *Basic:
- // unsafe.Pointer is treated like a regular pointer
- if u.kind == UnsafePointer {
- err = "unsafe.Pointer"
+ // The underlying type of a receiver base type can be a type parameter;
+ // e.g. for methods with a generic receiver T[P] with type T[P any] P.
+ underIs(T, func(u Type) bool {
+ switch u := u.(type) {
+ case *Basic:
+ // unsafe.Pointer is treated like a regular pointer
+ if u.kind == UnsafePointer {
+ err = "unsafe.Pointer"
+ return false
+ }
+ case *Pointer, *Interface:
+ err = "pointer or interface type"
+ return false
}
- case *Pointer, *Interface:
- err = "pointer or interface type"
- }
+ return true
+ })
}
- } else if T := asBasic(t); T != nil {
+ case *Basic:
err = "basic or unnamed type"
if check.conf.CompilerErrorMessages {
check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
err = ""
}
- } else {
+ default:
check.errorf(recv.pos, "invalid receiver type %s", recv.typ)
}
if err != "" {