diff options
| author | Robert Griesemer <gri@golang.org> | 2022-03-30 12:19:24 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2022-03-31 14:51:17 +0000 |
| commit | 2ea9376266b71e8a0752b8b3663bbf5b9ed48c4d (patch) | |
| tree | eba99ba55fa1427bc27e3c59c85a1200c80ee675 /src | |
| parent | 109a18dce7ef8ecb2aa60cef25362ebd05661ea0 (diff) | |
| download | go-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.go | 6 | ||||
| -rw-r--r-- | src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go | 32 | ||||
| -rw-r--r-- | src/cmd/compile/internal/types2/union.go | 6 | ||||
| -rw-r--r-- | src/go/types/testdata/examples/constraints.go | 6 | ||||
| -rw-r--r-- | src/go/types/testdata/fixedbugs/issue39948.go | 2 | ||||
| -rw-r--r-- | src/go/types/testdata/fixedbugs/issue47127.go | 32 | ||||
| -rw-r--r-- | src/go/types/union.go | 6 |
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) |
