github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/types/testdata/check/issues1.go (about) 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.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, the type argument's type set must be a subset of the instantiated type 55 // parameter's type set. 56 type T1[P interface{~uint}] struct{} 57 58 func _[P any]() { 59 _ = T1[P /* ERROR "P does not satisfy interface{~uint}" */ ]{} 60 } 61 62 // This is the original (simplified) program causing the same issue. 63 type Unsigned interface { 64 ~uint 65 } 66 67 type T2[U Unsigned] struct { 68 s U 69 } 70 71 func (u T2[U]) Add1() U { 72 return u.s + 1 73 } 74 75 func NewT2[U any]() T2[U /* ERROR "U does not satisfy Unsigned" */ ] { 76 return T2[U /* ERROR "U does not satisfy Unsigned" */ ]{} 77 } 78 79 func _() { 80 u := NewT2[string]() 81 _ = u.Add1() 82 } 83 84 // When we encounter an instantiated type such as Elem[T] we must 85 // not "expand" the instantiation when the type to be instantiated 86 // (Elem in this case) is not yet fully set up. 87 type Elem[T any] struct { 88 next *Elem[T] 89 list *List[T] 90 } 91 92 type List[T any] struct { 93 root Elem[T] 94 } 95 96 func (l *List[T]) Init() { 97 l.root.next = &l.root 98 } 99 100 // This is the original program causing the same issue. 101 type Element2[TElem any] struct { 102 next, prev *Element2[TElem] 103 list *List2[TElem] 104 Value TElem 105 } 106 107 type List2[TElem any] struct { 108 root Element2[TElem] 109 len int 110 } 111 112 func (l *List2[TElem]) Init() *List2[TElem] { 113 l.root.next = &l.root 114 l.root.prev = &l.root 115 l.len = 0 116 return l 117 } 118 119 // Self-recursive instantiations must work correctly. 120 type A[P any] struct { _ *A[P] } 121 122 type AB[P any] struct { _ *BA[P] } 123 type BA[P any] struct { _ *AB[P] } 124 125 // And a variation that also caused a problem with an 126 // unresolved underlying type. 127 type Element3[TElem any] struct { 128 next, prev *Element3[TElem] 129 list *List3[TElem] 130 Value TElem 131 } 132 133 func (e *Element3[TElem]) Next() *Element3[TElem] { 134 if p := e.next; e.list != nil && p != &e.list.root { 135 return p 136 } 137 return nil 138 } 139 140 type List3[TElem any] struct { 141 root Element3[TElem] 142 len int 143 } 144 145 // Infinite generic type declarations must lead to an error. 146 type inf1[T any] struct{ _ inf1 /* ERROR "invalid recursive type" */ [T] } 147 type inf2[T any] struct{ inf2 /* ERROR "invalid recursive type" */ [T] } 148 149 // The implementation of conversions T(x) between integers and floating-point 150 // numbers checks that both T and x have either integer or floating-point 151 // type. When the type of T or x is a type parameter, the respective simple 152 // predicate disjunction in the implementation was wrong because if a type set 153 // contains both an integer and a floating-point type, the type parameter is 154 // neither an integer or a floating-point number. 155 func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 { 156 return T2(v) 157 } 158 159 func _() { 160 convert[int, uint](5) 161 } 162 163 // When testing binary operators, for +, the operand types must either be 164 // both numeric, or both strings. The implementation had the same problem 165 // with this check as the conversion issue above (issue #39623). 166 167 func issue39623[T interface{~int | ~string}](x, y T) T { 168 return x + y 169 } 170 171 // Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI: 172 func Sum[T interface{~int | ~string}](s []T) (sum T) { 173 for _, v := range s { 174 sum += v 175 } 176 return 177 } 178 179 // Assignability of an unnamed pointer type to a type parameter that 180 // has a matching underlying type. 181 func _[T interface{}, PT interface{~*T}] (x T) PT { 182 return &x 183 } 184 185 // Indexing of type parameters containing type parameters in their constraint terms: 186 func at[T interface{ ~[]E }, E interface{}](x T, i int) E { 187 return x[i] 188 } 189 190 // Conversion of a local type to a type parameter. 191 func _[T interface{~int}](x T) { 192 type myint int 193 var _ int = int(x) 194 var _ T = 42 195 var _ T = T(myint(42)) 196 } 197 198 // Indexing a type parameter with an array type bound checks length. 199 // (Example by mdempsky@.) 200 func _[T interface { ~[10]int }](x T) { 201 _ = x[9] // ok 202 _ = x[20 /* ERROR "out of bounds" */ ] 203 } 204 205 // Pointer indirection of a type parameter. 206 func _[T interface{ ~*int }](p T) int { 207 return *p 208 } 209 210 // Channel sends and receives on type parameters. 211 func _[T interface{ ~chan int }](ch T) int { 212 ch <- 0 213 return <- ch 214 } 215 216 // Calling of a generic variable. 217 func _[T interface{ ~func() }](f T) { 218 f() 219 go f() 220 } 221 222 type F1 func() 223 type F2 func() 224 func _[T interface{ func()|F1|F2 }](f T) { 225 f() 226 go f() 227 } 228 229 // We must compare against the (possibly underlying) types of term list 230 // elements when checking if a constraint is satisfied by a type. 231 // The underlying type of each term must be computed after the 232 // interface has been instantiated as its constraint may contain 233 // a type parameter that was substituted with a defined type. 234 // Test case from an (originally) failing example. 235 236 type sliceOf[E any] interface{ ~[]E } 237 238 func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) } 239 240 var f func() 241 var cancelSlice []context.CancelFunc 242 var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f) 243 244 // A generic function must be instantiated with a type, not a value. 245 246 func g[T any](T) T { panic(0) } 247 248 var _ = g[int] 249 var _ = g[nil /* ERROR "is not a type" */ ] 250 var _ = g(0)