Skip to content

Commit 4ff0e04

Browse files
committed
[dev.typeparams] cmd/compile/internal/types2: embedding stand-alone type parameters is not permitted
For #47127. Change-Id: Ie979ff56ae7c2dd0e5ce0ff39588f98ae68b5ee9 Reviewed-on: https://go-review.googlesource.com/c/go/+/334151 Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 3a04732 commit 4ff0e04

File tree

9 files changed

+87
-40
lines changed

9 files changed

+87
-40
lines changed

src/cmd/compile/internal/types2/testdata/check/issues.go2

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func _[T interface{ ~func() }](f T) {
232232

233233
type sliceOf[E any] interface{ ~[]E }
234234

235-
func append[T interface{}, S sliceOf[T], T2 interface{ T }](s S, t ...T2) S
235+
func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S
236236

237237
var f func()
238238
var cancelSlice []context.CancelFunc

src/cmd/compile/internal/types2/testdata/check/tinference.go2

+22-20
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@ import "strconv"
88

99
type any interface{}
1010

11-
func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
12-
func _() {
13-
f := f0[string]
14-
f("a", "b", "c", "d")
15-
f0("a", "b", "c", "d")
16-
}
17-
18-
func f1[A any, B interface{~A}](A, B)
19-
func _() {
20-
f := f1[int]
21-
f(int(0), int(0))
22-
f1(int(0), int(0))
23-
}
11+
// Embedding stand-alone type parameters is not permitted for now. Disabled.
12+
// func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
13+
// func _() {
14+
// f := f0[string]
15+
// f("a", "b", "c", "d")
16+
// f0("a", "b", "c", "d")
17+
// }
18+
//
19+
// func f1[A any, B interface{~A}](A, B)
20+
// func _() {
21+
// f := f1[int]
22+
// f(int(0), int(0))
23+
// f1(int(0), int(0))
24+
// }
2425

2526
func f2[A any, B interface{~[]A}](A, B)
2627
func _() {
@@ -29,13 +30,14 @@ func _() {
2930
f2(byte(0), []byte{})
3031
}
3132

32-
func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
33-
func _() {
34-
f := f3[int]
35-
var x int
36-
f(x, &x, &x)
37-
f3(x, &x, &x)
38-
}
33+
// Embedding stand-alone type parameters is not permitted for now. Disabled.
34+
// func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
35+
// func _() {
36+
// f := f3[int]
37+
// var x int
38+
// f(x, &x, &x)
39+
// f3(x, &x, &x)
40+
// }
3941

4042
func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C)
4143
func _() {

src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go2

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ type x7[A any] struct{ foo7 }
3131
func main7() { var _ foo7 = x7[int]{} }
3232

3333
// crash 8
34-
type foo8[A any] interface { ~A }
35-
func bar8[A foo8[A]](a A) {}
36-
func main8() {}
34+
// Embedding stand-alone type parameters is not permitted for now. Disabled.
35+
// type foo8[A any] interface { ~A }
36+
// func bar8[A foo8[A]](a A) {}
37+
// func main8() {}
3738

3839
// crash 9
3940
type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }

src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go2

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
package p
66

7+
// Embedding stand-alone type parameters is not permitted for now. Disabled.
8+
9+
/*
710
import "fmt"
811

912
// Minimal test case.
@@ -25,3 +28,4 @@ func Print[T constr[T]](s []T) {
2528
func f() {
2629
Print([]string{"Hello, ", "playground\n"})
2730
}
31+
*/

src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go2

+2-8
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// TODO(gri) Eventually, once we disallow type lists, we need to
6-
// adjust this code: for 1.17 we don't accept type parameters,
7-
// and for 1.18 this code is valid.
8-
// Leaving for now so we can see that existing errors
9-
// are being reported.
10-
11-
package go1_17 // don't permit non-interface elements in interfaces
5+
package p
126

137
type T[P any] interface{
14-
P // ERROR P is a type parameter, not an interface
8+
P // ERROR cannot embed a type parameter
159
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Embedding of stand-alone type parameters is not permitted.
6+
7+
package p
8+
9+
type (
10+
_[P any] interface{ *P | []P | chan P | map[string]P }
11+
_[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
12+
_[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
13+
_[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
14+
_[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
15+
)
16+
17+
func _[P any]() {
18+
type (
19+
_[P any] interface{ *P | []P | chan P | map[string]P }
20+
_[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
21+
_[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
22+
_[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
23+
_[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
24+
25+
_ interface{ *P | []P | chan P | map[string]P }
26+
_ interface{ P /* ERROR "cannot embed a type parameter" */ }
27+
_ interface{ ~P /* ERROR "cannot embed a type parameter" */ }
28+
_ interface{ int | P /* ERROR "cannot embed a type parameter" */ }
29+
_ interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
30+
)
31+
}
32+
33+
func _[P any, Q interface{ *P | []P | chan P | map[string]P }]()
34+
func _[P any, Q interface{ P /* ERROR "cannot embed a type parameter" */ }]()
35+
func _[P any, Q interface{ ~P /* ERROR "cannot embed a type parameter" */ }]()
36+
func _[P any, Q interface{ int | P /* ERROR "cannot embed a type parameter" */ }]()
37+
func _[P any, Q interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }]()

src/cmd/compile/internal/types2/typeset.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,9 @@ func computeTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *TypeSet {
216216
// interface before go1.18.
217217
types = typ
218218
case *TypeParam:
219-
if check != nil && !check.allowVersion(check.pkg, 1, 18) {
220-
check.errorf(pos, "%s is a type parameter, not an interface", typ)
221-
continue
222-
}
223-
types = typ
219+
// Embedding stand-alone type parameters is not permitted for now.
220+
// This case is handled during union parsing.
221+
unreachable()
224222
default:
225223
if typ == Typ[Invalid] {
226224
continue

src/cmd/compile/internal/types2/union.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,18 @@ func parseUnion(check *Checker, tlist []syntax.Expr) Type {
128128
return newUnion(types, tilde)
129129
}
130130

131-
func parseTilde(check *Checker, x syntax.Expr) (Type, bool) {
132-
tilde := false
131+
func parseTilde(check *Checker, x syntax.Expr) (typ Type, tilde bool) {
133132
if op, _ := x.(*syntax.Operation); op != nil && op.Op == syntax.Tilde {
134133
x = op.X
135134
tilde = true
136135
}
137-
return check.anyType(x), tilde
136+
typ = check.anyType(x)
137+
// embedding stand-alone type parameters is not permitted (issue #47127).
138+
if _, ok := under(typ).(*TypeParam); ok {
139+
check.error(x, "cannot embed a type parameter")
140+
typ = Typ[Invalid]
141+
}
142+
return
138143
}
139144

140145
// intersect computes the intersection of the types x and y,

test/typeparam/typelist.go

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ func _[V any, T interface { type map[string]V }](p T) V {
6767
// Testing partial and full type inference, including the case where the types can
6868
// be inferred without needing the types of the function arguments.
6969

70+
// Cannot embed stand-alone type parameters. Disabled for now.
71+
/*
7072
func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
7173
func _() {
7274
f := f0[string]
@@ -82,6 +84,7 @@ func _() {
8284
f(0, 0)
8385
f1(0, 0)
8486
}
87+
*/
8588

8689
func f2[A any, B interface{type []A}](_ A, _ B)
8790
func _() {
@@ -92,13 +95,16 @@ func _() {
9295
// f2(0, []byte{}) - this one doesn't work
9396
}
9497

98+
// Cannot embed stand-alone type parameters. Disabled for now.
99+
/*
95100
func f3[A any, B interface{type C}, C interface{type *A}](a A, _ B, c C)
96101
func _() {
97102
f := f3[int]
98103
var x int
99104
f(x, &x, &x)
100105
f3(x, &x, &x)
101106
}
107+
*/
102108

103109
func f4[A any, B interface{type []C}, C interface{type *A}](_ A, _ B, c C)
104110
func _() {

0 commit comments

Comments
 (0)