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