Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a91d0b6

Browse files
committedOct 28, 2021
cmd/compile/internal/types2: disallow lone type parameter on RHS of type declaration
We may revisit this decision in a future release. By disallowing this for Go 1.18 we are ensuring that we don't lock in the generics design in a place that may need to change later. (Type declarations are the primary construct where it crucially matters what the underlying type of a type parameter is.) Comment out all tests that rely on this feature; add comments referring to issue so we can find all places easily should we change our minds. Fixes golang#45639. Change-Id: I730510e4da66d3716d455a9071c7778a1e4a1152 Reviewed-on: https://go-review.googlesource.com/c/go/+/359177 Trust: Robert Griesemer <[email protected]> Trust: Dan Scales <[email protected]> Reviewed-by: Dan Scales <[email protected]>
1 parent 79ff663 commit a91d0b6

File tree

20 files changed

+297
-309
lines changed

20 files changed

+297
-309
lines changed
 

‎src/cmd/compile/internal/types2/api_test.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -622,13 +622,6 @@ func TestDefsInfo(t *testing.T) {
622622
{`package p3; type x int`, `x`, `type p3.x int`},
623623
{`package p4; func f()`, `f`, `func p4.f()`},
624624
{`package p5; func f() int { x, _ := 1, 2; return x }`, `_`, `var _ int`},
625-
626-
// generic types must be sanitized
627-
// (need to use sufficiently nested types to provoke unexpanded types)
628-
{genericPkg + `g0; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
629-
{genericPkg + `g1; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
630-
{genericPkg + `g2; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
631-
{genericPkg + `g3; type t[P any] P; func f(x struct{ f t[string] }); var g = f`, `g`, `var generic_g3.g func(x struct{f generic_g3.t[string]})`},
632625
}
633626

634627
for _, test := range tests {
@@ -667,13 +660,6 @@ func TestUsesInfo(t *testing.T) {
667660
{`package p2; func _() { _ = x }; var x int`, `x`, `var p2.x int`},
668661
{`package p3; func _() { type _ x }; type x int`, `x`, `type p3.x int`},
669662
{`package p4; func _() { _ = f }; func f()`, `f`, `func p4.f()`},
670-
671-
// generic types must be sanitized
672-
// (need to use sufficiently nested types to provoke unexpanded types)
673-
{genericPkg + `g0; func _() { _ = x }; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
674-
{genericPkg + `g1; func _() { _ = x }; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
675-
{genericPkg + `g2; func _() { type _ x }; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
676-
{genericPkg + `g3; func _() { _ = f }; type t[P any] P; func f(x struct{ f t[string] })`, `f`, `func generic_g3.f(x struct{f generic_g3.t[string]})`},
677663
}
678664

679665
for _, test := range tests {

‎src/cmd/compile/internal/types2/decl.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,9 +604,12 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
604604
named.underlying = Typ[Invalid]
605605
}
606606

607-
// If the RHS is a type parameter, it must be from this type declaration.
608-
if tpar, _ := named.underlying.(*TypeParam); tpar != nil && tparamIndex(named.TypeParams().list(), tpar) < 0 {
609-
check.errorf(tdecl.Type, "cannot use function type parameter %s as RHS in type declaration", tpar)
607+
// Disallow a lone type parameter as the RHS of a type declaration (issue #45639).
608+
// We can look directly at named.underlying because even if it is still a *Named
609+
// type (underlying not fully resolved yet) it cannot become a type parameter due
610+
// to this very restriction.
611+
if tpar, _ := named.underlying.(*TypeParam); tpar != nil {
612+
check.error(tdecl.Type, "cannot use a type parameter as RHS in type declaration")
610613
named.underlying = Typ[Invalid]
611614
}
612615
}

‎src/cmd/compile/internal/types2/testdata/check/linalg.go2

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
package linalg
66

7-
import "math"
8-
97
// Numeric is type bound that matches any numeric type.
108
// It would likely be in a constraints package in the standard library.
119
type Numeric interface {
@@ -52,32 +50,33 @@ type Complex interface {
5250
~complex64 | ~complex128
5351
}
5452

55-
// OrderedAbs is a helper type that defines an Abs method for
56-
// ordered numeric types.
57-
type OrderedAbs[T OrderedNumeric] T
58-
59-
func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
60-
if a < 0 {
61-
return -a
62-
}
63-
return a
64-
}
65-
66-
// ComplexAbs is a helper type that defines an Abs method for
67-
// complex types.
68-
type ComplexAbs[T Complex] T
69-
70-
func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
71-
r := float64(real(a))
72-
i := float64(imag(a))
73-
d := math.Sqrt(r * r + i * i)
74-
return ComplexAbs[T](complex(d, 0))
75-
}
76-
77-
func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
78-
return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
79-
}
80-
81-
func ComplexAbsDifference[T Complex](a, b T) T {
82-
return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
83-
}
53+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
54+
// // OrderedAbs is a helper type that defines an Abs method for
55+
// // ordered numeric types.
56+
// type OrderedAbs[T OrderedNumeric] T
57+
//
58+
// func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
59+
// if a < 0 {
60+
// return -a
61+
// }
62+
// return a
63+
// }
64+
//
65+
// // ComplexAbs is a helper type that defines an Abs method for
66+
// // complex types.
67+
// type ComplexAbs[T Complex] T
68+
//
69+
// func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
70+
// r := float64(real(a))
71+
// i := float64(imag(a))
72+
// d := math.Sqrt(r * r + i * i)
73+
// return ComplexAbs[T](complex(d, 0))
74+
// }
75+
//
76+
// func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
77+
// return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
78+
// }
79+
//
80+
// func ComplexAbsDifference[T Complex](a, b T) T {
81+
// return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
82+
// }

‎src/cmd/compile/internal/types2/testdata/check/typeinst.go2

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ type myInt int
88

99
// Parameterized type declarations
1010

11-
type T1[P any] P
11+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
12+
type T1[P any] P // ERROR cannot use a type parameter as RHS in type declaration
1213

1314
type T2[P any] struct {
1415
f P
@@ -19,7 +20,7 @@ type List[P any] []P
1920

2021
// Alias type declarations cannot have type parameters.
2122
// Issue #46477 proposses to change that.
22-
type A1[P any] = /* ERROR cannot be alias */ P
23+
type A1[P any] = /* ERROR cannot be alias */ struct{}
2324

2425
// Pending clarification of #46477 we disallow aliases
2526
// of generic types.

‎src/cmd/compile/internal/types2/testdata/check/typeinst2.go2

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,27 @@ type NumericAbs[T any] interface {
8787

8888
func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
8989

90-
type OrderedAbs[T any] T
91-
92-
func (a OrderedAbs[T]) Abs() OrderedAbs[T]
93-
94-
func OrderedAbsDifference[T any](x T) {
95-
AbsDifference(OrderedAbs[T](x))
96-
}
90+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
91+
// type OrderedAbs[T any] T
92+
//
93+
// func (a OrderedAbs[T]) Abs() OrderedAbs[T]
94+
//
95+
// func OrderedAbsDifference[T any](x T) {
96+
// AbsDifference(OrderedAbs[T](x))
97+
// }
9798

9899
// same code, reduced to essence
99100

100101
func g[P interface{ m() P }](x P) { panic(0) }
101102

102-
type T4[P any] P
103-
104-
func (_ T4[P]) m() T4[P]
105-
106-
func _[Q any](x Q) {
107-
g(T4[Q](x))
108-
}
103+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
104+
// type T4[P any] P
105+
//
106+
// func (_ T4[P]) m() T4[P]
107+
//
108+
// func _[Q any](x Q) {
109+
// g(T4[Q](x))
110+
// }
109111

110112
// Another test case that caused problems in the past
111113

‎src/cmd/compile/internal/types2/testdata/check/typeparams.go2

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,16 @@ func _() {
353353

354354
// the previous example was extracted from
355355

356-
func f12[T interface{m() T}]() {}
357-
358-
type A[T any] T
359-
360-
func (a A[T]) m() A[T]
361-
362-
func _[T any]() {
363-
f12[A[T]]()
364-
}
356+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
357+
// func f12[T interface{m() T}]() {}
358+
//
359+
// type A[T any] T
360+
//
361+
// func (a A[T]) m() A[T]
362+
//
363+
// func _[T any]() {
364+
// f12[A[T]]()
365+
// }
365366

366367
// method expressions
367368

‎src/cmd/compile/internal/types2/testdata/examples/methods.go2

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
package p
88

9-
import "unsafe"
10-
119
// Parameterized types may have methods.
1210
type T1[A any] struct{ a A }
1311

@@ -97,17 +95,18 @@ type T0 struct{}
9795
func (T0) _() {}
9896
func (T1[A]) _() {}
9997

100-
// A generic receiver type may constrain its type parameter such
101-
// that it must be a pointer type. Such receiver types are not
102-
// permitted.
103-
type T3a[P interface{ ~int | ~string | ~float64 }] P
104-
105-
func (T3a[_]) m() {} // this is ok
106-
107-
type T3b[P interface{ ~unsafe.Pointer }] P
108-
109-
func (T3b /* ERROR invalid receiver */ [_]) m() {}
110-
111-
type T3c[P interface{ *int | *string }] P
112-
113-
func (T3c /* ERROR invalid receiver */ [_]) m() {}
98+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
99+
// // A generic receiver type may constrain its type parameter such
100+
// // that it must be a pointer type. Such receiver types are not
101+
// // permitted.
102+
// type T3a[P interface{ ~int | ~string | ~float64 }] P
103+
//
104+
// func (T3a[_]) m() {} // this is ok
105+
//
106+
// type T3b[P interface{ ~unsafe.Pointer }] P
107+
//
108+
// func (T3b /* ERROR invalid receiver */ [_]) m() {}
109+
//
110+
// type T3c[P interface{ *int | *string }] P
111+
//
112+
// func (T3c /* ERROR invalid receiver */ [_]) m() {}

‎src/cmd/compile/internal/types2/testdata/examples/types.go2

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,13 @@ type _ struct {
185185
// _ = y < 0
186186
// }
187187

188-
// It is not permitted to declare a local type whose underlying
189-
// type is a type parameter not declared by that type declaration.
190-
func _[T any]() {
191-
type _ T // ERROR cannot use function type parameter T as RHS in type declaration
192-
type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
193-
}
188+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
189+
// // It is not permitted to declare a local type whose underlying
190+
// // type is a type parameter not declared by that type declaration.
191+
// func _[T any]() {
192+
// type _ T // ERROR cannot use function type parameter T as RHS in type declaration
193+
// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
194+
// }
194195

195196
// As a special case, an explicit type argument may be omitted
196197
// from a type parameter bound if the type bound expects exactly

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
7474
type Z21 /* ERROR illegal cycle */ interface{ Z21 }
7575
func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
7676

77-
// crash 24
78-
type T24[P any] P
79-
func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
77+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
78+
// // crash 24
79+
// type T24[P any] P
80+
// func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
8081

8182
// crash 25
8283
type T25[A any] int

‎src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go2

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44

55
package p
66

7-
type T[P any] P
8-
type A = T // ERROR cannot use generic type
9-
var x A[int]
10-
var _ A
11-
12-
type B = T[int]
13-
var y B = x
14-
var _ B /* ERROR not a generic type */ [int]
7+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
8+
// type T[P any] P
9+
// type A = T // ERROR cannot use generic type
10+
// var x A[int]
11+
// var _ A
12+
//
13+
// type B = T[int]
14+
// var y B = x
15+
// var _ B /* ERROR not a generic type */ [int]
1516

1617
// test case from issue
1718

‎src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
package p
1010

11-
type E0[P any] P
11+
type E0[P any] []P
1212
type E1[P any] *P
1313
type E2[P any] struct{ _ P }
1414
type E3[P any] struct{ _ *P }

‎src/cmd/compile/internal/types2/testdata/fixedbugs/issue45639.go2

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
package P
66

7-
// It is not permitted to declare a local type whose underlying
8-
// type is a type parameters not declared by that type declaration.
9-
func _[T any]() {
10-
type _ T // ERROR cannot use function type parameter T as RHS in type declaration
11-
type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
12-
}
7+
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
8+
// // It is not permitted to declare a local type whose underlying
9+
// // type is a type parameters not declared by that type declaration.
10+
// func _[T any]() {
11+
// type _ T // ERROR cannot use function type parameter T as RHS in type declaration
12+
// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
13+
// }

0 commit comments

Comments
 (0)
Please sign in to comment.