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