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