1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package reflect
17
18 import (
19 "runtime"
20 "strconv"
21 "sync"
22 "unsafe"
23 )
24
25
26
27
28
29
30
31
32 type Type interface {
33
34
35
36
37 Align() int
38
39
40
41 FieldAlign() int
42
43
44
45
46
47
48
49
50
51 Method(int) Method
52
53
54
55
56
57
58
59
60
61 MethodByName(string) (Method, bool)
62
63
64 NumMethod() int
65
66
67
68 Name() string
69
70
71
72
73 PkgPath() string
74
75
76
77 Size() uintptr
78
79
80
81
82
83
84 String() string
85
86
87 Kind() Kind
88
89
90 Implements(u Type) bool
91
92
93 AssignableTo(u Type) bool
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 Bits() int
111
112
113
114 ChanDir() ChanDir
115
116
117
118
119
120
121
122
123
124
125
126
127
128 IsVariadic() bool
129
130
131
132 Elem() Type
133
134
135
136
137 Field(i int) StructField
138
139
140
141
142
143 FieldByIndex(index []int) StructField
144
145
146
147 FieldByName(name string) (StructField, bool)
148
149
150
151
152 FieldByNameFunc(match func(string) bool) (StructField, bool)
153
154
155
156
157 In(i int) Type
158
159
160
161 Key() Type
162
163
164
165 Len() int
166
167
168
169 NumField() int
170
171
172
173 NumIn() int
174
175
176
177 NumOut() int
178
179
180
181
182 Out(i int) Type
183
184 runtimeType() *runtime.Type
185 common() *commonType
186 uncommon() *uncommonType
187 }
188
189
190
191 type Kind uint8
192
193 const (
194 Invalid Kind = iota
195 Bool
196 Int
197 Int8
198 Int16
199 Int32
200 Int64
201 Uint
202 Uint8
203 Uint16
204 Uint32
205 Uint64
206 Uintptr
207 Float32
208 Float64
209 Complex64
210 Complex128
211 Array
212 Chan
213 Func
214 Interface
215 Map
216 Ptr
217 Slice
218 String
219 Struct
220 UnsafePointer
221 )
222
223 224 225 226 227 228 229 230 231 232 233 234
235
236
237
238
239
240
241 type commonType struct {
242 size uintptr
243 hash uint32
244 alg uint8
245 align uint8
246 fieldAlign uint8
247 kind uint8
248 string *string
249 *uncommonType
250 ptrToThis *runtime.Type
251 }
252
253 type method struct {
254 name *string
255 pkgPath *string
256 mtyp *runtime.Type
257 typ *runtime.Type
258 ifn unsafe.Pointer
259 tfn unsafe.Pointer
260 }
261
262 type uncommonType struct {
263 name *string
264 pkgPath *string
265 methods []method
266 }
267
268
269 type ChanDir int
270
271 const (
272 RecvDir ChanDir = 1 << iota
273 SendDir
274 BothDir = RecvDir | SendDir
275 )
276
277
278 type arrayType struct {
279 commonType `reflect:"array"`
280 elem *runtime.Type
281 slice *runtime.Type
282 len uintptr
283 }
284
285
286 type chanType struct {
287 commonType `reflect:"chan"`
288 elem *runtime.Type
289 dir uintptr
290 }
291
292
293 type funcType struct {
294 commonType `reflect:"func"`
295 dotdotdot bool
296 in []*runtime.Type
297 out []*runtime.Type
298 }
299
300
301 type imethod struct {
302 name *string
303 pkgPath *string
304 typ *runtime.Type
305 }
306
307
308 type interfaceType struct {
309 commonType `reflect:"interface"`
310 methods []imethod
311 }
312
313
314 type mapType struct {
315 commonType `reflect:"map"`
316 key *runtime.Type
317 elem *runtime.Type
318 }
319
320
321 type ptrType struct {
322 commonType `reflect:"ptr"`
323 elem *runtime.Type
324 }
325
326
327 type sliceType struct {
328 commonType `reflect:"slice"`
329 elem *runtime.Type
330 }
331
332
333 type structField struct {
334 name *string
335 pkgPath *string
336 typ *runtime.Type
337 tag *string
338 offset uintptr
339 }
340
341
342 type structType struct {
343 commonType `reflect:"struct"`
344 fields []structField
345 }
346
347 348 349 350
351
352
353 type Method struct {
354 PkgPath string
355 Name string
356 Type Type
357 Func Value
358 Index int
359 }
360
361
362
363 const kindMask = 0x7f
364
365 func (k Kind) String() string {
366 if int(k) < len(kindNames) {
367 return kindNames[k]
368 }
369 return "kind" + strconv.Itoa(int(k))
370 }
371
372 var kindNames = []string{
373 Invalid: "invalid",
374 Bool: "bool",
375 Int: "int",
376 Int8: "int8",
377 Int16: "int16",
378 Int32: "int32",
379 Int64: "int64",
380 Uint: "uint",
381 Uint8: "uint8",
382 Uint16: "uint16",
383 Uint32: "uint32",
384 Uint64: "uint64",
385 Uintptr: "uintptr",
386 Float32: "float32",
387 Float64: "float64",
388 Complex64: "complex64",
389 Complex128: "complex128",
390 Array: "array",
391 Chan: "chan",
392 Func: "func",
393 Interface: "interface",
394 Map: "map",
395 Ptr: "ptr",
396 Slice: "slice",
397 String: "string",
398 Struct: "struct",
399 UnsafePointer: "unsafe.Pointer",
400 }
401
402 func (t *uncommonType) uncommon() *uncommonType {
403 return t
404 }
405
406 func (t *uncommonType) PkgPath() string {
407 if t == nil || t.pkgPath == nil {
408 return ""
409 }
410 return *t.pkgPath
411 }
412
413 func (t *uncommonType) Name() string {
414 if t == nil || t.name == nil {
415 return ""
416 }
417 return *t.name
418 }
419
420 func (t *commonType) toType() Type {
421 if t == nil {
422 return nil
423 }
424 return t
425 }
426
427 func (t *commonType) String() string { return *t.string }
428
429 func (t *commonType) Size() uintptr { return t.size }
430
431 func (t *commonType) Bits() int {
432 if t == nil {
433 panic("reflect: Bits of nil Type")
434 }
435 k := t.Kind()
436 if k < Int || k > Complex128 {
437 panic("reflect: Bits of non-arithmetic Type " + t.String())
438 }
439 return int(t.size) * 8
440 }
441
442 func (t *commonType) Align() int { return int(t.align) }
443
444 func (t *commonType) FieldAlign() int { return int(t.fieldAlign) }
445
446 func (t *commonType) Kind() Kind { return Kind(t.kind & kindMask) }
447
448 func (t *commonType) common() *commonType { return t }
449
450 func (t *uncommonType) Method(i int) (m Method) {
451 if t == nil || i < 0 || i >= len(t.methods) {
452 panic("reflect: Method index out of range")
453 }
454 p := &t.methods[i]
455 if p.name != nil {
456 m.Name = *p.name
457 }
458 flag := uint32(0)
459 if p.pkgPath != nil {
460 m.PkgPath = *p.pkgPath
461 flag |= flagRO
462 }
463 m.Type = toType(p.typ)
464 fn := p.tfn
465 m.Func = valueFromIword(flag, m.Type, iword(fn))
466 m.Index = i
467 return
468 }
469
470 func (t *uncommonType) NumMethod() int {
471 if t == nil {
472 return 0
473 }
474 return len(t.methods)
475 }
476
477 func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
478 if t == nil {
479 return
480 }
481 var p *method
482 for i := range t.methods {
483 p = &t.methods[i]
484 if p.name != nil && *p.name == name {
485 return t.Method(i), true
486 }
487 }
488 return
489 }
490
491
492
493
494 func (t *commonType) NumMethod() int {
495 if t.Kind() == Interface {
496 tt := (*interfaceType)(unsafe.Pointer(t))
497 return tt.NumMethod()
498 }
499 return t.uncommonType.NumMethod()
500 }
501
502 func (t *commonType) Method(i int) (m Method) {
503 if t.Kind() == Interface {
504 tt := (*interfaceType)(unsafe.Pointer(t))
505 return tt.Method(i)
506 }
507 return t.uncommonType.Method(i)
508 }
509
510 func (t *commonType) MethodByName(name string) (m Method, ok bool) {
511 if t.Kind() == Interface {
512 tt := (*interfaceType)(unsafe.Pointer(t))
513 return tt.MethodByName(name)
514 }
515 return t.uncommonType.MethodByName(name)
516 }
517
518 func (t *commonType) PkgPath() string {
519 return t.uncommonType.PkgPath()
520 }
521
522 func (t *commonType) Name() string {
523 return t.uncommonType.Name()
524 }
525
526 func (t *commonType) ChanDir() ChanDir {
527 if t.Kind() != Chan {
528 panic("reflect: ChanDir of non-chan type")
529 }
530 tt := (*chanType)(unsafe.Pointer(t))
531 return ChanDir(tt.dir)
532 }
533
534 func (t *commonType) IsVariadic() bool {
535 if t.Kind() != Func {
536 panic("reflect: IsVariadic of non-func type")
537 }
538 tt := (*funcType)(unsafe.Pointer(t))
539 return tt.dotdotdot
540 }
541
542 func (t *commonType) Elem() Type {
543 switch t.Kind() {
544 case Array:
545 tt := (*arrayType)(unsafe.Pointer(t))
546 return toType(tt.elem)
547 case Chan:
548 tt := (*chanType)(unsafe.Pointer(t))
549 return toType(tt.elem)
550 case Map:
551 tt := (*mapType)(unsafe.Pointer(t))
552 return toType(tt.elem)
553 case Ptr:
554 tt := (*ptrType)(unsafe.Pointer(t))
555 return toType(tt.elem)
556 case Slice:
557 tt := (*sliceType)(unsafe.Pointer(t))
558 return toType(tt.elem)
559 }
560 panic("reflect; Elem of invalid type")
561 }
562
563 func (t *commonType) Field(i int) StructField {
564 if t.Kind() != Struct {
565 panic("reflect: Field of non-struct type")
566 }
567 tt := (*structType)(unsafe.Pointer(t))
568 return tt.Field(i)
569 }
570
571 func (t *commonType) FieldByIndex(index []int) StructField {
572 if t.Kind() != Struct {
573 panic("reflect: FieldByIndex of non-struct type")
574 }
575 tt := (*structType)(unsafe.Pointer(t))
576 return tt.FieldByIndex(index)
577 }
578
579 func (t *commonType) FieldByName(name string) (StructField, bool) {
580 if t.Kind() != Struct {
581 panic("reflect: FieldByName of non-struct type")
582 }
583 tt := (*structType)(unsafe.Pointer(t))
584 return tt.FieldByName(name)
585 }
586
587 func (t *commonType) FieldByNameFunc(match func(string) bool) (StructField, bool) {
588 if t.Kind() != Struct {
589 panic("reflect: FieldByNameFunc of non-struct type")
590 }
591 tt := (*structType)(unsafe.Pointer(t))
592 return tt.FieldByNameFunc(match)
593 }
594
595 func (t *commonType) In(i int) Type {
596 if t.Kind() != Func {
597 panic("reflect: In of non-func type")
598 }
599 tt := (*funcType)(unsafe.Pointer(t))
600 return toType(tt.in[i])
601 }
602
603 func (t *commonType) Key() Type {
604 if t.Kind() != Map {
605 panic("reflect: Key of non-map type")
606 }
607 tt := (*mapType)(unsafe.Pointer(t))
608 return toType(tt.key)
609 }
610
611 func (t *commonType) Len() int {
612 if t.Kind() != Array {
613 panic("reflect: Len of non-array type")
614 }
615 tt := (*arrayType)(unsafe.Pointer(t))
616 return int(tt.len)
617 }
618
619 func (t *commonType) NumField() int {
620 if t.Kind() != Struct {
621 panic("reflect: NumField of non-struct type")
622 }
623 tt := (*structType)(unsafe.Pointer(t))
624 return len(tt.fields)
625 }
626
627 func (t *commonType) NumIn() int {
628 if t.Kind() != Func {
629 panic("reflect; NumIn of non-func type")
630 }
631 tt := (*funcType)(unsafe.Pointer(t))
632 return len(tt.in)
633 }
634
635 func (t *commonType) NumOut() int {
636 if t.Kind() != Func {
637 panic("reflect; NumOut of non-func type")
638 }
639 tt := (*funcType)(unsafe.Pointer(t))
640 return len(tt.out)
641 }
642
643 func (t *commonType) Out(i int) Type {
644 if t.Kind() != Func {
645 panic("reflect: Out of non-func type")
646 }
647 tt := (*funcType)(unsafe.Pointer(t))
648 return toType(tt.out[i])
649 }
650
651 func (d ChanDir) String() string {
652 switch d {
653 case SendDir:
654 return "chan<-"
655 case RecvDir:
656 return "<-chan"
657 case BothDir:
658 return "chan"
659 }
660 return "ChanDir" + strconv.Itoa(int(d))
661 }
662
663
664 func (t *interfaceType) Method(i int) (m Method) {
665 if i < 0 || i >= len(t.methods) {
666 return
667 }
668 p := &t.methods[i]
669 m.Name = *p.name
670 if p.pkgPath != nil {
671 m.PkgPath = *p.pkgPath
672 }
673 m.Type = toType(p.typ)
674 m.Index = i
675 return
676 }
677
678
679 func (t *interfaceType) NumMethod() int { return len(t.methods) }
680
681
682 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
683 if t == nil {
684 return
685 }
686 var p *imethod
687 for i := range t.methods {
688 p = &t.methods[i]
689 if *p.name == name {
690 return t.Method(i), true
691 }
692 }
693 return
694 }
695
696 type StructField struct {
697 PkgPath string
698 Name string
699 Type Type
700 Tag StructTag
701 Offset uintptr
702 Index []int
703 Anonymous bool
704 }
705
706
707
708
709
710
711
712
713
714 type StructTag string
715
716
717
718
719
720 func (tag StructTag) Get(key string) string {
721 for tag != "" {
722
723 i := 0
724 for i < len(tag) && tag[i] == ' ' {
725 i++
726 }
727 tag = tag[i:]
728 if tag == "" {
729 break
730 }
731
732
733
734 i = 0
735 for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
736 i++
737 }
738 if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
739 break
740 }
741 name := string(tag[:i])
742 tag = tag[i+1:]
743
744
745 i = 1
746 for i < len(tag) && tag[i] != '"' {
747 if tag[i] == '\\' {
748 i++
749 }
750 i++
751 }
752 if i >= len(tag) {
753 break
754 }
755 qvalue := string(tag[:i+1])
756 tag = tag[i+1:]
757
758 if key == name {
759 value, _ := strconv.Unquote(qvalue)
760 return value
761 }
762 }
763 return ""
764 }
765
766
767 func (t *structType) Field(i int) (f StructField) {
768 if i < 0 || i >= len(t.fields) {
769 return
770 }
771 p := t.fields[i]
772 f.Type = toType(p.typ)
773 if p.name != nil {
774 f.Name = *p.name
775 } else {
776 t := f.Type
777 if t.Kind() == Ptr {
778 t = t.Elem()
779 }
780 f.Name = t.Name()
781 f.Anonymous = true
782 }
783 if p.pkgPath != nil {
784 f.PkgPath = *p.pkgPath
785 }
786 if p.tag != nil {
787 f.Tag = StructTag(*p.tag)
788 }
789 f.Offset = p.offset
790 f.Index = []int{i}
791 return
792 }
793
794
795
796
797
798 func (t *structType) FieldByIndex(index []int) (f StructField) {
799 f.Type = Type(t.toType())
800 for i, x := range index {
801 if i > 0 {
802 ft := f.Type
803 if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
804 ft = ft.Elem()
805 }
806 f.Type = ft
807 }
808 f = f.Type.Field(x)
809 }
810 return
811 }
812
813 const inf = 1 << 30
814
815 func (t *structType) fieldByNameFunc(match func(string) bool, mark map[*structType]bool, depth int) (ff StructField, fd int) {
816 fd = inf
817
818 if mark[t] {
819
820 return
821 }
822 mark[t] = true
823
824 var fi int
825 n := 0
826 L:
827 for i := range t.fields {
828 f := t.Field(i)
829 d := inf
830 switch {
831 case match(f.Name):
832
833 d = depth
834 case f.Anonymous:
835 ft := f.Type
836 if ft.Kind() == Ptr {
837 ft = ft.Elem()
838 }
839 switch {
840 case match(ft.Name()):
841
842 d = depth
843 case fd > depth:
844
845 if ft.Kind() == Struct {
846 st := (*structType)(unsafe.Pointer(ft.(*commonType)))
847 f, d = st.fieldByNameFunc(match, mark, depth+1)
848 }
849 }
850 }
851
852 switch {
853 case d < fd:
854
855 ff, fi, fd = f, i, d
856 n = 1
857 case d == fd:
858
859
860 n++
861 if d == depth {
862
863 break L
864 }
865 }
866 }
867
868 if n == 1 {
869
870 if len(ff.Index) <= depth {
871 ff.Index = make([]int, depth+1)
872 }
873 ff.Index[depth] = fi
874 } else {
875
876 fd = inf
877 }
878
879 mark[t] = false, false
880 return
881 }
882
883
884
885 func (t *structType) FieldByName(name string) (f StructField, present bool) {
886 return t.FieldByNameFunc(func(s string) bool { return s == name })
887 }
888
889
890
891 func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, present bool) {
892 if ff, fd := t.fieldByNameFunc(match, make(map[*structType]bool), 0); fd < inf {
893 ff.Index = ff.Index[0 : fd+1]
894 f, present = ff, true
895 }
896 return
897 }
898
899
900 func toCommonType(p *runtime.Type) *commonType {
901 if p == nil {
902 return nil
903 }
904 type hdr struct {
905 x interface{}
906 t commonType
907 }
908 x := unsafe.Pointer(p)
909 if uintptr(x)&reflectFlags != 0 {
910 panic("reflect: invalid interface value")
911 }
912 return &(*hdr)(x).t
913 }
914
915 func toType(p *runtime.Type) Type {
916 if p == nil {
917 return nil
918 }
919 return toCommonType(p).toType()
920 }
921
922
923 func TypeOf(i interface{}) Type {
924 eface := *(*emptyInterface)(unsafe.Pointer(&i))
925 return toType(eface.typ)
926 }
927
928
929 var ptrMap struct {
930 sync.RWMutex
931 m map[*commonType]*ptrType
932 }
933
934 func (t *commonType) runtimeType() *runtime.Type {
935
936
937 var rt struct {
938 i runtime.Type
939 ct commonType
940 }
941 return (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsafe.Offsetof(rt.ct)))
942 }
943
944
945
946 func PtrTo(t Type) Type {
947
948 ct := t.(*commonType)
949 if p := ct.ptrToThis; p != nil {
950 return toType(p)
951 }
952
953
954
955
956
957
958 ptrMap.RLock()
959 if m := ptrMap.m; m != nil {
960 if p := m[ct]; p != nil {
961 ptrMap.RUnlock()
962 return p.commonType.toType()
963 }
964 }
965 ptrMap.RUnlock()
966 ptrMap.Lock()
967 if ptrMap.m == nil {
968 ptrMap.m = make(map[*commonType]*ptrType)
969 }
970 p := ptrMap.m[ct]
971 if p != nil {
972
973 ptrMap.Unlock()
974 return p
975 }
976
977 var rt struct {
978 i runtime.Type
979 ptrType
980 }
981 rt.i = (*runtime.PtrType)(unsafe.Pointer(&rt.ptrType))
982
983
984
985
986 p = &rt.ptrType
987 bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.PtrType)))
988 *p = *bp
989
990 s := "*" + *ct.string
991 p.string = &s
992
993
994
995
996
997
998 p.hash = ct.hash*16777619 ^ '*'
999
1000 p.uncommonType = nil
1001 p.ptrToThis = nil
1002 p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - unsafe.Offsetof(rt.ptrType)))
1003
1004 ptrMap.m[ct] = p
1005 ptrMap.Unlock()
1006 return p.commonType.toType()
1007 }
1008
1009 func (t *commonType) Implements(u Type) bool {
1010 if u == nil {
1011 panic("reflect: nil type passed to Type.Implements")
1012 }
1013 if u.Kind() != Interface {
1014 panic("reflect: non-interface type passed to Type.Implements")
1015 }
1016 return implements(u.(*commonType), t)
1017 }
1018
1019 func (t *commonType) AssignableTo(u Type) bool {
1020 if u == nil {
1021 panic("reflect: nil type passed to Type.AssignableTo")
1022 }
1023 uu := u.(*commonType)
1024 return directlyAssignable(uu, t) || implements(uu, t)
1025 }
1026
1027
1028 func implements(T, V *commonType) bool {
1029 if T.Kind() != Interface {
1030 return false
1031 }
1032 t := (*interfaceType)(unsafe.Pointer(T))
1033 if len(t.methods) == 0 {
1034 return true
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 if V.Kind() == Interface {
1050 v := (*interfaceType)(unsafe.Pointer(V))
1051 i := 0
1052 for j := 0; j < len(v.methods); j++ {
1053 tm := &t.methods[i]
1054 vm := &v.methods[j]
1055 if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ {
1056 if i++; i >= len(t.methods) {
1057 return true
1058 }
1059 }
1060 }
1061 return false
1062 }
1063
1064 v := V.uncommon()
1065 if v == nil {
1066 return false
1067 }
1068 i := 0
1069 for j := 0; j < len(v.methods); j++ {
1070 tm := &t.methods[i]
1071 vm := &v.methods[j]
1072 if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ {
1073 if i++; i >= len(t.methods) {
1074 return true
1075 }
1076 }
1077 }
1078 return false
1079 }
1080
1081
1082
1083
1084
1085
1086 func directlyAssignable(T, V *commonType) bool {
1087
1088 if T == V {
1089 return true
1090 }
1091
1092
1093
1094 if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
1095 return false
1096 }
1097
1098
1099
1100
1101 switch T.Kind() {
1102 case Array:
1103 return T.Elem() == V.Elem() && T.Len() == V.Len()
1104
1105 case Chan:
1106
1107
1108
1109 if V.ChanDir() == BothDir && T.Elem() == V.Elem() {
1110 return true
1111 }
1112
1113
1114 return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
1115
1116 case Func:
1117 t := (*funcType)(unsafe.Pointer(T))
1118 v := (*funcType)(unsafe.Pointer(V))
1119 if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
1120 return false
1121 }
1122 for i, typ := range t.in {
1123 if typ != v.in[i] {
1124 return false
1125 }
1126 }
1127 for i, typ := range t.out {
1128 if typ != v.out[i] {
1129 return false
1130 }
1131 }
1132 return true
1133
1134 case Interface:
1135 t := (*interfaceType)(unsafe.Pointer(T))
1136 v := (*interfaceType)(unsafe.Pointer(V))
1137 if len(t.methods) == 0 && len(v.methods) == 0 {
1138 return true
1139 }
1140
1141
1142 return false
1143
1144 case Map:
1145 return T.Key() == V.Key() && T.Elem() == V.Elem()
1146
1147 case Ptr, Slice:
1148 return T.Elem() == V.Elem()
1149
1150 case Struct:
1151 t := (*structType)(unsafe.Pointer(T))
1152 v := (*structType)(unsafe.Pointer(V))
1153 if len(t.fields) != len(v.fields) {
1154 return false
1155 }
1156 for i := range t.fields {
1157 tf := &t.fields[i]
1158 vf := &v.fields[i]
1159 if tf.name != vf.name || tf.pkgPath != vf.pkgPath ||
1160 tf.typ != vf.typ || tf.tag != vf.tag || tf.offset != vf.offset {
1161 return false
1162 }
1163 }
1164 return true
1165 }
1166
1167 return false
1168 }