Skip to content

Commit b2f09cd

Browse files
committed
go/types: do not declare new methods on instantiated types
This is a port of CL 345472 to go/types. Change-Id: I0e2a88909ecebe9dea3325244153f5c74e4c3ce7 Reviewed-on: https://go-review.googlesource.com/c/go/+/346553 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 5e9ba0b commit b2f09cd

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

src/go/types/signature.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
127127
// Also: Don't report an error via genericType since it will be reported
128128
// again when we type-check the signature.
129129
// TODO(gri) maybe the receiver should be marked as invalid instead?
130-
if recv := asNamed(check.genericType(rname, false)); recv != nil {
130+
if recv, _ := check.genericType(rname, false).(*Named); recv != nil {
131131
recvTParams = recv.TParams().list()
132132
}
133133
}
@@ -201,6 +201,12 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
201201
switch T := rtyp.(type) {
202202
case *Named:
203203
T.expand(nil)
204+
// The receiver type may be an instantiated type referred to
205+
// by an alias (which cannot have receiver parameters for now).
206+
if T.TArgs() != nil && sig.RParams() == nil {
207+
check.errorf(atPos(recv.pos), _Todo, "cannot define methods on instantiated type %s", recv.typ)
208+
break
209+
}
204210
// spec: "The type denoted by T is called the receiver base type; it must not
205211
// be a pointer or interface type and it must be declared in the same package
206212
// as the method."
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
type T[P any] struct{}
8+
9+
func (T[P]) m1()
10+
11+
type A1 = T
12+
13+
func (A1[P]) m2() {}
14+
15+
type A2 = T[int]
16+
17+
func (A2 /* ERROR cannot define methods on instantiated type T\[int\] */) m3() {}
18+
func (_ /* ERROR cannot define methods on instantiated type T\[int\] */ A2) m4() {}
19+
20+
func (T[int]) m5() {} // int is the type parameter name, not an instantiation
21+
func (T[* /* ERROR must be an identifier */ int]) m6() {} // syntax error

0 commit comments

Comments
 (0)