Skip to content

Commit 7e714f4

Browse files
committed
[dev.typeparams] go/types: embedding stand-alone type parameters is not permitted
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 <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 82f875d commit 7e714f4

File tree

8 files changed

+81
-40
lines changed

8 files changed

+81
-40
lines changed

src/go/types/testdata/check/issues.go2

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

240240
type sliceOf[E any] interface{ ~[]E }
241241

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

244244
var f func()
245245
var cancelSlice []context.CancelFunc

src/go/types/testdata/check/tinference.go2

+22-20
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@ type any interface{}
1111
// TODO(rFindley) the below partially applied function types should probably
1212
// not be permitted (spec question).
1313

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

2829
func f2[A any, B interface{~[]A}](A, B)
2930
func _() {
@@ -32,13 +33,14 @@ func _() {
3233
f2(byte(0), []byte{})
3334
}
3435

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

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

src/go/types/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/go/types/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/go/types/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(rfindley) 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/go/types/typeset.go

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

src/go/types/union.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,18 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
131131
return newUnion(types, tilde)
132132
}
133133

134-
func parseTilde(check *Checker, x ast.Expr) (Type, bool) {
135-
tilde := false
134+
func parseTilde(check *Checker, x ast.Expr) (typ Type, tilde bool) {
136135
if op, _ := x.(*ast.UnaryExpr); op != nil && op.Op == token.TILDE {
137136
x = op.X
138137
tilde = true
139138
}
140-
return check.anyType(x), tilde
139+
typ = check.anyType(x)
140+
// embedding stand-alone type parameters is not permitted (issue #47127).
141+
if _, ok := under(typ).(*TypeParam); ok {
142+
check.error(x, _Todo, "cannot embed a type parameter")
143+
typ = Typ[Invalid]
144+
}
145+
return
141146
}
142147

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

0 commit comments

Comments
 (0)