1 // Copyright 2020 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 // This file contains regression tests for bugs found.
6
7 package p
8
9 import "io"
10 import "context"
11
12 func eql[T comparable](x, y T) bool {
13 return x == y
14 }
15
16 func _[X comparable, Y interface{comparable; m()}]() {
17 var x X
18 var y Y
19 eql(x, y /* ERROR does not match */ ) // interfaces of different types
20 eql(x, x)
21 eql(y, y)
22 eql(y, nil /* ERROR cannot use nil as Y value in argument to eql */ )
23 eql[io /* ERROR does not implement comparable */ .Reader](nil, nil)
24 }
25
26 // If we have a receiver of pointer to type parameter type (below: *T)
27 // we don't have any methods, like for interfaces.
28 type C[T any] interface {
29 m()
30 }
31
32 // using type bound C
33 func _[T C[T]](x *T) {
34 x.m /* ERROR x\.m undefined */ ()
35 }
36
37 // using an interface literal as bound
38 func _[T interface{ m() }](x *T) {
39 x.m /* ERROR x\.m undefined */ ()
40 }
41
42 func f2[_ interface{ m1(); m2() }]() {}
43
44 type T struct{}
45 func (T) m1()
46 func (*T) m2()
47
48 func _() {
49 f2[T /* ERROR m2 has pointer receiver */ ]()
50 f2[*T]()
51 }
52
53 // When a type parameter is used as an argument to instantiate a parameterized
54 // type with a type set constraint, all of the type argument's types in its
55 // bound, but at least one (!), must be in the type set of the bound of the
56 // corresponding parameterized type's type parameter.
57 type T1[P interface{~uint}] struct{}
58
59 func _[P any]() {
60 _ = T1[P /* ERROR P does not implement interface{~uint} */ ]{}
61 }
62
63 // This is the original (simplified) program causing the same issue.
64 type Unsigned interface {
65 ~uint
66 }
67
68 type T2[U Unsigned] struct {
69 s U
70 }
71
72 func (u T2[U]) Add1() U {
73 return u.s + 1
74 }
75
76 func NewT2[U any]() T2[U /* ERROR U does not implement Unsigned */ ] {
77 return T2[U /* ERROR U does not implement Unsigned */ ]{}
78 }
79
80 func _() {
81 u := NewT2[string]()
82 _ = u.Add1()
83 }
84
85 // When we encounter an instantiated type such as Elem[T] we must
86 // not "expand" the instantiation when the type to be instantiated
87 // (Elem in this case) is not yet fully set up.
88 type Elem[T any] struct {
89 next *Elem[T]
90 list *List[T]
91 }
92
93 type List[T any] struct {
94 root Elem[T]
95 }
96
97 func (l *List[T]) Init() {
98 l.root.next = &l.root
99 }
100
101 // This is the original program causing the same issue.
102 type Element2[TElem any] struct {
103 next, prev *Element2[TElem]
104 list *List2[TElem]
105 Value TElem
106 }
107
108 type List2[TElem any] struct {
109 root Element2[TElem]
110 len int
111 }
112
113 func (l *List2[TElem]) Init() *List2[TElem] {
114 l.root.next = &l.root
115 l.root.prev = &l.root
116 l.len = 0
117 return l
118 }
119
120 // Self-recursive instantiations must work correctly.
121 type A[P any] struct { _ *A[P] }
122
123 type AB[P any] struct { _ *BA[P] }
124 type BA[P any] struct { _ *AB[P] }
125
126 // And a variation that also caused a problem with an
127 // unresolved underlying type.
128 type Element3[TElem any] struct {
129 next, prev *Element3[TElem]
130 list *List3[TElem]
131 Value TElem
132 }
133
134 func (e *Element3[TElem]) Next() *Element3[TElem] {
135 if p := e.next; e.list != nil && p != &e.list.root {
136 return p
137 }
138 return nil
139 }
140
141 type List3[TElem any] struct {
142 root Element3[TElem]
143 len int
144 }
145
146 // Infinite generic type declarations must lead to an error.
147 type inf1[T any] struct{ _ inf1 /* ERROR illegal cycle */ [T] }
148 type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
149
150 // The implementation of conversions T(x) between integers and floating-point
151 // numbers checks that both T and x have either integer or floating-point
152 // type. When the type of T or x is a type parameter, the respective simple
153 // predicate disjunction in the implementation was wrong because if a term list
154 // contains both an integer and a floating-point type, the type parameter is
155 // neither an integer or a floating-point number.
156 func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
157 return T2(v)
158 }
159
160 func _() {
161 convert[int, uint](5)
162 }
163
164 // When testing binary operators, for +, the operand types must either be
165 // both numeric, or both strings. The implementation had the same problem
166 // with this check as the conversion issue above (issue #39623).
167
168 func issue39623[T interface{~int | ~string}](x, y T) T {
169 return x + y
170 }
171
172 // Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
173 func Sum[T interface{~int | ~string}](s []T) (sum T) {
174 for _, v := range s {
175 sum += v
176 }
177 return
178 }
179
180 // Assignability of an unnamed pointer type to a type parameter that
181 // has a matching underlying type.
182 func _[T interface{}, PT interface{~*T}] (x T) PT {
183 return &x
184 }
185
186 // Indexing of generic types containing type parameters in their term list:
187 func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
188 return x[i]
189 }
190
191 // A generic type inside a function acts like a named type. Its underlying
192 // type is itself, its "operational type" is defined by the term list in
193 // the tybe bound, if any.
194 func _[T interface{~int}](x T) {
195 type myint int
196 var _ int = int(x)
197 var _ T = 42
198 var _ T = T(myint(42))
199 }
200
201 // Indexing a generic type with an array type bound checks length.
202 // (Example by mdempsky@.)
203 func _[T interface { ~[10]int }](x T) {
204 _ = x[9] // ok
205 _ = x[20 /* ERROR out of bounds */ ]
206 }
207
208 // Pointer indirection of a generic type.
209 func _[T interface{ ~*int }](p T) int {
210 return *p
211 }
212
213 // Channel sends and receives on generic types.
214 func _[T interface{ ~chan int }](ch T) int {
215 ch <- 0
216 return <- ch
217 }
218
219 // Calling of a generic variable.
220 func _[T interface{ ~func() }](f T) {
221 f()
222 go f()
223 }
224
225 type F1 func()
226 type F2 func()
227 func _[T interface{ func()|F1|F2 }](f T) {
228 f()
229 go f()
230 }
231
232 // We must compare against the underlying type of term list entries
233 // when checking if a constraint is satisfied by a type. The under-
234 // lying type of each term list entry must be computed after the
235 // interface has been instantiated as its typelist may contain a
236 // type parameter that was substituted with a defined type.
237 // Test case from an (originally) failing example.
238
239 type sliceOf[E any] interface{ ~[]E }
240
241 func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) }
242
243 var f func()
244 var cancelSlice []context.CancelFunc
245 var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
246
247 // A generic function must be instantiated with a type, not a value.
248
249 func g[T any](T) T { panic(0) }
250
251 var _ = g[int]
252 var _ = g[nil /* ERROR is not a type */ ]
253 var _ = g(0)
254
View as plain text