1
2
3
4
5 package types
6
7
8
9 func Identical(t1, t2 *Type) bool {
10 return identical(t1, t2, true, nil)
11 }
12
13
14
15 func IdenticalIgnoreTags(t1, t2 *Type) bool {
16 return identical(t1, t2, false, nil)
17 }
18
19 type typePair struct {
20 t1 *Type
21 t2 *Type
22 }
23
24 func identical(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) bool {
25 if t1 == t2 {
26 return true
27 }
28 if t1 == nil || t2 == nil || t1.kind != t2.kind || t1.Broke() || t2.Broke() {
29 return false
30 }
31 if t1.sym != nil || t2.sym != nil {
32
33
34 switch t1.kind {
35 case TUINT8:
36 return (t1 == Types[TUINT8] || t1 == ByteType) && (t2 == Types[TUINT8] || t2 == ByteType)
37 case TINT32:
38 return (t1 == Types[TINT32] || t1 == RuneType) && (t2 == Types[TINT32] || t2 == RuneType)
39 default:
40 return false
41 }
42 }
43
44
45
46
47
48 if assumedEqual == nil {
49 assumedEqual = make(map[typePair]struct{})
50 } else if _, ok := assumedEqual[typePair{t1, t2}]; ok {
51 return true
52 }
53 assumedEqual[typePair{t1, t2}] = struct{}{}
54
55 switch t1.kind {
56 case TIDEAL:
57
58
59
60
61 return true
62
63 case TINTER:
64 if t1.AllMethods().Len() != t2.AllMethods().Len() {
65 return false
66 }
67 for i, f1 := range t1.AllMethods().Slice() {
68 f2 := t2.AllMethods().Index(i)
69 if f1.Sym != f2.Sym || !identical(f1.Type, f2.Type, cmpTags, assumedEqual) {
70 return false
71 }
72 }
73 return true
74
75 case TSTRUCT:
76 if t1.NumFields() != t2.NumFields() {
77 return false
78 }
79 for i, f1 := range t1.FieldSlice() {
80 f2 := t2.Field(i)
81 if f1.Sym != f2.Sym || f1.Embedded != f2.Embedded || !identical(f1.Type, f2.Type, cmpTags, assumedEqual) {
82 return false
83 }
84 if cmpTags && f1.Note != f2.Note {
85 return false
86 }
87 }
88 return true
89
90 case TFUNC:
91
92
93
94 for _, f := range ParamsResults {
95
96 fs1, fs2 := f(t1).FieldSlice(), f(t2).FieldSlice()
97 if len(fs1) != len(fs2) {
98 return false
99 }
100 for i, f1 := range fs1 {
101 f2 := fs2[i]
102 if f1.IsDDD() != f2.IsDDD() || !identical(f1.Type, f2.Type, cmpTags, assumedEqual) {
103 return false
104 }
105 }
106 }
107 return true
108
109 case TARRAY:
110 if t1.NumElem() != t2.NumElem() {
111 return false
112 }
113
114 case TCHAN:
115 if t1.ChanDir() != t2.ChanDir() {
116 return false
117 }
118
119 case TMAP:
120 if !identical(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
121 return false
122 }
123 }
124
125 return identical(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
126 }
127
View as plain text