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