aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2024-11-18 12:45:17 -0800
committerGopher Robot <gobot@golang.org>2024-11-20 20:03:55 +0000
commit91af7119cd33e59a04d96073bc0f40b588938163 (patch)
treece09ccacbb139c5223dd7b14280efe7365cb589e /src/internal
parentd69e6f63c349741a450e9de9585ad555babefad4 (diff)
downloadgo-91af7119cd33e59a04d96073bc0f40b588938163.tar.xz
go/types, types2: disallow new methods on generic alias and instantiated types
If the receiver is an alias declaring type parameters, report an error and ensure that the receiver type remains invalid. Collect type parameters etc. as before but do not attempt to find their constraints or instantiate the receiver type. The constraints of the type parameters will be invalid by default. The receiver type will not be (lazily) instantiated which causes problems with existing invariants. If a receiver denotes an instantiated (alias or defined) type, report an error and ensure that the receiver type remains invalid. While at it, add more comments and bring go/types and types2 closer together where there were differences. Fixes #70417. Change-Id: I87ef0b42d2f70464664cacc410f4b7eb1c994241 Reviewed-on: https://go-review.googlesource.com/c/go/+/629080 Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/types/testdata/fixedbugs/issue47968.go10
-rw-r--r--src/internal/types/testdata/fixedbugs/issue70417.go58
2 files changed, 64 insertions, 4 deletions
diff --git a/src/internal/types/testdata/fixedbugs/issue47968.go b/src/internal/types/testdata/fixedbugs/issue47968.go
index 83a1786133..e260c63a76 100644
--- a/src/internal/types/testdata/fixedbugs/issue47968.go
+++ b/src/internal/types/testdata/fixedbugs/issue47968.go
@@ -1,3 +1,5 @@
+// -gotypesalias=1
+
// 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.
@@ -10,12 +12,12 @@ func (T[P]) m1()
type A1 = T // ERROR "cannot use generic type"
-func (A1[P]) m2() {}
+func (A1[P]) m2() {} // don't report a follow-on error on A1
type A2 = T[int]
-func (A2 /* ERRORx `cannot define new methods on instantiated type (T\[int\]|A2)` */) m3() {}
-func (_ /* ERRORx `cannot define new methods on instantiated type (T\[int\]|A2)` */ A2) m4() {}
+func (A2 /* ERROR "cannot define new methods on instantiated type T[int]" */) m3() {}
+func (_ A2 /* ERROR "cannot define new methods on instantiated type T[int]" */) m4() {}
-func (T[int]) m5() {} // int is the type parameter name, not an instantiation
+func (T[int]) m5() {} // int is the type parameter name, not an instantiation
func (T[* /* ERROR "must be an identifier" */ int]) m6() {} // syntax error
diff --git a/src/internal/types/testdata/fixedbugs/issue70417.go b/src/internal/types/testdata/fixedbugs/issue70417.go
new file mode 100644
index 0000000000..74bdea3b8a
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue70417.go
@@ -0,0 +1,58 @@
+// -gotypesalias=1
+
+// Copyright 2024 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 T[P any] struct{}
+
+// A0
+type A0 = T[int]
+type B0 = *T[int]
+
+func (A0 /* ERROR "cannot define new methods on instantiated type T[int]" */) m() {}
+func (*A0 /* ERROR "cannot define new methods on instantiated type T[int]" */) m() {}
+func (B0 /* ERROR "cannot define new methods on instantiated type T[int]" */) m() {}
+
+// A1
+type A1[P any] = T[P]
+type B1[P any] = *T[P]
+
+func (A1 /* ERROR "cannot define new methods on generic alias type A1[P any]" */ [P]) m() {}
+func (*A1 /* ERROR "cannot define new methods on generic alias type A1[P any]" */ [P]) m() {}
+func (B1 /* ERROR "cannot define new methods on generic alias type B1[P any]" */ [P]) m() {}
+
+// A2
+type A2[P any] = T[int]
+type B2[P any] = *T[int]
+
+func (A2 /* ERROR "cannot define new methods on generic alias type A2[P any]" */ [P]) m() {}
+func (*A2 /* ERROR "cannot define new methods on generic alias type A2[P any]" */ [P]) m() {}
+func (B2 /* ERROR "cannot define new methods on generic alias type B2[P any]" */ [P]) m() {}
+
+// A3
+type A3 = T[int]
+type B3 = *T[int]
+
+func (A3 /* ERROR "cannot define new methods on instantiated type T[int]" */) m() {}
+func (*A3 /* ERROR "cannot define new methods on instantiated type T[int]" */) m() {}
+func (B3 /* ERROR "cannot define new methods on instantiated type T[int]" */) m() {}
+
+// A4
+type A4 = T // ERROR "cannot use generic type T[P any] without instantiation"
+type B4 = *T // ERROR "cannot use generic type T[P any] without instantiation"
+
+func (A4[P]) m1() {} // don't report a follow-on error on A4
+func (*A4[P]) m2() {} // don't report a follow-on error on A4
+func (B4[P]) m3() {} // don't report a follow-on error on B4
+
+// instantiation in the middle of an alias chain
+type S struct{}
+type C0 = S
+type C1[P any] = C0
+type C2 = *C1[int]
+
+func (C2 /* ERROR "cannot define new methods on instantiated type C1[int]" */) m() {}
+func (*C2 /* ERROR "cannot define new methods on instantiated type C1[int]" */) m() {}