mirror of
https://github.com/golang/go.git
synced 2025-05-28 19:02:22 +00:00
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>
This commit is contained in:
parent
109a18dce7
commit
2ea9376266
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 */ }]() {}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
32
src/go/types/testdata/fixedbugs/issue47127.go
vendored
32
src/go/types/testdata/fixedbugs/issue47127.go
vendored
@ -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 */ }]() {}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user