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