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)