]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: better error message for invalid type parameter term
authorRobert Griesemer <gri@golang.org>
Wed, 30 Mar 2022 19:19:24 +0000 (12:19 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 31 Mar 2022 14:51:17 +0000 (14:51 +0000)
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>
src/cmd/compile/internal/types2/testdata/examples/constraints.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go
src/cmd/compile/internal/types2/union.go
src/go/types/testdata/examples/constraints.go
src/go/types/testdata/fixedbugs/issue39948.go
src/go/types/testdata/fixedbugs/issue47127.go
src/go/types/union.go

index 4d7f70313a20ae48cf0afea39d9efe88c4f1f4dc..fb01be56a233f8f88c0568f16a65b76c379ed358 100644 (file)
@@ -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
index e38e57268d63d1fd00012274bd8ea23bc2a7c7df..c893cc049e44d6abf81d777002a37d09ee290270 100644 (file)
@@ -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
 }
index 108d600a38a6c9ce9075ca792ab7abf4077f1d8e..bb4b487eb2c6f0120b82d783604045216787a8a7 100644 (file)
@@ -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 */ }]() {}
index 132e73098a7c612c18a4aef36987549c4448742f..57f1a4fe2a9b9310daed543d368c37ab75db0a2f 100644 (file)
@@ -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)
index 4d7f70313a20ae48cf0afea39d9efe88c4f1f4dc..fb01be56a233f8f88c0568f16a65b76c379ed358 100644 (file)
@@ -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
index e38e57268d63d1fd00012274bd8ea23bc2a7c7df..c893cc049e44d6abf81d777002a37d09ee290270 100644 (file)
@@ -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
 }
index 108d600a38a6c9ce9075ca792ab7abf4077f1d8e..bb4b487eb2c6f0120b82d783604045216787a8a7 100644 (file)
@@ -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 */ }]() {}
index 1a8825fcab0928d4d0e746d1423c060a0bfb1fd1..b288dfab5cbd7210e1d73739e30c5aa24f1d9f51 100644 (file)
@@ -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)