aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2022-03-30 12:19:24 -0700
committerRobert Griesemer <gri@golang.org>2022-03-31 14:51:17 +0000
commit2ea9376266b71e8a0752b8b3663bbf5b9ed48c4d (patch)
treeeba99ba55fa1427bc27e3c59c85a1200c80ee675 /src
parent109a18dce7ef8ecb2aa60cef25362ebd05661ea0 (diff)
downloadgo-2ea9376266b71e8a0752b8b3663bbf5b9ed48c4d.tar.xz
go/types, types2: better error message for invalid type parameter term
The spec says "In a union, a term cannot be a type parameter,...", but it's really the type in a term that cannot be a type parameter. (Also, for the spec's purposes, a single term is still a union.) This CL changes the current error message from: "cannot use type parameter in typeset" to one of two messages: "term cannot be a type parameter" (for term of form P) "type in term ~P cannot be a type parameter (for term of form ~P) which are more specific and match the spec more closely. Fixes #50420. Change-Id: Id48503efc8416cabc03d5c40d8e64d5b3a7f078e Reviewed-on: https://go-review.googlesource.com/c/go/+/396874 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/testdata/examples/constraints.go6
-rw-r--r--src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go2
-rw-r--r--src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go32
-rw-r--r--src/cmd/compile/internal/types2/union.go6
-rw-r--r--src/go/types/testdata/examples/constraints.go6
-rw-r--r--src/go/types/testdata/fixedbugs/issue39948.go2
-rw-r--r--src/go/types/testdata/fixedbugs/issue47127.go32
-rw-r--r--src/go/types/union.go6
8 files changed, 50 insertions, 42 deletions
diff --git a/src/cmd/compile/internal/types2/testdata/examples/constraints.go b/src/cmd/compile/internal/types2/testdata/examples/constraints.go
index 4d7f70313a..fb01be56a2 100644
--- a/src/cmd/compile/internal/types2/testdata/examples/constraints.go
+++ b/src/cmd/compile/internal/types2/testdata/examples/constraints.go
@@ -44,9 +44,9 @@ type (
type (
_[T interface{ *T } ] struct{} // ok
_[T interface{ int | *T } ] struct{} // ok
- _[T interface{ T /* ERROR cannot embed a type parameter */ } ] struct{}
- _[T interface{ ~T /* ERROR cannot embed a type parameter */ } ] struct{}
- _[T interface{ int|T /* ERROR cannot embed a type parameter */ }] struct{}
+ _[T interface{ T /* ERROR term cannot be a type parameter */ } ] struct{}
+ _[T interface{ ~T /* ERROR type in term ~T cannot be a type parameter */ } ] struct{}
+ _[T interface{ int|T /* ERROR term cannot be a type parameter */ }] struct{}
)
// Multiple embedded union elements are intersected. The order in which they
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go
index e38e57268d..c893cc049e 100644
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go
@@ -5,5 +5,5 @@
package p
type T[P any] interface{
- P // ERROR cannot embed a type parameter
+ P // ERROR term cannot be a type parameter
}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go
index 108d600a38..bb4b487eb2 100644
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go
@@ -8,30 +8,30 @@ package p
type (
_[P any] interface{ *P | []P | chan P | map[string]P }
- _[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
+ _[P any] interface{ P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
+ _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
)
func _[P any]() {
type (
_[P any] interface{ *P | []P | chan P | map[string]P }
- _[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
+ _[P any] interface{ P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
+ _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
_ interface{ *P | []P | chan P | map[string]P }
- _ interface{ P /* ERROR "cannot embed a type parameter" */ }
- _ interface{ ~P /* ERROR "cannot embed a type parameter" */ }
- _ interface{ int | P /* ERROR "cannot embed a type parameter" */ }
- _ interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
+ _ interface{ P /* ERROR term cannot be a type parameter */ }
+ _ interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
+ _ interface{ int | P /* ERROR term cannot be a type parameter */ }
+ _ interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
)
}
func _[P any, Q interface{ *P | []P | chan P | map[string]P }]() {}
-func _[P any, Q interface{ P /* ERROR "cannot embed a type parameter" */ }]() {}
-func _[P any, Q interface{ ~P /* ERROR "cannot embed a type parameter" */ }]() {}
-func _[P any, Q interface{ int | P /* ERROR "cannot embed a type parameter" */ }]() {}
-func _[P any, Q interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }]() {}
+func _[P any, Q interface{ P /* ERROR term cannot be a type parameter */ }]() {}
+func _[P any, Q interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {}
+func _[P any, Q interface{ int | P /* ERROR term cannot be a type parameter */ }]() {}
+func _[P any, Q interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {}
diff --git a/src/cmd/compile/internal/types2/union.go b/src/cmd/compile/internal/types2/union.go
index 132e73098a..57f1a4fe2a 100644
--- a/src/cmd/compile/internal/types2/union.go
+++ b/src/cmd/compile/internal/types2/union.go
@@ -148,7 +148,11 @@ func parseTilde(check *Checker, tx syntax.Expr) *Term {
// simply use its underlying type (like we do for other named, embedded interfaces),
// and since the underlying type is an interface the embedding is well defined.
if isTypeParam(typ) {
- check.error(x, "cannot embed a type parameter")
+ if tilde {
+ check.errorf(x, "type in term %s cannot be a type parameter", tx)
+ } else {
+ check.error(x, "term cannot be a type parameter")
+ }
typ = Typ[Invalid]
}
term := NewTerm(tilde, typ)
diff --git a/src/go/types/testdata/examples/constraints.go b/src/go/types/testdata/examples/constraints.go
index 4d7f70313a..fb01be56a2 100644
--- a/src/go/types/testdata/examples/constraints.go
+++ b/src/go/types/testdata/examples/constraints.go
@@ -44,9 +44,9 @@ type (
type (
_[T interface{ *T } ] struct{} // ok
_[T interface{ int | *T } ] struct{} // ok
- _[T interface{ T /* ERROR cannot embed a type parameter */ } ] struct{}
- _[T interface{ ~T /* ERROR cannot embed a type parameter */ } ] struct{}
- _[T interface{ int|T /* ERROR cannot embed a type parameter */ }] struct{}
+ _[T interface{ T /* ERROR term cannot be a type parameter */ } ] struct{}
+ _[T interface{ ~T /* ERROR type in term ~T cannot be a type parameter */ } ] struct{}
+ _[T interface{ int|T /* ERROR term cannot be a type parameter */ }] struct{}
)
// Multiple embedded union elements are intersected. The order in which they
diff --git a/src/go/types/testdata/fixedbugs/issue39948.go b/src/go/types/testdata/fixedbugs/issue39948.go
index e38e57268d..c893cc049e 100644
--- a/src/go/types/testdata/fixedbugs/issue39948.go
+++ b/src/go/types/testdata/fixedbugs/issue39948.go
@@ -5,5 +5,5 @@
package p
type T[P any] interface{
- P // ERROR cannot embed a type parameter
+ P // ERROR term cannot be a type parameter
}
diff --git a/src/go/types/testdata/fixedbugs/issue47127.go b/src/go/types/testdata/fixedbugs/issue47127.go
index 108d600a38..bb4b487eb2 100644
--- a/src/go/types/testdata/fixedbugs/issue47127.go
+++ b/src/go/types/testdata/fixedbugs/issue47127.go
@@ -8,30 +8,30 @@ package p
type (
_[P any] interface{ *P | []P | chan P | map[string]P }
- _[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
+ _[P any] interface{ P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
+ _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
)
func _[P any]() {
type (
_[P any] interface{ *P | []P | chan P | map[string]P }
- _[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
- _[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
+ _[P any] interface{ P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
+ _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ }
+ _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
_ interface{ *P | []P | chan P | map[string]P }
- _ interface{ P /* ERROR "cannot embed a type parameter" */ }
- _ interface{ ~P /* ERROR "cannot embed a type parameter" */ }
- _ interface{ int | P /* ERROR "cannot embed a type parameter" */ }
- _ interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
+ _ interface{ P /* ERROR term cannot be a type parameter */ }
+ _ interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
+ _ interface{ int | P /* ERROR term cannot be a type parameter */ }
+ _ interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
)
}
func _[P any, Q interface{ *P | []P | chan P | map[string]P }]() {}
-func _[P any, Q interface{ P /* ERROR "cannot embed a type parameter" */ }]() {}
-func _[P any, Q interface{ ~P /* ERROR "cannot embed a type parameter" */ }]() {}
-func _[P any, Q interface{ int | P /* ERROR "cannot embed a type parameter" */ }]() {}
-func _[P any, Q interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }]() {}
+func _[P any, Q interface{ P /* ERROR term cannot be a type parameter */ }]() {}
+func _[P any, Q interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {}
+func _[P any, Q interface{ int | P /* ERROR term cannot be a type parameter */ }]() {}
+func _[P any, Q interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {}
diff --git a/src/go/types/union.go b/src/go/types/union.go
index 1a8825fcab..b288dfab5c 100644
--- a/src/go/types/union.go
+++ b/src/go/types/union.go
@@ -151,7 +151,11 @@ func parseTilde(check *Checker, tx ast.Expr) *Term {
// simply use its underlying type (like we do for other named, embedded interfaces),
// and since the underlying type is an interface the embedding is well defined.
if isTypeParam(typ) {
- check.error(x, _MisplacedTypeParam, "cannot embed a type parameter")
+ if tilde {
+ check.errorf(x, _MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
+ } else {
+ check.error(x, _MisplacedTypeParam, "term cannot be a type parameter")
+ }
typ = Typ[Invalid]
}
term := NewTerm(tilde, typ)