1
2
3
4
5
6
7 package types2
8
9
10 func isValid(t Type) bool { return Unalias(t) != Typ[Invalid] }
11
12
13
14
15
16 func isBoolean(t Type) bool { return isBasic(t, IsBoolean) }
17 func isInteger(t Type) bool { return isBasic(t, IsInteger) }
18 func isUnsigned(t Type) bool { return isBasic(t, IsUnsigned) }
19 func isFloat(t Type) bool { return isBasic(t, IsFloat) }
20 func isComplex(t Type) bool { return isBasic(t, IsComplex) }
21 func isNumeric(t Type) bool { return isBasic(t, IsNumeric) }
22 func isString(t Type) bool { return isBasic(t, IsString) }
23 func isIntegerOrFloat(t Type) bool { return isBasic(t, IsInteger|IsFloat) }
24 func isConstType(t Type) bool { return isBasic(t, IsConstType) }
25
26
27
28
29 func isBasic(t Type, info BasicInfo) bool {
30 u, _ := under(t).(*Basic)
31 return u != nil && u.info&info != 0
32 }
33
34
35
36
37
38
39
40 func allBoolean(t Type) bool { return allBasic(t, IsBoolean) }
41 func allInteger(t Type) bool { return allBasic(t, IsInteger) }
42 func allUnsigned(t Type) bool { return allBasic(t, IsUnsigned) }
43 func allNumeric(t Type) bool { return allBasic(t, IsNumeric) }
44 func allString(t Type) bool { return allBasic(t, IsString) }
45 func allOrdered(t Type) bool { return allBasic(t, IsOrdered) }
46 func allNumericOrString(t Type) bool { return allBasic(t, IsNumeric|IsString) }
47
48
49
50
51
52 func allBasic(t Type, info BasicInfo) bool {
53 if tpar, _ := Unalias(t).(*TypeParam); tpar != nil {
54 return tpar.is(func(t *term) bool { return t != nil && isBasic(t.typ, info) })
55 }
56 return isBasic(t, info)
57 }
58
59
60
61
62 func hasName(t Type) bool {
63 switch Unalias(t).(type) {
64 case *Basic, *Named, *TypeParam:
65 return true
66 }
67 return false
68 }
69
70
71
72
73 func isTypeLit(t Type) bool {
74 switch Unalias(t).(type) {
75 case *Named, *TypeParam:
76 return false
77 }
78 return true
79 }
80
81
82
83
84 func isTyped(t Type) bool {
85
86
87
88
89 b, _ := t.(*Basic)
90 return b == nil || b.info&IsUntyped == 0
91 }
92
93
94 func isUntyped(t Type) bool {
95 return !isTyped(t)
96 }
97
98
99 func IsInterface(t Type) bool {
100 _, ok := under(t).(*Interface)
101 return ok
102 }
103
104
105 func isNonTypeParamInterface(t Type) bool {
106 return !isTypeParam(t) && IsInterface(t)
107 }
108
109
110 func isTypeParam(t Type) bool {
111 _, ok := Unalias(t).(*TypeParam)
112 return ok
113 }
114
115
116
117
118
119 func hasEmptyTypeset(t Type) bool {
120 if tpar, _ := Unalias(t).(*TypeParam); tpar != nil && tpar.bound != nil {
121 iface, _ := safeUnderlying(tpar.bound).(*Interface)
122 return iface != nil && iface.tset != nil && iface.tset.IsEmpty()
123 }
124 return false
125 }
126
127
128
129
130 func isGeneric(t Type) bool {
131
132 named := asNamed(t)
133 return named != nil && named.obj != nil && named.inst == nil && named.TypeParams().Len() > 0
134 }
135
136
137 func Comparable(T Type) bool {
138 return comparable(T, true, nil, nil)
139 }
140
141
142
143 func comparable(T Type, dynamic bool, seen map[Type]bool, reportf func(string, ...interface{})) bool {
144 if seen[T] {
145 return true
146 }
147 if seen == nil {
148 seen = make(map[Type]bool)
149 }
150 seen[T] = true
151
152 switch t := under(T).(type) {
153 case *Basic:
154
155
156 return t.kind != UntypedNil
157 case *Pointer, *Chan:
158 return true
159 case *Struct:
160 for _, f := range t.fields {
161 if !comparable(f.typ, dynamic, seen, nil) {
162 if reportf != nil {
163 reportf("struct containing %s cannot be compared", f.typ)
164 }
165 return false
166 }
167 }
168 return true
169 case *Array:
170 if !comparable(t.elem, dynamic, seen, nil) {
171 if reportf != nil {
172 reportf("%s cannot be compared", t)
173 }
174 return false
175 }
176 return true
177 case *Interface:
178 if dynamic && !isTypeParam(T) || t.typeSet().IsComparable(seen) {
179 return true
180 }
181 if reportf != nil {
182 if t.typeSet().IsEmpty() {
183 reportf("empty type set")
184 } else {
185 reportf("incomparable types in type set")
186 }
187 }
188
189 }
190 return false
191 }
192
193
194 func hasNil(t Type) bool {
195 switch u := under(t).(type) {
196 case *Basic:
197 return u.kind == UnsafePointer
198 case *Slice, *Pointer, *Signature, *Map, *Chan:
199 return true
200 case *Interface:
201 return !isTypeParam(t) || u.typeSet().underIs(func(u Type) bool {
202 return u != nil && hasNil(u)
203 })
204 }
205 return false
206 }
207
208
209 type ifacePair struct {
210 x, y *Interface
211 prev *ifacePair
212 }
213
214 func (p *ifacePair) identical(q *ifacePair) bool {
215 return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
216 }
217
218
219 type comparer struct {
220 ignoreTags bool
221 ignoreInvalids bool
222 }
223
224
225 func (c *comparer) identical(x, y Type, p *ifacePair) bool {
226 x = Unalias(x)
227 y = Unalias(y)
228
229 if x == y {
230 return true
231 }
232
233 if c.ignoreInvalids && (!isValid(x) || !isValid(y)) {
234 return true
235 }
236
237 switch x := x.(type) {
238 case *Basic:
239
240
241
242 if y, ok := y.(*Basic); ok {
243 return x.kind == y.kind
244 }
245
246 case *Array:
247
248
249 if y, ok := y.(*Array); ok {
250
251
252 return (x.len < 0 || y.len < 0 || x.len == y.len) && c.identical(x.elem, y.elem, p)
253 }
254
255 case *Slice:
256
257 if y, ok := y.(*Slice); ok {
258 return c.identical(x.elem, y.elem, p)
259 }
260
261 case *Struct:
262
263
264
265
266 if y, ok := y.(*Struct); ok {
267 if x.NumFields() == y.NumFields() {
268 for i, f := range x.fields {
269 g := y.fields[i]
270 if f.embedded != g.embedded ||
271 !c.ignoreTags && x.Tag(i) != y.Tag(i) ||
272 !f.sameId(g.pkg, g.name) ||
273 !c.identical(f.typ, g.typ, p) {
274 return false
275 }
276 }
277 return true
278 }
279 }
280
281 case *Pointer:
282
283 if y, ok := y.(*Pointer); ok {
284 return c.identical(x.base, y.base, p)
285 }
286
287 case *Tuple:
288
289
290 if y, ok := y.(*Tuple); ok {
291 if x.Len() == y.Len() {
292 if x != nil {
293 for i, v := range x.vars {
294 w := y.vars[i]
295 if !c.identical(v.typ, w.typ, p) {
296 return false
297 }
298 }
299 }
300 return true
301 }
302 }
303
304 case *Signature:
305 y, _ := y.(*Signature)
306 if y == nil {
307 return false
308 }
309
310
311
312
313
314
315
316 if x.TypeParams().Len() != y.TypeParams().Len() {
317 return false
318 }
319
320
321
322 yparams := y.params
323 yresults := y.results
324
325 if x.TypeParams().Len() > 0 {
326
327
328 xtparams := x.TypeParams().list()
329 ytparams := y.TypeParams().list()
330
331 var targs []Type
332 for i := range xtparams {
333 targs = append(targs, x.TypeParams().At(i))
334 }
335 smap := makeSubstMap(ytparams, targs)
336
337 var check *Checker
338 ctxt := NewContext()
339
340
341 for i, xtparam := range xtparams {
342 ybound := check.subst(nopos, ytparams[i].bound, smap, nil, ctxt)
343 if !c.identical(xtparam.bound, ybound, p) {
344 return false
345 }
346 }
347
348 yparams = check.subst(nopos, y.params, smap, nil, ctxt).(*Tuple)
349 yresults = check.subst(nopos, y.results, smap, nil, ctxt).(*Tuple)
350 }
351
352 return x.variadic == y.variadic &&
353 c.identical(x.params, yparams, p) &&
354 c.identical(x.results, yresults, p)
355
356 case *Union:
357 if y, _ := y.(*Union); y != nil {
358
359
360 unionSets := make(map[*Union]*_TypeSet)
361 xset := computeUnionTypeSet(nil, unionSets, nopos, x)
362 yset := computeUnionTypeSet(nil, unionSets, nopos, y)
363 return xset.terms.equal(yset.terms)
364 }
365
366 case *Interface:
367
368
369
370
371
372
373
374 if y, ok := y.(*Interface); ok {
375 xset := x.typeSet()
376 yset := y.typeSet()
377 if xset.comparable != yset.comparable {
378 return false
379 }
380 if !xset.terms.equal(yset.terms) {
381 return false
382 }
383 a := xset.methods
384 b := yset.methods
385 if len(a) == len(b) {
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408 q := &ifacePair{x, y, p}
409 for p != nil {
410 if p.identical(q) {
411 return true
412 }
413 p = p.prev
414 }
415 if debug {
416 assertSortedMethods(a)
417 assertSortedMethods(b)
418 }
419 for i, f := range a {
420 g := b[i]
421 if f.Id() != g.Id() || !c.identical(f.typ, g.typ, q) {
422 return false
423 }
424 }
425 return true
426 }
427 }
428
429 case *Map:
430
431 if y, ok := y.(*Map); ok {
432 return c.identical(x.key, y.key, p) && c.identical(x.elem, y.elem, p)
433 }
434
435 case *Chan:
436
437
438 if y, ok := y.(*Chan); ok {
439 return x.dir == y.dir && c.identical(x.elem, y.elem, p)
440 }
441
442 case *Named:
443
444
445
446 if y := asNamed(y); y != nil {
447
448
449
450 xargs := x.TypeArgs().list()
451 yargs := y.TypeArgs().list()
452 if len(xargs) != len(yargs) {
453 return false
454 }
455 for i, xarg := range xargs {
456 if !Identical(xarg, yargs[i]) {
457 return false
458 }
459 }
460 return identicalOrigin(x, y)
461 }
462
463 case *TypeParam:
464
465
466 case nil:
467
468
469 default:
470 unreachable()
471 }
472
473 return false
474 }
475
476
477 func identicalOrigin(x, y *Named) bool {
478
479 return x.Origin().obj == y.Origin().obj
480 }
481
482
483
484
485 func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool {
486 if len(xargs) != len(yargs) {
487 return false
488 }
489
490 for i, xa := range xargs {
491 if !Identical(xa, yargs[i]) {
492 return false
493 }
494 }
495
496 return Identical(xorig, yorig)
497 }
498
499
500
501
502 func Default(t Type) Type {
503 if t, ok := Unalias(t).(*Basic); ok {
504 switch t.kind {
505 case UntypedBool:
506 return Typ[Bool]
507 case UntypedInt:
508 return Typ[Int]
509 case UntypedRune:
510 return universeRune
511 case UntypedFloat:
512 return Typ[Float64]
513 case UntypedComplex:
514 return Typ[Complex128]
515 case UntypedString:
516 return Typ[String]
517 }
518 }
519 return t
520 }
521
522
523
524
525
526 func maxType(x, y Type) Type {
527
528
529 if x == y {
530 return x
531 }
532 if isUntyped(x) && isUntyped(y) && isNumeric(x) && isNumeric(y) {
533
534 if x.(*Basic).kind > y.(*Basic).kind {
535 return x
536 }
537 return y
538 }
539 return nil
540 }
541
542
543 func clone[P *T, T any](p P) P {
544 c := *p
545 return &c
546 }
547
View as plain text