]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: embedding stand-alone type parameters is not permitted
authorRob Findley <rfindley@google.com>
Sat, 17 Jul 2021 00:57:10 +0000 (20:57 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 19 Jul 2021 17:09:54 +0000 (17:09 +0000)
This is a port of CL 334151 to go/types.

Fixes #47127

Change-Id: I57d69c498d2649a9e1657559e4c0271333096c88
Reviewed-on: https://go-review.googlesource.com/c/go/+/335082
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/testdata/check/issues.go2
src/go/types/testdata/check/tinference.go2
src/go/types/testdata/fixedbugs/issue39634.go2
src/go/types/testdata/fixedbugs/issue39680.go2
src/go/types/testdata/fixedbugs/issue39948.go2
src/go/types/testdata/fixedbugs/issue47127.go2 [new file with mode: 0644]
src/go/types/typeset.go
src/go/types/union.go

index 607da1df19eef90fbe2d38766820c6d58c578b82..c57f00230340d30fb8525be409a048ac1f1e9c6a 100644 (file)
@@ -239,7 +239,7 @@ func _[T interface{ ~func() }](f T) {
 
 type sliceOf[E any] interface{ ~[]E }
 
-func append[T interface{}, S sliceOf[T], T2 interface{ T }](s S, t ...T2) S
+func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S
 
 var f           func()
 var cancelSlice []context.CancelFunc
index 7ed358e078475af477ef0185a1669538e36a70e0..44e8dc00595f66a3c7f8390c647537b0e24a8408 100644 (file)
@@ -11,19 +11,20 @@ type any interface{}
 // TODO(rFindley) the below partially applied function types should probably
 //                not be permitted (spec question).
 
-func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
-func _() {
-       f := f0[string]
-       f("a", "b", "c", "d")
-       f0("a", "b", "c", "d")
-}
-
-func f1[A any, B interface{~A}](A, B)
-func _() {
-       f := f1[int]
-       f(int(0), int(0))
-       f1(int(0), int(0))
-}
+// Embedding stand-alone type parameters is not permitted for now. Disabled.
+// func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
+// func _() {
+//     f := f0[string]
+//     f("a", "b", "c", "d")
+//     f0("a", "b", "c", "d")
+// }
+//
+// func f1[A any, B interface{~A}](A, B)
+// func _() {
+//     f := f1[int]
+//     f(int(0), int(0))
+//     f1(int(0), int(0))
+// }
 
 func f2[A any, B interface{~[]A}](A, B)
 func _() {
@@ -32,13 +33,14 @@ func _() {
        f2(byte(0), []byte{})
 }
 
-func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
-func _() {
-       f := f3[int]
-       var x int
-       f(x, &x, &x)
-       f3(x, &x, &x)
-}
+// Embedding stand-alone type parameters is not permitted for now. Disabled.
+// func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
+// func _() {
+//     f := f3[int]
+//     var x int
+//     f(x, &x, &x)
+//     f3(x, &x, &x)
+// }
 
 func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C)
 func _() {
index 2a1367373f5ebb4ee9009256bc8f7418e139db4f..aec404e294be3bb1bfc28675b9dece84497f3f32 100644 (file)
@@ -31,9 +31,10 @@ type x7[A any] struct{ foo7 }
 func main7() { var _ foo7 = x7[int]{} }
 
 // crash 8
-type foo8[A any] interface { ~A }
-func bar8[A foo8[A]](a A) {}
-func main8() {}
+// Embedding stand-alone type parameters is not permitted for now. Disabled.
+// type foo8[A any] interface { ~A }
+// func bar8[A foo8[A]](a A) {}
+// func main8() {}
 
 // crash 9
 type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }
index 01eadd2dbf9c5b8a769974ec6fe1212d4e2550ef..e56bc3547582d190f110b6f70a231e9e38012572 100644 (file)
@@ -4,6 +4,9 @@
 
 package p
 
+// Embedding stand-alone type parameters is not permitted for now. Disabled.
+
+/*
 import "fmt"
 
 // Minimal test case.
@@ -25,3 +28,4 @@ func Print[T constr[T]](s []T) {
 func f() {
        Print([]string{"Hello, ", "playground\n"})
 }
+*/
index d83084b52a7c7a69b64288b45bb9f2532ea86d9c..e38e57268d63d1fd00012274bd8ea23bc2a7c7df 100644 (file)
@@ -2,14 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// TODO(rfindley) Eventually, once we disallow type lists, we need to
-//                adjust this code: for 1.17 we don't accept type parameters,
-//                and for 1.18 this code is valid.
-//                Leaving for now so we can see that existing errors
-//                are being reported.
-
-package go1_17 // don't permit non-interface elements in interfaces
+package p
 
 type T[P any] interface{
-       P // ERROR P is a type parameter, not an interface
+       P // ERROR cannot embed a type parameter
 }
diff --git a/src/go/types/testdata/fixedbugs/issue47127.go2 b/src/go/types/testdata/fixedbugs/issue47127.go2
new file mode 100644 (file)
index 0000000..387c946
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Embedding of stand-alone type parameters is not permitted.
+
+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" */ }
+)
+
+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" */ }
+
+                _ 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" */ }
+        )
+}
+
+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" */ }]()
index d8fe42f7d08f10f8171c93d17024558b5f4db6fd..3df2f1235f5341690f6211f2c1fc80364d58c6b5 100644 (file)
@@ -217,11 +217,9 @@ func computeTypeSet(check *Checker, pos token.Pos, ityp *Interface) *TypeSet {
                        //           interface before go1.18.
                        types = typ
                case *TypeParam:
-                       if check != nil && !check.allowVersion(check.pkg, 1, 18) {
-                               check.errorf(atPos(pos), _InvalidIfaceEmbed, "%s is a type parameter, not an interface", typ)
-                               continue
-                       }
-                       types = typ
+                       // Embedding stand-alone type parameters is not permitted for now.
+                       // This case is handled during union parsing.
+                       unreachable()
                default:
                        if typ == Typ[Invalid] {
                                continue
index 7c69ec7b1086c1fde6d4eee5e92014d2110a5a0b..556be46bf6a25679390d285f332a6d8bf2732230 100644 (file)
@@ -131,13 +131,18 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
        return newUnion(types, tilde)
 }
 
-func parseTilde(check *Checker, x ast.Expr) (Type, bool) {
-       tilde := false
+func parseTilde(check *Checker, x ast.Expr) (typ Type, tilde bool) {
        if op, _ := x.(*ast.UnaryExpr); op != nil && op.Op == token.TILDE {
                x = op.X
                tilde = true
        }
-       return check.anyType(x), tilde
+       typ = check.anyType(x)
+       // embedding stand-alone type parameters is not permitted (issue #47127).
+       if _, ok := under(typ).(*TypeParam); ok {
+               check.error(x, _Todo, "cannot embed a type parameter")
+               typ = Typ[Invalid]
+       }
+       return
 }
 
 // intersect computes the intersection of the types x and y,