Source file
src/reflect/all_test.go
Documentation: reflect
1
2
3
4
5 package reflect_test
6
7 import (
8 "bytes"
9 "encoding/base64"
10 "flag"
11 "fmt"
12 "go/token"
13 "io"
14 "math"
15 "math/rand"
16 "os"
17 . "reflect"
18 "reflect/internal/example1"
19 "reflect/internal/example2"
20 "runtime"
21 "sort"
22 "strconv"
23 "strings"
24 "sync"
25 "sync/atomic"
26 "testing"
27 "time"
28 "unsafe"
29 )
30
31 var sink interface{}
32
33 func TestBool(t *testing.T) {
34 v := ValueOf(true)
35 if v.Bool() != true {
36 t.Fatal("ValueOf(true).Bool() = false")
37 }
38 }
39
40 type integer int
41 type T struct {
42 a int
43 b float64
44 c string
45 d *int
46 }
47
48 type pair struct {
49 i interface{}
50 s string
51 }
52
53 func assert(t *testing.T, s, want string) {
54 if s != want {
55 t.Errorf("have %#q want %#q", s, want)
56 }
57 }
58
59 var typeTests = []pair{
60 {struct{ x int }{}, "int"},
61 {struct{ x int8 }{}, "int8"},
62 {struct{ x int16 }{}, "int16"},
63 {struct{ x int32 }{}, "int32"},
64 {struct{ x int64 }{}, "int64"},
65 {struct{ x uint }{}, "uint"},
66 {struct{ x uint8 }{}, "uint8"},
67 {struct{ x uint16 }{}, "uint16"},
68 {struct{ x uint32 }{}, "uint32"},
69 {struct{ x uint64 }{}, "uint64"},
70 {struct{ x float32 }{}, "float32"},
71 {struct{ x float64 }{}, "float64"},
72 {struct{ x int8 }{}, "int8"},
73 {struct{ x (**int8) }{}, "**int8"},
74 {struct{ x (**integer) }{}, "**reflect_test.integer"},
75 {struct{ x ([32]int32) }{}, "[32]int32"},
76 {struct{ x ([]int8) }{}, "[]int8"},
77 {struct{ x (map[string]int32) }{}, "map[string]int32"},
78 {struct{ x (chan<- string) }{}, "chan<- string"},
79 {struct{ x (chan<- chan string) }{}, "chan<- chan string"},
80 {struct{ x (chan<- <-chan string) }{}, "chan<- <-chan string"},
81 {struct{ x (<-chan <-chan string) }{}, "<-chan <-chan string"},
82 {struct{ x (chan (<-chan string)) }{}, "chan (<-chan string)"},
83 {struct {
84 x struct {
85 c chan *int32
86 d float32
87 }
88 }{},
89 "struct { c chan *int32; d float32 }",
90 },
91 {struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
92 {struct {
93 x struct {
94 c func(chan *integer, *int8)
95 }
96 }{},
97 "struct { c func(chan *reflect_test.integer, *int8) }",
98 },
99 {struct {
100 x struct {
101 a int8
102 b int32
103 }
104 }{},
105 "struct { a int8; b int32 }",
106 },
107 {struct {
108 x struct {
109 a int8
110 b int8
111 c int32
112 }
113 }{},
114 "struct { a int8; b int8; c int32 }",
115 },
116 {struct {
117 x struct {
118 a int8
119 b int8
120 c int8
121 d int32
122 }
123 }{},
124 "struct { a int8; b int8; c int8; d int32 }",
125 },
126 {struct {
127 x struct {
128 a int8
129 b int8
130 c int8
131 d int8
132 e int32
133 }
134 }{},
135 "struct { a int8; b int8; c int8; d int8; e int32 }",
136 },
137 {struct {
138 x struct {
139 a int8
140 b int8
141 c int8
142 d int8
143 e int8
144 f int32
145 }
146 }{},
147 "struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
148 },
149 {struct {
150 x struct {
151 a int8 `reflect:"hi there"`
152 }
153 }{},
154 `struct { a int8 "reflect:\"hi there\"" }`,
155 },
156 {struct {
157 x struct {
158 a int8 `reflect:"hi \x00there\t\n\"\\"`
159 }
160 }{},
161 `struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
162 },
163 {struct {
164 x struct {
165 f func(args ...int)
166 }
167 }{},
168 "struct { f func(...int) }",
169 },
170 {struct {
171 x (interface {
172 a(func(func(int) int) func(func(int)) int)
173 b()
174 })
175 }{},
176 "interface { reflect_test.a(func(func(int) int) func(func(int)) int); reflect_test.b() }",
177 },
178 {struct {
179 x struct {
180 int32
181 int64
182 }
183 }{},
184 "struct { int32; int64 }",
185 },
186 }
187
188 var valueTests = []pair{
189 {new(int), "132"},
190 {new(int8), "8"},
191 {new(int16), "16"},
192 {new(int32), "32"},
193 {new(int64), "64"},
194 {new(uint), "132"},
195 {new(uint8), "8"},
196 {new(uint16), "16"},
197 {new(uint32), "32"},
198 {new(uint64), "64"},
199 {new(float32), "256.25"},
200 {new(float64), "512.125"},
201 {new(complex64), "532.125+10i"},
202 {new(complex128), "564.25+1i"},
203 {new(string), "stringy cheese"},
204 {new(bool), "true"},
205 {new(*int8), "*int8(0)"},
206 {new(**int8), "**int8(0)"},
207 {new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
208 {new(**integer), "**reflect_test.integer(0)"},
209 {new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
210 {new(chan<- string), "chan<- string"},
211 {new(func(a int8, b int32)), "func(int8, int32)(0)"},
212 {new(struct {
213 c chan *int32
214 d float32
215 }),
216 "struct { c chan *int32; d float32 }{chan *int32, 0}",
217 },
218 {new(struct{ c func(chan *integer, *int8) }),
219 "struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}",
220 },
221 {new(struct {
222 a int8
223 b int32
224 }),
225 "struct { a int8; b int32 }{0, 0}",
226 },
227 {new(struct {
228 a int8
229 b int8
230 c int32
231 }),
232 "struct { a int8; b int8; c int32 }{0, 0, 0}",
233 },
234 }
235
236 func testType(t *testing.T, i int, typ Type, want string) {
237 s := typ.String()
238 if s != want {
239 t.Errorf("#%d: have %#q, want %#q", i, s, want)
240 }
241 }
242
243 func TestTypes(t *testing.T) {
244 for i, tt := range typeTests {
245 testType(t, i, ValueOf(tt.i).Field(0).Type(), tt.s)
246 }
247 }
248
249 func TestSet(t *testing.T) {
250 for i, tt := range valueTests {
251 v := ValueOf(tt.i)
252 v = v.Elem()
253 switch v.Kind() {
254 case Int:
255 v.SetInt(132)
256 case Int8:
257 v.SetInt(8)
258 case Int16:
259 v.SetInt(16)
260 case Int32:
261 v.SetInt(32)
262 case Int64:
263 v.SetInt(64)
264 case Uint:
265 v.SetUint(132)
266 case Uint8:
267 v.SetUint(8)
268 case Uint16:
269 v.SetUint(16)
270 case Uint32:
271 v.SetUint(32)
272 case Uint64:
273 v.SetUint(64)
274 case Float32:
275 v.SetFloat(256.25)
276 case Float64:
277 v.SetFloat(512.125)
278 case Complex64:
279 v.SetComplex(532.125 + 10i)
280 case Complex128:
281 v.SetComplex(564.25 + 1i)
282 case String:
283 v.SetString("stringy cheese")
284 case Bool:
285 v.SetBool(true)
286 }
287 s := valueToString(v)
288 if s != tt.s {
289 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
290 }
291 }
292 }
293
294 func TestSetValue(t *testing.T) {
295 for i, tt := range valueTests {
296 v := ValueOf(tt.i).Elem()
297 switch v.Kind() {
298 case Int:
299 v.Set(ValueOf(int(132)))
300 case Int8:
301 v.Set(ValueOf(int8(8)))
302 case Int16:
303 v.Set(ValueOf(int16(16)))
304 case Int32:
305 v.Set(ValueOf(int32(32)))
306 case Int64:
307 v.Set(ValueOf(int64(64)))
308 case Uint:
309 v.Set(ValueOf(uint(132)))
310 case Uint8:
311 v.Set(ValueOf(uint8(8)))
312 case Uint16:
313 v.Set(ValueOf(uint16(16)))
314 case Uint32:
315 v.Set(ValueOf(uint32(32)))
316 case Uint64:
317 v.Set(ValueOf(uint64(64)))
318 case Float32:
319 v.Set(ValueOf(float32(256.25)))
320 case Float64:
321 v.Set(ValueOf(512.125))
322 case Complex64:
323 v.Set(ValueOf(complex64(532.125 + 10i)))
324 case Complex128:
325 v.Set(ValueOf(complex128(564.25 + 1i)))
326 case String:
327 v.Set(ValueOf("stringy cheese"))
328 case Bool:
329 v.Set(ValueOf(true))
330 }
331 s := valueToString(v)
332 if s != tt.s {
333 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
334 }
335 }
336 }
337
338 func TestCanSetField(t *testing.T) {
339 type embed struct{ x, X int }
340 type Embed struct{ x, X int }
341 type S1 struct {
342 embed
343 x, X int
344 }
345 type S2 struct {
346 *embed
347 x, X int
348 }
349 type S3 struct {
350 Embed
351 x, X int
352 }
353 type S4 struct {
354 *Embed
355 x, X int
356 }
357
358 type testCase struct {
359
360 index []int
361 canSet bool
362 }
363 tests := []struct {
364 val Value
365 cases []testCase
366 }{{
367 val: ValueOf(&S1{}),
368 cases: []testCase{
369 {[]int{0}, false},
370 {[]int{0, -1}, false},
371 {[]int{0, 0}, false},
372 {[]int{0, 0, -1}, false},
373 {[]int{0, -1, 0}, false},
374 {[]int{0, -1, 0, -1}, false},
375 {[]int{0, 1}, true},
376 {[]int{0, 1, -1}, true},
377 {[]int{0, -1, 1}, true},
378 {[]int{0, -1, 1, -1}, true},
379 {[]int{1}, false},
380 {[]int{1, -1}, false},
381 {[]int{2}, true},
382 {[]int{2, -1}, true},
383 },
384 }, {
385 val: ValueOf(&S2{embed: &embed{}}),
386 cases: []testCase{
387 {[]int{0}, false},
388 {[]int{0, -1}, false},
389 {[]int{0, 0}, false},
390 {[]int{0, 0, -1}, false},
391 {[]int{0, -1, 0}, false},
392 {[]int{0, -1, 0, -1}, false},
393 {[]int{0, 1}, true},
394 {[]int{0, 1, -1}, true},
395 {[]int{0, -1, 1}, true},
396 {[]int{0, -1, 1, -1}, true},
397 {[]int{1}, false},
398 {[]int{2}, true},
399 },
400 }, {
401 val: ValueOf(&S3{}),
402 cases: []testCase{
403 {[]int{0}, true},
404 {[]int{0, -1}, true},
405 {[]int{0, 0}, false},
406 {[]int{0, 0, -1}, false},
407 {[]int{0, -1, 0}, false},
408 {[]int{0, -1, 0, -1}, false},
409 {[]int{0, 1}, true},
410 {[]int{0, 1, -1}, true},
411 {[]int{0, -1, 1}, true},
412 {[]int{0, -1, 1, -1}, true},
413 {[]int{1}, false},
414 {[]int{2}, true},
415 },
416 }, {
417 val: ValueOf(&S4{Embed: &Embed{}}),
418 cases: []testCase{
419 {[]int{0}, true},
420 {[]int{0, -1}, true},
421 {[]int{0, 0}, false},
422 {[]int{0, 0, -1}, false},
423 {[]int{0, -1, 0}, false},
424 {[]int{0, -1, 0, -1}, false},
425 {[]int{0, 1}, true},
426 {[]int{0, 1, -1}, true},
427 {[]int{0, -1, 1}, true},
428 {[]int{0, -1, 1, -1}, true},
429 {[]int{1}, false},
430 {[]int{2}, true},
431 },
432 }}
433
434 for _, tt := range tests {
435 t.Run(tt.val.Type().Name(), func(t *testing.T) {
436 for _, tc := range tt.cases {
437 f := tt.val
438 for _, i := range tc.index {
439 if f.Kind() == Ptr {
440 f = f.Elem()
441 }
442 if i == -1 {
443 f = f.Addr().Elem()
444 } else {
445 f = f.Field(i)
446 }
447 }
448 if got := f.CanSet(); got != tc.canSet {
449 t.Errorf("CanSet() = %v, want %v", got, tc.canSet)
450 }
451 }
452 })
453 }
454 }
455
456 var _i = 7
457
458 var valueToStringTests = []pair{
459 {123, "123"},
460 {123.5, "123.5"},
461 {byte(123), "123"},
462 {"abc", "abc"},
463 {T{123, 456.75, "hello", &_i}, "reflect_test.T{123, 456.75, hello, *int(&7)}"},
464 {new(chan *T), "*chan *reflect_test.T(&chan *reflect_test.T)"},
465 {[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
466 {&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[10]int(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
467 {[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
468 {&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
469 }
470
471 func TestValueToString(t *testing.T) {
472 for i, test := range valueToStringTests {
473 s := valueToString(ValueOf(test.i))
474 if s != test.s {
475 t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
476 }
477 }
478 }
479
480 func TestArrayElemSet(t *testing.T) {
481 v := ValueOf(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).Elem()
482 v.Index(4).SetInt(123)
483 s := valueToString(v)
484 const want = "[10]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
485 if s != want {
486 t.Errorf("[10]int: have %#q want %#q", s, want)
487 }
488
489 v = ValueOf([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
490 v.Index(4).SetInt(123)
491 s = valueToString(v)
492 const want1 = "[]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
493 if s != want1 {
494 t.Errorf("[]int: have %#q want %#q", s, want1)
495 }
496 }
497
498 func TestPtrPointTo(t *testing.T) {
499 var ip *int32
500 var i int32 = 1234
501 vip := ValueOf(&ip)
502 vi := ValueOf(&i).Elem()
503 vip.Elem().Set(vi.Addr())
504 if *ip != 1234 {
505 t.Errorf("got %d, want 1234", *ip)
506 }
507
508 ip = nil
509 vp := ValueOf(&ip).Elem()
510 vp.Set(Zero(vp.Type()))
511 if ip != nil {
512 t.Errorf("got non-nil (%p), want nil", ip)
513 }
514 }
515
516 func TestPtrSetNil(t *testing.T) {
517 var i int32 = 1234
518 ip := &i
519 vip := ValueOf(&ip)
520 vip.Elem().Set(Zero(vip.Elem().Type()))
521 if ip != nil {
522 t.Errorf("got non-nil (%d), want nil", *ip)
523 }
524 }
525
526 func TestMapSetNil(t *testing.T) {
527 m := make(map[string]int)
528 vm := ValueOf(&m)
529 vm.Elem().Set(Zero(vm.Elem().Type()))
530 if m != nil {
531 t.Errorf("got non-nil (%p), want nil", m)
532 }
533 }
534
535 func TestAll(t *testing.T) {
536 testType(t, 1, TypeOf((int8)(0)), "int8")
537 testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
538
539 typ := TypeOf((*struct {
540 c chan *int32
541 d float32
542 })(nil))
543 testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
544 etyp := typ.Elem()
545 testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
546 styp := etyp
547 f := styp.Field(0)
548 testType(t, 5, f.Type, "chan *int32")
549
550 f, present := styp.FieldByName("d")
551 if !present {
552 t.Errorf("FieldByName says present field is absent")
553 }
554 testType(t, 6, f.Type, "float32")
555
556 f, present = styp.FieldByName("absent")
557 if present {
558 t.Errorf("FieldByName says absent field is present")
559 }
560
561 typ = TypeOf([32]int32{})
562 testType(t, 7, typ, "[32]int32")
563 testType(t, 8, typ.Elem(), "int32")
564
565 typ = TypeOf((map[string]*int32)(nil))
566 testType(t, 9, typ, "map[string]*int32")
567 mtyp := typ
568 testType(t, 10, mtyp.Key(), "string")
569 testType(t, 11, mtyp.Elem(), "*int32")
570
571 typ = TypeOf((chan<- string)(nil))
572 testType(t, 12, typ, "chan<- string")
573 testType(t, 13, typ.Elem(), "string")
574
575
576 typ = TypeOf(struct {
577 d []uint32 `reflect:"TAG"`
578 }{}).Field(0).Type
579 testType(t, 14, typ, "[]uint32")
580 }
581
582 func TestInterfaceGet(t *testing.T) {
583 var inter struct {
584 E interface{}
585 }
586 inter.E = 123.456
587 v1 := ValueOf(&inter)
588 v2 := v1.Elem().Field(0)
589 assert(t, v2.Type().String(), "interface {}")
590 i2 := v2.Interface()
591 v3 := ValueOf(i2)
592 assert(t, v3.Type().String(), "float64")
593 }
594
595 func TestInterfaceValue(t *testing.T) {
596 var inter struct {
597 E interface{}
598 }
599 inter.E = 123.456
600 v1 := ValueOf(&inter)
601 v2 := v1.Elem().Field(0)
602 assert(t, v2.Type().String(), "interface {}")
603 v3 := v2.Elem()
604 assert(t, v3.Type().String(), "float64")
605
606 i3 := v2.Interface()
607 if _, ok := i3.(float64); !ok {
608 t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
609 }
610 }
611
612 func TestFunctionValue(t *testing.T) {
613 var x interface{} = func() {}
614 v := ValueOf(x)
615 if fmt.Sprint(v.Interface()) != fmt.Sprint(x) {
616 t.Fatalf("TestFunction returned wrong pointer")
617 }
618 assert(t, v.Type().String(), "func()")
619 }
620
621 var appendTests = []struct {
622 orig, extra []int
623 }{
624 {make([]int, 2, 4), []int{22}},
625 {make([]int, 2, 4), []int{22, 33, 44}},
626 }
627
628 func sameInts(x, y []int) bool {
629 if len(x) != len(y) {
630 return false
631 }
632 for i, xx := range x {
633 if xx != y[i] {
634 return false
635 }
636 }
637 return true
638 }
639
640 func TestAppend(t *testing.T) {
641 for i, test := range appendTests {
642 origLen, extraLen := len(test.orig), len(test.extra)
643 want := append(test.orig, test.extra...)
644
645 e0 := make([]Value, len(test.extra))
646 for j, e := range test.extra {
647 e0[j] = ValueOf(e)
648 }
649
650 e1 := ValueOf(test.extra)
651
652 a0 := ValueOf(test.orig)
653 have0 := Append(a0, e0...).Interface().([]int)
654 if !sameInts(have0, want) {
655 t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0)
656 }
657
658 if len(test.orig) != origLen {
659 t.Errorf("Append #%d origLen: have %v, want %v", i, len(test.orig), origLen)
660 }
661 if len(test.extra) != extraLen {
662 t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
663 }
664
665 a1 := ValueOf(test.orig)
666 have1 := AppendSlice(a1, e1).Interface().([]int)
667 if !sameInts(have1, want) {
668 t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
669 }
670
671 if len(test.orig) != origLen {
672 t.Errorf("AppendSlice #%d origLen: have %v, want %v", i, len(test.orig), origLen)
673 }
674 if len(test.extra) != extraLen {
675 t.Errorf("AppendSlice #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
676 }
677 }
678 }
679
680 func TestCopy(t *testing.T) {
681 a := []int{1, 2, 3, 4, 10, 9, 8, 7}
682 b := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
683 c := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
684 for i := 0; i < len(b); i++ {
685 if b[i] != c[i] {
686 t.Fatalf("b != c before test")
687 }
688 }
689 a1 := a
690 b1 := b
691 aa := ValueOf(&a1).Elem()
692 ab := ValueOf(&b1).Elem()
693 for tocopy := 1; tocopy <= 7; tocopy++ {
694 aa.SetLen(tocopy)
695 Copy(ab, aa)
696 aa.SetLen(8)
697 for i := 0; i < tocopy; i++ {
698 if a[i] != b[i] {
699 t.Errorf("(i) tocopy=%d a[%d]=%d, b[%d]=%d",
700 tocopy, i, a[i], i, b[i])
701 }
702 }
703 for i := tocopy; i < len(b); i++ {
704 if b[i] != c[i] {
705 if i < len(a) {
706 t.Errorf("(ii) tocopy=%d a[%d]=%d, b[%d]=%d, c[%d]=%d",
707 tocopy, i, a[i], i, b[i], i, c[i])
708 } else {
709 t.Errorf("(iii) tocopy=%d b[%d]=%d, c[%d]=%d",
710 tocopy, i, b[i], i, c[i])
711 }
712 } else {
713 t.Logf("tocopy=%d elem %d is okay\n", tocopy, i)
714 }
715 }
716 }
717 }
718
719 func TestCopyString(t *testing.T) {
720 t.Run("Slice", func(t *testing.T) {
721 s := bytes.Repeat([]byte{'_'}, 8)
722 val := ValueOf(s)
723
724 n := Copy(val, ValueOf(""))
725 if expecting := []byte("________"); n != 0 || !bytes.Equal(s, expecting) {
726 t.Errorf("got n = %d, s = %s, expecting n = 0, s = %s", n, s, expecting)
727 }
728
729 n = Copy(val, ValueOf("hello"))
730 if expecting := []byte("hello___"); n != 5 || !bytes.Equal(s, expecting) {
731 t.Errorf("got n = %d, s = %s, expecting n = 5, s = %s", n, s, expecting)
732 }
733
734 n = Copy(val, ValueOf("helloworld"))
735 if expecting := []byte("hellowor"); n != 8 || !bytes.Equal(s, expecting) {
736 t.Errorf("got n = %d, s = %s, expecting n = 8, s = %s", n, s, expecting)
737 }
738 })
739 t.Run("Array", func(t *testing.T) {
740 s := [...]byte{'_', '_', '_', '_', '_', '_', '_', '_'}
741 val := ValueOf(&s).Elem()
742
743 n := Copy(val, ValueOf(""))
744 if expecting := []byte("________"); n != 0 || !bytes.Equal(s[:], expecting) {
745 t.Errorf("got n = %d, s = %s, expecting n = 0, s = %s", n, s[:], expecting)
746 }
747
748 n = Copy(val, ValueOf("hello"))
749 if expecting := []byte("hello___"); n != 5 || !bytes.Equal(s[:], expecting) {
750 t.Errorf("got n = %d, s = %s, expecting n = 5, s = %s", n, s[:], expecting)
751 }
752
753 n = Copy(val, ValueOf("helloworld"))
754 if expecting := []byte("hellowor"); n != 8 || !bytes.Equal(s[:], expecting) {
755 t.Errorf("got n = %d, s = %s, expecting n = 8, s = %s", n, s[:], expecting)
756 }
757 })
758 }
759
760 func TestCopyArray(t *testing.T) {
761 a := [8]int{1, 2, 3, 4, 10, 9, 8, 7}
762 b := [11]int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
763 c := b
764 aa := ValueOf(&a).Elem()
765 ab := ValueOf(&b).Elem()
766 Copy(ab, aa)
767 for i := 0; i < len(a); i++ {
768 if a[i] != b[i] {
769 t.Errorf("(i) a[%d]=%d, b[%d]=%d", i, a[i], i, b[i])
770 }
771 }
772 for i := len(a); i < len(b); i++ {
773 if b[i] != c[i] {
774 t.Errorf("(ii) b[%d]=%d, c[%d]=%d", i, b[i], i, c[i])
775 } else {
776 t.Logf("elem %d is okay\n", i)
777 }
778 }
779 }
780
781 func TestBigUnnamedStruct(t *testing.T) {
782 b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
783 v := ValueOf(b)
784 b1 := v.Interface().(struct {
785 a, b, c, d int64
786 })
787 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
788 t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
789 }
790 }
791
792 type big struct {
793 a, b, c, d, e int64
794 }
795
796 func TestBigStruct(t *testing.T) {
797 b := big{1, 2, 3, 4, 5}
798 v := ValueOf(b)
799 b1 := v.Interface().(big)
800 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
801 t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
802 }
803 }
804
805 type Basic struct {
806 x int
807 y float32
808 }
809
810 type NotBasic Basic
811
812 type DeepEqualTest struct {
813 a, b interface{}
814 eq bool
815 }
816
817
818 var (
819 fn1 func()
820 fn2 func()
821 fn3 = func() { fn1() }
822 )
823
824 type self struct{}
825
826 type Loop *Loop
827 type Loopy interface{}
828
829 var loop1, loop2 Loop
830 var loopy1, loopy2 Loopy
831 var cycleMap1, cycleMap2, cycleMap3 map[string]interface{}
832
833 type structWithSelfPtr struct {
834 p *structWithSelfPtr
835 s string
836 }
837
838 func init() {
839 loop1 = &loop2
840 loop2 = &loop1
841
842 loopy1 = &loopy2
843 loopy2 = &loopy1
844
845 cycleMap1 = map[string]interface{}{}
846 cycleMap1["cycle"] = cycleMap1
847 cycleMap2 = map[string]interface{}{}
848 cycleMap2["cycle"] = cycleMap2
849 cycleMap3 = map[string]interface{}{}
850 cycleMap3["different"] = cycleMap3
851 }
852
853 var deepEqualTests = []DeepEqualTest{
854
855 {nil, nil, true},
856 {1, 1, true},
857 {int32(1), int32(1), true},
858 {0.5, 0.5, true},
859 {float32(0.5), float32(0.5), true},
860 {"hello", "hello", true},
861 {make([]int, 10), make([]int, 10), true},
862 {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
863 {Basic{1, 0.5}, Basic{1, 0.5}, true},
864 {error(nil), error(nil), true},
865 {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
866 {fn1, fn2, true},
867
868
869 {1, 2, false},
870 {int32(1), int32(2), false},
871 {0.5, 0.6, false},
872 {float32(0.5), float32(0.6), false},
873 {"hello", "hey", false},
874 {make([]int, 10), make([]int, 11), false},
875 {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
876 {Basic{1, 0.5}, Basic{1, 0.6}, false},
877 {Basic{1, 0}, Basic{2, 0}, false},
878 {map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
879 {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
880 {map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
881 {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
882 {nil, 1, false},
883 {1, nil, false},
884 {fn1, fn3, false},
885 {fn3, fn3, false},
886 {[][]int{{1}}, [][]int{{2}}, false},
887 {math.NaN(), math.NaN(), false},
888 {&[1]float64{math.NaN()}, &[1]float64{math.NaN()}, false},
889 {&[1]float64{math.NaN()}, self{}, true},
890 {[]float64{math.NaN()}, []float64{math.NaN()}, false},
891 {[]float64{math.NaN()}, self{}, true},
892 {map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false},
893 {map[float64]float64{math.NaN(): 1}, self{}, true},
894 {&structWithSelfPtr{p: &structWithSelfPtr{s: "a"}}, &structWithSelfPtr{p: &structWithSelfPtr{s: "b"}}, false},
895
896
897 {[]int{}, []int(nil), false},
898 {[]int{}, []int{}, true},
899 {[]int(nil), []int(nil), true},
900 {map[int]int{}, map[int]int(nil), false},
901 {map[int]int{}, map[int]int{}, true},
902 {map[int]int(nil), map[int]int(nil), true},
903
904
905 {1, 1.0, false},
906 {int32(1), int64(1), false},
907 {0.5, "hello", false},
908 {[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
909 {&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false},
910 {Basic{1, 0.5}, NotBasic{1, 0.5}, false},
911 {map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
912
913
914 {&loop1, &loop1, true},
915 {&loop1, &loop2, true},
916 {&loopy1, &loopy1, true},
917 {&loopy1, &loopy2, true},
918 {&cycleMap1, &cycleMap2, true},
919 {&cycleMap1, &cycleMap3, false},
920 }
921
922 func TestDeepEqual(t *testing.T) {
923 for _, test := range deepEqualTests {
924 if test.b == (self{}) {
925 test.b = test.a
926 }
927 if r := DeepEqual(test.a, test.b); r != test.eq {
928 t.Errorf("DeepEqual(%#v, %#v) = %v, want %v", test.a, test.b, r, test.eq)
929 }
930 }
931 }
932
933 func TestTypeOf(t *testing.T) {
934
935 if typ := TypeOf(nil); typ != nil {
936 t.Errorf("expected nil type for nil value; got %v", typ)
937 }
938 for _, test := range deepEqualTests {
939 v := ValueOf(test.a)
940 if !v.IsValid() {
941 continue
942 }
943 typ := TypeOf(test.a)
944 if typ != v.Type() {
945 t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
946 }
947 }
948 }
949
950 type Recursive struct {
951 x int
952 r *Recursive
953 }
954
955 func TestDeepEqualRecursiveStruct(t *testing.T) {
956 a, b := new(Recursive), new(Recursive)
957 *a = Recursive{12, a}
958 *b = Recursive{12, b}
959 if !DeepEqual(a, b) {
960 t.Error("DeepEqual(recursive same) = false, want true")
961 }
962 }
963
964 type _Complex struct {
965 a int
966 b [3]*_Complex
967 c *string
968 d map[float64]float64
969 }
970
971 func TestDeepEqualComplexStruct(t *testing.T) {
972 m := make(map[float64]float64)
973 stra, strb := "hello", "hello"
974 a, b := new(_Complex), new(_Complex)
975 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
976 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
977 if !DeepEqual(a, b) {
978 t.Error("DeepEqual(complex same) = false, want true")
979 }
980 }
981
982 func TestDeepEqualComplexStructInequality(t *testing.T) {
983 m := make(map[float64]float64)
984 stra, strb := "hello", "helloo"
985 a, b := new(_Complex), new(_Complex)
986 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
987 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
988 if DeepEqual(a, b) {
989 t.Error("DeepEqual(complex different) = true, want false")
990 }
991 }
992
993 type UnexpT struct {
994 m map[int]int
995 }
996
997 func TestDeepEqualUnexportedMap(t *testing.T) {
998
999 x1 := UnexpT{map[int]int{1: 2}}
1000 x2 := UnexpT{map[int]int{1: 2}}
1001 if !DeepEqual(&x1, &x2) {
1002 t.Error("DeepEqual(x1, x2) = false, want true")
1003 }
1004
1005 y1 := UnexpT{map[int]int{2: 3}}
1006 if DeepEqual(&x1, &y1) {
1007 t.Error("DeepEqual(x1, y1) = true, want false")
1008 }
1009 }
1010
1011 func check2ndField(x interface{}, offs uintptr, t *testing.T) {
1012 s := ValueOf(x)
1013 f := s.Type().Field(1)
1014 if f.Offset != offs {
1015 t.Error("mismatched offsets in structure alignment:", f.Offset, offs)
1016 }
1017 }
1018
1019
1020
1021 func TestAlignment(t *testing.T) {
1022 type T1inner struct {
1023 a int
1024 }
1025 type T1 struct {
1026 T1inner
1027 f int
1028 }
1029 type T2inner struct {
1030 a, b int
1031 }
1032 type T2 struct {
1033 T2inner
1034 f int
1035 }
1036
1037 x := T1{T1inner{2}, 17}
1038 check2ndField(x, uintptr(unsafe.Pointer(&x.f))-uintptr(unsafe.Pointer(&x)), t)
1039
1040 x1 := T2{T2inner{2, 3}, 17}
1041 check2ndField(x1, uintptr(unsafe.Pointer(&x1.f))-uintptr(unsafe.Pointer(&x1)), t)
1042 }
1043
1044 func Nil(a interface{}, t *testing.T) {
1045 n := ValueOf(a).Field(0)
1046 if !n.IsNil() {
1047 t.Errorf("%v should be nil", a)
1048 }
1049 }
1050
1051 func NotNil(a interface{}, t *testing.T) {
1052 n := ValueOf(a).Field(0)
1053 if n.IsNil() {
1054 t.Errorf("value of type %v should not be nil", ValueOf(a).Type().String())
1055 }
1056 }
1057
1058 func TestIsNil(t *testing.T) {
1059
1060
1061 doNil := []interface{}{
1062 struct{ x *int }{},
1063 struct{ x interface{} }{},
1064 struct{ x map[string]int }{},
1065 struct{ x func() bool }{},
1066 struct{ x chan int }{},
1067 struct{ x []string }{},
1068 struct{ x unsafe.Pointer }{},
1069 }
1070 for _, ts := range doNil {
1071 ty := TypeOf(ts).Field(0).Type
1072 v := Zero(ty)
1073 v.IsNil()
1074 }
1075
1076
1077 var pi struct {
1078 x *int
1079 }
1080 Nil(pi, t)
1081 pi.x = new(int)
1082 NotNil(pi, t)
1083
1084 var si struct {
1085 x []int
1086 }
1087 Nil(si, t)
1088 si.x = make([]int, 10)
1089 NotNil(si, t)
1090
1091 var ci struct {
1092 x chan int
1093 }
1094 Nil(ci, t)
1095 ci.x = make(chan int)
1096 NotNil(ci, t)
1097
1098 var mi struct {
1099 x map[int]int
1100 }
1101 Nil(mi, t)
1102 mi.x = make(map[int]int)
1103 NotNil(mi, t)
1104
1105 var ii struct {
1106 x interface{}
1107 }
1108 Nil(ii, t)
1109 ii.x = 2
1110 NotNil(ii, t)
1111
1112 var fi struct {
1113 x func(t *testing.T)
1114 }
1115 Nil(fi, t)
1116 fi.x = TestIsNil
1117 NotNil(fi, t)
1118 }
1119
1120 func TestIsZero(t *testing.T) {
1121 for i, tt := range []struct {
1122 x interface{}
1123 want bool
1124 }{
1125
1126 {true, false},
1127 {false, true},
1128
1129 {int(0), true},
1130 {int(1), false},
1131 {int8(0), true},
1132 {int8(1), false},
1133 {int16(0), true},
1134 {int16(1), false},
1135 {int32(0), true},
1136 {int32(1), false},
1137 {int64(0), true},
1138 {int64(1), false},
1139 {uint(0), true},
1140 {uint(1), false},
1141 {uint8(0), true},
1142 {uint8(1), false},
1143 {uint16(0), true},
1144 {uint16(1), false},
1145 {uint32(0), true},
1146 {uint32(1), false},
1147 {uint64(0), true},
1148 {uint64(1), false},
1149 {float32(0), true},
1150 {float32(1.2), false},
1151 {float64(0), true},
1152 {float64(1.2), false},
1153 {math.Copysign(0, -1), false},
1154 {complex64(0), true},
1155 {complex64(1.2), false},
1156 {complex128(0), true},
1157 {complex128(1.2), false},
1158 {complex(math.Copysign(0, -1), 0), false},
1159 {complex(0, math.Copysign(0, -1)), false},
1160 {complex(math.Copysign(0, -1), math.Copysign(0, -1)), false},
1161 {uintptr(0), true},
1162 {uintptr(128), false},
1163
1164 {Zero(TypeOf([5]string{})).Interface(), true},
1165 {[5]string{"", "", "", "", ""}, true},
1166 {[5]string{}, true},
1167 {[5]string{"", "", "", "a", ""}, false},
1168
1169 {(chan string)(nil), true},
1170 {make(chan string), false},
1171 {time.After(1), false},
1172
1173 {(func())(nil), true},
1174 {New, false},
1175
1176 {New(TypeOf(new(error)).Elem()).Elem(), true},
1177 {(io.Reader)(strings.NewReader("")), false},
1178
1179 {(map[string]string)(nil), true},
1180 {map[string]string{}, false},
1181 {make(map[string]string), false},
1182
1183 {(*func())(nil), true},
1184 {(*int)(nil), true},
1185 {new(int), false},
1186
1187 {[]string{}, false},
1188 {([]string)(nil), true},
1189 {make([]string, 0), false},
1190
1191 {"", true},
1192 {"not-zero", false},
1193
1194 {T{}, true},
1195 {T{123, 456.75, "hello", &_i}, false},
1196
1197 {(unsafe.Pointer)(nil), true},
1198 {(unsafe.Pointer)(new(int)), false},
1199 } {
1200 var x Value
1201 if v, ok := tt.x.(Value); ok {
1202 x = v
1203 } else {
1204 x = ValueOf(tt.x)
1205 }
1206
1207 b := x.IsZero()
1208 if b != tt.want {
1209 t.Errorf("%d: IsZero((%s)(%+v)) = %t, want %t", i, x.Kind(), tt.x, b, tt.want)
1210 }
1211
1212 if !Zero(TypeOf(tt.x)).IsZero() {
1213 t.Errorf("%d: IsZero(Zero(TypeOf((%s)(%+v)))) is false", i, x.Kind(), tt.x)
1214 }
1215 }
1216
1217 func() {
1218 defer func() {
1219 if r := recover(); r == nil {
1220 t.Error("should panic for invalid value")
1221 }
1222 }()
1223 (Value{}).IsZero()
1224 }()
1225 }
1226
1227 func TestInterfaceExtraction(t *testing.T) {
1228 var s struct {
1229 W io.Writer
1230 }
1231
1232 s.W = os.Stdout
1233 v := Indirect(ValueOf(&s)).Field(0).Interface()
1234 if v != s.W.(interface{}) {
1235 t.Error("Interface() on interface: ", v, s.W)
1236 }
1237 }
1238
1239 func TestNilPtrValueSub(t *testing.T) {
1240 var pi *int
1241 if pv := ValueOf(pi); pv.Elem().IsValid() {
1242 t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
1243 }
1244 }
1245
1246 func TestMap(t *testing.T) {
1247 m := map[string]int{"a": 1, "b": 2}
1248 mv := ValueOf(m)
1249 if n := mv.Len(); n != len(m) {
1250 t.Errorf("Len = %d, want %d", n, len(m))
1251 }
1252 keys := mv.MapKeys()
1253 newmap := MakeMap(mv.Type())
1254 for k, v := range m {
1255
1256
1257 seen := false
1258 for _, kv := range keys {
1259 if kv.String() == k {
1260 seen = true
1261 break
1262 }
1263 }
1264 if !seen {
1265 t.Errorf("Missing key %q", k)
1266 }
1267
1268
1269 vv := mv.MapIndex(ValueOf(k))
1270 if vi := vv.Int(); vi != int64(v) {
1271 t.Errorf("Key %q: have value %d, want %d", k, vi, v)
1272 }
1273
1274
1275 newmap.SetMapIndex(ValueOf(k), ValueOf(v))
1276 }
1277 vv := mv.MapIndex(ValueOf("not-present"))
1278 if vv.IsValid() {
1279 t.Errorf("Invalid key: got non-nil value %s", valueToString(vv))
1280 }
1281
1282 newm := newmap.Interface().(map[string]int)
1283 if len(newm) != len(m) {
1284 t.Errorf("length after copy: newm=%d, m=%d", len(newm), len(m))
1285 }
1286
1287 for k, v := range newm {
1288 mv, ok := m[k]
1289 if mv != v {
1290 t.Errorf("newm[%q] = %d, but m[%q] = %d, %v", k, v, k, mv, ok)
1291 }
1292 }
1293
1294 newmap.SetMapIndex(ValueOf("a"), Value{})
1295 v, ok := newm["a"]
1296 if ok {
1297 t.Errorf("newm[\"a\"] = %d after delete", v)
1298 }
1299
1300 mv = ValueOf(&m).Elem()
1301 mv.Set(Zero(mv.Type()))
1302 if m != nil {
1303 t.Errorf("mv.Set(nil) failed")
1304 }
1305 }
1306
1307 func TestNilMap(t *testing.T) {
1308 var m map[string]int
1309 mv := ValueOf(m)
1310 keys := mv.MapKeys()
1311 if len(keys) != 0 {
1312 t.Errorf(">0 keys for nil map: %v", keys)
1313 }
1314
1315
1316 x := mv.MapIndex(ValueOf("hello"))
1317 if x.Kind() != Invalid {
1318 t.Errorf("m.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
1319 }
1320
1321
1322 var mbig map[string][10 << 20]byte
1323 x = ValueOf(mbig).MapIndex(ValueOf("hello"))
1324 if x.Kind() != Invalid {
1325 t.Errorf("mbig.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
1326 }
1327
1328
1329 mv.SetMapIndex(ValueOf("hi"), Value{})
1330 }
1331
1332 func TestChan(t *testing.T) {
1333 for loop := 0; loop < 2; loop++ {
1334 var c chan int
1335 var cv Value
1336
1337
1338 switch loop {
1339 case 1:
1340 c = make(chan int, 1)
1341 cv = ValueOf(c)
1342 case 0:
1343 cv = MakeChan(TypeOf(c), 1)
1344 c = cv.Interface().(chan int)
1345 }
1346
1347
1348 cv.Send(ValueOf(2))
1349 if i := <-c; i != 2 {
1350 t.Errorf("reflect Send 2, native recv %d", i)
1351 }
1352
1353
1354 c <- 3
1355 if i, ok := cv.Recv(); i.Int() != 3 || !ok {
1356 t.Errorf("native send 3, reflect Recv %d, %t", i.Int(), ok)
1357 }
1358
1359
1360 val, ok := cv.TryRecv()
1361 if val.IsValid() || ok {
1362 t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
1363 }
1364
1365
1366 c <- 4
1367 val, ok = cv.TryRecv()
1368 if !val.IsValid() {
1369 t.Errorf("TryRecv on ready chan got nil")
1370 } else if i := val.Int(); i != 4 || !ok {
1371 t.Errorf("native send 4, TryRecv %d, %t", i, ok)
1372 }
1373
1374
1375 c <- 100
1376 ok = cv.TrySend(ValueOf(5))
1377 i := <-c
1378 if ok {
1379 t.Errorf("TrySend on full chan succeeded: value %d", i)
1380 }
1381
1382
1383 ok = cv.TrySend(ValueOf(6))
1384 if !ok {
1385 t.Errorf("TrySend on empty chan failed")
1386 select {
1387 case x := <-c:
1388 t.Errorf("TrySend failed but it did send %d", x)
1389 default:
1390 }
1391 } else {
1392 if i = <-c; i != 6 {
1393 t.Errorf("TrySend 6, recv %d", i)
1394 }
1395 }
1396
1397
1398 c <- 123
1399 cv.Close()
1400 if i, ok := cv.Recv(); i.Int() != 123 || !ok {
1401 t.Errorf("send 123 then close; Recv %d, %t", i.Int(), ok)
1402 }
1403 if i, ok := cv.Recv(); i.Int() != 0 || ok {
1404 t.Errorf("after close Recv %d, %t", i.Int(), ok)
1405 }
1406 }
1407
1408
1409 var c chan int
1410 cv := MakeChan(TypeOf(c), 0)
1411 c = cv.Interface().(chan int)
1412 if cv.TrySend(ValueOf(7)) {
1413 t.Errorf("TrySend on sync chan succeeded")
1414 }
1415 if v, ok := cv.TryRecv(); v.IsValid() || ok {
1416 t.Errorf("TryRecv on sync chan succeeded: isvalid=%v ok=%v", v.IsValid(), ok)
1417 }
1418
1419
1420 cv = MakeChan(TypeOf(c), 10)
1421 c = cv.Interface().(chan int)
1422 for i := 0; i < 3; i++ {
1423 c <- i
1424 }
1425 if l, m := cv.Len(), cv.Cap(); l != len(c) || m != cap(c) {
1426 t.Errorf("Len/Cap = %d/%d want %d/%d", l, m, len(c), cap(c))
1427 }
1428 }
1429
1430
1431 type caseInfo struct {
1432 desc string
1433 canSelect bool
1434 recv Value
1435 closed bool
1436 helper func()
1437 panic bool
1438 }
1439
1440 var allselect = flag.Bool("allselect", false, "exhaustive select test")
1441
1442 func TestSelect(t *testing.T) {
1443 selectWatch.once.Do(func() { go selectWatcher() })
1444
1445 var x exhaustive
1446 nch := 0
1447 newop := func(n int, cap int) (ch, val Value) {
1448 nch++
1449 if nch%101%2 == 1 {
1450 c := make(chan int, cap)
1451 ch = ValueOf(c)
1452 val = ValueOf(n)
1453 } else {
1454 c := make(chan string, cap)
1455 ch = ValueOf(c)
1456 val = ValueOf(fmt.Sprint(n))
1457 }
1458 return
1459 }
1460
1461 for n := 0; x.Next(); n++ {
1462 if testing.Short() && n >= 1000 {
1463 break
1464 }
1465 if n >= 100000 && !*allselect {
1466 break
1467 }
1468 if n%100000 == 0 && testing.Verbose() {
1469 println("TestSelect", n)
1470 }
1471 var cases []SelectCase
1472 var info []caseInfo
1473
1474
1475 if x.Maybe() {
1476 ch, val := newop(len(cases), 1)
1477 cases = append(cases, SelectCase{
1478 Dir: SelectSend,
1479 Chan: ch,
1480 Send: val,
1481 })
1482 info = append(info, caseInfo{desc: "ready send", canSelect: true})
1483 }
1484
1485
1486 if x.Maybe() {
1487 ch, val := newop(len(cases), 1)
1488 ch.Send(val)
1489 cases = append(cases, SelectCase{
1490 Dir: SelectRecv,
1491 Chan: ch,
1492 })
1493 info = append(info, caseInfo{desc: "ready recv", canSelect: true, recv: val})
1494 }
1495
1496
1497 if x.Maybe() {
1498 ch, val := newop(len(cases), 0)
1499 cases = append(cases, SelectCase{
1500 Dir: SelectSend,
1501 Chan: ch,
1502 Send: val,
1503 })
1504
1505 if x.Maybe() {
1506 f := func() { ch.Recv() }
1507 info = append(info, caseInfo{desc: "blocking send", helper: f})
1508 } else {
1509 info = append(info, caseInfo{desc: "blocking send"})
1510 }
1511 }
1512
1513
1514 if x.Maybe() {
1515 ch, val := newop(len(cases), 0)
1516 cases = append(cases, SelectCase{
1517 Dir: SelectRecv,
1518 Chan: ch,
1519 })
1520
1521 if x.Maybe() {
1522 f := func() { ch.Send(val) }
1523 info = append(info, caseInfo{desc: "blocking recv", recv: val, helper: f})
1524 } else {
1525 info = append(info, caseInfo{desc: "blocking recv"})
1526 }
1527 }
1528
1529
1530 if x.Maybe() {
1531
1532 var val Value
1533 if x.Maybe() {
1534 val = ValueOf(100)
1535 }
1536 cases = append(cases, SelectCase{
1537 Dir: SelectSend,
1538 Send: val,
1539 })
1540 info = append(info, caseInfo{desc: "zero Chan send"})
1541 }
1542
1543
1544 if x.Maybe() {
1545 cases = append(cases, SelectCase{
1546 Dir: SelectRecv,
1547 })
1548 info = append(info, caseInfo{desc: "zero Chan recv"})
1549 }
1550
1551
1552 if x.Maybe() {
1553 cases = append(cases, SelectCase{
1554 Dir: SelectSend,
1555 Chan: ValueOf((chan int)(nil)),
1556 Send: ValueOf(101),
1557 })
1558 info = append(info, caseInfo{desc: "nil Chan send"})
1559 }
1560
1561
1562 if x.Maybe() {
1563 cases = append(cases, SelectCase{
1564 Dir: SelectRecv,
1565 Chan: ValueOf((chan int)(nil)),
1566 })
1567 info = append(info, caseInfo{desc: "nil Chan recv"})
1568 }
1569
1570
1571 if x.Maybe() {
1572 ch := make(chan int)
1573 close(ch)
1574 cases = append(cases, SelectCase{
1575 Dir: SelectSend,
1576 Chan: ValueOf(ch),
1577 Send: ValueOf(101),
1578 })
1579 info = append(info, caseInfo{desc: "closed Chan send", canSelect: true, panic: true})
1580 }
1581
1582
1583 if x.Maybe() {
1584 ch, val := newop(len(cases), 0)
1585 ch.Close()
1586 val = Zero(val.Type())
1587 cases = append(cases, SelectCase{
1588 Dir: SelectRecv,
1589 Chan: ch,
1590 })
1591 info = append(info, caseInfo{desc: "closed Chan recv", canSelect: true, closed: true, recv: val})
1592 }
1593
1594 var helper func()
1595
1596
1597
1598
1599 numCanSelect := 0
1600 canProceed := false
1601 canBlock := true
1602 canPanic := false
1603 helpers := []int{}
1604 for i, c := range info {
1605 if c.canSelect {
1606 canProceed = true
1607 canBlock = false
1608 numCanSelect++
1609 if c.panic {
1610 canPanic = true
1611 }
1612 } else if c.helper != nil {
1613 canProceed = true
1614 helpers = append(helpers, i)
1615 }
1616 }
1617 if !canProceed || x.Maybe() {
1618 cases = append(cases, SelectCase{
1619 Dir: SelectDefault,
1620 })
1621 info = append(info, caseInfo{desc: "default", canSelect: canBlock})
1622 numCanSelect++
1623 } else if canBlock {
1624
1625 cas := &info[helpers[x.Choose(len(helpers))]]
1626 helper = cas.helper
1627 cas.canSelect = true
1628 numCanSelect++
1629 }
1630
1631
1632
1633
1634 for loop := 0; loop < 2; loop++ {
1635 i := x.Choose(len(cases))
1636 j := x.Choose(len(cases))
1637 cases[i], cases[j] = cases[j], cases[i]
1638 info[i], info[j] = info[j], info[i]
1639 }
1640
1641 if helper != nil {
1642
1643
1644
1645
1646
1647 pause := 10 * time.Microsecond
1648 if testing.Short() {
1649 pause = 100 * time.Microsecond
1650 }
1651 time.AfterFunc(pause, helper)
1652 }
1653
1654
1655 i, recv, recvOK, panicErr := runSelect(cases, info)
1656 if panicErr != nil && !canPanic {
1657 t.Fatalf("%s\npanicked unexpectedly: %v", fmtSelect(info), panicErr)
1658 }
1659 if panicErr == nil && canPanic && numCanSelect == 1 {
1660 t.Fatalf("%s\nselected #%d incorrectly (should panic)", fmtSelect(info), i)
1661 }
1662 if panicErr != nil {
1663 continue
1664 }
1665
1666 cas := info[i]
1667 if !cas.canSelect {
1668 recvStr := ""
1669 if recv.IsValid() {
1670 recvStr = fmt.Sprintf(", received %v, %v", recv.Interface(), recvOK)
1671 }
1672 t.Fatalf("%s\nselected #%d incorrectly%s", fmtSelect(info), i, recvStr)
1673 continue
1674 }
1675 if cas.panic {
1676 t.Fatalf("%s\nselected #%d incorrectly (case should panic)", fmtSelect(info), i)
1677 continue
1678 }
1679
1680 if cases[i].Dir == SelectRecv {
1681 if !recv.IsValid() {
1682 t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, cas.recv.Interface(), !cas.closed)
1683 }
1684 if !cas.recv.IsValid() {
1685 t.Fatalf("%s\nselected #%d but internal error: missing recv value", fmtSelect(info), i)
1686 }
1687 if recv.Interface() != cas.recv.Interface() || recvOK != !cas.closed {
1688 if recv.Interface() == cas.recv.Interface() && recvOK == !cas.closed {
1689 t.Fatalf("%s\nselected #%d, got %#v, %v, and DeepEqual is broken on %T", fmtSelect(info), i, recv.Interface(), recvOK, recv.Interface())
1690 }
1691 t.Fatalf("%s\nselected #%d but got %#v, %v, want %#v, %v", fmtSelect(info), i, recv.Interface(), recvOK, cas.recv.Interface(), !cas.closed)
1692 }
1693 } else {
1694 if recv.IsValid() || recvOK {
1695 t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, Value{}, false)
1696 }
1697 }
1698 }
1699 }
1700
1701 func TestSelectMaxCases(t *testing.T) {
1702 var sCases []SelectCase
1703 channel := make(chan int)
1704 close(channel)
1705 for i := 0; i < 65536; i++ {
1706 sCases = append(sCases, SelectCase{
1707 Dir: SelectRecv,
1708 Chan: ValueOf(channel),
1709 })
1710 }
1711
1712 _, _, _ = Select(sCases)
1713 sCases = append(sCases, SelectCase{
1714 Dir: SelectRecv,
1715 Chan: ValueOf(channel),
1716 })
1717 defer func() {
1718 if err := recover(); err != nil {
1719 if err.(string) != "reflect.Select: too many cases (max 65536)" {
1720 t.Fatalf("unexpected error from select call with greater than max supported cases")
1721 }
1722 } else {
1723 t.Fatalf("expected select call to panic with greater than max supported cases")
1724 }
1725 }()
1726
1727 _, _, _ = Select(sCases)
1728 }
1729
1730 func TestSelectNop(t *testing.T) {
1731
1732 chosen, _, _ := Select([]SelectCase{{Dir: SelectDefault}})
1733 if chosen != 0 {
1734 t.Fatalf("expected Select to return 0, but got %#v", chosen)
1735 }
1736 }
1737
1738 func BenchmarkSelect(b *testing.B) {
1739 channel := make(chan int)
1740 close(channel)
1741 var cases []SelectCase
1742 for i := 0; i < 8; i++ {
1743 cases = append(cases, SelectCase{
1744 Dir: SelectRecv,
1745 Chan: ValueOf(channel),
1746 })
1747 }
1748 for _, numCases := range []int{1, 4, 8} {
1749 b.Run(strconv.Itoa(numCases), func(b *testing.B) {
1750 b.ReportAllocs()
1751 for i := 0; i < b.N; i++ {
1752 _, _, _ = Select(cases[:numCases])
1753 }
1754 })
1755 }
1756 }
1757
1758
1759
1760
1761 var selectWatch struct {
1762 sync.Mutex
1763 once sync.Once
1764 now time.Time
1765 info []caseInfo
1766 }
1767
1768 func selectWatcher() {
1769 for {
1770 time.Sleep(1 * time.Second)
1771 selectWatch.Lock()
1772 if selectWatch.info != nil && time.Since(selectWatch.now) > 10*time.Second {
1773 fmt.Fprintf(os.Stderr, "TestSelect:\n%s blocked indefinitely\n", fmtSelect(selectWatch.info))
1774 panic("select stuck")
1775 }
1776 selectWatch.Unlock()
1777 }
1778 }
1779
1780
1781
1782
1783 func runSelect(cases []SelectCase, info []caseInfo) (chosen int, recv Value, recvOK bool, panicErr interface{}) {
1784 defer func() {
1785 panicErr = recover()
1786
1787 selectWatch.Lock()
1788 selectWatch.info = nil
1789 selectWatch.Unlock()
1790 }()
1791
1792 selectWatch.Lock()
1793 selectWatch.now = time.Now()
1794 selectWatch.info = info
1795 selectWatch.Unlock()
1796
1797 chosen, recv, recvOK = Select(cases)
1798 return
1799 }
1800
1801
1802 func fmtSelect(info []caseInfo) string {
1803 var buf bytes.Buffer
1804 fmt.Fprintf(&buf, "\nselect {\n")
1805 for i, cas := range info {
1806 fmt.Fprintf(&buf, "%d: %s", i, cas.desc)
1807 if cas.recv.IsValid() {
1808 fmt.Fprintf(&buf, " val=%#v", cas.recv.Interface())
1809 }
1810 if cas.canSelect {
1811 fmt.Fprintf(&buf, " canselect")
1812 }
1813 if cas.panic {
1814 fmt.Fprintf(&buf, " panic")
1815 }
1816 fmt.Fprintf(&buf, "\n")
1817 }
1818 fmt.Fprintf(&buf, "}")
1819 return buf.String()
1820 }
1821
1822 type two [2]uintptr
1823
1824
1825
1826 func dummy(b byte, c int, d byte, e two, f byte, g float32, h byte) (i byte, j int, k byte, l two, m byte, n float32, o byte) {
1827 return b, c, d, e, f, g, h
1828 }
1829
1830 func TestFunc(t *testing.T) {
1831 ret := ValueOf(dummy).Call([]Value{
1832 ValueOf(byte(10)),
1833 ValueOf(20),
1834 ValueOf(byte(30)),
1835 ValueOf(two{40, 50}),
1836 ValueOf(byte(60)),
1837 ValueOf(float32(70)),
1838 ValueOf(byte(80)),
1839 })
1840 if len(ret) != 7 {
1841 t.Fatalf("Call returned %d values, want 7", len(ret))
1842 }
1843
1844 i := byte(ret[0].Uint())
1845 j := int(ret[1].Int())
1846 k := byte(ret[2].Uint())
1847 l := ret[3].Interface().(two)
1848 m := byte(ret[4].Uint())
1849 n := float32(ret[5].Float())
1850 o := byte(ret[6].Uint())
1851
1852 if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
1853 t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
1854 }
1855
1856 for i, v := range ret {
1857 if v.CanAddr() {
1858 t.Errorf("result %d is addressable", i)
1859 }
1860 }
1861 }
1862
1863 func TestCallConvert(t *testing.T) {
1864 v := ValueOf(new(io.ReadWriter)).Elem()
1865 f := ValueOf(func(r io.Reader) io.Reader { return r })
1866 out := f.Call([]Value{v})
1867 if len(out) != 1 || out[0].Type() != TypeOf(new(io.Reader)).Elem() || !out[0].IsNil() {
1868 t.Errorf("expected [nil], got %v", out)
1869 }
1870 }
1871
1872 type emptyStruct struct{}
1873
1874 type nonEmptyStruct struct {
1875 member int
1876 }
1877
1878 func returnEmpty() emptyStruct {
1879 return emptyStruct{}
1880 }
1881
1882 func takesEmpty(e emptyStruct) {
1883 }
1884
1885 func returnNonEmpty(i int) nonEmptyStruct {
1886 return nonEmptyStruct{member: i}
1887 }
1888
1889 func takesNonEmpty(n nonEmptyStruct) int {
1890 return n.member
1891 }
1892
1893 func TestCallWithStruct(t *testing.T) {
1894 r := ValueOf(returnEmpty).Call(nil)
1895 if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) {
1896 t.Errorf("returning empty struct returned %#v instead", r)
1897 }
1898 r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})})
1899 if len(r) != 0 {
1900 t.Errorf("takesEmpty returned values: %#v", r)
1901 }
1902 r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)})
1903 if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 {
1904 t.Errorf("returnNonEmpty returned %#v", r)
1905 }
1906 r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})})
1907 if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 {
1908 t.Errorf("takesNonEmpty returned %#v", r)
1909 }
1910 }
1911
1912 func TestCallReturnsEmpty(t *testing.T) {
1913
1914
1915 runtime.GC()
1916 var finalized uint32
1917 f := func() (emptyStruct, *[2]int64) {
1918 i := new([2]int64)
1919 runtime.SetFinalizer(i, func(*[2]int64) { atomic.StoreUint32(&finalized, 1) })
1920 return emptyStruct{}, i
1921 }
1922 v := ValueOf(f).Call(nil)[0]
1923 timeout := time.After(5 * time.Second)
1924 for atomic.LoadUint32(&finalized) == 0 {
1925 select {
1926 case <-timeout:
1927 t.Fatal("finalizer did not run")
1928 default:
1929 }
1930 runtime.Gosched()
1931 runtime.GC()
1932 }
1933 runtime.KeepAlive(v)
1934 }
1935
1936 func BenchmarkCall(b *testing.B) {
1937 fv := ValueOf(func(a, b string) {})
1938 b.ReportAllocs()
1939 b.RunParallel(func(pb *testing.PB) {
1940 args := []Value{ValueOf("a"), ValueOf("b")}
1941 for pb.Next() {
1942 fv.Call(args)
1943 }
1944 })
1945 }
1946
1947 type myint int64
1948
1949 func (i *myint) inc() {
1950 *i = *i + 1
1951 }
1952
1953 func BenchmarkCallMethod(b *testing.B) {
1954 b.ReportAllocs()
1955 z := new(myint)
1956
1957 v := ValueOf(z.inc)
1958 for i := 0; i < b.N; i++ {
1959 v.Call(nil)
1960 }
1961 }
1962
1963 func BenchmarkCallArgCopy(b *testing.B) {
1964 byteArray := func(n int) Value {
1965 return Zero(ArrayOf(n, TypeOf(byte(0))))
1966 }
1967 sizes := [...]struct {
1968 fv Value
1969 arg Value
1970 }{
1971 {ValueOf(func(a [128]byte) {}), byteArray(128)},
1972 {ValueOf(func(a [256]byte) {}), byteArray(256)},
1973 {ValueOf(func(a [1024]byte) {}), byteArray(1024)},
1974 {ValueOf(func(a [4096]byte) {}), byteArray(4096)},
1975 {ValueOf(func(a [65536]byte) {}), byteArray(65536)},
1976 }
1977 for _, size := range sizes {
1978 bench := func(b *testing.B) {
1979 args := []Value{size.arg}
1980 b.SetBytes(int64(size.arg.Len()))
1981 b.ResetTimer()
1982 b.RunParallel(func(pb *testing.PB) {
1983 for pb.Next() {
1984 size.fv.Call(args)
1985 }
1986 })
1987 }
1988 name := fmt.Sprintf("size=%v", size.arg.Len())
1989 b.Run(name, bench)
1990 }
1991 }
1992
1993 func TestMakeFunc(t *testing.T) {
1994 f := dummy
1995 fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
1996 ValueOf(&f).Elem().Set(fv)
1997
1998
1999
2000
2001 g := dummy
2002 g(1, 2, 3, two{4, 5}, 6, 7, 8)
2003
2004
2005 i, j, k, l, m, n, o := f(10, 20, 30, two{40, 50}, 60, 70, 80)
2006 if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
2007 t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
2008 }
2009 }
2010
2011 func TestMakeFuncInterface(t *testing.T) {
2012 fn := func(i int) int { return i }
2013 incr := func(in []Value) []Value {
2014 return []Value{ValueOf(int(in[0].Int() + 1))}
2015 }
2016 fv := MakeFunc(TypeOf(fn), incr)
2017 ValueOf(&fn).Elem().Set(fv)
2018 if r := fn(2); r != 3 {
2019 t.Errorf("Call returned %d, want 3", r)
2020 }
2021 if r := fv.Call([]Value{ValueOf(14)})[0].Int(); r != 15 {
2022 t.Errorf("Call returned %d, want 15", r)
2023 }
2024 if r := fv.Interface().(func(int) int)(26); r != 27 {
2025 t.Errorf("Call returned %d, want 27", r)
2026 }
2027 }
2028
2029 func TestMakeFuncVariadic(t *testing.T) {
2030
2031 fn := func(_ int, is ...int) []int { return nil }
2032 fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] })
2033 ValueOf(&fn).Elem().Set(fv)
2034
2035 r := fn(1, 2, 3)
2036 if r[0] != 2 || r[1] != 3 {
2037 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
2038 }
2039
2040 r = fn(1, []int{2, 3}...)
2041 if r[0] != 2 || r[1] != 3 {
2042 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
2043 }
2044
2045 r = fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int)
2046 if r[0] != 2 || r[1] != 3 {
2047 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
2048 }
2049
2050 r = fv.CallSlice([]Value{ValueOf(1), ValueOf([]int{2, 3})})[0].Interface().([]int)
2051 if r[0] != 2 || r[1] != 3 {
2052 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
2053 }
2054
2055 f := fv.Interface().(func(int, ...int) []int)
2056
2057 r = f(1, 2, 3)
2058 if r[0] != 2 || r[1] != 3 {
2059 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
2060 }
2061 r = f(1, []int{2, 3}...)
2062 if r[0] != 2 || r[1] != 3 {
2063 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
2064 }
2065 }
2066
2067
2068 type WC struct {
2069 }
2070
2071 func (w *WC) Write(p []byte) (n int, err error) {
2072 return 0, nil
2073 }
2074 func (w *WC) Close() error {
2075 return nil
2076 }
2077
2078 func TestMakeFuncValidReturnAssignments(t *testing.T) {
2079
2080
2081
2082
2083 var f func() error
2084 f = MakeFunc(TypeOf(f), func([]Value) []Value {
2085 return []Value{ValueOf(io.EOF)}
2086 }).Interface().(func() error)
2087 f()
2088
2089
2090 var g func() io.Writer
2091 g = MakeFunc(TypeOf(g), func([]Value) []Value {
2092 var w io.WriteCloser = &WC{}
2093 return []Value{ValueOf(&w).Elem()}
2094 }).Interface().(func() io.Writer)
2095 g()
2096
2097
2098 var h func() <-chan int
2099 h = MakeFunc(TypeOf(h), func([]Value) []Value {
2100 return []Value{ValueOf(make(chan int))}
2101 }).Interface().(func() <-chan int)
2102 h()
2103
2104
2105 type T struct{ a, b, c int }
2106 var i func() T
2107 i = MakeFunc(TypeOf(i), func([]Value) []Value {
2108 return []Value{ValueOf(struct{ a, b, c int }{a: 1, b: 2, c: 3})}
2109 }).Interface().(func() T)
2110 i()
2111 }
2112
2113 func TestMakeFuncInvalidReturnAssignments(t *testing.T) {
2114
2115 shouldPanic("", func() {
2116 var f func() error
2117 f = MakeFunc(TypeOf(f), func([]Value) []Value {
2118 return []Value{ValueOf(int(7))}
2119 }).Interface().(func() error)
2120 f()
2121 })
2122
2123 shouldPanic("", func() {
2124 var f func() io.ReadWriteCloser
2125 f = MakeFunc(TypeOf(f), func([]Value) []Value {
2126 var w io.WriteCloser = &WC{}
2127 return []Value{ValueOf(&w).Elem()}
2128 }).Interface().(func() io.ReadWriteCloser)
2129 f()
2130 })
2131
2132 shouldPanic("", func() {
2133 var f func() chan int
2134 f = MakeFunc(TypeOf(f), func([]Value) []Value {
2135 var c <-chan int = make(chan int)
2136 return []Value{ValueOf(c)}
2137 }).Interface().(func() chan int)
2138 f()
2139 })
2140
2141 shouldPanic("", func() {
2142 type T struct{ a, b, c int }
2143 type U struct{ a, b, c int }
2144 var f func() T
2145 f = MakeFunc(TypeOf(f), func([]Value) []Value {
2146 return []Value{ValueOf(U{a: 1, b: 2, c: 3})}
2147 }).Interface().(func() T)
2148 f()
2149 })
2150 }
2151
2152 type Point struct {
2153 x, y int
2154 }
2155
2156
2157 func (p Point) AnotherMethod(scale int) int {
2158 return -1
2159 }
2160
2161
2162 func (p Point) Dist(scale int) int {
2163
2164 return p.x*p.x*scale + p.y*p.y*scale
2165 }
2166
2167
2168 func (p Point) GCMethod(k int) int {
2169 runtime.GC()
2170 return k + p.x
2171 }
2172
2173
2174 func (p Point) NoArgs() {
2175
2176 }
2177
2178
2179 func (p Point) TotalDist(points ...Point) int {
2180 tot := 0
2181 for _, q := range points {
2182 dx := q.x - p.x
2183 dy := q.y - p.y
2184 tot += dx*dx + dy*dy
2185
2186 }
2187 return tot
2188 }
2189
2190
2191 func (p *Point) Int64Method(x int64) int64 {
2192 return x
2193 }
2194
2195
2196 func (p *Point) Int32Method(x int32) int32 {
2197 return x
2198 }
2199
2200 func TestMethod(t *testing.T) {
2201
2202 p := Point{3, 4}
2203 i := TypeOf(p).Method(1).Func.Call([]Value{ValueOf(p), ValueOf(10)})[0].Int()
2204 if i != 250 {
2205 t.Errorf("Type Method returned %d; want 250", i)
2206 }
2207
2208 m, ok := TypeOf(p).MethodByName("Dist")
2209 if !ok {
2210 t.Fatalf("method by name failed")
2211 }
2212 i = m.Func.Call([]Value{ValueOf(p), ValueOf(11)})[0].Int()
2213 if i != 275 {
2214 t.Errorf("Type MethodByName returned %d; want 275", i)
2215 }
2216
2217 m, ok = TypeOf(p).MethodByName("NoArgs")
2218 if !ok {
2219 t.Fatalf("method by name failed")
2220 }
2221 n := len(m.Func.Call([]Value{ValueOf(p)}))
2222 if n != 0 {
2223 t.Errorf("NoArgs returned %d values; want 0", n)
2224 }
2225
2226 i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
2227 if i != 300 {
2228 t.Errorf("Pointer Type Method returned %d; want 300", i)
2229 }
2230
2231 m, ok = TypeOf(&p).MethodByName("Dist")
2232 if !ok {
2233 t.Fatalf("ptr method by name failed")
2234 }
2235 i = m.Func.Call([]Value{ValueOf(&p), ValueOf(13)})[0].Int()
2236 if i != 325 {
2237 t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
2238 }
2239
2240 m, ok = TypeOf(&p).MethodByName("NoArgs")
2241 if !ok {
2242 t.Fatalf("method by name failed")
2243 }
2244 n = len(m.Func.Call([]Value{ValueOf(&p)}))
2245 if n != 0 {
2246 t.Errorf("NoArgs returned %d values; want 0", n)
2247 }
2248
2249
2250 tfunc := TypeOf((func(int) int)(nil))
2251 v := ValueOf(p).Method(1)
2252 if tt := v.Type(); tt != tfunc {
2253 t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
2254 }
2255 i = v.Call([]Value{ValueOf(14)})[0].Int()
2256 if i != 350 {
2257 t.Errorf("Value Method returned %d; want 350", i)
2258 }
2259 v = ValueOf(p).MethodByName("Dist")
2260 if tt := v.Type(); tt != tfunc {
2261 t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
2262 }
2263 i = v.Call([]Value{ValueOf(15)})[0].Int()
2264 if i != 375 {
2265 t.Errorf("Value MethodByName returned %d; want 375", i)
2266 }
2267 v = ValueOf(p).MethodByName("NoArgs")
2268 v.Call(nil)
2269
2270
2271 v = ValueOf(&p).Method(1)
2272 if tt := v.Type(); tt != tfunc {
2273 t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
2274 }
2275 i = v.Call([]Value{ValueOf(16)})[0].Int()
2276 if i != 400 {
2277 t.Errorf("Pointer Value Method returned %d; want 400", i)
2278 }
2279 v = ValueOf(&p).MethodByName("Dist")
2280 if tt := v.Type(); tt != tfunc {
2281 t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
2282 }
2283 i = v.Call([]Value{ValueOf(17)})[0].Int()
2284 if i != 425 {
2285 t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
2286 }
2287 v = ValueOf(&p).MethodByName("NoArgs")
2288 v.Call(nil)
2289
2290
2291
2292
2293
2294 var x interface {
2295 Dist(int) int
2296 } = p
2297 pv := ValueOf(&x).Elem()
2298 v = pv.Method(0)
2299 if tt := v.Type(); tt != tfunc {
2300 t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
2301 }
2302 i = v.Call([]Value{ValueOf(18)})[0].Int()
2303 if i != 450 {
2304 t.Errorf("Interface Method returned %d; want 450", i)
2305 }
2306 v = pv.MethodByName("Dist")
2307 if tt := v.Type(); tt != tfunc {
2308 t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
2309 }
2310 i = v.Call([]Value{ValueOf(19)})[0].Int()
2311 if i != 475 {
2312 t.Errorf("Interface MethodByName returned %d; want 475", i)
2313 }
2314 }
2315
2316 func TestMethodValue(t *testing.T) {
2317 p := Point{3, 4}
2318 var i int64
2319
2320
2321 tfunc := TypeOf((func(int) int)(nil))
2322 v := ValueOf(p).Method(1)
2323 if tt := v.Type(); tt != tfunc {
2324 t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
2325 }
2326 i = ValueOf(v.Interface()).Call([]Value{ValueOf(10)})[0].Int()
2327 if i != 250 {
2328 t.Errorf("Value Method returned %d; want 250", i)
2329 }
2330 v = ValueOf(p).MethodByName("Dist")
2331 if tt := v.Type(); tt != tfunc {
2332 t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
2333 }
2334 i = ValueOf(v.Interface()).Call([]Value{ValueOf(11)})[0].Int()
2335 if i != 275 {
2336 t.Errorf("Value MethodByName returned %d; want 275", i)
2337 }
2338 v = ValueOf(p).MethodByName("NoArgs")
2339 ValueOf(v.Interface()).Call(nil)
2340 v.Interface().(func())()
2341
2342
2343 v = ValueOf(&p).Method(1)
2344 if tt := v.Type(); tt != tfunc {
2345 t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
2346 }
2347 i = ValueOf(v.Interface()).Call([]Value{ValueOf(12)})[0].Int()
2348 if i != 300 {
2349 t.Errorf("Pointer Value Method returned %d; want 300", i)
2350 }
2351 v = ValueOf(&p).MethodByName("Dist")
2352 if tt := v.Type(); tt != tfunc {
2353 t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
2354 }
2355 i = ValueOf(v.Interface()).Call([]Value{ValueOf(13)})[0].Int()
2356 if i != 325 {
2357 t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
2358 }
2359 v = ValueOf(&p).MethodByName("NoArgs")
2360 ValueOf(v.Interface()).Call(nil)
2361 v.Interface().(func())()
2362
2363
2364 pp := &p
2365 v = ValueOf(&pp).Elem().Method(1)
2366 if tt := v.Type(); tt != tfunc {
2367 t.Errorf("Pointer Pointer Value Method Type is %s; want %s", tt, tfunc)
2368 }
2369 i = ValueOf(v.Interface()).Call([]Value{ValueOf(14)})[0].Int()
2370 if i != 350 {
2371 t.Errorf("Pointer Pointer Value Method returned %d; want 350", i)
2372 }
2373 v = ValueOf(&pp).Elem().MethodByName("Dist")
2374 if tt := v.Type(); tt != tfunc {
2375 t.Errorf("Pointer Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
2376 }
2377 i = ValueOf(v.Interface()).Call([]Value{ValueOf(15)})[0].Int()
2378 if i != 375 {
2379 t.Errorf("Pointer Pointer Value MethodByName returned %d; want 375", i)
2380 }
2381
2382
2383
2384
2385
2386 var s = struct {
2387 X interface {
2388 Dist(int) int
2389 }
2390 }{p}
2391 pv := ValueOf(s).Field(0)
2392 v = pv.Method(0)
2393 if tt := v.Type(); tt != tfunc {
2394 t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
2395 }
2396 i = ValueOf(v.Interface()).Call([]Value{ValueOf(16)})[0].Int()
2397 if i != 400 {
2398 t.Errorf("Interface Method returned %d; want 400", i)
2399 }
2400 v = pv.MethodByName("Dist")
2401 if tt := v.Type(); tt != tfunc {
2402 t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
2403 }
2404 i = ValueOf(v.Interface()).Call([]Value{ValueOf(17)})[0].Int()
2405 if i != 425 {
2406 t.Errorf("Interface MethodByName returned %d; want 425", i)
2407 }
2408
2409
2410
2411 m64 := ValueOf(&p).MethodByName("Int64Method").Interface().(func(int64) int64)
2412 if x := m64(123); x != 123 {
2413 t.Errorf("Int64Method returned %d; want 123", x)
2414 }
2415 m32 := ValueOf(&p).MethodByName("Int32Method").Interface().(func(int32) int32)
2416 if x := m32(456); x != 456 {
2417 t.Errorf("Int32Method returned %d; want 456", x)
2418 }
2419 }
2420
2421 func TestVariadicMethodValue(t *testing.T) {
2422 p := Point{3, 4}
2423 points := []Point{{20, 21}, {22, 23}, {24, 25}}
2424 want := int64(p.TotalDist(points[0], points[1], points[2]))
2425
2426
2427 tfunc := TypeOf((func(Point, ...Point) int)(nil))
2428 if tt := TypeOf(p).Method(4).Type; tt != tfunc {
2429 t.Errorf("Variadic Method Type from TypeOf is %s; want %s", tt, tfunc)
2430 }
2431
2432
2433 tfunc = TypeOf((func(...Point) int)(nil))
2434 v := ValueOf(p).Method(4)
2435 if tt := v.Type(); tt != tfunc {
2436 t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
2437 }
2438 i := ValueOf(v.Interface()).Call([]Value{ValueOf(points[0]), ValueOf(points[1]), ValueOf(points[2])})[0].Int()
2439 if i != want {
2440 t.Errorf("Variadic Method returned %d; want %d", i, want)
2441 }
2442 i = ValueOf(v.Interface()).CallSlice([]Value{ValueOf(points)})[0].Int()
2443 if i != want {
2444 t.Errorf("Variadic Method CallSlice returned %d; want %d", i, want)
2445 }
2446
2447 f := v.Interface().(func(...Point) int)
2448 i = int64(f(points[0], points[1], points[2]))
2449 if i != want {
2450 t.Errorf("Variadic Method Interface returned %d; want %d", i, want)
2451 }
2452 i = int64(f(points...))
2453 if i != want {
2454 t.Errorf("Variadic Method Interface Slice returned %d; want %d", i, want)
2455 }
2456 }
2457
2458 type DirectIfaceT struct {
2459 p *int
2460 }
2461
2462 func (d DirectIfaceT) M() int { return *d.p }
2463
2464 func TestDirectIfaceMethod(t *testing.T) {
2465 x := 42
2466 v := DirectIfaceT{&x}
2467 typ := TypeOf(v)
2468 m, ok := typ.MethodByName("M")
2469 if !ok {
2470 t.Fatalf("cannot find method M")
2471 }
2472 in := []Value{ValueOf(v)}
2473 out := m.Func.Call(in)
2474 if got := out[0].Int(); got != 42 {
2475 t.Errorf("Call with value receiver got %d, want 42", got)
2476 }
2477
2478 pv := &v
2479 typ = TypeOf(pv)
2480 m, ok = typ.MethodByName("M")
2481 if !ok {
2482 t.Fatalf("cannot find method M")
2483 }
2484 in = []Value{ValueOf(pv)}
2485 out = m.Func.Call(in)
2486 if got := out[0].Int(); got != 42 {
2487 t.Errorf("Call with pointer receiver got %d, want 42", got)
2488 }
2489 }
2490
2491
2492
2493
2494
2495
2496
2497 type Tinter interface {
2498 M(int, byte) (byte, int)
2499 }
2500
2501 type Tsmallv byte
2502
2503 func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x + int(v) }
2504
2505 type Tsmallp byte
2506
2507 func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
2508
2509 type Twordv uintptr
2510
2511 func (v Twordv) M(x int, b byte) (byte, int) { return b, x + int(v) }
2512
2513 type Twordp uintptr
2514
2515 func (p *Twordp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
2516
2517 type Tbigv [2]uintptr
2518
2519 func (v Tbigv) M(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
2520
2521 type Tbigp [2]uintptr
2522
2523 func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
2524
2525 type tinter interface {
2526 m(int, byte) (byte, int)
2527 }
2528
2529
2530
2531 type Tm1 struct {
2532 Tm2
2533 }
2534
2535 type Tm2 struct {
2536 *Tm3
2537 }
2538
2539 type Tm3 struct {
2540 *Tm4
2541 }
2542
2543 type Tm4 struct {
2544 }
2545
2546 func (t4 Tm4) M(x int, b byte) (byte, int) { return b, x + 40 }
2547
2548 func TestMethod5(t *testing.T) {
2549 CheckF := func(name string, f func(int, byte) (byte, int), inc int) {
2550 b, x := f(1000, 99)
2551 if b != 99 || x != 1000+inc {
2552 t.Errorf("%s(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
2553 }
2554 }
2555
2556 CheckV := func(name string, i Value, inc int) {
2557 bx := i.Method(0).Call([]Value{ValueOf(1000), ValueOf(byte(99))})
2558 b := bx[0].Interface()
2559 x := bx[1].Interface()
2560 if b != byte(99) || x != 1000+inc {
2561 t.Errorf("direct %s.M(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
2562 }
2563
2564 CheckF(name+".M", i.Method(0).Interface().(func(int, byte) (byte, int)), inc)
2565 }
2566
2567 var TinterType = TypeOf(new(Tinter)).Elem()
2568
2569 CheckI := func(name string, i interface{}, inc int) {
2570 v := ValueOf(i)
2571 CheckV(name, v, inc)
2572 CheckV("(i="+name+")", v.Convert(TinterType), inc)
2573 }
2574
2575 sv := Tsmallv(1)
2576 CheckI("sv", sv, 1)
2577 CheckI("&sv", &sv, 1)
2578
2579 sp := Tsmallp(2)
2580 CheckI("&sp", &sp, 2)
2581
2582 wv := Twordv(3)
2583 CheckI("wv", wv, 3)
2584 CheckI("&wv", &wv, 3)
2585
2586 wp := Twordp(4)
2587 CheckI("&wp", &wp, 4)
2588
2589 bv := Tbigv([2]uintptr{5, 6})
2590 CheckI("bv", bv, 11)
2591 CheckI("&bv", &bv, 11)
2592
2593 bp := Tbigp([2]uintptr{7, 8})
2594 CheckI("&bp", &bp, 15)
2595
2596 t4 := Tm4{}
2597 t3 := Tm3{&t4}
2598 t2 := Tm2{&t3}
2599 t1 := Tm1{t2}
2600 CheckI("t4", t4, 40)
2601 CheckI("&t4", &t4, 40)
2602 CheckI("t3", t3, 40)
2603 CheckI("&t3", &t3, 40)
2604 CheckI("t2", t2, 40)
2605 CheckI("&t2", &t2, 40)
2606 CheckI("t1", t1, 40)
2607 CheckI("&t1", &t1, 40)
2608
2609 var tnil Tinter
2610 vnil := ValueOf(&tnil).Elem()
2611 shouldPanic("Method", func() { vnil.Method(0) })
2612 }
2613
2614 func TestInterfaceSet(t *testing.T) {
2615 p := &Point{3, 4}
2616
2617 var s struct {
2618 I interface{}
2619 P interface {
2620 Dist(int) int
2621 }
2622 }
2623 sv := ValueOf(&s).Elem()
2624 sv.Field(0).Set(ValueOf(p))
2625 if q := s.I.(*Point); q != p {
2626 t.Errorf("i: have %p want %p", q, p)
2627 }
2628
2629 pv := sv.Field(1)
2630 pv.Set(ValueOf(p))
2631 if q := s.P.(*Point); q != p {
2632 t.Errorf("i: have %p want %p", q, p)
2633 }
2634
2635 i := pv.Method(0).Call([]Value{ValueOf(10)})[0].Int()
2636 if i != 250 {
2637 t.Errorf("Interface Method returned %d; want 250", i)
2638 }
2639 }
2640
2641 type T1 struct {
2642 a string
2643 int
2644 }
2645
2646 func TestAnonymousFields(t *testing.T) {
2647 var field StructField
2648 var ok bool
2649 var t1 T1
2650 type1 := TypeOf(t1)
2651 if field, ok = type1.FieldByName("int"); !ok {
2652 t.Fatal("no field 'int'")
2653 }
2654 if field.Index[0] != 1 {
2655 t.Error("field index should be 1; is", field.Index)
2656 }
2657 }
2658
2659 type FTest struct {
2660 s interface{}
2661 name string
2662 index []int
2663 value int
2664 }
2665
2666 type D1 struct {
2667 d int
2668 }
2669 type D2 struct {
2670 d int
2671 }
2672
2673 type S0 struct {
2674 A, B, C int
2675 D1
2676 D2
2677 }
2678
2679 type S1 struct {
2680 B int
2681 S0
2682 }
2683
2684 type S2 struct {
2685 A int
2686 *S1
2687 }
2688
2689 type S1x struct {
2690 S1
2691 }
2692
2693 type S1y struct {
2694 S1
2695 }
2696
2697 type S3 struct {
2698 S1x
2699 S2
2700 D, E int
2701 *S1y
2702 }
2703
2704 type S4 struct {
2705 *S4
2706 A int
2707 }
2708
2709
2710 type S5 struct {
2711 S6
2712 S7
2713 S8
2714 }
2715
2716 type S6 struct {
2717 X int
2718 }
2719
2720 type S7 S6
2721
2722 type S8 struct {
2723 S9
2724 }
2725
2726 type S9 struct {
2727 X int
2728 Y int
2729 }
2730
2731
2732 type S10 struct {
2733 S11
2734 S12
2735 S13
2736 }
2737
2738 type S11 struct {
2739 S6
2740 }
2741
2742 type S12 struct {
2743 S6
2744 }
2745
2746 type S13 struct {
2747 S8
2748 }
2749
2750
2751 type S14 struct {
2752 S15
2753 S16
2754 }
2755
2756 type S15 struct {
2757 S11
2758 }
2759
2760 type S16 struct {
2761 S11
2762 }
2763
2764 var fieldTests = []FTest{
2765 {struct{}{}, "", nil, 0},
2766 {struct{}{}, "Foo", nil, 0},
2767 {S0{A: 'a'}, "A", []int{0}, 'a'},
2768 {S0{}, "D", nil, 0},
2769 {S1{S0: S0{A: 'a'}}, "A", []int{1, 0}, 'a'},
2770 {S1{B: 'b'}, "B", []int{0}, 'b'},
2771 {S1{}, "S0", []int{1}, 0},
2772 {S1{S0: S0{C: 'c'}}, "C", []int{1, 2}, 'c'},
2773 {S2{A: 'a'}, "A", []int{0}, 'a'},
2774 {S2{}, "S1", []int{1}, 0},
2775 {S2{S1: &S1{B: 'b'}}, "B", []int{1, 0}, 'b'},
2776 {S2{S1: &S1{S0: S0{C: 'c'}}}, "C", []int{1, 1, 2}, 'c'},
2777 {S2{}, "D", nil, 0},
2778 {S3{}, "S1", nil, 0},
2779 {S3{S2: S2{A: 'a'}}, "A", []int{1, 0}, 'a'},
2780 {S3{}, "B", nil, 0},
2781 {S3{D: 'd'}, "D", []int{2}, 0},
2782 {S3{E: 'e'}, "E", []int{3}, 'e'},
2783 {S4{A: 'a'}, "A", []int{1}, 'a'},
2784 {S4{}, "B", nil, 0},
2785 {S5{}, "X", nil, 0},
2786 {S5{}, "Y", []int{2, 0, 1}, 0},
2787 {S10{}, "X", nil, 0},
2788 {S10{}, "Y", []int{2, 0, 0, 1}, 0},
2789 {S14{}, "X", nil, 0},
2790 }
2791
2792 func TestFieldByIndex(t *testing.T) {
2793 for _, test := range fieldTests {
2794 s := TypeOf(test.s)
2795 f := s.FieldByIndex(test.index)
2796 if f.Name != "" {
2797 if test.index != nil {
2798 if f.Name != test.name {
2799 t.Errorf("%s.%s found; want %s", s.Name(), f.Name, test.name)
2800 }
2801 } else {
2802 t.Errorf("%s.%s found", s.Name(), f.Name)
2803 }
2804 } else if len(test.index) > 0 {
2805 t.Errorf("%s.%s not found", s.Name(), test.name)
2806 }
2807
2808 if test.value != 0 {
2809 v := ValueOf(test.s).FieldByIndex(test.index)
2810 if v.IsValid() {
2811 if x, ok := v.Interface().(int); ok {
2812 if x != test.value {
2813 t.Errorf("%s%v is %d; want %d", s.Name(), test.index, x, test.value)
2814 }
2815 } else {
2816 t.Errorf("%s%v value not an int", s.Name(), test.index)
2817 }
2818 } else {
2819 t.Errorf("%s%v value not found", s.Name(), test.index)
2820 }
2821 }
2822 }
2823 }
2824
2825 func TestFieldByName(t *testing.T) {
2826 for _, test := range fieldTests {
2827 s := TypeOf(test.s)
2828 f, found := s.FieldByName(test.name)
2829 if found {
2830 if test.index != nil {
2831
2832 if len(f.Index) != len(test.index) {
2833 t.Errorf("%s.%s depth %d; want %d: %v vs %v", s.Name(), test.name, len(f.Index), len(test.index), f.Index, test.index)
2834 } else {
2835 for i, x := range f.Index {
2836 if x != test.index[i] {
2837 t.Errorf("%s.%s.Index[%d] is %d; want %d", s.Name(), test.name, i, x, test.index[i])
2838 }
2839 }
2840 }
2841 } else {
2842 t.Errorf("%s.%s found", s.Name(), f.Name)
2843 }
2844 } else if len(test.index) > 0 {
2845 t.Errorf("%s.%s not found", s.Name(), test.name)
2846 }
2847
2848 if test.value != 0 {
2849 v := ValueOf(test.s).FieldByName(test.name)
2850 if v.IsValid() {
2851 if x, ok := v.Interface().(int); ok {
2852 if x != test.value {
2853 t.Errorf("%s.%s is %d; want %d", s.Name(), test.name, x, test.value)
2854 }
2855 } else {
2856 t.Errorf("%s.%s value not an int", s.Name(), test.name)
2857 }
2858 } else {
2859 t.Errorf("%s.%s value not found", s.Name(), test.name)
2860 }
2861 }
2862 }
2863 }
2864
2865 func TestImportPath(t *testing.T) {
2866 tests := []struct {
2867 t Type
2868 path string
2869 }{
2870 {TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
2871 {TypeOf(int(0)), ""},
2872 {TypeOf(int8(0)), ""},
2873 {TypeOf(int16(0)), ""},
2874 {TypeOf(int32(0)), ""},
2875 {TypeOf(int64(0)), ""},
2876 {TypeOf(uint(0)), ""},
2877 {TypeOf(uint8(0)), ""},
2878 {TypeOf(uint16(0)), ""},
2879 {TypeOf(uint32(0)), ""},
2880 {TypeOf(uint64(0)), ""},
2881 {TypeOf(uintptr(0)), ""},
2882 {TypeOf(float32(0)), ""},
2883 {TypeOf(float64(0)), ""},
2884 {TypeOf(complex64(0)), ""},
2885 {TypeOf(complex128(0)), ""},
2886 {TypeOf(byte(0)), ""},
2887 {TypeOf(rune(0)), ""},
2888 {TypeOf([]byte(nil)), ""},
2889 {TypeOf([]rune(nil)), ""},
2890 {TypeOf(string("")), ""},
2891 {TypeOf((*interface{})(nil)).Elem(), ""},
2892 {TypeOf((*byte)(nil)), ""},
2893 {TypeOf((*rune)(nil)), ""},
2894 {TypeOf((*int64)(nil)), ""},
2895 {TypeOf(map[string]int{}), ""},
2896 {TypeOf((*error)(nil)).Elem(), ""},
2897 {TypeOf((*Point)(nil)), ""},
2898 {TypeOf((*Point)(nil)).Elem(), "reflect_test"},
2899 }
2900 for _, test := range tests {
2901 if path := test.t.PkgPath(); path != test.path {
2902 t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
2903 }
2904 }
2905 }
2906
2907 func TestFieldPkgPath(t *testing.T) {
2908 type x int
2909 typ := TypeOf(struct {
2910 Exported string
2911 unexported string
2912 OtherPkgFields
2913 int
2914 *x
2915 }{})
2916
2917 type pkgpathTest struct {
2918 index []int
2919 pkgPath string
2920 embedded bool
2921 exported bool
2922 }
2923
2924 checkPkgPath := func(name string, s []pkgpathTest) {
2925 for _, test := range s {
2926 f := typ.FieldByIndex(test.index)
2927 if got, want := f.PkgPath, test.pkgPath; got != want {
2928 t.Errorf("%s: Field(%d).PkgPath = %q, want %q", name, test.index, got, want)
2929 }
2930 if got, want := f.Anonymous, test.embedded; got != want {
2931 t.Errorf("%s: Field(%d).Anonymous = %v, want %v", name, test.index, got, want)
2932 }
2933 if got, want := f.IsExported(), test.exported; got != want {
2934 t.Errorf("%s: Field(%d).IsExported = %v, want %v", name, test.index, got, want)
2935 }
2936 }
2937 }
2938
2939 checkPkgPath("testStruct", []pkgpathTest{
2940 {[]int{0}, "", false, true},
2941 {[]int{1}, "reflect_test", false, false},
2942 {[]int{2}, "", true, true},
2943 {[]int{2, 0}, "", false, true},
2944 {[]int{2, 1}, "reflect", false, false},
2945 {[]int{3}, "reflect_test", true, false},
2946 {[]int{4}, "reflect_test", true, false},
2947 })
2948
2949 type localOtherPkgFields OtherPkgFields
2950 typ = TypeOf(localOtherPkgFields{})
2951 checkPkgPath("localOtherPkgFields", []pkgpathTest{
2952 {[]int{0}, "", false, true},
2953 {[]int{1}, "reflect", false, false},
2954 })
2955 }
2956
2957 func TestMethodPkgPath(t *testing.T) {
2958 type I interface {
2959 x()
2960 X()
2961 }
2962 typ := TypeOf((*interface {
2963 I
2964 y()
2965 Y()
2966 })(nil)).Elem()
2967
2968 tests := []struct {
2969 name string
2970 pkgPath string
2971 exported bool
2972 }{
2973 {"X", "", true},
2974 {"Y", "", true},
2975 {"x", "reflect_test", false},
2976 {"y", "reflect_test", false},
2977 }
2978
2979 for _, test := range tests {
2980 m, _ := typ.MethodByName(test.name)
2981 if got, want := m.PkgPath, test.pkgPath; got != want {
2982 t.Errorf("MethodByName(%q).PkgPath = %q, want %q", test.name, got, want)
2983 }
2984 if got, want := m.IsExported(), test.exported; got != want {
2985 t.Errorf("MethodByName(%q).IsExported = %v, want %v", test.name, got, want)
2986 }
2987 }
2988 }
2989
2990 func TestVariadicType(t *testing.T) {
2991
2992 var f func(x int, y ...float64)
2993 typ := TypeOf(f)
2994 if typ.NumIn() == 2 && typ.In(0) == TypeOf(int(0)) {
2995 sl := typ.In(1)
2996 if sl.Kind() == Slice {
2997 if sl.Elem() == TypeOf(0.0) {
2998
2999 return
3000 }
3001 }
3002 }
3003
3004
3005 t.Errorf("want NumIn() = 2, In(0) = int, In(1) = []float64")
3006 s := fmt.Sprintf("have NumIn() = %d", typ.NumIn())
3007 for i := 0; i < typ.NumIn(); i++ {
3008 s += fmt.Sprintf(", In(%d) = %s", i, typ.In(i))
3009 }
3010 t.Error(s)
3011 }
3012
3013 type inner struct {
3014 x int
3015 }
3016
3017 type outer struct {
3018 y int
3019 inner
3020 }
3021
3022 func (*inner) M() {}
3023 func (*outer) M() {}
3024
3025 func TestNestedMethods(t *testing.T) {
3026 typ := TypeOf((*outer)(nil))
3027 if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*outer).M).Pointer() {
3028 t.Errorf("Wrong method table for outer: (M=%p)", (*outer).M)
3029 for i := 0; i < typ.NumMethod(); i++ {
3030 m := typ.Method(i)
3031 t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
3032 }
3033 }
3034 }
3035
3036 type unexp struct{}
3037
3038 func (*unexp) f() (int32, int8) { return 7, 7 }
3039 func (*unexp) g() (int64, int8) { return 8, 8 }
3040
3041 type unexpI interface {
3042 f() (int32, int8)
3043 }
3044
3045 var unexpi unexpI = new(unexp)
3046
3047 func TestUnexportedMethods(t *testing.T) {
3048 typ := TypeOf(unexpi)
3049
3050 if got := typ.NumMethod(); got != 0 {
3051 t.Errorf("NumMethod=%d, want 0 satisfied methods", got)
3052 }
3053 }
3054
3055 type InnerInt struct {
3056 X int
3057 }
3058
3059 type OuterInt struct {
3060 Y int
3061 InnerInt
3062 }
3063
3064 func (i *InnerInt) M() int {
3065 return i.X
3066 }
3067
3068 func TestEmbeddedMethods(t *testing.T) {
3069 typ := TypeOf((*OuterInt)(nil))
3070 if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*OuterInt).M).Pointer() {
3071 t.Errorf("Wrong method table for OuterInt: (m=%p)", (*OuterInt).M)
3072 for i := 0; i < typ.NumMethod(); i++ {
3073 m := typ.Method(i)
3074 t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
3075 }
3076 }
3077
3078 i := &InnerInt{3}
3079 if v := ValueOf(i).Method(0).Call(nil)[0].Int(); v != 3 {
3080 t.Errorf("i.M() = %d, want 3", v)
3081 }
3082
3083 o := &OuterInt{1, InnerInt{2}}
3084 if v := ValueOf(o).Method(0).Call(nil)[0].Int(); v != 2 {
3085 t.Errorf("i.M() = %d, want 2", v)
3086 }
3087
3088 f := (*OuterInt).M
3089 if v := f(o); v != 2 {
3090 t.Errorf("f(o) = %d, want 2", v)
3091 }
3092 }
3093
3094 type FuncDDD func(...interface{}) error
3095
3096 func (f FuncDDD) M() {}
3097
3098 func TestNumMethodOnDDD(t *testing.T) {
3099 rv := ValueOf((FuncDDD)(nil))
3100 if n := rv.NumMethod(); n != 1 {
3101 t.Fatalf("NumMethod()=%d, want 1", n)
3102 }
3103 }
3104
3105 func TestPtrTo(t *testing.T) {
3106
3107
3108
3109 var x unsafe.Pointer
3110 var y = &x
3111 var z = &y
3112
3113 var i int
3114
3115 typ := TypeOf(z)
3116 for i = 0; i < 100; i++ {
3117 typ = PtrTo(typ)
3118 }
3119 for i = 0; i < 100; i++ {
3120 typ = typ.Elem()
3121 }
3122 if typ != TypeOf(z) {
3123 t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(z))
3124 }
3125 }
3126
3127 func TestPtrToGC(t *testing.T) {
3128 type T *uintptr
3129 tt := TypeOf(T(nil))
3130 pt := PtrTo(tt)
3131 const n = 100
3132 var x []interface{}
3133 for i := 0; i < n; i++ {
3134 v := New(pt)
3135 p := new(*uintptr)
3136 *p = new(uintptr)
3137 **p = uintptr(i)
3138 v.Elem().Set(ValueOf(p).Convert(pt))
3139 x = append(x, v.Interface())
3140 }
3141 runtime.GC()
3142
3143 for i, xi := range x {
3144 k := ValueOf(xi).Elem().Elem().Elem().Interface().(uintptr)
3145 if k != uintptr(i) {
3146 t.Errorf("lost x[%d] = %d, want %d", i, k, i)
3147 }
3148 }
3149 }
3150
3151 func BenchmarkPtrTo(b *testing.B) {
3152
3153 type T struct{ int }
3154 t := SliceOf(TypeOf(T{}))
3155 ptrToThis := ValueOf(t).Elem().FieldByName("ptrToThis")
3156 if !ptrToThis.IsValid() {
3157 b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
3158 }
3159 if ptrToThis.Int() != 0 {
3160 b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
3161 }
3162 b.ResetTimer()
3163
3164
3165
3166 b.RunParallel(func(pb *testing.PB) {
3167 for pb.Next() {
3168 PtrTo(t)
3169 }
3170 })
3171 }
3172
3173 func TestAddr(t *testing.T) {
3174 var p struct {
3175 X, Y int
3176 }
3177
3178 v := ValueOf(&p)
3179 v = v.Elem()
3180 v = v.Addr()
3181 v = v.Elem()
3182 v = v.Field(0)
3183 v.SetInt(2)
3184 if p.X != 2 {
3185 t.Errorf("Addr.Elem.Set failed to set value")
3186 }
3187
3188
3189
3190 q := &p
3191 v = ValueOf(&q).Elem()
3192 v = v.Addr()
3193 v = v.Elem()
3194 v = v.Elem()
3195 v = v.Addr()
3196 v = v.Elem()
3197 v = v.Field(0)
3198 v.SetInt(3)
3199 if p.X != 3 {
3200 t.Errorf("Addr.Elem.Set failed to set value")
3201 }
3202
3203
3204
3205 qq := p
3206 v = ValueOf(&qq).Elem()
3207 v0 := v
3208 v = v.Addr()
3209 v = v.Elem()
3210 v = v.Field(0)
3211 v.SetInt(4)
3212 if p.X != 3 {
3213 t.Errorf("somehow value Set changed original p")
3214 }
3215 p = v0.Interface().(struct {
3216 X, Y int
3217 })
3218 if p.X != 4 {
3219 t.Errorf("Addr.Elem.Set valued to set value in top value")
3220 }
3221
3222
3223
3224
3225 var s struct {
3226 B *bool
3227 }
3228 ps := ValueOf(&s).Elem().Field(0).Addr().Interface()
3229 *(ps.(**bool)) = new(bool)
3230 if s.B == nil {
3231 t.Errorf("Addr.Interface direct assignment failed")
3232 }
3233 }
3234
3235 func noAlloc(t *testing.T, n int, f func(int)) {
3236 if testing.Short() {
3237 t.Skip("skipping malloc count in short mode")
3238 }
3239 if runtime.GOMAXPROCS(0) > 1 {
3240 t.Skip("skipping; GOMAXPROCS>1")
3241 }
3242 i := -1
3243 allocs := testing.AllocsPerRun(n, func() {
3244 f(i)
3245 i++
3246 })
3247 if allocs > 0 {
3248 t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
3249 }
3250 }
3251
3252 func TestAllocations(t *testing.T) {
3253 noAlloc(t, 100, func(j int) {
3254 var i interface{}
3255 var v Value
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267 i = func(j int) int { return j }
3268 v = ValueOf(i)
3269 if v.Interface().(func(int) int)(j) != j {
3270 panic("wrong result")
3271 }
3272 })
3273 }
3274
3275 func TestSmallNegativeInt(t *testing.T) {
3276 i := int16(-1)
3277 v := ValueOf(i)
3278 if v.Int() != -1 {
3279 t.Errorf("int16(-1).Int() returned %v", v.Int())
3280 }
3281 }
3282
3283 func TestIndex(t *testing.T) {
3284 xs := []byte{1, 2, 3, 4, 5, 6, 7, 8}
3285 v := ValueOf(xs).Index(3).Interface().(byte)
3286 if v != xs[3] {
3287 t.Errorf("xs.Index(3) = %v; expected %v", v, xs[3])
3288 }
3289 xa := [8]byte{10, 20, 30, 40, 50, 60, 70, 80}
3290 v = ValueOf(xa).Index(2).Interface().(byte)
3291 if v != xa[2] {
3292 t.Errorf("xa.Index(2) = %v; expected %v", v, xa[2])
3293 }
3294 s := "0123456789"
3295 v = ValueOf(s).Index(3).Interface().(byte)
3296 if v != s[3] {
3297 t.Errorf("s.Index(3) = %v; expected %v", v, s[3])
3298 }
3299 }
3300
3301 func TestSlice(t *testing.T) {
3302 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
3303 v := ValueOf(xs).Slice(3, 5).Interface().([]int)
3304 if len(v) != 2 {
3305 t.Errorf("len(xs.Slice(3, 5)) = %d", len(v))
3306 }
3307 if cap(v) != 5 {
3308 t.Errorf("cap(xs.Slice(3, 5)) = %d", cap(v))
3309 }
3310 if !DeepEqual(v[0:5], xs[3:]) {
3311 t.Errorf("xs.Slice(3, 5)[0:5] = %v", v[0:5])
3312 }
3313 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
3314 v = ValueOf(&xa).Elem().Slice(2, 5).Interface().([]int)
3315 if len(v) != 3 {
3316 t.Errorf("len(xa.Slice(2, 5)) = %d", len(v))
3317 }
3318 if cap(v) != 6 {
3319 t.Errorf("cap(xa.Slice(2, 5)) = %d", cap(v))
3320 }
3321 if !DeepEqual(v[0:6], xa[2:]) {
3322 t.Errorf("xs.Slice(2, 5)[0:6] = %v", v[0:6])
3323 }
3324 s := "0123456789"
3325 vs := ValueOf(s).Slice(3, 5).Interface().(string)
3326 if vs != s[3:5] {
3327 t.Errorf("s.Slice(3, 5) = %q; expected %q", vs, s[3:5])
3328 }
3329
3330 rv := ValueOf(&xs).Elem()
3331 rv = rv.Slice(3, 4)
3332 ptr2 := rv.Pointer()
3333 rv = rv.Slice(5, 5)
3334 ptr3 := rv.Pointer()
3335 if ptr3 != ptr2 {
3336 t.Errorf("xs.Slice(3,4).Slice3(5,5).Pointer() = %#x, want %#x", ptr3, ptr2)
3337 }
3338 }
3339
3340 func TestSlice3(t *testing.T) {
3341 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
3342 v := ValueOf(xs).Slice3(3, 5, 7).Interface().([]int)
3343 if len(v) != 2 {
3344 t.Errorf("len(xs.Slice3(3, 5, 7)) = %d", len(v))
3345 }
3346 if cap(v) != 4 {
3347 t.Errorf("cap(xs.Slice3(3, 5, 7)) = %d", cap(v))
3348 }
3349 if !DeepEqual(v[0:4], xs[3:7:7]) {
3350 t.Errorf("xs.Slice3(3, 5, 7)[0:4] = %v", v[0:4])
3351 }
3352 rv := ValueOf(&xs).Elem()
3353 shouldPanic("Slice3", func() { rv.Slice3(1, 2, 1) })
3354 shouldPanic("Slice3", func() { rv.Slice3(1, 1, 11) })
3355 shouldPanic("Slice3", func() { rv.Slice3(2, 2, 1) })
3356
3357 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
3358 v = ValueOf(&xa).Elem().Slice3(2, 5, 6).Interface().([]int)
3359 if len(v) != 3 {
3360 t.Errorf("len(xa.Slice(2, 5, 6)) = %d", len(v))
3361 }
3362 if cap(v) != 4 {
3363 t.Errorf("cap(xa.Slice(2, 5, 6)) = %d", cap(v))
3364 }
3365 if !DeepEqual(v[0:4], xa[2:6:6]) {
3366 t.Errorf("xs.Slice(2, 5, 6)[0:4] = %v", v[0:4])
3367 }
3368 rv = ValueOf(&xa).Elem()
3369 shouldPanic("Slice3", func() { rv.Slice3(1, 2, 1) })
3370 shouldPanic("Slice3", func() { rv.Slice3(1, 1, 11) })
3371 shouldPanic("Slice3", func() { rv.Slice3(2, 2, 1) })
3372
3373 s := "hello world"
3374 rv = ValueOf(&s).Elem()
3375 shouldPanic("Slice3", func() { rv.Slice3(1, 2, 3) })
3376
3377 rv = ValueOf(&xs).Elem()
3378 rv = rv.Slice3(3, 5, 7)
3379 ptr2 := rv.Pointer()
3380 rv = rv.Slice3(4, 4, 4)
3381 ptr3 := rv.Pointer()
3382 if ptr3 != ptr2 {
3383 t.Errorf("xs.Slice3(3,5,7).Slice3(4,4,4).Pointer() = %#x, want %#x", ptr3, ptr2)
3384 }
3385 }
3386
3387 func TestSetLenCap(t *testing.T) {
3388 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
3389 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
3390
3391 vs := ValueOf(&xs).Elem()
3392 shouldPanic("SetLen", func() { vs.SetLen(10) })
3393 shouldPanic("SetCap", func() { vs.SetCap(10) })
3394 shouldPanic("SetLen", func() { vs.SetLen(-1) })
3395 shouldPanic("SetCap", func() { vs.SetCap(-1) })
3396 shouldPanic("SetCap", func() { vs.SetCap(6) })
3397 vs.SetLen(5)
3398 if len(xs) != 5 || cap(xs) != 8 {
3399 t.Errorf("after SetLen(5), len, cap = %d, %d, want 5, 8", len(xs), cap(xs))
3400 }
3401 vs.SetCap(6)
3402 if len(xs) != 5 || cap(xs) != 6 {
3403 t.Errorf("after SetCap(6), len, cap = %d, %d, want 5, 6", len(xs), cap(xs))
3404 }
3405 vs.SetCap(5)
3406 if len(xs) != 5 || cap(xs) != 5 {
3407 t.Errorf("after SetCap(5), len, cap = %d, %d, want 5, 5", len(xs), cap(xs))
3408 }
3409 shouldPanic("SetCap", func() { vs.SetCap(4) })
3410 shouldPanic("SetLen", func() { vs.SetLen(6) })
3411
3412 va := ValueOf(&xa).Elem()
3413 shouldPanic("SetLen", func() { va.SetLen(8) })
3414 shouldPanic("SetCap", func() { va.SetCap(8) })
3415 }
3416
3417 func TestVariadic(t *testing.T) {
3418 var b bytes.Buffer
3419 V := ValueOf
3420
3421 b.Reset()
3422 V(fmt.Fprintf).Call([]Value{V(&b), V("%s, %d world"), V("hello"), V(42)})
3423 if b.String() != "hello, 42 world" {
3424 t.Errorf("after Fprintf Call: %q != %q", b.String(), "hello 42 world")
3425 }
3426
3427 b.Reset()
3428 V(fmt.Fprintf).CallSlice([]Value{V(&b), V("%s, %d world"), V([]interface{}{"hello", 42})})
3429 if b.String() != "hello, 42 world" {
3430 t.Errorf("after Fprintf CallSlice: %q != %q", b.String(), "hello 42 world")
3431 }
3432 }
3433
3434 func TestFuncArg(t *testing.T) {
3435 f1 := func(i int, f func(int) int) int { return f(i) }
3436 f2 := func(i int) int { return i + 1 }
3437 r := ValueOf(f1).Call([]Value{ValueOf(100), ValueOf(f2)})
3438 if r[0].Int() != 101 {
3439 t.Errorf("function returned %d, want 101", r[0].Int())
3440 }
3441 }
3442
3443 func TestStructArg(t *testing.T) {
3444 type padded struct {
3445 B string
3446 C int32
3447 }
3448 var (
3449 gotA padded
3450 gotB uint32
3451 wantA = padded{"3", 4}
3452 wantB = uint32(5)
3453 )
3454 f := func(a padded, b uint32) {
3455 gotA, gotB = a, b
3456 }
3457 ValueOf(f).Call([]Value{ValueOf(wantA), ValueOf(wantB)})
3458 if gotA != wantA || gotB != wantB {
3459 t.Errorf("function called with (%v, %v), want (%v, %v)", gotA, gotB, wantA, wantB)
3460 }
3461 }
3462
3463 var tagGetTests = []struct {
3464 Tag StructTag
3465 Key string
3466 Value string
3467 }{
3468 {`protobuf:"PB(1,2)"`, `protobuf`, `PB(1,2)`},
3469 {`protobuf:"PB(1,2)"`, `foo`, ``},
3470 {`protobuf:"PB(1,2)"`, `rotobuf`, ``},
3471 {`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
3472 {`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
3473 {`k0:"values contain spaces" k1:"and\ttabs"`, "k0", "values contain spaces"},
3474 {`k0:"values contain spaces" k1:"and\ttabs"`, "k1", "and\ttabs"},
3475 }
3476
3477 func TestTagGet(t *testing.T) {
3478 for _, tt := range tagGetTests {
3479 if v := tt.Tag.Get(tt.Key); v != tt.Value {
3480 t.Errorf("StructTag(%#q).Get(%#q) = %#q, want %#q", tt.Tag, tt.Key, v, tt.Value)
3481 }
3482 }
3483 }
3484
3485 func TestBytes(t *testing.T) {
3486 type B []byte
3487 x := B{1, 2, 3, 4}
3488 y := ValueOf(x).Bytes()
3489 if !bytes.Equal(x, y) {
3490 t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
3491 }
3492 if &x[0] != &y[0] {
3493 t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
3494 }
3495 }
3496
3497 func TestSetBytes(t *testing.T) {
3498 type B []byte
3499 var x B
3500 y := []byte{1, 2, 3, 4}
3501 ValueOf(&x).Elem().SetBytes(y)
3502 if !bytes.Equal(x, y) {
3503 t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
3504 }
3505 if &x[0] != &y[0] {
3506 t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
3507 }
3508 }
3509
3510 type Private struct {
3511 x int
3512 y **int
3513 Z int
3514 }
3515
3516 func (p *Private) m() {
3517 }
3518
3519 type private struct {
3520 Z int
3521 z int
3522 S string
3523 A [1]Private
3524 T []Private
3525 }
3526
3527 func (p *private) P() {
3528 }
3529
3530 type Public struct {
3531 X int
3532 Y **int
3533 private
3534 }
3535
3536 func (p *Public) M() {
3537 }
3538
3539 func TestUnexported(t *testing.T) {
3540 var pub Public
3541 pub.S = "S"
3542 pub.T = pub.A[:]
3543 v := ValueOf(&pub)
3544 isValid(v.Elem().Field(0))
3545 isValid(v.Elem().Field(1))
3546 isValid(v.Elem().Field(2))
3547 isValid(v.Elem().FieldByName("X"))
3548 isValid(v.Elem().FieldByName("Y"))
3549 isValid(v.Elem().FieldByName("Z"))
3550 isValid(v.Type().Method(0).Func)
3551 m, _ := v.Type().MethodByName("M")
3552 isValid(m.Func)
3553 m, _ = v.Type().MethodByName("P")
3554 isValid(m.Func)
3555 isNonNil(v.Elem().Field(0).Interface())
3556 isNonNil(v.Elem().Field(1).Interface())
3557 isNonNil(v.Elem().Field(2).Field(2).Index(0))
3558 isNonNil(v.Elem().FieldByName("X").Interface())
3559 isNonNil(v.Elem().FieldByName("Y").Interface())
3560 isNonNil(v.Elem().FieldByName("Z").Interface())
3561 isNonNil(v.Elem().FieldByName("S").Index(0).Interface())
3562 isNonNil(v.Type().Method(0).Func.Interface())
3563 m, _ = v.Type().MethodByName("P")
3564 isNonNil(m.Func.Interface())
3565
3566 var priv Private
3567 v = ValueOf(&priv)
3568 isValid(v.Elem().Field(0))
3569 isValid(v.Elem().Field(1))
3570 isValid(v.Elem().FieldByName("x"))
3571 isValid(v.Elem().FieldByName("y"))
3572 shouldPanic("Interface", func() { v.Elem().Field(0).Interface() })
3573 shouldPanic("Interface", func() { v.Elem().Field(1).Interface() })
3574 shouldPanic("Interface", func() { v.Elem().FieldByName("x").Interface() })
3575 shouldPanic("Interface", func() { v.Elem().FieldByName("y").Interface() })
3576 shouldPanic("Method", func() { v.Type().Method(0) })
3577 }
3578
3579 func TestSetPanic(t *testing.T) {
3580 ok := func(f func()) { f() }
3581 bad := func(f func()) { shouldPanic("Set", f) }
3582 clear := func(v Value) { v.Set(Zero(v.Type())) }
3583
3584 type t0 struct {
3585 W int
3586 }
3587
3588 type t1 struct {
3589 Y int
3590 t0
3591 }
3592
3593 type T2 struct {
3594 Z int
3595 namedT0 t0
3596 }
3597
3598 type T struct {
3599 X int
3600 t1
3601 T2
3602 NamedT1 t1
3603 NamedT2 T2
3604 namedT1 t1
3605 namedT2 T2
3606 }
3607
3608
3609 v := ValueOf(T{})
3610 bad(func() { clear(v.Field(0)) })
3611 bad(func() { clear(v.Field(1)) })
3612 bad(func() { clear(v.Field(1).Field(0)) })
3613 bad(func() { clear(v.Field(1).Field(1)) })
3614 bad(func() { clear(v.Field(1).Field(1).Field(0)) })
3615 bad(func() { clear(v.Field(2)) })
3616 bad(func() { clear(v.Field(2).Field(0)) })
3617 bad(func() { clear(v.Field(2).Field(1)) })
3618 bad(func() { clear(v.Field(2).Field(1).Field(0)) })
3619 bad(func() { clear(v.Field(3)) })
3620 bad(func() { clear(v.Field(3).Field(0)) })
3621 bad(func() { clear(v.Field(3).Field(1)) })
3622 bad(func() { clear(v.Field(3).Field(1).Field(0)) })
3623 bad(func() { clear(v.Field(4)) })
3624 bad(func() { clear(v.Field(4).Field(0)) })
3625 bad(func() { clear(v.Field(4).Field(1)) })
3626 bad(func() { clear(v.Field(4).Field(1).Field(0)) })
3627 bad(func() { clear(v.Field(5)) })
3628 bad(func() { clear(v.Field(5).Field(0)) })
3629 bad(func() { clear(v.Field(5).Field(1)) })
3630 bad(func() { clear(v.Field(5).Field(1).Field(0)) })
3631 bad(func() { clear(v.Field(6)) })
3632 bad(func() { clear(v.Field(6).Field(0)) })
3633 bad(func() { clear(v.Field(6).Field(1)) })
3634 bad(func() { clear(v.Field(6).Field(1).Field(0)) })
3635
3636
3637 v = ValueOf(&T{}).Elem()
3638 ok(func() { clear(v.Field(0)) })
3639 bad(func() { clear(v.Field(1)) })
3640 ok(func() { clear(v.Field(1).Field(0)) })
3641 bad(func() { clear(v.Field(1).Field(1)) })
3642 ok(func() { clear(v.Field(1).Field(1).Field(0)) })
3643 ok(func() { clear(v.Field(2)) })
3644 ok(func() { clear(v.Field(2).Field(0)) })
3645 bad(func() { clear(v.Field(2).Field(1)) })
3646 bad(func() { clear(v.Field(2).Field(1).Field(0)) })
3647 ok(func() { clear(v.Field(3)) })
3648 ok(func() { clear(v.Field(3).Field(0)) })
3649 bad(func() { clear(v.Field(3).Field(1)) })
3650 ok(func() { clear(v.Field(3).Field(1).Field(0)) })
3651 ok(func() { clear(v.Field(4)) })
3652 ok(func() { clear(v.Field(4).Field(0)) })
3653 bad(func() { clear(v.Field(4).Field(1)) })
3654 bad(func() { clear(v.Field(4).Field(1).Field(0)) })
3655 bad(func() { clear(v.Field(5)) })
3656 bad(func() { clear(v.Field(5).Field(0)) })
3657 bad(func() { clear(v.Field(5).Field(1)) })
3658 bad(func() { clear(v.Field(5).Field(1).Field(0)) })
3659 bad(func() { clear(v.Field(6)) })
3660 bad(func() { clear(v.Field(6).Field(0)) })
3661 bad(func() { clear(v.Field(6).Field(1)) })
3662 bad(func() { clear(v.Field(6).Field(1).Field(0)) })
3663 }
3664
3665 type timp int
3666
3667 func (t timp) W() {}
3668 func (t timp) Y() {}
3669 func (t timp) w() {}
3670 func (t timp) y() {}
3671
3672 func TestCallPanic(t *testing.T) {
3673 type t0 interface {
3674 W()
3675 w()
3676 }
3677 type T1 interface {
3678 Y()
3679 y()
3680 }
3681 type T2 struct {
3682 T1
3683 t0
3684 }
3685 type T struct {
3686 t0
3687 T1
3688
3689 NamedT0 t0
3690 NamedT1 T1
3691 NamedT2 T2
3692
3693 namedT0 t0
3694 namedT1 T1
3695 namedT2 T2
3696 }
3697 ok := func(f func()) { f() }
3698 badCall := func(f func()) { shouldPanic("Call", f) }
3699 badMethod := func(f func()) { shouldPanic("Method", f) }
3700 call := func(v Value) { v.Call(nil) }
3701
3702 i := timp(0)
3703 v := ValueOf(T{i, i, i, i, T2{i, i}, i, i, T2{i, i}})
3704 badCall(func() { call(v.Field(0).Method(0)) })
3705 badCall(func() { call(v.Field(0).Elem().Method(0)) })
3706 badCall(func() { call(v.Field(0).Method(1)) })
3707 badMethod(func() { call(v.Field(0).Elem().Method(2)) })
3708 ok(func() { call(v.Field(1).Method(0)) })
3709 ok(func() { call(v.Field(1).Elem().Method(0)) })
3710 badCall(func() { call(v.Field(1).Method(1)) })
3711 badMethod(func() { call(v.Field(1).Elem().Method(2)) })
3712
3713 ok(func() { call(v.Field(2).Method(0)) })
3714 ok(func() { call(v.Field(2).Elem().Method(0)) })
3715 badCall(func() { call(v.Field(2).Method(1)) })
3716 badMethod(func() { call(v.Field(2).Elem().Method(2)) })
3717
3718 ok(func() { call(v.Field(3).Method(0)) })
3719 ok(func() { call(v.Field(3).Elem().Method(0)) })
3720 badCall(func() { call(v.Field(3).Method(1)) })
3721 badMethod(func() { call(v.Field(3).Elem().Method(3)) })
3722
3723 ok(func() { call(v.Field(4).Field(0).Method(0)) })
3724 ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) })
3725 badCall(func() { call(v.Field(4).Field(1).Method(0)) })
3726 badCall(func() { call(v.Field(4).Field(1).Elem().Method(0)) })
3727
3728 badCall(func() { call(v.Field(5).Method(0)) })
3729 badCall(func() { call(v.Field(5).Elem().Method(0)) })
3730 badCall(func() { call(v.Field(5).Method(1)) })
3731 badMethod(func() { call(v.Field(5).Elem().Method(2)) })
3732
3733 badCall(func() { call(v.Field(6).Method(0)) })
3734 badCall(func() { call(v.Field(6).Elem().Method(0)) })
3735 badCall(func() { call(v.Field(6).Method(0)) })
3736 badCall(func() { call(v.Field(6).Elem().Method(0)) })
3737
3738 badCall(func() { call(v.Field(7).Field(0).Method(0)) })
3739 badCall(func() { call(v.Field(7).Field(0).Elem().Method(0)) })
3740 badCall(func() { call(v.Field(7).Field(1).Method(0)) })
3741 badCall(func() { call(v.Field(7).Field(1).Elem().Method(0)) })
3742 }
3743
3744 func shouldPanic(expect string, f func()) {
3745 defer func() {
3746 r := recover()
3747 if r == nil {
3748 panic("did not panic")
3749 }
3750 if expect != "" {
3751 var s string
3752 switch r := r.(type) {
3753 case string:
3754 s = r
3755 case *ValueError:
3756 s = r.Error()
3757 default:
3758 panic(fmt.Sprintf("panicked with unexpected type %T", r))
3759 }
3760 if !strings.HasPrefix(s, "reflect") {
3761 panic(`panic string does not start with "reflect": ` + s)
3762 }
3763 if !strings.Contains(s, expect) {
3764 panic(`panic string does not contain "` + expect + `": ` + s)
3765 }
3766 }
3767 }()
3768 f()
3769 }
3770
3771 func isNonNil(x interface{}) {
3772 if x == nil {
3773 panic("nil interface")
3774 }
3775 }
3776
3777 func isValid(v Value) {
3778 if !v.IsValid() {
3779 panic("zero Value")
3780 }
3781 }
3782
3783 func TestAlias(t *testing.T) {
3784 x := string("hello")
3785 v := ValueOf(&x).Elem()
3786 oldvalue := v.Interface()
3787 v.SetString("world")
3788 newvalue := v.Interface()
3789
3790 if oldvalue != "hello" || newvalue != "world" {
3791 t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue)
3792 }
3793 }
3794
3795 var V = ValueOf
3796
3797 func EmptyInterfaceV(x interface{}) Value {
3798 return ValueOf(&x).Elem()
3799 }
3800
3801 func ReaderV(x io.Reader) Value {
3802 return ValueOf(&x).Elem()
3803 }
3804
3805 func ReadWriterV(x io.ReadWriter) Value {
3806 return ValueOf(&x).Elem()
3807 }
3808
3809 type Empty struct{}
3810 type MyStruct struct {
3811 x int `some:"tag"`
3812 }
3813 type MyStruct1 struct {
3814 x struct {
3815 int `some:"bar"`
3816 }
3817 }
3818 type MyStruct2 struct {
3819 x struct {
3820 int `some:"foo"`
3821 }
3822 }
3823 type MyString string
3824 type MyBytes []byte
3825 type MyBytesArrayPtr0 *[0]byte
3826 type MyBytesArrayPtr *[4]byte
3827 type MyBytesArray0 [0]byte
3828 type MyBytesArray [4]byte
3829 type MyRunes []int32
3830 type MyFunc func()
3831 type MyByte byte
3832
3833 type IntChan chan int
3834 type IntChanRecv <-chan int
3835 type IntChanSend chan<- int
3836 type BytesChan chan []byte
3837 type BytesChanRecv <-chan []byte
3838 type BytesChanSend chan<- []byte
3839
3840 var convertTests = []struct {
3841 in Value
3842 out Value
3843 }{
3844
3845
3876 {V(int8(1)), V(int8(1))},
3877 {V(int8(2)), V(uint8(2))},
3878 {V(uint8(3)), V(int8(3))},
3879 {V(int8(4)), V(int16(4))},
3880 {V(int16(5)), V(int8(5))},
3881 {V(int8(6)), V(uint16(6))},
3882 {V(uint16(7)), V(int8(7))},
3883 {V(int8(8)), V(int32(8))},
3884 {V(int32(9)), V(int8(9))},
3885 {V(int8(10)), V(uint32(10))},
3886 {V(uint32(11)), V(int8(11))},
3887 {V(int8(12)), V(int64(12))},
3888 {V(int64(13)), V(int8(13))},
3889 {V(int8(14)), V(uint64(14))},
3890 {V(uint64(15)), V(int8(15))},
3891 {V(int8(16)), V(int(16))},
3892 {V(int(17)), V(int8(17))},
3893 {V(int8(18)), V(uint(18))},
3894 {V(uint(19)), V(int8(19))},
3895 {V(int8(20)), V(uintptr(20))},
3896 {V(uintptr(21)), V(int8(21))},
3897 {V(int8(22)), V(float32(22))},
3898 {V(float32(23)), V(int8(23))},
3899 {V(int8(24)), V(float64(24))},
3900 {V(float64(25)), V(int8(25))},
3901 {V(uint8(26)), V(uint8(26))},
3902 {V(uint8(27)), V(int16(27))},
3903 {V(int16(28)), V(uint8(28))},
3904 {V(uint8(29)), V(uint16(29))},
3905 {V(uint16(30)), V(uint8(30))},
3906 {V(uint8(31)), V(int32(31))},
3907 {V(int32(32)), V(uint8(32))},
3908 {V(uint8(33)), V(uint32(33))},
3909 {V(uint32(34)), V(uint8(34))},
3910 {V(uint8(35)), V(int64(35))},
3911 {V(int64(36)), V(uint8(36))},
3912 {V(uint8(37)), V(uint64(37))},
3913 {V(uint64(38)), V(uint8(38))},
3914 {V(uint8(39)), V(int(39))},
3915 {V(int(40)), V(uint8(40))},
3916 {V(uint8(41)), V(uint(41))},
3917 {V(uint(42)), V(uint8(42))},
3918 {V(uint8(43)), V(uintptr(43))},
3919 {V(uintptr(44)), V(uint8(44))},
3920 {V(uint8(45)), V(float32(45))},
3921 {V(float32(46)), V(uint8(46))},
3922 {V(uint8(47)), V(float64(47))},
3923 {V(float64(48)), V(uint8(48))},
3924 {V(int16(49)), V(int16(49))},
3925 {V(int16(50)), V(uint16(50))},
3926 {V(uint16(51)), V(int16(51))},
3927 {V(int16(52)), V(int32(52))},
3928 {V(int32(53)), V(int16(53))},
3929 {V(int16(54)), V(uint32(54))},
3930 {V(uint32(55)), V(int16(55))},
3931 {V(int16(56)), V(int64(56))},
3932 {V(int64(57)), V(int16(57))},
3933 {V(int16(58)), V(uint64(58))},
3934 {V(uint64(59)), V(int16(59))},
3935 {V(int16(60)), V(int(60))},
3936 {V(int(61)), V(int16(61))},
3937 {V(int16(62)), V(uint(62))},
3938 {V(uint(63)), V(int16(63))},
3939 {V(int16(64)), V(uintptr(64))},
3940 {V(uintptr(65)), V(int16(65))},
3941 {V(int16(66)), V(float32(66))},
3942 {V(float32(67)), V(int16(67))},
3943 {V(int16(68)), V(float64(68))},
3944 {V(float64(69)), V(int16(69))},
3945 {V(uint16(70)), V(uint16(70))},
3946 {V(uint16(71)), V(int32(71))},
3947 {V(int32(72)), V(uint16(72))},
3948 {V(uint16(73)), V(uint32(73))},
3949 {V(uint32(74)), V(uint16(74))},
3950 {V(uint16(75)), V(int64(75))},
3951 {V(int64(76)), V(uint16(76))},
3952 {V(uint16(77)), V(uint64(77))},
3953 {V(uint64(78)), V(uint16(78))},
3954 {V(uint16(79)), V(int(79))},
3955 {V(int(80)), V(uint16(80))},
3956 {V(uint16(81)), V(uint(81))},
3957 {V(uint(82)), V(uint16(82))},
3958 {V(uint16(83)), V(uintptr(83))},
3959 {V(uintptr(84)), V(uint16(84))},
3960 {V(uint16(85)), V(float32(85))},
3961 {V(float32(86)), V(uint16(86))},
3962 {V(uint16(87)), V(float64(87))},
3963 {V(float64(88)), V(uint16(88))},
3964 {V(int32(89)), V(int32(89))},
3965 {V(int32(90)), V(uint32(90))},
3966 {V(uint32(91)), V(int32(91))},
3967 {V(int32(92)), V(int64(92))},
3968 {V(int64(93)), V(int32(93))},
3969 {V(int32(94)), V(uint64(94))},
3970 {V(uint64(95)), V(int32(95))},
3971 {V(int32(96)), V(int(96))},
3972 {V(int(97)), V(int32(97))},
3973 {V(int32(98)), V(uint(98))},
3974 {V(uint(99)), V(int32(99))},
3975 {V(int32(100)), V(uintptr(100))},
3976 {V(uintptr(101)), V(int32(101))},
3977 {V(int32(102)), V(float32(102))},
3978 {V(float32(103)), V(int32(103))},
3979 {V(int32(104)), V(float64(104))},
3980 {V(float64(105)), V(int32(105))},
3981 {V(uint32(106)), V(uint32(106))},
3982 {V(uint32(107)), V(int64(107))},
3983 {V(int64(108)), V(uint32(108))},
3984 {V(uint32(109)), V(uint64(109))},
3985 {V(uint64(110)), V(uint32(110))},
3986 {V(uint32(111)), V(int(111))},
3987 {V(int(112)), V(uint32(112))},
3988 {V(uint32(113)), V(uint(113))},
3989 {V(uint(114)), V(uint32(114))},
3990 {V(uint32(115)), V(uintptr(115))},
3991 {V(uintptr(116)), V(uint32(116))},
3992 {V(uint32(117)), V(float32(117))},
3993 {V(float32(118)), V(uint32(118))},
3994 {V(uint32(119)), V(float64(119))},
3995 {V(float64(120)), V(uint32(120))},
3996 {V(int64(121)), V(int64(121))},
3997 {V(int64(122)), V(uint64(122))},
3998 {V(uint64(123)), V(int64(123))},
3999 {V(int64(124)), V(int(124))},
4000 {V(int(125)), V(int64(125))},
4001 {V(int64(126)), V(uint(126))},
4002 {V(uint(127)), V(int64(127))},
4003 {V(int64(128)), V(uintptr(128))},
4004 {V(uintptr(129)), V(int64(129))},
4005 {V(int64(130)), V(float32(130))},
4006 {V(float32(131)), V(int64(131))},
4007 {V(int64(132)), V(float64(132))},
4008 {V(float64(133)), V(int64(133))},
4009 {V(uint64(134)), V(uint64(134))},
4010 {V(uint64(135)), V(int(135))},
4011 {V(int(136)), V(uint64(136))},
4012 {V(uint64(137)), V(uint(137))},
4013 {V(uint(138)), V(uint64(138))},
4014 {V(uint64(139)), V(uintptr(139))},
4015 {V(uintptr(140)), V(uint64(140))},
4016 {V(uint64(141)), V(float32(141))},
4017 {V(float32(142)), V(uint64(142))},
4018 {V(uint64(143)), V(float64(143))},
4019 {V(float64(144)), V(uint64(144))},
4020 {V(int(145)), V(int(145))},
4021 {V(int(146)), V(uint(146))},
4022 {V(uint(147)), V(int(147))},
4023 {V(int(148)), V(uintptr(148))},
4024 {V(uintptr(149)), V(int(149))},
4025 {V(int(150)), V(float32(150))},
4026 {V(float32(151)), V(int(151))},
4027 {V(int(152)), V(float64(152))},
4028 {V(float64(153)), V(int(153))},
4029 {V(uint(154)), V(uint(154))},
4030 {V(uint(155)), V(uintptr(155))},
4031 {V(uintptr(156)), V(uint(156))},
4032 {V(uint(157)), V(float32(157))},
4033 {V(float32(158)), V(uint(158))},
4034 {V(uint(159)), V(float64(159))},
4035 {V(float64(160)), V(uint(160))},
4036 {V(uintptr(161)), V(uintptr(161))},
4037 {V(uintptr(162)), V(float32(162))},
4038 {V(float32(163)), V(uintptr(163))},
4039 {V(uintptr(164)), V(float64(164))},
4040 {V(float64(165)), V(uintptr(165))},
4041 {V(float32(166)), V(float32(166))},
4042 {V(float32(167)), V(float64(167))},
4043 {V(float64(168)), V(float32(168))},
4044 {V(float64(169)), V(float64(169))},
4045
4046
4047 {V(float64(1.5)), V(int(1))},
4048
4049
4050 {V(complex64(1i)), V(complex64(1i))},
4051 {V(complex64(2i)), V(complex128(2i))},
4052 {V(complex128(3i)), V(complex64(3i))},
4053 {V(complex128(4i)), V(complex128(4i))},
4054
4055
4056 {V(string("hello")), V(string("hello"))},
4057 {V(string("bytes1")), V([]byte("bytes1"))},
4058 {V([]byte("bytes2")), V(string("bytes2"))},
4059 {V([]byte("bytes3")), V([]byte("bytes3"))},
4060 {V(string("runes♝")), V([]rune("runes♝"))},
4061 {V([]rune("runes♕")), V(string("runes♕"))},
4062 {V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
4063 {V(int('a')), V(string("a"))},
4064 {V(int8('a')), V(string("a"))},
4065 {V(int16('a')), V(string("a"))},
4066 {V(int32('a')), V(string("a"))},
4067 {V(int64('a')), V(string("a"))},
4068 {V(uint('a')), V(string("a"))},
4069 {V(uint8('a')), V(string("a"))},
4070 {V(uint16('a')), V(string("a"))},
4071 {V(uint32('a')), V(string("a"))},
4072 {V(uint64('a')), V(string("a"))},
4073 {V(uintptr('a')), V(string("a"))},
4074 {V(int(-1)), V(string("\uFFFD"))},
4075 {V(int8(-2)), V(string("\uFFFD"))},
4076 {V(int16(-3)), V(string("\uFFFD"))},
4077 {V(int32(-4)), V(string("\uFFFD"))},
4078 {V(int64(-5)), V(string("\uFFFD"))},
4079 {V(int64(-1 << 32)), V(string("\uFFFD"))},
4080 {V(int64(1 << 32)), V(string("\uFFFD"))},
4081 {V(uint(0x110001)), V(string("\uFFFD"))},
4082 {V(uint32(0x110002)), V(string("\uFFFD"))},
4083 {V(uint64(0x110003)), V(string("\uFFFD"))},
4084 {V(uint64(1 << 32)), V(string("\uFFFD"))},
4085 {V(uintptr(0x110004)), V(string("\uFFFD"))},
4086
4087
4088 {V(MyString("hello")), V(string("hello"))},
4089 {V(string("hello")), V(MyString("hello"))},
4090 {V(string("hello")), V(string("hello"))},
4091 {V(MyString("hello")), V(MyString("hello"))},
4092 {V(MyString("bytes1")), V([]byte("bytes1"))},
4093 {V([]byte("bytes2")), V(MyString("bytes2"))},
4094 {V([]byte("bytes3")), V([]byte("bytes3"))},
4095 {V(MyString("runes♝")), V([]rune("runes♝"))},
4096 {V([]rune("runes♕")), V(MyString("runes♕"))},
4097 {V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
4098 {V([]rune("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
4099 {V(MyRunes("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
4100 {V(int('a')), V(MyString("a"))},
4101 {V(int8('a')), V(MyString("a"))},
4102 {V(int16('a')), V(MyString("a"))},
4103 {V(int32('a')), V(MyString("a"))},
4104 {V(int64('a')), V(MyString("a"))},
4105 {V(uint('a')), V(MyString("a"))},
4106 {V(uint8('a')), V(MyString("a"))},
4107 {V(uint16('a')), V(MyString("a"))},
4108 {V(uint32('a')), V(MyString("a"))},
4109 {V(uint64('a')), V(MyString("a"))},
4110 {V(uintptr('a')), V(MyString("a"))},
4111 {V(int(-1)), V(MyString("\uFFFD"))},
4112 {V(int8(-2)), V(MyString("\uFFFD"))},
4113 {V(int16(-3)), V(MyString("\uFFFD"))},
4114 {V(int32(-4)), V(MyString("\uFFFD"))},
4115 {V(int64(-5)), V(MyString("\uFFFD"))},
4116 {V(uint(0x110001)), V(MyString("\uFFFD"))},
4117 {V(uint32(0x110002)), V(MyString("\uFFFD"))},
4118 {V(uint64(0x110003)), V(MyString("\uFFFD"))},
4119 {V(uintptr(0x110004)), V(MyString("\uFFFD"))},
4120
4121
4122 {V(string("bytes1")), V(MyBytes("bytes1"))},
4123 {V(MyBytes("bytes2")), V(string("bytes2"))},
4124 {V(MyBytes("bytes3")), V(MyBytes("bytes3"))},
4125 {V(MyString("bytes1")), V(MyBytes("bytes1"))},
4126 {V(MyBytes("bytes2")), V(MyString("bytes2"))},
4127
4128
4129 {V(string("runes♝")), V(MyRunes("runes♝"))},
4130 {V(MyRunes("runes♕")), V(string("runes♕"))},
4131 {V(MyRunes("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
4132 {V(MyString("runes♝")), V(MyRunes("runes♝"))},
4133 {V(MyRunes("runes♕")), V(MyString("runes♕"))},
4134
4135
4136 {V([]byte(nil)), V((*[0]byte)(nil))},
4137 {V([]byte{}), V(new([0]byte))},
4138 {V([]byte{7}), V(&[1]byte{7})},
4139 {V(MyBytes([]byte(nil))), V((*[0]byte)(nil))},
4140 {V(MyBytes([]byte{})), V(new([0]byte))},
4141 {V(MyBytes([]byte{9})), V(&[1]byte{9})},
4142 {V([]byte(nil)), V(MyBytesArrayPtr0(nil))},
4143 {V([]byte{}), V(MyBytesArrayPtr0(new([0]byte)))},
4144 {V([]byte{1, 2, 3, 4}), V(MyBytesArrayPtr(&[4]byte{1, 2, 3, 4}))},
4145 {V(MyBytes([]byte{})), V(MyBytesArrayPtr0(new([0]byte)))},
4146 {V(MyBytes([]byte{5, 6, 7, 8})), V(MyBytesArrayPtr(&[4]byte{5, 6, 7, 8}))},
4147
4148 {V([]byte(nil)), V((*MyBytesArray0)(nil))},
4149 {V([]byte{}), V((*MyBytesArray0)(new([0]byte)))},
4150 {V([]byte{1, 2, 3, 4}), V(&MyBytesArray{1, 2, 3, 4})},
4151 {V(MyBytes([]byte(nil))), V((*MyBytesArray0)(nil))},
4152 {V(MyBytes([]byte{})), V((*MyBytesArray0)(new([0]byte)))},
4153 {V(MyBytes([]byte{5, 6, 7, 8})), V(&MyBytesArray{5, 6, 7, 8})},
4154 {V(new([0]byte)), V(new(MyBytesArray0))},
4155 {V(new(MyBytesArray0)), V(new([0]byte))},
4156 {V(MyBytesArrayPtr0(nil)), V((*[0]byte)(nil))},
4157 {V((*[0]byte)(nil)), V(MyBytesArrayPtr0(nil))},
4158
4159
4160 {V(new(int)), V(new(integer))},
4161 {V(new(integer)), V(new(int))},
4162 {V(Empty{}), V(struct{}{})},
4163 {V(new(Empty)), V(new(struct{}))},
4164 {V(struct{}{}), V(Empty{})},
4165 {V(new(struct{})), V(new(Empty))},
4166 {V(Empty{}), V(Empty{})},
4167 {V(MyBytes{}), V([]byte{})},
4168 {V([]byte{}), V(MyBytes{})},
4169 {V((func())(nil)), V(MyFunc(nil))},
4170 {V((MyFunc)(nil)), V((func())(nil))},
4171
4172
4173 {V(struct {
4174 x int `some:"foo"`
4175 }{}), V(struct {
4176 x int `some:"bar"`
4177 }{})},
4178
4179 {V(struct {
4180 x int `some:"bar"`
4181 }{}), V(struct {
4182 x int `some:"foo"`
4183 }{})},
4184
4185 {V(MyStruct{}), V(struct {
4186 x int `some:"foo"`
4187 }{})},
4188
4189 {V(struct {
4190 x int `some:"foo"`
4191 }{}), V(MyStruct{})},
4192
4193 {V(MyStruct{}), V(struct {
4194 x int `some:"bar"`
4195 }{})},
4196
4197 {V(struct {
4198 x int `some:"bar"`
4199 }{}), V(MyStruct{})},
4200
4201 {V(MyStruct1{}), V(MyStruct2{})},
4202 {V(MyStruct2{}), V(MyStruct1{})},
4203
4204
4205 {V((*byte)(nil)), V((*MyByte)(nil))},
4206 {V((*MyByte)(nil)), V((*byte)(nil))},
4207
4208
4209 {V([2]byte{}), V([2]byte{})},
4210 {V([3]byte{}), V([3]byte{})},
4211
4212
4213 {V((**byte)(nil)), V((**byte)(nil))},
4214 {V((**MyByte)(nil)), V((**MyByte)(nil))},
4215 {V((chan byte)(nil)), V((chan byte)(nil))},
4216 {V((chan MyByte)(nil)), V((chan MyByte)(nil))},
4217 {V(([]byte)(nil)), V(([]byte)(nil))},
4218 {V(([]MyByte)(nil)), V(([]MyByte)(nil))},
4219 {V((map[int]byte)(nil)), V((map[int]byte)(nil))},
4220 {V((map[int]MyByte)(nil)), V((map[int]MyByte)(nil))},
4221 {V((map[byte]int)(nil)), V((map[byte]int)(nil))},
4222 {V((map[MyByte]int)(nil)), V((map[MyByte]int)(nil))},
4223 {V([2]byte{}), V([2]byte{})},
4224 {V([2]MyByte{}), V([2]MyByte{})},
4225
4226
4227 {V((***int)(nil)), V((***int)(nil))},
4228 {V((***byte)(nil)), V((***byte)(nil))},
4229 {V((***int32)(nil)), V((***int32)(nil))},
4230 {V((***int64)(nil)), V((***int64)(nil))},
4231 {V((chan byte)(nil)), V((chan byte)(nil))},
4232 {V((chan MyByte)(nil)), V((chan MyByte)(nil))},
4233 {V((map[int]bool)(nil)), V((map[int]bool)(nil))},
4234 {V((map[int]byte)(nil)), V((map[int]byte)(nil))},
4235 {V((map[uint]bool)(nil)), V((map[uint]bool)(nil))},
4236 {V([]uint(nil)), V([]uint(nil))},
4237 {V([]int(nil)), V([]int(nil))},
4238 {V(new(interface{})), V(new(interface{}))},
4239 {V(new(io.Reader)), V(new(io.Reader))},
4240 {V(new(io.Writer)), V(new(io.Writer))},
4241
4242
4243 {V(IntChan(nil)), V((chan<- int)(nil))},
4244 {V(IntChan(nil)), V((<-chan int)(nil))},
4245 {V((chan int)(nil)), V(IntChanRecv(nil))},
4246 {V((chan int)(nil)), V(IntChanSend(nil))},
4247 {V(IntChanRecv(nil)), V((<-chan int)(nil))},
4248 {V((<-chan int)(nil)), V(IntChanRecv(nil))},
4249 {V(IntChanSend(nil)), V((chan<- int)(nil))},
4250 {V((chan<- int)(nil)), V(IntChanSend(nil))},
4251 {V(IntChan(nil)), V((chan int)(nil))},
4252 {V((chan int)(nil)), V(IntChan(nil))},
4253 {V((chan int)(nil)), V((<-chan int)(nil))},
4254 {V((chan int)(nil)), V((chan<- int)(nil))},
4255 {V(BytesChan(nil)), V((chan<- []byte)(nil))},
4256 {V(BytesChan(nil)), V((<-chan []byte)(nil))},
4257 {V((chan []byte)(nil)), V(BytesChanRecv(nil))},
4258 {V((chan []byte)(nil)), V(BytesChanSend(nil))},
4259 {V(BytesChanRecv(nil)), V((<-chan []byte)(nil))},
4260 {V((<-chan []byte)(nil)), V(BytesChanRecv(nil))},
4261 {V(BytesChanSend(nil)), V((chan<- []byte)(nil))},
4262 {V((chan<- []byte)(nil)), V(BytesChanSend(nil))},
4263 {V(BytesChan(nil)), V((chan []byte)(nil))},
4264 {V((chan []byte)(nil)), V(BytesChan(nil))},
4265 {V((chan []byte)(nil)), V((<-chan []byte)(nil))},
4266 {V((chan []byte)(nil)), V((chan<- []byte)(nil))},
4267
4268
4269 {V(IntChan(nil)), V(IntChan(nil))},
4270 {V(IntChanRecv(nil)), V(IntChanRecv(nil))},
4271 {V(IntChanSend(nil)), V(IntChanSend(nil))},
4272 {V(BytesChan(nil)), V(BytesChan(nil))},
4273 {V(BytesChanRecv(nil)), V(BytesChanRecv(nil))},
4274 {V(BytesChanSend(nil)), V(BytesChanSend(nil))},
4275
4276
4277 {V(int(1)), EmptyInterfaceV(int(1))},
4278 {V(string("hello")), EmptyInterfaceV(string("hello"))},
4279 {V(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
4280 {ReadWriterV(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
4281 {V(new(bytes.Buffer)), ReadWriterV(new(bytes.Buffer))},
4282 }
4283
4284 func TestConvert(t *testing.T) {
4285 canConvert := map[[2]Type]bool{}
4286 all := map[Type]bool{}
4287
4288 for _, tt := range convertTests {
4289 t1 := tt.in.Type()
4290 if !t1.ConvertibleTo(t1) {
4291 t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t1)
4292 continue
4293 }
4294
4295 t2 := tt.out.Type()
4296 if !t1.ConvertibleTo(t2) {
4297 t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t2)
4298 continue
4299 }
4300
4301 all[t1] = true
4302 all[t2] = true
4303 canConvert[[2]Type{t1, t2}] = true
4304
4305
4306 v1 := tt.in
4307 if !v1.CanConvert(t1) {
4308 t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t1)
4309 }
4310 vout1 := v1.Convert(t1)
4311 out1 := vout1.Interface()
4312 if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
4313 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t1, out1, tt.in.Interface())
4314 }
4315
4316
4317 if !v1.CanConvert(t2) {
4318 t.Errorf("ValueOf(%T(%[1]v)).CanConvert(%s) = false, want true", tt.in.Interface(), t2)
4319 }
4320 vout2 := v1.Convert(t2)
4321 out2 := vout2.Interface()
4322 if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
4323 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out2, tt.out.Interface())
4324 }
4325 if got, want := vout2.Kind(), vout2.Type().Kind(); got != want {
4326 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) has internal kind %v want %v", tt.in.Interface(), t1, got, want)
4327 }
4328
4329
4330
4331 vout3 := New(t2).Elem()
4332 vout3.Set(vout2)
4333 out3 := vout3.Interface()
4334 if vout3.Type() != tt.out.Type() || !DeepEqual(out3, tt.out.Interface()) {
4335 t.Errorf("Set(ValueOf(%T(%[1]v)).Convert(%s)) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out3, tt.out.Interface())
4336 }
4337
4338 if IsRO(v1) {
4339 t.Errorf("table entry %v is RO, should not be", v1)
4340 }
4341 if IsRO(vout1) {
4342 t.Errorf("self-conversion output %v is RO, should not be", vout1)
4343 }
4344 if IsRO(vout2) {
4345 t.Errorf("conversion output %v is RO, should not be", vout2)
4346 }
4347 if IsRO(vout3) {
4348 t.Errorf("set(conversion output) %v is RO, should not be", vout3)
4349 }
4350 if !IsRO(MakeRO(v1).Convert(t1)) {
4351 t.Errorf("RO self-conversion output %v is not RO, should be", v1)
4352 }
4353 if !IsRO(MakeRO(v1).Convert(t2)) {
4354 t.Errorf("RO conversion output %v is not RO, should be", v1)
4355 }
4356 }
4357
4358
4359
4360
4361
4362 for t1 := range all {
4363 for t2 := range all {
4364 expectOK := t1 == t2 || canConvert[[2]Type{t1, t2}] || t2.Kind() == Interface && t2.NumMethod() == 0
4365 if ok := t1.ConvertibleTo(t2); ok != expectOK {
4366 t.Errorf("(%s).ConvertibleTo(%s) = %v, want %v", t1, t2, ok, expectOK)
4367 }
4368 }
4369 }
4370 }
4371
4372 func TestConvertPanic(t *testing.T) {
4373 s := make([]byte, 4)
4374 p := new([8]byte)
4375 v := ValueOf(s)
4376 pt := TypeOf(p)
4377 if !v.Type().ConvertibleTo(pt) {
4378 t.Errorf("[]byte should be convertible to *[8]byte")
4379 }
4380 if v.CanConvert(pt) {
4381 t.Errorf("slice with length 4 should not be convertible to *[8]byte")
4382 }
4383 shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() {
4384 _ = v.Convert(pt)
4385 })
4386 }
4387
4388 var gFloat32 float32
4389
4390 func TestConvertNaNs(t *testing.T) {
4391 const snan uint32 = 0x7f800001
4392 type myFloat32 float32
4393 x := V(myFloat32(math.Float32frombits(snan)))
4394 y := x.Convert(TypeOf(float32(0)))
4395 z := y.Interface().(float32)
4396 if got := math.Float32bits(z); got != snan {
4397 t.Errorf("signaling nan conversion got %x, want %x", got, snan)
4398 }
4399 }
4400
4401 type ComparableStruct struct {
4402 X int
4403 }
4404
4405 type NonComparableStruct struct {
4406 X int
4407 Y map[string]int
4408 }
4409
4410 var comparableTests = []struct {
4411 typ Type
4412 ok bool
4413 }{
4414 {TypeOf(1), true},
4415 {TypeOf("hello"), true},
4416 {TypeOf(new(byte)), true},
4417 {TypeOf((func())(nil)), false},
4418 {TypeOf([]byte{}), false},
4419 {TypeOf(map[string]int{}), false},
4420 {TypeOf(make(chan int)), true},
4421 {TypeOf(1.5), true},
4422 {TypeOf(false), true},
4423 {TypeOf(1i), true},
4424 {TypeOf(ComparableStruct{}), true},
4425 {TypeOf(NonComparableStruct{}), false},
4426 {TypeOf([10]map[string]int{}), false},
4427 {TypeOf([10]string{}), true},
4428 {TypeOf(new(interface{})).Elem(), true},
4429 }
4430
4431 func TestComparable(t *testing.T) {
4432 for _, tt := range comparableTests {
4433 if ok := tt.typ.Comparable(); ok != tt.ok {
4434 t.Errorf("TypeOf(%v).Comparable() = %v, want %v", tt.typ, ok, tt.ok)
4435 }
4436 }
4437 }
4438
4439 func TestOverflow(t *testing.T) {
4440 if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
4441 t.Errorf("%v wrongly overflows float64", 1e300)
4442 }
4443
4444 maxFloat32 := float64((1<<24 - 1) << (127 - 23))
4445 if ovf := V(float32(0)).OverflowFloat(maxFloat32); ovf {
4446 t.Errorf("%v wrongly overflows float32", maxFloat32)
4447 }
4448 ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
4449 if ovf := V(float32(0)).OverflowFloat(ovfFloat32); !ovf {
4450 t.Errorf("%v should overflow float32", ovfFloat32)
4451 }
4452 if ovf := V(float32(0)).OverflowFloat(-ovfFloat32); !ovf {
4453 t.Errorf("%v should overflow float32", -ovfFloat32)
4454 }
4455
4456 maxInt32 := int64(0x7fffffff)
4457 if ovf := V(int32(0)).OverflowInt(maxInt32); ovf {
4458 t.Errorf("%v wrongly overflows int32", maxInt32)
4459 }
4460 if ovf := V(int32(0)).OverflowInt(-1 << 31); ovf {
4461 t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
4462 }
4463 ovfInt32 := int64(1 << 31)
4464 if ovf := V(int32(0)).OverflowInt(ovfInt32); !ovf {
4465 t.Errorf("%v should overflow int32", ovfInt32)
4466 }
4467
4468 maxUint32 := uint64(0xffffffff)
4469 if ovf := V(uint32(0)).OverflowUint(maxUint32); ovf {
4470 t.Errorf("%v wrongly overflows uint32", maxUint32)
4471 }
4472 ovfUint32 := uint64(1 << 32)
4473 if ovf := V(uint32(0)).OverflowUint(ovfUint32); !ovf {
4474 t.Errorf("%v should overflow uint32", ovfUint32)
4475 }
4476 }
4477
4478 func checkSameType(t *testing.T, x Type, y interface{}) {
4479 if x != TypeOf(y) || TypeOf(Zero(x).Interface()) != TypeOf(y) {
4480 t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
4481 }
4482 }
4483
4484 func TestArrayOf(t *testing.T) {
4485
4486 tests := []struct {
4487 n int
4488 value func(i int) interface{}
4489 comparable bool
4490 want string
4491 }{
4492 {
4493 n: 0,
4494 value: func(i int) interface{} { type Tint int; return Tint(i) },
4495 comparable: true,
4496 want: "[]",
4497 },
4498 {
4499 n: 10,
4500 value: func(i int) interface{} { type Tint int; return Tint(i) },
4501 comparable: true,
4502 want: "[0 1 2 3 4 5 6 7 8 9]",
4503 },
4504 {
4505 n: 10,
4506 value: func(i int) interface{} { type Tfloat float64; return Tfloat(i) },
4507 comparable: true,
4508 want: "[0 1 2 3 4 5 6 7 8 9]",
4509 },
4510 {
4511 n: 10,
4512 value: func(i int) interface{} { type Tstring string; return Tstring(strconv.Itoa(i)) },
4513 comparable: true,
4514 want: "[0 1 2 3 4 5 6 7 8 9]",
4515 },
4516 {
4517 n: 10,
4518 value: func(i int) interface{} { type Tstruct struct{ V int }; return Tstruct{i} },
4519 comparable: true,
4520 want: "[{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}]",
4521 },
4522 {
4523 n: 10,
4524 value: func(i int) interface{} { type Tint int; return []Tint{Tint(i)} },
4525 comparable: false,
4526 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
4527 },
4528 {
4529 n: 10,
4530 value: func(i int) interface{} { type Tint int; return [1]Tint{Tint(i)} },
4531 comparable: true,
4532 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
4533 },
4534 {
4535 n: 10,
4536 value: func(i int) interface{} { type Tstruct struct{ V [1]int }; return Tstruct{[1]int{i}} },
4537 comparable: true,
4538 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
4539 },
4540 {
4541 n: 10,
4542 value: func(i int) interface{} { type Tstruct struct{ V []int }; return Tstruct{[]int{i}} },
4543 comparable: false,
4544 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
4545 },
4546 {
4547 n: 10,
4548 value: func(i int) interface{} { type TstructUV struct{ U, V int }; return TstructUV{i, i} },
4549 comparable: true,
4550 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
4551 },
4552 {
4553 n: 10,
4554 value: func(i int) interface{} {
4555 type TstructUV struct {
4556 U int
4557 V float64
4558 }
4559 return TstructUV{i, float64(i)}
4560 },
4561 comparable: true,
4562 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
4563 },
4564 }
4565
4566 for _, table := range tests {
4567 at := ArrayOf(table.n, TypeOf(table.value(0)))
4568 v := New(at).Elem()
4569 vok := New(at).Elem()
4570 vnot := New(at).Elem()
4571 for i := 0; i < v.Len(); i++ {
4572 v.Index(i).Set(ValueOf(table.value(i)))
4573 vok.Index(i).Set(ValueOf(table.value(i)))
4574 j := i
4575 if i+1 == v.Len() {
4576 j = i + 1
4577 }
4578 vnot.Index(i).Set(ValueOf(table.value(j)))
4579 }
4580 s := fmt.Sprint(v.Interface())
4581 if s != table.want {
4582 t.Errorf("constructed array = %s, want %s", s, table.want)
4583 }
4584
4585 if table.comparable != at.Comparable() {
4586 t.Errorf("constructed array (%#v) is comparable=%v, want=%v", v.Interface(), at.Comparable(), table.comparable)
4587 }
4588 if table.comparable {
4589 if table.n > 0 {
4590 if DeepEqual(vnot.Interface(), v.Interface()) {
4591 t.Errorf(
4592 "arrays (%#v) compare ok (but should not)",
4593 v.Interface(),
4594 )
4595 }
4596 }
4597 if !DeepEqual(vok.Interface(), v.Interface()) {
4598 t.Errorf(
4599 "arrays (%#v) compare NOT-ok (but should)",
4600 v.Interface(),
4601 )
4602 }
4603 }
4604 }
4605
4606
4607 type T int
4608 checkSameType(t, ArrayOf(5, TypeOf(T(1))), [5]T{})
4609 }
4610
4611 func TestArrayOfGC(t *testing.T) {
4612 type T *uintptr
4613 tt := TypeOf(T(nil))
4614 const n = 100
4615 var x []interface{}
4616 for i := 0; i < n; i++ {
4617 v := New(ArrayOf(n, tt)).Elem()
4618 for j := 0; j < v.Len(); j++ {
4619 p := new(uintptr)
4620 *p = uintptr(i*n + j)
4621 v.Index(j).Set(ValueOf(p).Convert(tt))
4622 }
4623 x = append(x, v.Interface())
4624 }
4625 runtime.GC()
4626
4627 for i, xi := range x {
4628 v := ValueOf(xi)
4629 for j := 0; j < v.Len(); j++ {
4630 k := v.Index(j).Elem().Interface()
4631 if k != uintptr(i*n+j) {
4632 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4633 }
4634 }
4635 }
4636 }
4637
4638 func TestArrayOfAlg(t *testing.T) {
4639 at := ArrayOf(6, TypeOf(byte(0)))
4640 v1 := New(at).Elem()
4641 v2 := New(at).Elem()
4642 if v1.Interface() != v1.Interface() {
4643 t.Errorf("constructed array %v not equal to itself", v1.Interface())
4644 }
4645 v1.Index(5).Set(ValueOf(byte(1)))
4646 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
4647 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
4648 }
4649
4650 at = ArrayOf(6, TypeOf([]int(nil)))
4651 v1 = New(at).Elem()
4652 shouldPanic("", func() { _ = v1.Interface() == v1.Interface() })
4653 }
4654
4655 func TestArrayOfGenericAlg(t *testing.T) {
4656 at1 := ArrayOf(5, TypeOf(string("")))
4657 at := ArrayOf(6, at1)
4658 v1 := New(at).Elem()
4659 v2 := New(at).Elem()
4660 if v1.Interface() != v1.Interface() {
4661 t.Errorf("constructed array %v not equal to itself", v1.Interface())
4662 }
4663
4664 v1.Index(0).Index(0).Set(ValueOf("abc"))
4665 v2.Index(0).Index(0).Set(ValueOf("efg"))
4666 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
4667 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
4668 }
4669
4670 v1.Index(0).Index(0).Set(ValueOf("abc"))
4671 v2.Index(0).Index(0).Set(ValueOf((v1.Index(0).Index(0).String() + " ")[:3]))
4672 if i1, i2 := v1.Interface(), v2.Interface(); i1 != i2 {
4673 t.Errorf("constructed arrays %v and %v should be equal", i1, i2)
4674 }
4675
4676
4677 m := MakeMap(MapOf(at, TypeOf(int(0))))
4678 m.SetMapIndex(v1, ValueOf(1))
4679 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
4680 t.Errorf("constructed arrays %v and %v have different hashes", i1, i2)
4681 }
4682 }
4683
4684 func TestArrayOfDirectIface(t *testing.T) {
4685 {
4686 type T [1]*byte
4687 i1 := Zero(TypeOf(T{})).Interface()
4688 v1 := ValueOf(&i1).Elem()
4689 p1 := v1.InterfaceData()[1]
4690
4691 i2 := Zero(ArrayOf(1, PtrTo(TypeOf(int8(0))))).Interface()
4692 v2 := ValueOf(&i2).Elem()
4693 p2 := v2.InterfaceData()[1]
4694
4695 if p1 != 0 {
4696 t.Errorf("got p1=%v. want=%v", p1, nil)
4697 }
4698
4699 if p2 != 0 {
4700 t.Errorf("got p2=%v. want=%v", p2, nil)
4701 }
4702 }
4703 {
4704 type T [0]*byte
4705 i1 := Zero(TypeOf(T{})).Interface()
4706 v1 := ValueOf(&i1).Elem()
4707 p1 := v1.InterfaceData()[1]
4708
4709 i2 := Zero(ArrayOf(0, PtrTo(TypeOf(int8(0))))).Interface()
4710 v2 := ValueOf(&i2).Elem()
4711 p2 := v2.InterfaceData()[1]
4712
4713 if p1 == 0 {
4714 t.Errorf("got p1=%v. want=not-%v", p1, nil)
4715 }
4716
4717 if p2 == 0 {
4718 t.Errorf("got p2=%v. want=not-%v", p2, nil)
4719 }
4720 }
4721 }
4722
4723
4724
4725 func TestArrayOfPanicOnNegativeLength(t *testing.T) {
4726 shouldPanic("reflect: negative length passed to ArrayOf", func() {
4727 ArrayOf(-1, TypeOf(byte(0)))
4728 })
4729 }
4730
4731 func TestSliceOf(t *testing.T) {
4732
4733 type T int
4734 st := SliceOf(TypeOf(T(1)))
4735 if got, want := st.String(), "[]reflect_test.T"; got != want {
4736 t.Errorf("SliceOf(T(1)).String()=%q, want %q", got, want)
4737 }
4738 v := MakeSlice(st, 10, 10)
4739 runtime.GC()
4740 for i := 0; i < v.Len(); i++ {
4741 v.Index(i).Set(ValueOf(T(i)))
4742 runtime.GC()
4743 }
4744 s := fmt.Sprint(v.Interface())
4745 want := "[0 1 2 3 4 5 6 7 8 9]"
4746 if s != want {
4747 t.Errorf("constructed slice = %s, want %s", s, want)
4748 }
4749
4750
4751 type T1 int
4752 checkSameType(t, SliceOf(TypeOf(T1(1))), []T1{})
4753 }
4754
4755 func TestSliceOverflow(t *testing.T) {
4756
4757 const S = 1e6
4758 s := uint(S)
4759 l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
4760 if l*s >= s {
4761 t.Fatal("slice size does not overflow")
4762 }
4763 var x [S]byte
4764 st := SliceOf(TypeOf(x))
4765 defer func() {
4766 err := recover()
4767 if err == nil {
4768 t.Fatal("slice overflow does not panic")
4769 }
4770 }()
4771 MakeSlice(st, int(l), int(l))
4772 }
4773
4774 func TestSliceOfGC(t *testing.T) {
4775 type T *uintptr
4776 tt := TypeOf(T(nil))
4777 st := SliceOf(tt)
4778 const n = 100
4779 var x []interface{}
4780 for i := 0; i < n; i++ {
4781 v := MakeSlice(st, n, n)
4782 for j := 0; j < v.Len(); j++ {
4783 p := new(uintptr)
4784 *p = uintptr(i*n + j)
4785 v.Index(j).Set(ValueOf(p).Convert(tt))
4786 }
4787 x = append(x, v.Interface())
4788 }
4789 runtime.GC()
4790
4791 for i, xi := range x {
4792 v := ValueOf(xi)
4793 for j := 0; j < v.Len(); j++ {
4794 k := v.Index(j).Elem().Interface()
4795 if k != uintptr(i*n+j) {
4796 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4797 }
4798 }
4799 }
4800 }
4801
4802 func TestStructOfFieldName(t *testing.T) {
4803
4804 shouldPanic("has invalid name", func() {
4805 StructOf([]StructField{
4806 {Name: "Valid", Type: TypeOf("")},
4807 {Name: "1nvalid", Type: TypeOf("")},
4808 })
4809 })
4810
4811
4812 shouldPanic("has invalid name", func() {
4813 StructOf([]StructField{
4814 {Name: "Val1d", Type: TypeOf("")},
4815 {Name: "+", Type: TypeOf("")},
4816 })
4817 })
4818
4819
4820 shouldPanic("has no name", func() {
4821 StructOf([]StructField{
4822 {Name: "", Type: TypeOf("")},
4823 })
4824 })
4825
4826
4827 validFields := []StructField{
4828 {
4829 Name: "φ",
4830 Type: TypeOf(""),
4831 },
4832 {
4833 Name: "ValidName",
4834 Type: TypeOf(""),
4835 },
4836 {
4837 Name: "Val1dNam5",
4838 Type: TypeOf(""),
4839 },
4840 }
4841
4842 validStruct := StructOf(validFields)
4843
4844 const structStr = `struct { φ string; ValidName string; Val1dNam5 string }`
4845 if got, want := validStruct.String(), structStr; got != want {
4846 t.Errorf("StructOf(validFields).String()=%q, want %q", got, want)
4847 }
4848 }
4849
4850 func TestStructOf(t *testing.T) {
4851
4852 fields := []StructField{
4853 {
4854 Name: "S",
4855 Tag: "s",
4856 Type: TypeOf(""),
4857 },
4858 {
4859 Name: "X",
4860 Tag: "x",
4861 Type: TypeOf(byte(0)),
4862 },
4863 {
4864 Name: "Y",
4865 Type: TypeOf(uint64(0)),
4866 },
4867 {
4868 Name: "Z",
4869 Type: TypeOf([3]uint16{}),
4870 },
4871 }
4872
4873 st := StructOf(fields)
4874 v := New(st).Elem()
4875 runtime.GC()
4876 v.FieldByName("X").Set(ValueOf(byte(2)))
4877 v.FieldByIndex([]int{1}).Set(ValueOf(byte(1)))
4878 runtime.GC()
4879
4880 s := fmt.Sprint(v.Interface())
4881 want := `{ 1 0 [0 0 0]}`
4882 if s != want {
4883 t.Errorf("constructed struct = %s, want %s", s, want)
4884 }
4885 const stStr = `struct { S string "s"; X uint8 "x"; Y uint64; Z [3]uint16 }`
4886 if got, want := st.String(), stStr; got != want {
4887 t.Errorf("StructOf(fields).String()=%q, want %q", got, want)
4888 }
4889
4890
4891 stt := TypeOf(struct {
4892 String string
4893 X byte
4894 Y uint64
4895 Z [3]uint16
4896 }{})
4897 if st.Size() != stt.Size() {
4898 t.Errorf("constructed struct size = %v, want %v", st.Size(), stt.Size())
4899 }
4900 if st.Align() != stt.Align() {
4901 t.Errorf("constructed struct align = %v, want %v", st.Align(), stt.Align())
4902 }
4903 if st.FieldAlign() != stt.FieldAlign() {
4904 t.Errorf("constructed struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
4905 }
4906 for i := 0; i < st.NumField(); i++ {
4907 o1 := st.Field(i).Offset
4908 o2 := stt.Field(i).Offset
4909 if o1 != o2 {
4910 t.Errorf("constructed struct field %v offset = %v, want %v", i, o1, o2)
4911 }
4912 }
4913
4914
4915 st = StructOf([]StructField{
4916 {
4917 Name: "F1",
4918 Type: TypeOf(byte(0)),
4919 },
4920 {
4921 Name: "F2",
4922 Type: TypeOf([0]*byte{}),
4923 },
4924 })
4925 stt = TypeOf(struct {
4926 G1 byte
4927 G2 [0]*byte
4928 }{})
4929 if st.Size() != stt.Size() {
4930 t.Errorf("constructed zero-padded struct size = %v, want %v", st.Size(), stt.Size())
4931 }
4932 if st.Align() != stt.Align() {
4933 t.Errorf("constructed zero-padded struct align = %v, want %v", st.Align(), stt.Align())
4934 }
4935 if st.FieldAlign() != stt.FieldAlign() {
4936 t.Errorf("constructed zero-padded struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
4937 }
4938 for i := 0; i < st.NumField(); i++ {
4939 o1 := st.Field(i).Offset
4940 o2 := stt.Field(i).Offset
4941 if o1 != o2 {
4942 t.Errorf("constructed zero-padded struct field %v offset = %v, want %v", i, o1, o2)
4943 }
4944 }
4945
4946
4947 shouldPanic("duplicate field", func() {
4948 StructOf([]StructField{
4949 {Name: "string", PkgPath: "p", Type: TypeOf("")},
4950 {Name: "string", PkgPath: "p", Type: TypeOf("")},
4951 })
4952 })
4953 shouldPanic("has no name", func() {
4954 StructOf([]StructField{
4955 {Type: TypeOf("")},
4956 {Name: "string", PkgPath: "p", Type: TypeOf("")},
4957 })
4958 })
4959 shouldPanic("has no name", func() {
4960 StructOf([]StructField{
4961 {Type: TypeOf("")},
4962 {Type: TypeOf("")},
4963 })
4964 })
4965
4966 checkSameType(t, StructOf(fields[2:3]), struct{ Y uint64 }{})
4967
4968
4969 type structFieldType interface{}
4970 checkSameType(t,
4971 StructOf([]StructField{
4972 {
4973 Name: "F",
4974 Type: TypeOf((*structFieldType)(nil)).Elem(),
4975 },
4976 }),
4977 struct{ F structFieldType }{})
4978 }
4979
4980 func TestStructOfExportRules(t *testing.T) {
4981 type S1 struct{}
4982 type s2 struct{}
4983 type ΦType struct{}
4984 type φType struct{}
4985
4986 testPanic := func(i int, mustPanic bool, f func()) {
4987 defer func() {
4988 err := recover()
4989 if err == nil && mustPanic {
4990 t.Errorf("test-%d did not panic", i)
4991 }
4992 if err != nil && !mustPanic {
4993 t.Errorf("test-%d panicked: %v\n", i, err)
4994 }
4995 }()
4996 f()
4997 }
4998
4999 tests := []struct {
5000 field StructField
5001 mustPanic bool
5002 exported bool
5003 }{
5004 {
5005 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf(S1{})},
5006 exported: true,
5007 },
5008 {
5009 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf((*S1)(nil))},
5010 exported: true,
5011 },
5012 {
5013 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf(s2{})},
5014 mustPanic: true,
5015 },
5016 {
5017 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf((*s2)(nil))},
5018 mustPanic: true,
5019 },
5020 {
5021 field: StructField{Name: "Name", Type: nil, PkgPath: ""},
5022 mustPanic: true,
5023 },
5024 {
5025 field: StructField{Name: "", Type: TypeOf(S1{}), PkgPath: ""},
5026 mustPanic: true,
5027 },
5028 {
5029 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf(S1{}), PkgPath: "other/pkg"},
5030 mustPanic: true,
5031 },
5032 {
5033 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
5034 mustPanic: true,
5035 },
5036 {
5037 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf(s2{}), PkgPath: "other/pkg"},
5038 mustPanic: true,
5039 },
5040 {
5041 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
5042 mustPanic: true,
5043 },
5044 {
5045 field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
5046 },
5047 {
5048 field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
5049 },
5050 {
5051 field: StructField{Name: "S", Type: TypeOf(S1{})},
5052 exported: true,
5053 },
5054 {
5055 field: StructField{Name: "S", Type: TypeOf((*S1)(nil))},
5056 exported: true,
5057 },
5058 {
5059 field: StructField{Name: "S", Type: TypeOf(s2{})},
5060 exported: true,
5061 },
5062 {
5063 field: StructField{Name: "S", Type: TypeOf((*s2)(nil))},
5064 exported: true,
5065 },
5066 {
5067 field: StructField{Name: "s", Type: TypeOf(S1{})},
5068 mustPanic: true,
5069 },
5070 {
5071 field: StructField{Name: "s", Type: TypeOf((*S1)(nil))},
5072 mustPanic: true,
5073 },
5074 {
5075 field: StructField{Name: "s", Type: TypeOf(s2{})},
5076 mustPanic: true,
5077 },
5078 {
5079 field: StructField{Name: "s", Type: TypeOf((*s2)(nil))},
5080 mustPanic: true,
5081 },
5082 {
5083 field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
5084 },
5085 {
5086 field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
5087 },
5088 {
5089 field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
5090 },
5091 {
5092 field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
5093 },
5094 {
5095 field: StructField{Name: "", Type: TypeOf(ΦType{})},
5096 mustPanic: true,
5097 },
5098 {
5099 field: StructField{Name: "", Type: TypeOf(φType{})},
5100 mustPanic: true,
5101 },
5102 {
5103 field: StructField{Name: "Φ", Type: TypeOf(0)},
5104 exported: true,
5105 },
5106 {
5107 field: StructField{Name: "φ", Type: TypeOf(0)},
5108 exported: false,
5109 },
5110 }
5111
5112 for i, test := range tests {
5113 testPanic(i, test.mustPanic, func() {
5114 typ := StructOf([]StructField{test.field})
5115 if typ == nil {
5116 t.Errorf("test-%d: error creating struct type", i)
5117 return
5118 }
5119 field := typ.Field(0)
5120 n := field.Name
5121 if n == "" {
5122 panic("field.Name must not be empty")
5123 }
5124 exported := token.IsExported(n)
5125 if exported != test.exported {
5126 t.Errorf("test-%d: got exported=%v want exported=%v", i, exported, test.exported)
5127 }
5128 if field.PkgPath != test.field.PkgPath {
5129 t.Errorf("test-%d: got PkgPath=%q want pkgPath=%q", i, field.PkgPath, test.field.PkgPath)
5130 }
5131 })
5132 }
5133 }
5134
5135 func TestStructOfGC(t *testing.T) {
5136 type T *uintptr
5137 tt := TypeOf(T(nil))
5138 fields := []StructField{
5139 {Name: "X", Type: tt},
5140 {Name: "Y", Type: tt},
5141 }
5142 st := StructOf(fields)
5143
5144 const n = 10000
5145 var x []interface{}
5146 for i := 0; i < n; i++ {
5147 v := New(st).Elem()
5148 for j := 0; j < v.NumField(); j++ {
5149 p := new(uintptr)
5150 *p = uintptr(i*n + j)
5151 v.Field(j).Set(ValueOf(p).Convert(tt))
5152 }
5153 x = append(x, v.Interface())
5154 }
5155 runtime.GC()
5156
5157 for i, xi := range x {
5158 v := ValueOf(xi)
5159 for j := 0; j < v.NumField(); j++ {
5160 k := v.Field(j).Elem().Interface()
5161 if k != uintptr(i*n+j) {
5162 t.Errorf("lost x[%d].%c = %d, want %d", i, "XY"[j], k, i*n+j)
5163 }
5164 }
5165 }
5166 }
5167
5168 func TestStructOfAlg(t *testing.T) {
5169 st := StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf(int(0))}})
5170 v1 := New(st).Elem()
5171 v2 := New(st).Elem()
5172 if !DeepEqual(v1.Interface(), v1.Interface()) {
5173 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
5174 }
5175 v1.FieldByName("X").Set(ValueOf(int(1)))
5176 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
5177 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
5178 }
5179
5180 st = StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf([]int(nil))}})
5181 v1 = New(st).Elem()
5182 shouldPanic("", func() { _ = v1.Interface() == v1.Interface() })
5183 }
5184
5185 func TestStructOfGenericAlg(t *testing.T) {
5186 st1 := StructOf([]StructField{
5187 {Name: "X", Tag: "x", Type: TypeOf(int64(0))},
5188 {Name: "Y", Type: TypeOf(string(""))},
5189 })
5190 st := StructOf([]StructField{
5191 {Name: "S0", Type: st1},
5192 {Name: "S1", Type: st1},
5193 })
5194
5195 tests := []struct {
5196 rt Type
5197 idx []int
5198 }{
5199 {
5200 rt: st,
5201 idx: []int{0, 1},
5202 },
5203 {
5204 rt: st1,
5205 idx: []int{1},
5206 },
5207 {
5208 rt: StructOf(
5209 []StructField{
5210 {Name: "XX", Type: TypeOf([0]int{})},
5211 {Name: "YY", Type: TypeOf("")},
5212 },
5213 ),
5214 idx: []int{1},
5215 },
5216 {
5217 rt: StructOf(
5218 []StructField{
5219 {Name: "XX", Type: TypeOf([0]int{})},
5220 {Name: "YY", Type: TypeOf("")},
5221 {Name: "ZZ", Type: TypeOf([2]int{})},
5222 },
5223 ),
5224 idx: []int{1},
5225 },
5226 {
5227 rt: StructOf(
5228 []StructField{
5229 {Name: "XX", Type: TypeOf([1]int{})},
5230 {Name: "YY", Type: TypeOf("")},
5231 },
5232 ),
5233 idx: []int{1},
5234 },
5235 {
5236 rt: StructOf(
5237 []StructField{
5238 {Name: "XX", Type: TypeOf([1]int{})},
5239 {Name: "YY", Type: TypeOf("")},
5240 {Name: "ZZ", Type: TypeOf([1]int{})},
5241 },
5242 ),
5243 idx: []int{1},
5244 },
5245 {
5246 rt: StructOf(
5247 []StructField{
5248 {Name: "XX", Type: TypeOf([2]int{})},
5249 {Name: "YY", Type: TypeOf("")},
5250 {Name: "ZZ", Type: TypeOf([2]int{})},
5251 },
5252 ),
5253 idx: []int{1},
5254 },
5255 {
5256 rt: StructOf(
5257 []StructField{
5258 {Name: "XX", Type: TypeOf(int64(0))},
5259 {Name: "YY", Type: TypeOf(byte(0))},
5260 {Name: "ZZ", Type: TypeOf("")},
5261 },
5262 ),
5263 idx: []int{2},
5264 },
5265 {
5266 rt: StructOf(
5267 []StructField{
5268 {Name: "XX", Type: TypeOf(int64(0))},
5269 {Name: "YY", Type: TypeOf(int64(0))},
5270 {Name: "ZZ", Type: TypeOf("")},
5271 {Name: "AA", Type: TypeOf([1]int64{})},
5272 },
5273 ),
5274 idx: []int{2},
5275 },
5276 }
5277
5278 for _, table := range tests {
5279 v1 := New(table.rt).Elem()
5280 v2 := New(table.rt).Elem()
5281
5282 if !DeepEqual(v1.Interface(), v1.Interface()) {
5283 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
5284 }
5285
5286 v1.FieldByIndex(table.idx).Set(ValueOf("abc"))
5287 v2.FieldByIndex(table.idx).Set(ValueOf("def"))
5288 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
5289 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
5290 }
5291
5292 abc := "abc"
5293 v1.FieldByIndex(table.idx).Set(ValueOf(abc))
5294 val := "+" + abc + "-"
5295 v2.FieldByIndex(table.idx).Set(ValueOf(val[1:4]))
5296 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
5297 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
5298 }
5299
5300
5301 m := MakeMap(MapOf(table.rt, TypeOf(int(0))))
5302 m.SetMapIndex(v1, ValueOf(1))
5303 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
5304 t.Errorf("constructed structs %#v and %#v have different hashes", i1, i2)
5305 }
5306
5307 v2.FieldByIndex(table.idx).Set(ValueOf("abc"))
5308 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
5309 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
5310 }
5311
5312 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
5313 t.Errorf("constructed structs %v and %v have different hashes", i1, i2)
5314 }
5315 }
5316 }
5317
5318 func TestStructOfDirectIface(t *testing.T) {
5319 {
5320 type T struct{ X [1]*byte }
5321 i1 := Zero(TypeOf(T{})).Interface()
5322 v1 := ValueOf(&i1).Elem()
5323 p1 := v1.InterfaceData()[1]
5324
5325 i2 := Zero(StructOf([]StructField{
5326 {
5327 Name: "X",
5328 Type: ArrayOf(1, TypeOf((*int8)(nil))),
5329 },
5330 })).Interface()
5331 v2 := ValueOf(&i2).Elem()
5332 p2 := v2.InterfaceData()[1]
5333
5334 if p1 != 0 {
5335 t.Errorf("got p1=%v. want=%v", p1, nil)
5336 }
5337
5338 if p2 != 0 {
5339 t.Errorf("got p2=%v. want=%v", p2, nil)
5340 }
5341 }
5342 {
5343 type T struct{ X [0]*byte }
5344 i1 := Zero(TypeOf(T{})).Interface()
5345 v1 := ValueOf(&i1).Elem()
5346 p1 := v1.InterfaceData()[1]
5347
5348 i2 := Zero(StructOf([]StructField{
5349 {
5350 Name: "X",
5351 Type: ArrayOf(0, TypeOf((*int8)(nil))),
5352 },
5353 })).Interface()
5354 v2 := ValueOf(&i2).Elem()
5355 p2 := v2.InterfaceData()[1]
5356
5357 if p1 == 0 {
5358 t.Errorf("got p1=%v. want=not-%v", p1, nil)
5359 }
5360
5361 if p2 == 0 {
5362 t.Errorf("got p2=%v. want=not-%v", p2, nil)
5363 }
5364 }
5365 }
5366
5367 type StructI int
5368
5369 func (i StructI) Get() int { return int(i) }
5370
5371 type StructIPtr int
5372
5373 func (i *StructIPtr) Get() int { return int(*i) }
5374 func (i *StructIPtr) Set(v int) { *(*int)(i) = v }
5375
5376 type SettableStruct struct {
5377 SettableField int
5378 }
5379
5380 func (p *SettableStruct) Set(v int) { p.SettableField = v }
5381
5382 type SettablePointer struct {
5383 SettableField *int
5384 }
5385
5386 func (p *SettablePointer) Set(v int) { *p.SettableField = v }
5387
5388 func TestStructOfWithInterface(t *testing.T) {
5389 const want = 42
5390 type Iface interface {
5391 Get() int
5392 }
5393 type IfaceSet interface {
5394 Set(int)
5395 }
5396 tests := []struct {
5397 name string
5398 typ Type
5399 val Value
5400 impl bool
5401 }{
5402 {
5403 name: "StructI",
5404 typ: TypeOf(StructI(want)),
5405 val: ValueOf(StructI(want)),
5406 impl: true,
5407 },
5408 {
5409 name: "StructI",
5410 typ: PtrTo(TypeOf(StructI(want))),
5411 val: ValueOf(func() interface{} {
5412 v := StructI(want)
5413 return &v
5414 }()),
5415 impl: true,
5416 },
5417 {
5418 name: "StructIPtr",
5419 typ: PtrTo(TypeOf(StructIPtr(want))),
5420 val: ValueOf(func() interface{} {
5421 v := StructIPtr(want)
5422 return &v
5423 }()),
5424 impl: true,
5425 },
5426 {
5427 name: "StructIPtr",
5428 typ: TypeOf(StructIPtr(want)),
5429 val: ValueOf(StructIPtr(want)),
5430 impl: false,
5431 },
5432
5433
5434
5435
5436
5437 }
5438
5439 for i, table := range tests {
5440 for j := 0; j < 2; j++ {
5441 var fields []StructField
5442 if j == 1 {
5443 fields = append(fields, StructField{
5444 Name: "Dummy",
5445 PkgPath: "",
5446 Type: TypeOf(int(0)),
5447 })
5448 }
5449 fields = append(fields, StructField{
5450 Name: table.name,
5451 Anonymous: true,
5452 PkgPath: "",
5453 Type: table.typ,
5454 })
5455
5456
5457
5458
5459
5460
5461
5462 if j == 1 && table.impl {
5463 func() {
5464 defer func() {
5465 if err := recover(); err == nil {
5466 t.Errorf("test-%d-%d did not panic", i, j)
5467 }
5468 }()
5469 _ = StructOf(fields)
5470 }()
5471 continue
5472 }
5473
5474 rt := StructOf(fields)
5475 rv := New(rt).Elem()
5476 rv.Field(j).Set(table.val)
5477
5478 if _, ok := rv.Interface().(Iface); ok != table.impl {
5479 if table.impl {
5480 t.Errorf("test-%d-%d: type=%v fails to implement Iface.\n", i, j, table.typ)
5481 } else {
5482 t.Errorf("test-%d-%d: type=%v should NOT implement Iface\n", i, j, table.typ)
5483 }
5484 continue
5485 }
5486
5487 if !table.impl {
5488 continue
5489 }
5490
5491 v := rv.Interface().(Iface).Get()
5492 if v != want {
5493 t.Errorf("test-%d-%d: x.Get()=%v. want=%v\n", i, j, v, want)
5494 }
5495
5496 fct := rv.MethodByName("Get")
5497 out := fct.Call(nil)
5498 if !DeepEqual(out[0].Interface(), want) {
5499 t.Errorf("test-%d-%d: x.Get()=%v. want=%v\n", i, j, out[0].Interface(), want)
5500 }
5501 }
5502 }
5503
5504
5505 fields := []StructField{{
5506 Name: "StructIPtr",
5507 Anonymous: true,
5508 Type: PtrTo(TypeOf(StructIPtr(want))),
5509 }}
5510 rt := StructOf(fields)
5511 rv := New(rt).Elem()
5512
5513 shouldPanic("", func() {
5514 rv.Interface().(IfaceSet).Set(want)
5515 })
5516
5517
5518
5519 fields = []StructField{{
5520 Name: "SettableStruct",
5521 Anonymous: true,
5522 Type: PtrTo(TypeOf(SettableStruct{})),
5523 }}
5524 rt = StructOf(fields)
5525 rv = New(rt).Elem()
5526
5527 shouldPanic("", func() {
5528 rv.Interface().(IfaceSet).Set(want)
5529 })
5530
5531
5532
5533
5534 fields = []StructField{
5535 {
5536 Name: "SettableStruct",
5537 Anonymous: true,
5538 Type: PtrTo(TypeOf(SettableStruct{})),
5539 },
5540 {
5541 Name: "EmptyStruct",
5542 Anonymous: true,
5543 Type: StructOf(nil),
5544 },
5545 }
5546
5547
5548
5549 shouldPanic("", func() {
5550 StructOf(fields)
5551 })
5552
5553
5554
5555 fields = []StructField{
5556 {
5557 Name: "SettablePointer",
5558 Anonymous: true,
5559 Type: TypeOf(SettablePointer{}),
5560 },
5561 {
5562 Name: "EmptyStruct",
5563 Anonymous: true,
5564 Type: StructOf(nil),
5565 },
5566 }
5567
5568
5569
5570 shouldPanic("", func() {
5571 StructOf(fields)
5572 })
5573 }
5574
5575 func TestStructOfTooManyFields(t *testing.T) {
5576
5577 tt := StructOf([]StructField{
5578 {Name: "Time", Type: TypeOf(time.Time{}), Anonymous: true},
5579 })
5580
5581 if _, present := tt.MethodByName("After"); !present {
5582 t.Errorf("Expected method `After` to be found")
5583 }
5584 }
5585
5586 func TestStructOfDifferentPkgPath(t *testing.T) {
5587 fields := []StructField{
5588 {
5589 Name: "f1",
5590 PkgPath: "p1",
5591 Type: TypeOf(int(0)),
5592 },
5593 {
5594 Name: "f2",
5595 PkgPath: "p2",
5596 Type: TypeOf(int(0)),
5597 },
5598 }
5599 shouldPanic("different PkgPath", func() {
5600 StructOf(fields)
5601 })
5602 }
5603
5604 func TestChanOf(t *testing.T) {
5605
5606 type T string
5607 ct := ChanOf(BothDir, TypeOf(T("")))
5608 v := MakeChan(ct, 2)
5609 runtime.GC()
5610 v.Send(ValueOf(T("hello")))
5611 runtime.GC()
5612 v.Send(ValueOf(T("world")))
5613 runtime.GC()
5614
5615 sv1, _ := v.Recv()
5616 sv2, _ := v.Recv()
5617 s1 := sv1.String()
5618 s2 := sv2.String()
5619 if s1 != "hello" || s2 != "world" {
5620 t.Errorf("constructed chan: have %q, %q, want %q, %q", s1, s2, "hello", "world")
5621 }
5622
5623
5624 type T1 int
5625 checkSameType(t, ChanOf(BothDir, TypeOf(T1(1))), (chan T1)(nil))
5626
5627
5628 var left chan<- chan T
5629 var right chan (<-chan T)
5630 tLeft := ChanOf(SendDir, ChanOf(BothDir, TypeOf(T(""))))
5631 tRight := ChanOf(BothDir, ChanOf(RecvDir, TypeOf(T(""))))
5632 if tLeft != TypeOf(left) {
5633 t.Errorf("chan<-chan: have %s, want %T", tLeft, left)
5634 }
5635 if tRight != TypeOf(right) {
5636 t.Errorf("chan<-chan: have %s, want %T", tRight, right)
5637 }
5638 }
5639
5640 func TestChanOfDir(t *testing.T) {
5641
5642 type T string
5643 crt := ChanOf(RecvDir, TypeOf(T("")))
5644 cst := ChanOf(SendDir, TypeOf(T("")))
5645
5646
5647 type T1 int
5648 checkSameType(t, ChanOf(RecvDir, TypeOf(T1(1))), (<-chan T1)(nil))
5649 checkSameType(t, ChanOf(SendDir, TypeOf(T1(1))), (chan<- T1)(nil))
5650
5651
5652 if crt.ChanDir().String() != "<-chan" {
5653 t.Errorf("chan dir: have %q, want %q", crt.ChanDir().String(), "<-chan")
5654 }
5655 if cst.ChanDir().String() != "chan<-" {
5656 t.Errorf("chan dir: have %q, want %q", cst.ChanDir().String(), "chan<-")
5657 }
5658 }
5659
5660 func TestChanOfGC(t *testing.T) {
5661 done := make(chan bool, 1)
5662 go func() {
5663 select {
5664 case <-done:
5665 case <-time.After(5 * time.Second):
5666 panic("deadlock in TestChanOfGC")
5667 }
5668 }()
5669
5670 defer func() {
5671 done <- true
5672 }()
5673
5674 type T *uintptr
5675 tt := TypeOf(T(nil))
5676 ct := ChanOf(BothDir, tt)
5677
5678
5679
5680
5681 const n = 100
5682 var x []interface{}
5683 for i := 0; i < n; i++ {
5684 v := MakeChan(ct, n)
5685 for j := 0; j < n; j++ {
5686 p := new(uintptr)
5687 *p = uintptr(i*n + j)
5688 v.Send(ValueOf(p).Convert(tt))
5689 }
5690 pv := New(ct)
5691 pv.Elem().Set(v)
5692 x = append(x, pv.Interface())
5693 }
5694 runtime.GC()
5695
5696 for i, xi := range x {
5697 v := ValueOf(xi).Elem()
5698 for j := 0; j < n; j++ {
5699 pv, _ := v.Recv()
5700 k := pv.Elem().Interface()
5701 if k != uintptr(i*n+j) {
5702 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
5703 }
5704 }
5705 }
5706 }
5707
5708 func TestMapOf(t *testing.T) {
5709
5710 type K string
5711 type V float64
5712
5713 v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
5714 runtime.GC()
5715 v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
5716 runtime.GC()
5717
5718 s := fmt.Sprint(v.Interface())
5719 want := "map[a:1]"
5720 if s != want {
5721 t.Errorf("constructed map = %s, want %s", s, want)
5722 }
5723
5724
5725 checkSameType(t, MapOf(TypeOf(V(0)), TypeOf(K(""))), map[V]K(nil))
5726
5727
5728 shouldPanic("invalid key type", func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
5729 }
5730
5731 func TestMapOfGCKeys(t *testing.T) {
5732 type T *uintptr
5733 tt := TypeOf(T(nil))
5734 mt := MapOf(tt, TypeOf(false))
5735
5736
5737
5738
5739 const n = 100
5740 var x []interface{}
5741 for i := 0; i < n; i++ {
5742 v := MakeMap(mt)
5743 for j := 0; j < n; j++ {
5744 p := new(uintptr)
5745 *p = uintptr(i*n + j)
5746 v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
5747 }
5748 pv := New(mt)
5749 pv.Elem().Set(v)
5750 x = append(x, pv.Interface())
5751 }
5752 runtime.GC()
5753
5754 for i, xi := range x {
5755 v := ValueOf(xi).Elem()
5756 var out []int
5757 for _, kv := range v.MapKeys() {
5758 out = append(out, int(kv.Elem().Interface().(uintptr)))
5759 }
5760 sort.Ints(out)
5761 for j, k := range out {
5762 if k != i*n+j {
5763 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
5764 }
5765 }
5766 }
5767 }
5768
5769 func TestMapOfGCValues(t *testing.T) {
5770 type T *uintptr
5771 tt := TypeOf(T(nil))
5772 mt := MapOf(TypeOf(1), tt)
5773
5774
5775
5776
5777 const n = 100
5778 var x []interface{}
5779 for i := 0; i < n; i++ {
5780 v := MakeMap(mt)
5781 for j := 0; j < n; j++ {
5782 p := new(uintptr)
5783 *p = uintptr(i*n + j)
5784 v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
5785 }
5786 pv := New(mt)
5787 pv.Elem().Set(v)
5788 x = append(x, pv.Interface())
5789 }
5790 runtime.GC()
5791
5792 for i, xi := range x {
5793 v := ValueOf(xi).Elem()
5794 for j := 0; j < n; j++ {
5795 k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
5796 if k != uintptr(i*n+j) {
5797 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
5798 }
5799 }
5800 }
5801 }
5802
5803 func TestTypelinksSorted(t *testing.T) {
5804 var last string
5805 for i, n := range TypeLinks() {
5806 if n < last {
5807 t.Errorf("typelinks not sorted: %q [%d] > %q [%d]", last, i-1, n, i)
5808 }
5809 last = n
5810 }
5811 }
5812
5813 func TestFuncOf(t *testing.T) {
5814
5815 type K string
5816 type V float64
5817
5818 fn := func(args []Value) []Value {
5819 if len(args) != 1 {
5820 t.Errorf("args == %v, want exactly one arg", args)
5821 } else if args[0].Type() != TypeOf(K("")) {
5822 t.Errorf("args[0] is type %v, want %v", args[0].Type(), TypeOf(K("")))
5823 } else if args[0].String() != "gopher" {
5824 t.Errorf("args[0] = %q, want %q", args[0].String(), "gopher")
5825 }
5826 return []Value{ValueOf(V(3.14))}
5827 }
5828 v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
5829
5830 outs := v.Call([]Value{ValueOf(K("gopher"))})
5831 if len(outs) != 1 {
5832 t.Fatalf("v.Call returned %v, want exactly one result", outs)
5833 } else if outs[0].Type() != TypeOf(V(0)) {
5834 t.Fatalf("c.Call[0] is type %v, want %v", outs[0].Type(), TypeOf(V(0)))
5835 }
5836 f := outs[0].Float()
5837 if f != 3.14 {
5838 t.Errorf("constructed func returned %f, want %f", f, 3.14)
5839 }
5840
5841
5842 type T1 int
5843 testCases := []struct {
5844 in, out []Type
5845 variadic bool
5846 want interface{}
5847 }{
5848 {in: []Type{TypeOf(T1(0))}, want: (func(T1))(nil)},
5849 {in: []Type{TypeOf(int(0))}, want: (func(int))(nil)},
5850 {in: []Type{SliceOf(TypeOf(int(0)))}, variadic: true, want: (func(...int))(nil)},
5851 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false)}, want: (func(int) bool)(nil)},
5852 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
5853 }
5854 for _, tt := range testCases {
5855 checkSameType(t, FuncOf(tt.in, tt.out, tt.variadic), tt.want)
5856 }
5857
5858
5859 FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
5860 shouldPanic("must be slice", func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
5861 shouldPanic("must be slice", func() { FuncOf(nil, nil, true) })
5862 }
5863
5864 type B1 struct {
5865 X int
5866 Y int
5867 Z int
5868 }
5869
5870 func BenchmarkFieldByName1(b *testing.B) {
5871 t := TypeOf(B1{})
5872 b.RunParallel(func(pb *testing.PB) {
5873 for pb.Next() {
5874 t.FieldByName("Z")
5875 }
5876 })
5877 }
5878
5879 func BenchmarkFieldByName2(b *testing.B) {
5880 t := TypeOf(S3{})
5881 b.RunParallel(func(pb *testing.PB) {
5882 for pb.Next() {
5883 t.FieldByName("B")
5884 }
5885 })
5886 }
5887
5888 type R0 struct {
5889 *R1
5890 *R2
5891 *R3
5892 *R4
5893 }
5894
5895 type R1 struct {
5896 *R5
5897 *R6
5898 *R7
5899 *R8
5900 }
5901
5902 type R2 R1
5903 type R3 R1
5904 type R4 R1
5905
5906 type R5 struct {
5907 *R9
5908 *R10
5909 *R11
5910 *R12
5911 }
5912
5913 type R6 R5
5914 type R7 R5
5915 type R8 R5
5916
5917 type R9 struct {
5918 *R13
5919 *R14
5920 *R15
5921 *R16
5922 }
5923
5924 type R10 R9
5925 type R11 R9
5926 type R12 R9
5927
5928 type R13 struct {
5929 *R17
5930 *R18
5931 *R19
5932 *R20
5933 }
5934
5935 type R14 R13
5936 type R15 R13
5937 type R16 R13
5938
5939 type R17 struct {
5940 *R21
5941 *R22
5942 *R23
5943 *R24
5944 }
5945
5946 type R18 R17
5947 type R19 R17
5948 type R20 R17
5949
5950 type R21 struct {
5951 X int
5952 }
5953
5954 type R22 R21
5955 type R23 R21
5956 type R24 R21
5957
5958 func TestEmbed(t *testing.T) {
5959 typ := TypeOf(R0{})
5960 f, ok := typ.FieldByName("X")
5961 if ok {
5962 t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
5963 }
5964 }
5965
5966 func BenchmarkFieldByName3(b *testing.B) {
5967 t := TypeOf(R0{})
5968 b.RunParallel(func(pb *testing.PB) {
5969 for pb.Next() {
5970 t.FieldByName("X")
5971 }
5972 })
5973 }
5974
5975 type S struct {
5976 i1 int64
5977 i2 int64
5978 }
5979
5980 func BenchmarkInterfaceBig(b *testing.B) {
5981 v := ValueOf(S{})
5982 b.RunParallel(func(pb *testing.PB) {
5983 for pb.Next() {
5984 v.Interface()
5985 }
5986 })
5987 b.StopTimer()
5988 }
5989
5990 func TestAllocsInterfaceBig(t *testing.T) {
5991 if testing.Short() {
5992 t.Skip("skipping malloc count in short mode")
5993 }
5994 v := ValueOf(S{})
5995 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
5996 t.Error("allocs:", allocs)
5997 }
5998 }
5999
6000 func BenchmarkInterfaceSmall(b *testing.B) {
6001 v := ValueOf(int64(0))
6002 b.RunParallel(func(pb *testing.PB) {
6003 for pb.Next() {
6004 v.Interface()
6005 }
6006 })
6007 }
6008
6009 func TestAllocsInterfaceSmall(t *testing.T) {
6010 if testing.Short() {
6011 t.Skip("skipping malloc count in short mode")
6012 }
6013 v := ValueOf(int64(0))
6014 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
6015 t.Error("allocs:", allocs)
6016 }
6017 }
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062 type exhaustive struct {
6063 r *rand.Rand
6064 pos int
6065 last []choice
6066 }
6067
6068 type choice struct {
6069 off int
6070 n int
6071 max int
6072 }
6073
6074 func (x *exhaustive) Next() bool {
6075 if x.r == nil {
6076 x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
6077 }
6078 x.pos = 0
6079 if x.last == nil {
6080 x.last = []choice{}
6081 return true
6082 }
6083 for i := len(x.last) - 1; i >= 0; i-- {
6084 c := &x.last[i]
6085 if c.n+1 < c.max {
6086 c.n++
6087 x.last = x.last[:i+1]
6088 return true
6089 }
6090 }
6091 return false
6092 }
6093
6094 func (x *exhaustive) Choose(max int) int {
6095 if x.pos >= len(x.last) {
6096 x.last = append(x.last, choice{x.r.Intn(max), 0, max})
6097 }
6098 c := &x.last[x.pos]
6099 x.pos++
6100 if c.max != max {
6101 panic("inconsistent use of exhaustive tester")
6102 }
6103 return (c.n + c.off) % max
6104 }
6105
6106 func (x *exhaustive) Maybe() bool {
6107 return x.Choose(2) == 1
6108 }
6109
6110 func GCFunc(args []Value) []Value {
6111 runtime.GC()
6112 return []Value{}
6113 }
6114
6115 func TestReflectFuncTraceback(t *testing.T) {
6116 f := MakeFunc(TypeOf(func() {}), GCFunc)
6117 f.Call([]Value{})
6118 }
6119
6120 func TestReflectMethodTraceback(t *testing.T) {
6121 p := Point{3, 4}
6122 m := ValueOf(p).MethodByName("GCMethod")
6123 i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
6124 if i != 8 {
6125 t.Errorf("Call returned %d; want 8", i)
6126 }
6127 }
6128
6129 func TestSmallZero(t *testing.T) {
6130 type T [10]byte
6131 typ := TypeOf(T{})
6132 if allocs := testing.AllocsPerRun(100, func() { Zero(typ) }); allocs > 0 {
6133 t.Errorf("Creating small zero values caused %f allocs, want 0", allocs)
6134 }
6135 }
6136
6137 func TestBigZero(t *testing.T) {
6138 const size = 1 << 10
6139 var v [size]byte
6140 z := Zero(ValueOf(v).Type()).Interface().([size]byte)
6141 for i := 0; i < size; i++ {
6142 if z[i] != 0 {
6143 t.Fatalf("Zero object not all zero, index %d", i)
6144 }
6145 }
6146 }
6147
6148 func TestZeroSet(t *testing.T) {
6149 type T [16]byte
6150 type S struct {
6151 a uint64
6152 T T
6153 b uint64
6154 }
6155 v := S{
6156 a: 0xaaaaaaaaaaaaaaaa,
6157 T: T{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9},
6158 b: 0xbbbbbbbbbbbbbbbb,
6159 }
6160 ValueOf(&v).Elem().Field(1).Set(Zero(TypeOf(T{})))
6161 if v != (S{
6162 a: 0xaaaaaaaaaaaaaaaa,
6163 b: 0xbbbbbbbbbbbbbbbb,
6164 }) {
6165 t.Fatalf("Setting a field to a Zero value didn't work")
6166 }
6167 }
6168
6169 func TestFieldByIndexNil(t *testing.T) {
6170 type P struct {
6171 F int
6172 }
6173 type T struct {
6174 *P
6175 }
6176 v := ValueOf(T{})
6177
6178 v.FieldByName("P")
6179
6180 defer func() {
6181 if err := recover(); err == nil {
6182 t.Fatalf("no error")
6183 } else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
6184 t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
6185 }
6186 }()
6187 v.FieldByName("F")
6188
6189 t.Fatalf("did not panic")
6190 }
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233 type Outer struct {
6234 *Inner
6235 R io.Reader
6236 }
6237
6238 type Inner struct {
6239 X *Outer
6240 P1 uintptr
6241 P2 uintptr
6242 }
6243
6244 func (pi *Inner) M() {
6245
6246
6247
6248 pi.X.Inner = nil
6249
6250
6251
6252
6253
6254
6255 pi.P1 = 1
6256 pi.P2 = uintptr(unsafe.Pointer(pi))
6257 }
6258
6259 func TestCallMethodJump(t *testing.T) {
6260
6261
6262
6263 *CallGC = true
6264
6265 p := &Outer{Inner: new(Inner)}
6266 p.Inner.X = p
6267 ValueOf(p).Method(0).Call(nil)
6268
6269
6270 *CallGC = false
6271 }
6272
6273 func TestCallArgLive(t *testing.T) {
6274 type T struct{ X, Y *string }
6275
6276 F := func(t T) { *t.X = "ok" }
6277
6278
6279
6280 *CallGC = true
6281
6282 x := new(string)
6283 runtime.SetFinalizer(x, func(p *string) {
6284 if *p != "ok" {
6285 t.Errorf("x dead prematurely")
6286 }
6287 })
6288 v := T{x, nil}
6289
6290 ValueOf(F).Call([]Value{ValueOf(v)})
6291
6292
6293 *CallGC = false
6294 }
6295
6296 func TestMakeFuncStackCopy(t *testing.T) {
6297 target := func(in []Value) []Value {
6298 runtime.GC()
6299 useStack(16)
6300 return []Value{ValueOf(9)}
6301 }
6302
6303 var concrete func(*int, int) int
6304 fn := MakeFunc(ValueOf(concrete).Type(), target)
6305 ValueOf(&concrete).Elem().Set(fn)
6306 x := concrete(nil, 7)
6307 if x != 9 {
6308 t.Errorf("have %#q want 9", x)
6309 }
6310 }
6311
6312
6313 func useStack(n int) {
6314 if n == 0 {
6315 return
6316 }
6317 var b [1024]byte
6318 useStack(n - 1 + int(b[99]))
6319 }
6320
6321 type Impl struct{}
6322
6323 func (Impl) F() {}
6324
6325 func TestValueString(t *testing.T) {
6326 rv := ValueOf(Impl{})
6327 if rv.String() != "<reflect_test.Impl Value>" {
6328 t.Errorf("ValueOf(Impl{}).String() = %q, want %q", rv.String(), "<reflect_test.Impl Value>")
6329 }
6330
6331 method := rv.Method(0)
6332 if method.String() != "<func() Value>" {
6333 t.Errorf("ValueOf(Impl{}).Method(0).String() = %q, want %q", method.String(), "<func() Value>")
6334 }
6335 }
6336
6337 func TestInvalid(t *testing.T) {
6338
6339 type T struct{ v interface{} }
6340
6341 v := ValueOf(T{}).Field(0)
6342 if v.IsValid() != true || v.Kind() != Interface {
6343 t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
6344 }
6345 v = v.Elem()
6346 if v.IsValid() != false || v.Kind() != Invalid {
6347 t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
6348 }
6349 }
6350
6351
6352 func TestLargeGCProg(t *testing.T) {
6353 fv := ValueOf(func([256]*byte) {})
6354 fv.Call([]Value{ValueOf([256]*byte{})})
6355 }
6356
6357 func fieldIndexRecover(t Type, i int) (recovered interface{}) {
6358 defer func() {
6359 recovered = recover()
6360 }()
6361
6362 t.Field(i)
6363 return
6364 }
6365
6366
6367 func TestTypeFieldOutOfRangePanic(t *testing.T) {
6368 typ := TypeOf(struct{ X int }{10})
6369 testIndices := [...]struct {
6370 i int
6371 mustPanic bool
6372 }{
6373 0: {-2, true},
6374 1: {0, false},
6375 2: {1, true},
6376 3: {1 << 10, true},
6377 }
6378 for i, tt := range testIndices {
6379 recoveredErr := fieldIndexRecover(typ, tt.i)
6380 if tt.mustPanic {
6381 if recoveredErr == nil {
6382 t.Errorf("#%d: fieldIndex %d expected to panic", i, tt.i)
6383 }
6384 } else {
6385 if recoveredErr != nil {
6386 t.Errorf("#%d: got err=%v, expected no panic", i, recoveredErr)
6387 }
6388 }
6389 }
6390 }
6391
6392
6393 func TestCallGC(t *testing.T) {
6394 f := func(a, b, c, d, e string) {
6395 }
6396 g := func(in []Value) []Value {
6397 runtime.GC()
6398 return nil
6399 }
6400 typ := ValueOf(f).Type()
6401 f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string))
6402 f2("four", "five5", "six666", "seven77", "eight888")
6403 }
6404
6405
6406 func TestKeepFuncLive(t *testing.T) {
6407
6408
6409 typ := TypeOf(func(i int) {})
6410 var f, g func(in []Value) []Value
6411 f = func(in []Value) []Value {
6412 clobber()
6413 i := int(in[0].Int())
6414 if i > 0 {
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425 MakeFunc(typ, g).Interface().(func(i int))(i - 1)
6426 }
6427 return nil
6428 }
6429 g = func(in []Value) []Value {
6430 clobber()
6431 i := int(in[0].Int())
6432 MakeFunc(typ, f).Interface().(func(i int))(i)
6433 return nil
6434 }
6435 MakeFunc(typ, f).Call([]Value{ValueOf(10)})
6436 }
6437
6438 type UnExportedFirst int
6439
6440 func (i UnExportedFirst) ΦExported() {}
6441 func (i UnExportedFirst) unexported() {}
6442
6443
6444 func TestMethodByNameUnExportedFirst(t *testing.T) {
6445 defer func() {
6446 if recover() != nil {
6447 t.Errorf("should not panic")
6448 }
6449 }()
6450 typ := TypeOf(UnExportedFirst(0))
6451 m, _ := typ.MethodByName("ΦExported")
6452 if m.Name != "ΦExported" {
6453 t.Errorf("got %s, expected ΦExported", m.Name)
6454 }
6455 }
6456
6457
6458 type KeepMethodLive struct{}
6459
6460 func (k KeepMethodLive) Method1(i int) {
6461 clobber()
6462 if i > 0 {
6463 ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1)
6464 }
6465 }
6466
6467 func (k KeepMethodLive) Method2(i int) {
6468 clobber()
6469 ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i)
6470 }
6471
6472 func TestKeepMethodLive(t *testing.T) {
6473
6474
6475 KeepMethodLive{}.Method1(10)
6476 }
6477
6478
6479 func clobber() {
6480 runtime.GC()
6481 for i := 1; i < 32; i++ {
6482 for j := 0; j < 10; j++ {
6483 obj := make([]*byte, i)
6484 sink = obj
6485 }
6486 }
6487 runtime.GC()
6488 }
6489
6490 func TestFuncLayout(t *testing.T) {
6491 align := func(x uintptr) uintptr {
6492 return (x + PtrSize - 1) &^ (PtrSize - 1)
6493 }
6494 var r []byte
6495 if PtrSize == 4 {
6496 r = []byte{0, 0, 0, 1}
6497 } else {
6498 r = []byte{0, 0, 1}
6499 }
6500
6501 type S struct {
6502 a, b uintptr
6503 c, d *byte
6504 }
6505
6506 type test struct {
6507 rcvr, typ Type
6508 size, argsize, retOffset uintptr
6509 stack, gc, inRegs, outRegs []byte
6510 intRegs, floatRegs int
6511 floatRegSize uintptr
6512 }
6513 tests := []test{
6514 {
6515 typ: ValueOf(func(a, b string) string { return "" }).Type(),
6516 size: 6 * PtrSize,
6517 argsize: 4 * PtrSize,
6518 retOffset: 4 * PtrSize,
6519 stack: []byte{1, 0, 1, 0, 1},
6520 gc: []byte{1, 0, 1, 0, 1},
6521 },
6522 {
6523 typ: ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
6524 size: align(align(3*4) + PtrSize + 2),
6525 argsize: align(3*4) + PtrSize + 2,
6526 retOffset: align(align(3*4) + PtrSize + 2),
6527 stack: r,
6528 gc: r,
6529 },
6530 {
6531 typ: ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
6532 size: 4 * PtrSize,
6533 argsize: 4 * PtrSize,
6534 retOffset: 4 * PtrSize,
6535 stack: []byte{1, 0, 1, 1},
6536 gc: []byte{1, 0, 1, 1},
6537 },
6538 {
6539 typ: ValueOf(func(a S) {}).Type(),
6540 size: 4 * PtrSize,
6541 argsize: 4 * PtrSize,
6542 retOffset: 4 * PtrSize,
6543 stack: []byte{0, 0, 1, 1},
6544 gc: []byte{0, 0, 1, 1},
6545 },
6546 {
6547 rcvr: ValueOf((*byte)(nil)).Type(),
6548 typ: ValueOf(func(a uintptr, b *int) {}).Type(),
6549 size: 3 * PtrSize,
6550 argsize: 3 * PtrSize,
6551 retOffset: 3 * PtrSize,
6552 stack: []byte{1, 0, 1},
6553 gc: []byte{1, 0, 1},
6554 },
6555 {
6556 typ: ValueOf(func(a uintptr) {}).Type(),
6557 size: PtrSize,
6558 argsize: PtrSize,
6559 retOffset: PtrSize,
6560 stack: []byte{},
6561 gc: []byte{},
6562 },
6563 {
6564 typ: ValueOf(func() uintptr { return 0 }).Type(),
6565 size: PtrSize,
6566 argsize: 0,
6567 retOffset: 0,
6568 stack: []byte{},
6569 gc: []byte{},
6570 },
6571 {
6572 rcvr: ValueOf(uintptr(0)).Type(),
6573 typ: ValueOf(func(a uintptr) {}).Type(),
6574 size: 2 * PtrSize,
6575 argsize: 2 * PtrSize,
6576 retOffset: 2 * PtrSize,
6577 stack: []byte{1},
6578 gc: []byte{1},
6579
6580
6581
6582 },
6583
6584 }
6585 for _, lt := range tests {
6586 name := lt.typ.String()
6587 if lt.rcvr != nil {
6588 name = lt.rcvr.String() + "." + name
6589 }
6590 t.Run(name, func(t *testing.T) {
6591 defer SetArgRegs(SetArgRegs(lt.intRegs, lt.floatRegs, lt.floatRegSize))
6592
6593 typ, argsize, retOffset, stack, gc, inRegs, outRegs, ptrs := FuncLayout(lt.typ, lt.rcvr)
6594 if typ.Size() != lt.size {
6595 t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.typ, lt.rcvr, typ.Size(), lt.size)
6596 }
6597 if argsize != lt.argsize {
6598 t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.typ, lt.rcvr, argsize, lt.argsize)
6599 }
6600 if retOffset != lt.retOffset {
6601 t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.typ, lt.rcvr, retOffset, lt.retOffset)
6602 }
6603 if !bytes.Equal(stack, lt.stack) {
6604 t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.typ, lt.rcvr, stack, lt.stack)
6605 }
6606 if !bytes.Equal(gc, lt.gc) {
6607 t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.typ, lt.rcvr, gc, lt.gc)
6608 }
6609 if !bytes.Equal(inRegs, lt.inRegs) {
6610 t.Errorf("funcLayout(%v, %v).inRegs=%v, want %v", lt.typ, lt.rcvr, inRegs, lt.inRegs)
6611 }
6612 if !bytes.Equal(outRegs, lt.outRegs) {
6613 t.Errorf("funcLayout(%v, %v).outRegs=%v, want %v", lt.typ, lt.rcvr, outRegs, lt.outRegs)
6614 }
6615 if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
6616 t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.typ, lt.rcvr, ptrs, !ptrs)
6617 }
6618 })
6619 }
6620 }
6621
6622 func verifyGCBits(t *testing.T, typ Type, bits []byte) {
6623 heapBits := GCBits(New(typ).Interface())
6624 if !bytes.Equal(heapBits, bits) {
6625 _, _, line, _ := runtime.Caller(1)
6626 t.Errorf("line %d: heapBits incorrect for %v\nhave %v\nwant %v", line, typ, heapBits, bits)
6627 }
6628 }
6629
6630 func verifyGCBitsSlice(t *testing.T, typ Type, cap int, bits []byte) {
6631
6632
6633
6634
6635 val := MakeSlice(typ, 0, cap)
6636 data := NewAt(ArrayOf(cap, typ), unsafe.Pointer(val.Pointer()))
6637 heapBits := GCBits(data.Interface())
6638
6639
6640 bits = rep(cap, bits)
6641 for len(bits) > 0 && bits[len(bits)-1] == 0 {
6642 bits = bits[:len(bits)-1]
6643 }
6644 if !bytes.Equal(heapBits, bits) {
6645 t.Errorf("heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", typ, cap, heapBits, bits)
6646 }
6647 }
6648
6649 func TestGCBits(t *testing.T) {
6650 verifyGCBits(t, TypeOf((*byte)(nil)), []byte{1})
6651
6652
6653
6654
6655 type Xscalar struct{ x uintptr }
6656 type Xptr struct{ x *byte }
6657 type Xptrscalar struct {
6658 *byte
6659 uintptr
6660 }
6661 type Xscalarptr struct {
6662 uintptr
6663 *byte
6664 }
6665 type Xbigptrscalar struct {
6666 _ [100]*byte
6667 _ [100]uintptr
6668 }
6669
6670 var Tscalar, Tint64, Tptr, Tscalarptr, Tptrscalar, Tbigptrscalar Type
6671 {
6672
6673
6674
6675
6676
6677
6678
6679 type Scalar struct{ x uintptr }
6680 type Ptr struct{ x *byte }
6681 type Ptrscalar struct {
6682 *byte
6683 uintptr
6684 }
6685 type Scalarptr struct {
6686 uintptr
6687 *byte
6688 }
6689 type Bigptrscalar struct {
6690 _ [100]*byte
6691 _ [100]uintptr
6692 }
6693 type Int64 int64
6694 Tscalar = TypeOf(Scalar{})
6695 Tint64 = TypeOf(Int64(0))
6696 Tptr = TypeOf(Ptr{})
6697 Tscalarptr = TypeOf(Scalarptr{})
6698 Tptrscalar = TypeOf(Ptrscalar{})
6699 Tbigptrscalar = TypeOf(Bigptrscalar{})
6700 }
6701
6702 empty := []byte{}
6703
6704 verifyGCBits(t, TypeOf(Xscalar{}), empty)
6705 verifyGCBits(t, Tscalar, empty)
6706 verifyGCBits(t, TypeOf(Xptr{}), lit(1))
6707 verifyGCBits(t, Tptr, lit(1))
6708 verifyGCBits(t, TypeOf(Xscalarptr{}), lit(0, 1))
6709 verifyGCBits(t, Tscalarptr, lit(0, 1))
6710 verifyGCBits(t, TypeOf(Xptrscalar{}), lit(1))
6711 verifyGCBits(t, Tptrscalar, lit(1))
6712
6713 verifyGCBits(t, TypeOf([0]Xptr{}), empty)
6714 verifyGCBits(t, ArrayOf(0, Tptr), empty)
6715 verifyGCBits(t, TypeOf([1]Xptrscalar{}), lit(1))
6716 verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
6717 verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
6718 verifyGCBits(t, ArrayOf(2, Tscalar), empty)
6719 verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
6720 verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
6721 verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
6722 verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
6723 verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
6724 verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
6725 verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
6726 verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
6727 verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
6728 verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
6729 verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
6730 verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
6731 verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
6732 verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
6733 verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
6734 verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
6735 verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
6736 verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
6737 verifyGCBits(t, TypeOf([4]Xbigptrscalar{}), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
6738 verifyGCBits(t, ArrayOf(4, Tbigptrscalar), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
6739
6740 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 0, empty)
6741 verifyGCBitsSlice(t, SliceOf(Tptr), 0, empty)
6742 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 1, lit(1))
6743 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 1, lit(1))
6744 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 2, lit(0))
6745 verifyGCBitsSlice(t, SliceOf(Tscalar), 2, lit(0))
6746 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 10000, lit(0))
6747 verifyGCBitsSlice(t, SliceOf(Tscalar), 10000, lit(0))
6748 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 2, lit(1))
6749 verifyGCBitsSlice(t, SliceOf(Tptr), 2, lit(1))
6750 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 10000, lit(1))
6751 verifyGCBitsSlice(t, SliceOf(Tptr), 10000, lit(1))
6752 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 2, lit(0, 1))
6753 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 2, lit(0, 1))
6754 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 10000, lit(0, 1))
6755 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 10000, lit(0, 1))
6756 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 2, lit(1, 0))
6757 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 2, lit(1, 0))
6758 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 10000, lit(1, 0))
6759 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 10000, lit(1, 0))
6760 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 1, rep(10000, lit(1, 0)))
6761 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 1, rep(10000, lit(1, 0)))
6762 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 2, rep(10000, lit(1, 0)))
6763 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 2, rep(10000, lit(1, 0)))
6764 verifyGCBitsSlice(t, TypeOf([]Xbigptrscalar{}), 4, join(rep(100, lit(1)), rep(100, lit(0))))
6765 verifyGCBitsSlice(t, SliceOf(Tbigptrscalar), 4, join(rep(100, lit(1)), rep(100, lit(0))))
6766
6767 verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
6768 verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
6769
6770 verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
6771 verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
6772
6773 verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
6774 verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
6775
6776 verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
6777 verifyGCBits(t, PtrTo(ArrayOf(10000, Tscalar)), lit(1))
6778
6779 verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
6780 verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
6781
6782 hdr := make([]byte, 8/PtrSize)
6783
6784 verifyMapBucket := func(t *testing.T, k, e Type, m interface{}, want []byte) {
6785 verifyGCBits(t, MapBucketOf(k, e), want)
6786 verifyGCBits(t, CachedBucketOf(TypeOf(m)), want)
6787 }
6788 verifyMapBucket(t,
6789 Tscalar, Tptr,
6790 map[Xscalar]Xptr(nil),
6791 join(hdr, rep(8, lit(0)), rep(8, lit(1)), lit(1)))
6792 verifyMapBucket(t,
6793 Tscalarptr, Tptr,
6794 map[Xscalarptr]Xptr(nil),
6795 join(hdr, rep(8, lit(0, 1)), rep(8, lit(1)), lit(1)))
6796 verifyMapBucket(t, Tint64, Tptr,
6797 map[int64]Xptr(nil),
6798 join(hdr, rep(8, rep(8/PtrSize, lit(0))), rep(8, lit(1)), lit(1)))
6799 verifyMapBucket(t,
6800 Tscalar, Tscalar,
6801 map[Xscalar]Xscalar(nil),
6802 empty)
6803 verifyMapBucket(t,
6804 ArrayOf(2, Tscalarptr), ArrayOf(3, Tptrscalar),
6805 map[[2]Xscalarptr][3]Xptrscalar(nil),
6806 join(hdr, rep(8*2, lit(0, 1)), rep(8*3, lit(1, 0)), lit(1)))
6807 verifyMapBucket(t,
6808 ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
6809 map[[64 / PtrSize]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
6810 join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
6811 verifyMapBucket(t,
6812 ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
6813 map[[64/PtrSize + 1]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
6814 join(hdr, rep(8, lit(1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
6815 verifyMapBucket(t,
6816 ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
6817 map[[64 / PtrSize]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
6818 join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8, lit(1)), lit(1)))
6819 verifyMapBucket(t,
6820 ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
6821 map[[64/PtrSize + 1]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
6822 join(hdr, rep(8, lit(1)), rep(8, lit(1)), lit(1)))
6823 }
6824
6825 func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) }
6826 func join(b ...[]byte) []byte { return bytes.Join(b, nil) }
6827 func lit(x ...byte) []byte { return x }
6828
6829 func TestTypeOfTypeOf(t *testing.T) {
6830
6831
6832
6833 check := func(name string, typ Type) {
6834 if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
6835 t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
6836 }
6837 }
6838
6839 type T struct{ int }
6840 check("TypeOf", TypeOf(T{}))
6841
6842 check("ArrayOf", ArrayOf(10, TypeOf(T{})))
6843 check("ChanOf", ChanOf(BothDir, TypeOf(T{})))
6844 check("FuncOf", FuncOf([]Type{TypeOf(T{})}, nil, false))
6845 check("MapOf", MapOf(TypeOf(T{}), TypeOf(T{})))
6846 check("PtrTo", PtrTo(TypeOf(T{})))
6847 check("SliceOf", SliceOf(TypeOf(T{})))
6848 }
6849
6850 type XM struct{ _ bool }
6851
6852 func (*XM) String() string { return "" }
6853
6854 func TestPtrToMethods(t *testing.T) {
6855 var y struct{ XM }
6856 yp := New(TypeOf(y)).Interface()
6857 _, ok := yp.(fmt.Stringer)
6858 if !ok {
6859 t.Fatal("does not implement Stringer, but should")
6860 }
6861 }
6862
6863 func TestMapAlloc(t *testing.T) {
6864 m := ValueOf(make(map[int]int, 10))
6865 k := ValueOf(5)
6866 v := ValueOf(7)
6867 allocs := testing.AllocsPerRun(100, func() {
6868 m.SetMapIndex(k, v)
6869 })
6870 if allocs > 0.5 {
6871 t.Errorf("allocs per map assignment: want 0 got %f", allocs)
6872 }
6873
6874 const size = 1000
6875 tmp := 0
6876 val := ValueOf(&tmp).Elem()
6877 allocs = testing.AllocsPerRun(100, func() {
6878 mv := MakeMapWithSize(TypeOf(map[int]int{}), size)
6879
6880 for i := 0; i < size/2; i++ {
6881 val.SetInt(int64(i))
6882 mv.SetMapIndex(val, val)
6883 }
6884 })
6885 if allocs > 10 {
6886 t.Errorf("allocs per map assignment: want at most 10 got %f", allocs)
6887 }
6888
6889
6890
6891 }
6892
6893 func TestChanAlloc(t *testing.T) {
6894
6895
6896 c := ValueOf(make(chan *int, 1))
6897 v := ValueOf(new(int))
6898 allocs := testing.AllocsPerRun(100, func() {
6899 c.Send(v)
6900 _, _ = c.Recv()
6901 })
6902 if allocs < 0.5 || allocs > 1.5 {
6903 t.Errorf("allocs per chan send/recv: want 1 got %f", allocs)
6904 }
6905
6906
6907
6908 }
6909
6910 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
6911
6912 type nameTest struct {
6913 v interface{}
6914 want string
6915 }
6916
6917 var nameTests = []nameTest{
6918 {(*int32)(nil), "int32"},
6919 {(*D1)(nil), "D1"},
6920 {(*[]D1)(nil), ""},
6921 {(*chan D1)(nil), ""},
6922 {(*func() D1)(nil), ""},
6923 {(*<-chan D1)(nil), ""},
6924 {(*chan<- D1)(nil), ""},
6925 {(*interface{})(nil), ""},
6926 {(*interface {
6927 F()
6928 })(nil), ""},
6929 {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
6930 }
6931
6932 func TestNames(t *testing.T) {
6933 for _, test := range nameTests {
6934 typ := TypeOf(test.v).Elem()
6935 if got := typ.Name(); got != test.want {
6936 t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
6937 }
6938 }
6939 }
6940
6941 func TestExported(t *testing.T) {
6942 type ΦExported struct{}
6943 type φUnexported struct{}
6944 type BigP *big
6945 type P int
6946 type p *P
6947 type P2 p
6948 type p3 p
6949
6950 type exportTest struct {
6951 v interface{}
6952 want bool
6953 }
6954 exportTests := []exportTest{
6955 {D1{}, true},
6956 {(*D1)(nil), true},
6957 {big{}, false},
6958 {(*big)(nil), false},
6959 {(BigP)(nil), true},
6960 {(*BigP)(nil), true},
6961 {ΦExported{}, true},
6962 {φUnexported{}, false},
6963 {P(0), true},
6964 {(p)(nil), false},
6965 {(P2)(nil), true},
6966 {(p3)(nil), false},
6967 }
6968
6969 for i, test := range exportTests {
6970 typ := TypeOf(test.v)
6971 if got := IsExported(typ); got != test.want {
6972 t.Errorf("%d: %s exported=%v, want %v", i, typ.Name(), got, test.want)
6973 }
6974 }
6975 }
6976
6977 func TestTypeStrings(t *testing.T) {
6978 type stringTest struct {
6979 typ Type
6980 want string
6981 }
6982 stringTests := []stringTest{
6983 {TypeOf(func(int) {}), "func(int)"},
6984 {FuncOf([]Type{TypeOf(int(0))}, nil, false), "func(int)"},
6985 {TypeOf(XM{}), "reflect_test.XM"},
6986 {TypeOf(new(XM)), "*reflect_test.XM"},
6987 {TypeOf(new(XM).String), "func() string"},
6988 {TypeOf(new(XM)).Method(0).Type, "func(*reflect_test.XM) string"},
6989 {ChanOf(3, TypeOf(XM{})), "chan reflect_test.XM"},
6990 {MapOf(TypeOf(int(0)), TypeOf(XM{})), "map[int]reflect_test.XM"},
6991 {ArrayOf(3, TypeOf(XM{})), "[3]reflect_test.XM"},
6992 {ArrayOf(3, TypeOf(struct{}{})), "[3]struct {}"},
6993 }
6994
6995 for i, test := range stringTests {
6996 if got, want := test.typ.String(), test.want; got != want {
6997 t.Errorf("type %d String()=%q, want %q", i, got, want)
6998 }
6999 }
7000 }
7001
7002 func TestOffsetLock(t *testing.T) {
7003 var wg sync.WaitGroup
7004 for i := 0; i < 4; i++ {
7005 i := i
7006 wg.Add(1)
7007 go func() {
7008 for j := 0; j < 50; j++ {
7009 ResolveReflectName(fmt.Sprintf("OffsetLockName:%d:%d", i, j))
7010 }
7011 wg.Done()
7012 }()
7013 }
7014 wg.Wait()
7015 }
7016
7017 func BenchmarkNew(b *testing.B) {
7018 v := TypeOf(XM{})
7019 b.RunParallel(func(pb *testing.PB) {
7020 for pb.Next() {
7021 New(v)
7022 }
7023 })
7024 }
7025
7026 func TestSwapper(t *testing.T) {
7027 type I int
7028 var a, b, c I
7029 type pair struct {
7030 x, y int
7031 }
7032 type pairPtr struct {
7033 x, y int
7034 p *I
7035 }
7036 type S string
7037
7038 tests := []struct {
7039 in interface{}
7040 i, j int
7041 want interface{}
7042 }{
7043 {
7044 in: []int{1, 20, 300},
7045 i: 0,
7046 j: 2,
7047 want: []int{300, 20, 1},
7048 },
7049 {
7050 in: []uintptr{1, 20, 300},
7051 i: 0,
7052 j: 2,
7053 want: []uintptr{300, 20, 1},
7054 },
7055 {
7056 in: []int16{1, 20, 300},
7057 i: 0,
7058 j: 2,
7059 want: []int16{300, 20, 1},
7060 },
7061 {
7062 in: []int8{1, 20, 100},
7063 i: 0,
7064 j: 2,
7065 want: []int8{100, 20, 1},
7066 },
7067 {
7068 in: []*I{&a, &b, &c},
7069 i: 0,
7070 j: 2,
7071 want: []*I{&c, &b, &a},
7072 },
7073 {
7074 in: []string{"eric", "sergey", "larry"},
7075 i: 0,
7076 j: 2,
7077 want: []string{"larry", "sergey", "eric"},
7078 },
7079 {
7080 in: []S{"eric", "sergey", "larry"},
7081 i: 0,
7082 j: 2,
7083 want: []S{"larry", "sergey", "eric"},
7084 },
7085 {
7086 in: []pair{{1, 2}, {3, 4}, {5, 6}},
7087 i: 0,
7088 j: 2,
7089 want: []pair{{5, 6}, {3, 4}, {1, 2}},
7090 },
7091 {
7092 in: []pairPtr{{1, 2, &a}, {3, 4, &b}, {5, 6, &c}},
7093 i: 0,
7094 j: 2,
7095 want: []pairPtr{{5, 6, &c}, {3, 4, &b}, {1, 2, &a}},
7096 },
7097 }
7098
7099 for i, tt := range tests {
7100 inStr := fmt.Sprint(tt.in)
7101 Swapper(tt.in)(tt.i, tt.j)
7102 if !DeepEqual(tt.in, tt.want) {
7103 t.Errorf("%d. swapping %v and %v of %v = %v; want %v", i, tt.i, tt.j, inStr, tt.in, tt.want)
7104 }
7105 }
7106 }
7107
7108
7109
7110
7111
7112
7113 func TestUnaddressableField(t *testing.T) {
7114 var b Buffer
7115 var localBuffer struct {
7116 buf []byte
7117 }
7118 lv := ValueOf(&localBuffer).Elem()
7119 rv := ValueOf(b)
7120 shouldPanic("Set", func() {
7121 lv.Set(rv)
7122 })
7123 }
7124
7125 type Tint int
7126
7127 type Tint2 = Tint
7128
7129 type Talias1 struct {
7130 byte
7131 uint8
7132 int
7133 int32
7134 rune
7135 }
7136
7137 type Talias2 struct {
7138 Tint
7139 Tint2
7140 }
7141
7142 func TestAliasNames(t *testing.T) {
7143 t1 := Talias1{byte: 1, uint8: 2, int: 3, int32: 4, rune: 5}
7144 out := fmt.Sprintf("%#v", t1)
7145 want := "reflect_test.Talias1{byte:0x1, uint8:0x2, int:3, int32:4, rune:5}"
7146 if out != want {
7147 t.Errorf("Talias1 print:\nhave: %s\nwant: %s", out, want)
7148 }
7149
7150 t2 := Talias2{Tint: 1, Tint2: 2}
7151 out = fmt.Sprintf("%#v", t2)
7152 want = "reflect_test.Talias2{Tint:1, Tint2:2}"
7153 if out != want {
7154 t.Errorf("Talias2 print:\nhave: %s\nwant: %s", out, want)
7155 }
7156 }
7157
7158 func TestIssue22031(t *testing.T) {
7159 type s []struct{ C int }
7160
7161 type t1 struct{ s }
7162 type t2 struct{ f s }
7163
7164 tests := []Value{
7165 ValueOf(t1{s{{}}}).Field(0).Index(0).Field(0),
7166 ValueOf(t2{s{{}}}).Field(0).Index(0).Field(0),
7167 }
7168
7169 for i, test := range tests {
7170 if test.CanSet() {
7171 t.Errorf("%d: CanSet: got true, want false", i)
7172 }
7173 }
7174 }
7175
7176 type NonExportedFirst int
7177
7178 func (i NonExportedFirst) ΦExported() {}
7179 func (i NonExportedFirst) nonexported() int { panic("wrong") }
7180
7181 func TestIssue22073(t *testing.T) {
7182 m := ValueOf(NonExportedFirst(0)).Method(0)
7183
7184 if got := m.Type().NumOut(); got != 0 {
7185 t.Errorf("NumOut: got %v, want 0", got)
7186 }
7187
7188
7189 m.Call(nil)
7190 }
7191
7192 func TestMapIterNonEmptyMap(t *testing.T) {
7193 m := map[string]int{"one": 1, "two": 2, "three": 3}
7194 iter := ValueOf(m).MapRange()
7195 if got, want := iterateToString(iter), `[one: 1, three: 3, two: 2]`; got != want {
7196 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7197 }
7198 }
7199
7200 func TestMapIterNilMap(t *testing.T) {
7201 var m map[string]int
7202 iter := ValueOf(m).MapRange()
7203 if got, want := iterateToString(iter), `[]`; got != want {
7204 t.Errorf("non-empty result iteratoring nil map: %s", got)
7205 }
7206 }
7207
7208 func TestMapIterSafety(t *testing.T) {
7209
7210 func() {
7211 defer func() { recover() }()
7212 new(MapIter).Key()
7213 t.Fatal("Key did not panic")
7214 }()
7215 func() {
7216 defer func() { recover() }()
7217 new(MapIter).Value()
7218 t.Fatal("Value did not panic")
7219 }()
7220 func() {
7221 defer func() { recover() }()
7222 new(MapIter).Next()
7223 t.Fatal("Next did not panic")
7224 }()
7225
7226
7227
7228 var m map[string]int
7229 iter := ValueOf(m).MapRange()
7230
7231 func() {
7232 defer func() { recover() }()
7233 iter.Key()
7234 t.Fatal("Key did not panic")
7235 }()
7236 func() {
7237 defer func() { recover() }()
7238 iter.Value()
7239 t.Fatal("Value did not panic")
7240 }()
7241
7242
7243
7244 iter.Next()
7245 func() {
7246 defer func() { recover() }()
7247 iter.Key()
7248 t.Fatal("Key did not panic")
7249 }()
7250 func() {
7251 defer func() { recover() }()
7252 iter.Value()
7253 t.Fatal("Value did not panic")
7254 }()
7255 func() {
7256 defer func() { recover() }()
7257 iter.Next()
7258 t.Fatal("Next did not panic")
7259 }()
7260 }
7261
7262 func TestMapIterNext(t *testing.T) {
7263
7264
7265 m := map[string]int{}
7266 iter := ValueOf(m).MapRange()
7267 m["one"] = 1
7268 if got, want := iterateToString(iter), `[one: 1]`; got != want {
7269 t.Errorf("iterator returned deleted elements: got %s, want %s", got, want)
7270 }
7271 }
7272
7273 func TestMapIterDelete0(t *testing.T) {
7274
7275 m := map[string]int{"one": 1, "two": 2, "three": 3}
7276 iter := ValueOf(m).MapRange()
7277 delete(m, "one")
7278 delete(m, "two")
7279 delete(m, "three")
7280 if got, want := iterateToString(iter), `[]`; got != want {
7281 t.Errorf("iterator returned deleted elements: got %s, want %s", got, want)
7282 }
7283 }
7284
7285 func TestMapIterDelete1(t *testing.T) {
7286
7287 m := map[string]int{"one": 1, "two": 2, "three": 3}
7288 iter := ValueOf(m).MapRange()
7289 var got []string
7290 for iter.Next() {
7291 got = append(got, fmt.Sprint(iter.Key(), iter.Value()))
7292 delete(m, "one")
7293 delete(m, "two")
7294 delete(m, "three")
7295 }
7296 if len(got) != 1 {
7297 t.Errorf("iterator returned wrong number of elements: got %d, want 1", len(got))
7298 }
7299 }
7300
7301
7302
7303 func iterateToString(it *MapIter) string {
7304 var got []string
7305 for it.Next() {
7306 line := fmt.Sprintf("%v: %v", it.Key(), it.Value())
7307 got = append(got, line)
7308 }
7309 sort.Strings(got)
7310 return "[" + strings.Join(got, ", ") + "]"
7311 }
7312
7313 func TestConvertibleTo(t *testing.T) {
7314 t1 := ValueOf(example1.MyStruct{}).Type()
7315 t2 := ValueOf(example2.MyStruct{}).Type()
7316
7317
7318 if t1.ConvertibleTo(t2) {
7319 t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t1, t2)
7320 }
7321 }
7322
View as plain text