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 func TestConvertSlice2Array(t *testing.T) {
4800 s := make([]int, 4)
4801 p := [4]int{}
4802 pt := TypeOf(p)
4803 ov := ValueOf(s)
4804 v := ov.Convert(pt)
4805
4806
4807 if v.CanAddr() {
4808 t.Fatalf("convert slice to non-empty array returns an addressable copy array")
4809 }
4810 for i := range s {
4811 ov.Index(i).Set(ValueOf(i + 1))
4812 }
4813 for i := range s {
4814 if v.Index(i).Int() != 0 {
4815 t.Fatalf("slice (%v) mutation visible in converted result (%v)", ov, v)
4816 }
4817 }
4818 }
4819
4820 var gFloat32 float32
4821
4822 const snan uint32 = 0x7f800001
4823
4824 func TestConvertNaNs(t *testing.T) {
4825
4826
4827 gFloat32 = math.Float32frombits(snan)
4828 runtime.Gosched()
4829 if got := math.Float32bits(gFloat32); got != snan {
4830 t.Errorf("store/load of sNaN not faithful, got %x want %x", got, snan)
4831 }
4832
4833 type myFloat32 float32
4834 x := V(myFloat32(math.Float32frombits(snan)))
4835 y := x.Convert(TypeOf(float32(0)))
4836 z := y.Interface().(float32)
4837 if got := math.Float32bits(z); got != snan {
4838 t.Errorf("signaling nan conversion got %x, want %x", got, snan)
4839 }
4840 }
4841
4842 type ComparableStruct struct {
4843 X int
4844 }
4845
4846 type NonComparableStruct struct {
4847 X int
4848 Y map[string]int
4849 }
4850
4851 var comparableTests = []struct {
4852 typ Type
4853 ok bool
4854 }{
4855 {TypeOf(1), true},
4856 {TypeOf("hello"), true},
4857 {TypeOf(new(byte)), true},
4858 {TypeOf((func())(nil)), false},
4859 {TypeOf([]byte{}), false},
4860 {TypeOf(map[string]int{}), false},
4861 {TypeOf(make(chan int)), true},
4862 {TypeOf(1.5), true},
4863 {TypeOf(false), true},
4864 {TypeOf(1i), true},
4865 {TypeOf(ComparableStruct{}), true},
4866 {TypeOf(NonComparableStruct{}), false},
4867 {TypeOf([10]map[string]int{}), false},
4868 {TypeOf([10]string{}), true},
4869 {TypeOf(new(any)).Elem(), true},
4870 }
4871
4872 func TestComparable(t *testing.T) {
4873 for _, tt := range comparableTests {
4874 if ok := tt.typ.Comparable(); ok != tt.ok {
4875 t.Errorf("TypeOf(%v).Comparable() = %v, want %v", tt.typ, ok, tt.ok)
4876 }
4877 }
4878 }
4879
4880 func TestValueOverflow(t *testing.T) {
4881 if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
4882 t.Errorf("%v wrongly overflows float64", 1e300)
4883 }
4884
4885 maxFloat32 := float64((1<<24 - 1) << (127 - 23))
4886 if ovf := V(float32(0)).OverflowFloat(maxFloat32); ovf {
4887 t.Errorf("%v wrongly overflows float32", maxFloat32)
4888 }
4889 ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
4890 if ovf := V(float32(0)).OverflowFloat(ovfFloat32); !ovf {
4891 t.Errorf("%v should overflow float32", ovfFloat32)
4892 }
4893 if ovf := V(float32(0)).OverflowFloat(-ovfFloat32); !ovf {
4894 t.Errorf("%v should overflow float32", -ovfFloat32)
4895 }
4896
4897 maxInt32 := int64(0x7fffffff)
4898 if ovf := V(int32(0)).OverflowInt(maxInt32); ovf {
4899 t.Errorf("%v wrongly overflows int32", maxInt32)
4900 }
4901 if ovf := V(int32(0)).OverflowInt(-1 << 31); ovf {
4902 t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
4903 }
4904 ovfInt32 := int64(1 << 31)
4905 if ovf := V(int32(0)).OverflowInt(ovfInt32); !ovf {
4906 t.Errorf("%v should overflow int32", ovfInt32)
4907 }
4908
4909 maxUint32 := uint64(0xffffffff)
4910 if ovf := V(uint32(0)).OverflowUint(maxUint32); ovf {
4911 t.Errorf("%v wrongly overflows uint32", maxUint32)
4912 }
4913 ovfUint32 := uint64(1 << 32)
4914 if ovf := V(uint32(0)).OverflowUint(ovfUint32); !ovf {
4915 t.Errorf("%v should overflow uint32", ovfUint32)
4916 }
4917 }
4918
4919 func TestTypeOverflow(t *testing.T) {
4920 if ovf := TypeFor[float64]().OverflowFloat(1e300); ovf {
4921 t.Errorf("%v wrongly overflows float64", 1e300)
4922 }
4923
4924 maxFloat32 := float64((1<<24 - 1) << (127 - 23))
4925 if ovf := TypeFor[float32]().OverflowFloat(maxFloat32); ovf {
4926 t.Errorf("%v wrongly overflows float32", maxFloat32)
4927 }
4928 ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
4929 if ovf := TypeFor[float32]().OverflowFloat(ovfFloat32); !ovf {
4930 t.Errorf("%v should overflow float32", ovfFloat32)
4931 }
4932 if ovf := TypeFor[float32]().OverflowFloat(-ovfFloat32); !ovf {
4933 t.Errorf("%v should overflow float32", -ovfFloat32)
4934 }
4935
4936 maxInt32 := int64(0x7fffffff)
4937 if ovf := TypeFor[int32]().OverflowInt(maxInt32); ovf {
4938 t.Errorf("%v wrongly overflows int32", maxInt32)
4939 }
4940 if ovf := TypeFor[int32]().OverflowInt(-1 << 31); ovf {
4941 t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
4942 }
4943 ovfInt32 := int64(1 << 31)
4944 if ovf := TypeFor[int32]().OverflowInt(ovfInt32); !ovf {
4945 t.Errorf("%v should overflow int32", ovfInt32)
4946 }
4947
4948 maxUint32 := uint64(0xffffffff)
4949 if ovf := TypeFor[uint32]().OverflowUint(maxUint32); ovf {
4950 t.Errorf("%v wrongly overflows uint32", maxUint32)
4951 }
4952 ovfUint32 := uint64(1 << 32)
4953 if ovf := TypeFor[uint32]().OverflowUint(ovfUint32); !ovf {
4954 t.Errorf("%v should overflow uint32", ovfUint32)
4955 }
4956 }
4957
4958 func checkSameType(t *testing.T, x Type, y any) {
4959 if x != TypeOf(y) || TypeOf(Zero(x).Interface()) != TypeOf(y) {
4960 t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
4961 }
4962 }
4963
4964 func TestArrayOf(t *testing.T) {
4965
4966 tests := []struct {
4967 n int
4968 value func(i int) any
4969 comparable bool
4970 want string
4971 }{
4972 {
4973 n: 0,
4974 value: func(i int) any { type Tint int; return Tint(i) },
4975 comparable: true,
4976 want: "[]",
4977 },
4978 {
4979 n: 10,
4980 value: func(i int) any { type Tint int; return Tint(i) },
4981 comparable: true,
4982 want: "[0 1 2 3 4 5 6 7 8 9]",
4983 },
4984 {
4985 n: 10,
4986 value: func(i int) any { type Tfloat float64; return Tfloat(i) },
4987 comparable: true,
4988 want: "[0 1 2 3 4 5 6 7 8 9]",
4989 },
4990 {
4991 n: 10,
4992 value: func(i int) any { type Tstring string; return Tstring(strconv.Itoa(i)) },
4993 comparable: true,
4994 want: "[0 1 2 3 4 5 6 7 8 9]",
4995 },
4996 {
4997 n: 10,
4998 value: func(i int) any { type Tstruct struct{ V int }; return Tstruct{i} },
4999 comparable: true,
5000 want: "[{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}]",
5001 },
5002 {
5003 n: 10,
5004 value: func(i int) any { type Tint int; return []Tint{Tint(i)} },
5005 comparable: false,
5006 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
5007 },
5008 {
5009 n: 10,
5010 value: func(i int) any { type Tint int; return [1]Tint{Tint(i)} },
5011 comparable: true,
5012 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
5013 },
5014 {
5015 n: 10,
5016 value: func(i int) any { type Tstruct struct{ V [1]int }; return Tstruct{[1]int{i}} },
5017 comparable: true,
5018 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
5019 },
5020 {
5021 n: 10,
5022 value: func(i int) any { type Tstruct struct{ V []int }; return Tstruct{[]int{i}} },
5023 comparable: false,
5024 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
5025 },
5026 {
5027 n: 10,
5028 value: func(i int) any { type TstructUV struct{ U, V int }; return TstructUV{i, i} },
5029 comparable: true,
5030 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
5031 },
5032 {
5033 n: 10,
5034 value: func(i int) any {
5035 type TstructUV struct {
5036 U int
5037 V float64
5038 }
5039 return TstructUV{i, float64(i)}
5040 },
5041 comparable: true,
5042 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
5043 },
5044 }
5045
5046 for _, table := range tests {
5047 at := ArrayOf(table.n, TypeOf(table.value(0)))
5048 v := New(at).Elem()
5049 vok := New(at).Elem()
5050 vnot := New(at).Elem()
5051 for i := 0; i < v.Len(); i++ {
5052 v.Index(i).Set(ValueOf(table.value(i)))
5053 vok.Index(i).Set(ValueOf(table.value(i)))
5054 j := i
5055 if i+1 == v.Len() {
5056 j = i + 1
5057 }
5058 vnot.Index(i).Set(ValueOf(table.value(j)))
5059 }
5060 s := fmt.Sprint(v.Interface())
5061 if s != table.want {
5062 t.Errorf("constructed array = %s, want %s", s, table.want)
5063 }
5064
5065 if table.comparable != at.Comparable() {
5066 t.Errorf("constructed array (%#v) is comparable=%v, want=%v", v.Interface(), at.Comparable(), table.comparable)
5067 }
5068 if table.comparable {
5069 if table.n > 0 {
5070 if DeepEqual(vnot.Interface(), v.Interface()) {
5071 t.Errorf(
5072 "arrays (%#v) compare ok (but should not)",
5073 v.Interface(),
5074 )
5075 }
5076 }
5077 if !DeepEqual(vok.Interface(), v.Interface()) {
5078 t.Errorf(
5079 "arrays (%#v) compare NOT-ok (but should)",
5080 v.Interface(),
5081 )
5082 }
5083 }
5084 }
5085
5086
5087 type T int
5088 checkSameType(t, ArrayOf(5, TypeOf(T(1))), [5]T{})
5089 }
5090
5091 func TestArrayOfGC(t *testing.T) {
5092 type T *uintptr
5093 tt := TypeOf(T(nil))
5094 const n = 100
5095 var x []any
5096 for i := 0; i < n; i++ {
5097 v := New(ArrayOf(n, tt)).Elem()
5098 for j := 0; j < v.Len(); j++ {
5099 p := new(uintptr)
5100 *p = uintptr(i*n + j)
5101 v.Index(j).Set(ValueOf(p).Convert(tt))
5102 }
5103 x = append(x, v.Interface())
5104 }
5105 runtime.GC()
5106
5107 for i, xi := range x {
5108 v := ValueOf(xi)
5109 for j := 0; j < v.Len(); j++ {
5110 k := v.Index(j).Elem().Interface()
5111 if k != uintptr(i*n+j) {
5112 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
5113 }
5114 }
5115 }
5116 }
5117
5118 func TestArrayOfAlg(t *testing.T) {
5119 at := ArrayOf(6, TypeOf(byte(0)))
5120 v1 := New(at).Elem()
5121 v2 := New(at).Elem()
5122 if v1.Interface() != v1.Interface() {
5123 t.Errorf("constructed array %v not equal to itself", v1.Interface())
5124 }
5125 v1.Index(5).Set(ValueOf(byte(1)))
5126 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
5127 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
5128 }
5129
5130 at = ArrayOf(6, TypeOf([]int(nil)))
5131 v1 = New(at).Elem()
5132 shouldPanic("", func() { _ = v1.Interface() == v1.Interface() })
5133 }
5134
5135 func TestArrayOfGenericAlg(t *testing.T) {
5136 at1 := ArrayOf(5, TypeOf(string("")))
5137 at := ArrayOf(6, at1)
5138 v1 := New(at).Elem()
5139 v2 := New(at).Elem()
5140 if v1.Interface() != v1.Interface() {
5141 t.Errorf("constructed array %v not equal to itself", v1.Interface())
5142 }
5143
5144 v1.Index(0).Index(0).Set(ValueOf("abc"))
5145 v2.Index(0).Index(0).Set(ValueOf("efg"))
5146 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
5147 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
5148 }
5149
5150 v1.Index(0).Index(0).Set(ValueOf("abc"))
5151 v2.Index(0).Index(0).Set(ValueOf((v1.Index(0).Index(0).String() + " ")[:3]))
5152 if i1, i2 := v1.Interface(), v2.Interface(); i1 != i2 {
5153 t.Errorf("constructed arrays %v and %v should be equal", i1, i2)
5154 }
5155
5156
5157 m := MakeMap(MapOf(at, TypeOf(int(0))))
5158 m.SetMapIndex(v1, ValueOf(1))
5159 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
5160 t.Errorf("constructed arrays %v and %v have different hashes", i1, i2)
5161 }
5162 }
5163
5164 func TestArrayOfDirectIface(t *testing.T) {
5165 {
5166 type T [1]*byte
5167 i1 := Zero(TypeOf(T{})).Interface()
5168 v1 := ValueOf(&i1).Elem()
5169 p1 := v1.InterfaceData()[1]
5170
5171 i2 := Zero(ArrayOf(1, PointerTo(TypeOf(int8(0))))).Interface()
5172 v2 := ValueOf(&i2).Elem()
5173 p2 := v2.InterfaceData()[1]
5174
5175 if p1 != 0 {
5176 t.Errorf("got p1=%v. want=%v", p1, nil)
5177 }
5178
5179 if p2 != 0 {
5180 t.Errorf("got p2=%v. want=%v", p2, nil)
5181 }
5182 }
5183 {
5184 type T [0]*byte
5185 i1 := Zero(TypeOf(T{})).Interface()
5186 v1 := ValueOf(&i1).Elem()
5187 p1 := v1.InterfaceData()[1]
5188
5189 i2 := Zero(ArrayOf(0, PointerTo(TypeOf(int8(0))))).Interface()
5190 v2 := ValueOf(&i2).Elem()
5191 p2 := v2.InterfaceData()[1]
5192
5193 if p1 == 0 {
5194 t.Errorf("got p1=%v. want=not-%v", p1, nil)
5195 }
5196
5197 if p2 == 0 {
5198 t.Errorf("got p2=%v. want=not-%v", p2, nil)
5199 }
5200 }
5201 }
5202
5203
5204
5205 func TestArrayOfPanicOnNegativeLength(t *testing.T) {
5206 shouldPanic("reflect: negative length passed to ArrayOf", func() {
5207 ArrayOf(-1, TypeOf(byte(0)))
5208 })
5209 }
5210
5211 func TestSliceOf(t *testing.T) {
5212
5213 type T int
5214 st := SliceOf(TypeOf(T(1)))
5215 if got, want := st.String(), "[]reflect_test.T"; got != want {
5216 t.Errorf("SliceOf(T(1)).String()=%q, want %q", got, want)
5217 }
5218 v := MakeSlice(st, 10, 10)
5219 runtime.GC()
5220 for i := 0; i < v.Len(); i++ {
5221 v.Index(i).Set(ValueOf(T(i)))
5222 runtime.GC()
5223 }
5224 s := fmt.Sprint(v.Interface())
5225 want := "[0 1 2 3 4 5 6 7 8 9]"
5226 if s != want {
5227 t.Errorf("constructed slice = %s, want %s", s, want)
5228 }
5229
5230
5231 type T1 int
5232 checkSameType(t, SliceOf(TypeOf(T1(1))), []T1{})
5233 }
5234
5235 func TestSliceOverflow(t *testing.T) {
5236
5237 const S = 1e6
5238 s := uint(S)
5239 l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
5240 if l*s >= s {
5241 t.Fatal("slice size does not overflow")
5242 }
5243 var x [S]byte
5244 st := SliceOf(TypeOf(x))
5245 defer func() {
5246 err := recover()
5247 if err == nil {
5248 t.Fatal("slice overflow does not panic")
5249 }
5250 }()
5251 MakeSlice(st, int(l), int(l))
5252 }
5253
5254 func TestSliceOfGC(t *testing.T) {
5255 type T *uintptr
5256 tt := TypeOf(T(nil))
5257 st := SliceOf(tt)
5258 const n = 100
5259 var x []any
5260 for i := 0; i < n; i++ {
5261 v := MakeSlice(st, n, n)
5262 for j := 0; j < v.Len(); j++ {
5263 p := new(uintptr)
5264 *p = uintptr(i*n + j)
5265 v.Index(j).Set(ValueOf(p).Convert(tt))
5266 }
5267 x = append(x, v.Interface())
5268 }
5269 runtime.GC()
5270
5271 for i, xi := range x {
5272 v := ValueOf(xi)
5273 for j := 0; j < v.Len(); j++ {
5274 k := v.Index(j).Elem().Interface()
5275 if k != uintptr(i*n+j) {
5276 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
5277 }
5278 }
5279 }
5280 }
5281
5282 func TestStructOfFieldName(t *testing.T) {
5283
5284 shouldPanic("has invalid name", func() {
5285 StructOf([]StructField{
5286 {Name: "Valid", Type: TypeOf("")},
5287 {Name: "1nvalid", Type: TypeOf("")},
5288 })
5289 })
5290
5291
5292 shouldPanic("has invalid name", func() {
5293 StructOf([]StructField{
5294 {Name: "Val1d", Type: TypeOf("")},
5295 {Name: "+", Type: TypeOf("")},
5296 })
5297 })
5298
5299
5300 shouldPanic("has no name", func() {
5301 StructOf([]StructField{
5302 {Name: "", Type: TypeOf("")},
5303 })
5304 })
5305
5306
5307 validFields := []StructField{
5308 {
5309 Name: "φ",
5310 Type: TypeOf(""),
5311 },
5312 {
5313 Name: "ValidName",
5314 Type: TypeOf(""),
5315 },
5316 {
5317 Name: "Val1dNam5",
5318 Type: TypeOf(""),
5319 },
5320 }
5321
5322 validStruct := StructOf(validFields)
5323
5324 const structStr = `struct { φ string; ValidName string; Val1dNam5 string }`
5325 if got, want := validStruct.String(), structStr; got != want {
5326 t.Errorf("StructOf(validFields).String()=%q, want %q", got, want)
5327 }
5328 }
5329
5330 func TestStructOf(t *testing.T) {
5331
5332 fields := []StructField{
5333 {
5334 Name: "S",
5335 Tag: "s",
5336 Type: TypeOf(""),
5337 },
5338 {
5339 Name: "X",
5340 Tag: "x",
5341 Type: TypeOf(byte(0)),
5342 },
5343 {
5344 Name: "Y",
5345 Type: TypeOf(uint64(0)),
5346 },
5347 {
5348 Name: "Z",
5349 Type: TypeOf([3]uint16{}),
5350 },
5351 }
5352
5353 st := StructOf(fields)
5354 v := New(st).Elem()
5355 runtime.GC()
5356 v.FieldByName("X").Set(ValueOf(byte(2)))
5357 v.FieldByIndex([]int{1}).Set(ValueOf(byte(1)))
5358 runtime.GC()
5359
5360 s := fmt.Sprint(v.Interface())
5361 want := `{ 1 0 [0 0 0]}`
5362 if s != want {
5363 t.Errorf("constructed struct = %s, want %s", s, want)
5364 }
5365 const stStr = `struct { S string "s"; X uint8 "x"; Y uint64; Z [3]uint16 }`
5366 if got, want := st.String(), stStr; got != want {
5367 t.Errorf("StructOf(fields).String()=%q, want %q", got, want)
5368 }
5369
5370
5371 stt := TypeOf(struct {
5372 String string
5373 X byte
5374 Y uint64
5375 Z [3]uint16
5376 }{})
5377 if st.Size() != stt.Size() {
5378 t.Errorf("constructed struct size = %v, want %v", st.Size(), stt.Size())
5379 }
5380 if st.Align() != stt.Align() {
5381 t.Errorf("constructed struct align = %v, want %v", st.Align(), stt.Align())
5382 }
5383 if st.FieldAlign() != stt.FieldAlign() {
5384 t.Errorf("constructed struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
5385 }
5386 for i := 0; i < st.NumField(); i++ {
5387 o1 := st.Field(i).Offset
5388 o2 := stt.Field(i).Offset
5389 if o1 != o2 {
5390 t.Errorf("constructed struct field %v offset = %v, want %v", i, o1, o2)
5391 }
5392 }
5393
5394
5395 st = StructOf([]StructField{
5396 {
5397 Name: "F1",
5398 Type: TypeOf(byte(0)),
5399 },
5400 {
5401 Name: "F2",
5402 Type: TypeOf([0]*byte{}),
5403 },
5404 })
5405 stt = TypeOf(struct {
5406 G1 byte
5407 G2 [0]*byte
5408 }{})
5409 if st.Size() != stt.Size() {
5410 t.Errorf("constructed zero-padded struct size = %v, want %v", st.Size(), stt.Size())
5411 }
5412 if st.Align() != stt.Align() {
5413 t.Errorf("constructed zero-padded struct align = %v, want %v", st.Align(), stt.Align())
5414 }
5415 if st.FieldAlign() != stt.FieldAlign() {
5416 t.Errorf("constructed zero-padded struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
5417 }
5418 for i := 0; i < st.NumField(); i++ {
5419 o1 := st.Field(i).Offset
5420 o2 := stt.Field(i).Offset
5421 if o1 != o2 {
5422 t.Errorf("constructed zero-padded struct field %v offset = %v, want %v", i, o1, o2)
5423 }
5424 }
5425
5426
5427 shouldPanic("duplicate field", func() {
5428 StructOf([]StructField{
5429 {Name: "string", PkgPath: "p", Type: TypeOf("")},
5430 {Name: "string", PkgPath: "p", Type: TypeOf("")},
5431 })
5432 })
5433 shouldPanic("has no name", func() {
5434 StructOf([]StructField{
5435 {Type: TypeOf("")},
5436 {Name: "string", PkgPath: "p", Type: TypeOf("")},
5437 })
5438 })
5439 shouldPanic("has no name", func() {
5440 StructOf([]StructField{
5441 {Type: TypeOf("")},
5442 {Type: TypeOf("")},
5443 })
5444 })
5445
5446 checkSameType(t, StructOf(fields[2:3]), struct{ Y uint64 }{})
5447
5448
5449 type structFieldType any
5450 checkSameType(t,
5451 StructOf([]StructField{
5452 {
5453 Name: "F",
5454 Type: TypeOf((*structFieldType)(nil)).Elem(),
5455 },
5456 }),
5457 struct{ F structFieldType }{})
5458 }
5459
5460 func TestStructOfExportRules(t *testing.T) {
5461 type S1 struct{}
5462 type s2 struct{}
5463 type ΦType struct{}
5464 type φType struct{}
5465
5466 testPanic := func(i int, mustPanic bool, f func()) {
5467 defer func() {
5468 err := recover()
5469 if err == nil && mustPanic {
5470 t.Errorf("test-%d did not panic", i)
5471 }
5472 if err != nil && !mustPanic {
5473 t.Errorf("test-%d panicked: %v\n", i, err)
5474 }
5475 }()
5476 f()
5477 }
5478
5479 tests := []struct {
5480 field StructField
5481 mustPanic bool
5482 exported bool
5483 }{
5484 {
5485 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf(S1{})},
5486 exported: true,
5487 },
5488 {
5489 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf((*S1)(nil))},
5490 exported: true,
5491 },
5492 {
5493 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf(s2{})},
5494 mustPanic: true,
5495 },
5496 {
5497 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf((*s2)(nil))},
5498 mustPanic: true,
5499 },
5500 {
5501 field: StructField{Name: "Name", Type: nil, PkgPath: ""},
5502 mustPanic: true,
5503 },
5504 {
5505 field: StructField{Name: "", Type: TypeOf(S1{}), PkgPath: ""},
5506 mustPanic: true,
5507 },
5508 {
5509 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf(S1{}), PkgPath: "other/pkg"},
5510 mustPanic: true,
5511 },
5512 {
5513 field: StructField{Name: "S1", Anonymous: true, Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
5514 mustPanic: true,
5515 },
5516 {
5517 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf(s2{}), PkgPath: "other/pkg"},
5518 mustPanic: true,
5519 },
5520 {
5521 field: StructField{Name: "s2", Anonymous: true, Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
5522 mustPanic: true,
5523 },
5524 {
5525 field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
5526 },
5527 {
5528 field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"},
5529 },
5530 {
5531 field: StructField{Name: "S", Type: TypeOf(S1{})},
5532 exported: true,
5533 },
5534 {
5535 field: StructField{Name: "S", Type: TypeOf((*S1)(nil))},
5536 exported: true,
5537 },
5538 {
5539 field: StructField{Name: "S", Type: TypeOf(s2{})},
5540 exported: true,
5541 },
5542 {
5543 field: StructField{Name: "S", Type: TypeOf((*s2)(nil))},
5544 exported: true,
5545 },
5546 {
5547 field: StructField{Name: "s", Type: TypeOf(S1{})},
5548 mustPanic: true,
5549 },
5550 {
5551 field: StructField{Name: "s", Type: TypeOf((*S1)(nil))},
5552 mustPanic: true,
5553 },
5554 {
5555 field: StructField{Name: "s", Type: TypeOf(s2{})},
5556 mustPanic: true,
5557 },
5558 {
5559 field: StructField{Name: "s", Type: TypeOf((*s2)(nil))},
5560 mustPanic: true,
5561 },
5562 {
5563 field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
5564 },
5565 {
5566 field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
5567 },
5568 {
5569 field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
5570 },
5571 {
5572 field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
5573 },
5574 {
5575 field: StructField{Name: "", Type: TypeOf(ΦType{})},
5576 mustPanic: true,
5577 },
5578 {
5579 field: StructField{Name: "", Type: TypeOf(φType{})},
5580 mustPanic: true,
5581 },
5582 {
5583 field: StructField{Name: "Φ", Type: TypeOf(0)},
5584 exported: true,
5585 },
5586 {
5587 field: StructField{Name: "φ", Type: TypeOf(0)},
5588 exported: false,
5589 },
5590 }
5591
5592 for i, test := range tests {
5593 testPanic(i, test.mustPanic, func() {
5594 typ := StructOf([]StructField{test.field})
5595 if typ == nil {
5596 t.Errorf("test-%d: error creating struct type", i)
5597 return
5598 }
5599 field := typ.Field(0)
5600 n := field.Name
5601 if n == "" {
5602 panic("field.Name must not be empty")
5603 }
5604 exported := token.IsExported(n)
5605 if exported != test.exported {
5606 t.Errorf("test-%d: got exported=%v want exported=%v", i, exported, test.exported)
5607 }
5608 if field.PkgPath != test.field.PkgPath {
5609 t.Errorf("test-%d: got PkgPath=%q want pkgPath=%q", i, field.PkgPath, test.field.PkgPath)
5610 }
5611 })
5612 }
5613 }
5614
5615 func TestStructOfGC(t *testing.T) {
5616 type T *uintptr
5617 tt := TypeOf(T(nil))
5618 fields := []StructField{
5619 {Name: "X", Type: tt},
5620 {Name: "Y", Type: tt},
5621 }
5622 st := StructOf(fields)
5623
5624 const n = 10000
5625 var x []any
5626 for i := 0; i < n; i++ {
5627 v := New(st).Elem()
5628 for j := 0; j < v.NumField(); j++ {
5629 p := new(uintptr)
5630 *p = uintptr(i*n + j)
5631 v.Field(j).Set(ValueOf(p).Convert(tt))
5632 }
5633 x = append(x, v.Interface())
5634 }
5635 runtime.GC()
5636
5637 for i, xi := range x {
5638 v := ValueOf(xi)
5639 for j := 0; j < v.NumField(); j++ {
5640 k := v.Field(j).Elem().Interface()
5641 if k != uintptr(i*n+j) {
5642 t.Errorf("lost x[%d].%c = %d, want %d", i, "XY"[j], k, i*n+j)
5643 }
5644 }
5645 }
5646 }
5647
5648 func TestStructOfAlg(t *testing.T) {
5649 st := StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf(int(0))}})
5650 v1 := New(st).Elem()
5651 v2 := New(st).Elem()
5652 if !DeepEqual(v1.Interface(), v1.Interface()) {
5653 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
5654 }
5655 v1.FieldByName("X").Set(ValueOf(int(1)))
5656 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
5657 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
5658 }
5659
5660 st = StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf([]int(nil))}})
5661 v1 = New(st).Elem()
5662 shouldPanic("", func() { _ = v1.Interface() == v1.Interface() })
5663 }
5664
5665 func TestStructOfGenericAlg(t *testing.T) {
5666 st1 := StructOf([]StructField{
5667 {Name: "X", Tag: "x", Type: TypeOf(int64(0))},
5668 {Name: "Y", Type: TypeOf(string(""))},
5669 })
5670 st := StructOf([]StructField{
5671 {Name: "S0", Type: st1},
5672 {Name: "S1", Type: st1},
5673 })
5674
5675 tests := []struct {
5676 rt Type
5677 idx []int
5678 }{
5679 {
5680 rt: st,
5681 idx: []int{0, 1},
5682 },
5683 {
5684 rt: st1,
5685 idx: []int{1},
5686 },
5687 {
5688 rt: StructOf(
5689 []StructField{
5690 {Name: "XX", Type: TypeOf([0]int{})},
5691 {Name: "YY", Type: TypeOf("")},
5692 },
5693 ),
5694 idx: []int{1},
5695 },
5696 {
5697 rt: StructOf(
5698 []StructField{
5699 {Name: "XX", Type: TypeOf([0]int{})},
5700 {Name: "YY", Type: TypeOf("")},
5701 {Name: "ZZ", Type: TypeOf([2]int{})},
5702 },
5703 ),
5704 idx: []int{1},
5705 },
5706 {
5707 rt: StructOf(
5708 []StructField{
5709 {Name: "XX", Type: TypeOf([1]int{})},
5710 {Name: "YY", Type: TypeOf("")},
5711 },
5712 ),
5713 idx: []int{1},
5714 },
5715 {
5716 rt: StructOf(
5717 []StructField{
5718 {Name: "XX", Type: TypeOf([1]int{})},
5719 {Name: "YY", Type: TypeOf("")},
5720 {Name: "ZZ", Type: TypeOf([1]int{})},
5721 },
5722 ),
5723 idx: []int{1},
5724 },
5725 {
5726 rt: StructOf(
5727 []StructField{
5728 {Name: "XX", Type: TypeOf([2]int{})},
5729 {Name: "YY", Type: TypeOf("")},
5730 {Name: "ZZ", Type: TypeOf([2]int{})},
5731 },
5732 ),
5733 idx: []int{1},
5734 },
5735 {
5736 rt: StructOf(
5737 []StructField{
5738 {Name: "XX", Type: TypeOf(int64(0))},
5739 {Name: "YY", Type: TypeOf(byte(0))},
5740 {Name: "ZZ", Type: TypeOf("")},
5741 },
5742 ),
5743 idx: []int{2},
5744 },
5745 {
5746 rt: StructOf(
5747 []StructField{
5748 {Name: "XX", Type: TypeOf(int64(0))},
5749 {Name: "YY", Type: TypeOf(int64(0))},
5750 {Name: "ZZ", Type: TypeOf("")},
5751 {Name: "AA", Type: TypeOf([1]int64{})},
5752 },
5753 ),
5754 idx: []int{2},
5755 },
5756 }
5757
5758 for _, table := range tests {
5759 v1 := New(table.rt).Elem()
5760 v2 := New(table.rt).Elem()
5761
5762 if !DeepEqual(v1.Interface(), v1.Interface()) {
5763 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
5764 }
5765
5766 v1.FieldByIndex(table.idx).Set(ValueOf("abc"))
5767 v2.FieldByIndex(table.idx).Set(ValueOf("def"))
5768 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
5769 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
5770 }
5771
5772 abc := "abc"
5773 v1.FieldByIndex(table.idx).Set(ValueOf(abc))
5774 val := "+" + abc + "-"
5775 v2.FieldByIndex(table.idx).Set(ValueOf(val[1:4]))
5776 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
5777 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
5778 }
5779
5780
5781 m := MakeMap(MapOf(table.rt, TypeOf(int(0))))
5782 m.SetMapIndex(v1, ValueOf(1))
5783 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
5784 t.Errorf("constructed structs %#v and %#v have different hashes", i1, i2)
5785 }
5786
5787 v2.FieldByIndex(table.idx).Set(ValueOf("abc"))
5788 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
5789 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
5790 }
5791
5792 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
5793 t.Errorf("constructed structs %v and %v have different hashes", i1, i2)
5794 }
5795 }
5796 }
5797
5798 func TestStructOfDirectIface(t *testing.T) {
5799 {
5800 type T struct{ X [1]*byte }
5801 i1 := Zero(TypeOf(T{})).Interface()
5802 v1 := ValueOf(&i1).Elem()
5803 p1 := v1.InterfaceData()[1]
5804
5805 i2 := Zero(StructOf([]StructField{
5806 {
5807 Name: "X",
5808 Type: ArrayOf(1, TypeOf((*int8)(nil))),
5809 },
5810 })).Interface()
5811 v2 := ValueOf(&i2).Elem()
5812 p2 := v2.InterfaceData()[1]
5813
5814 if p1 != 0 {
5815 t.Errorf("got p1=%v. want=%v", p1, nil)
5816 }
5817
5818 if p2 != 0 {
5819 t.Errorf("got p2=%v. want=%v", p2, nil)
5820 }
5821 }
5822 {
5823 type T struct{ X [0]*byte }
5824 i1 := Zero(TypeOf(T{})).Interface()
5825 v1 := ValueOf(&i1).Elem()
5826 p1 := v1.InterfaceData()[1]
5827
5828 i2 := Zero(StructOf([]StructField{
5829 {
5830 Name: "X",
5831 Type: ArrayOf(0, TypeOf((*int8)(nil))),
5832 },
5833 })).Interface()
5834 v2 := ValueOf(&i2).Elem()
5835 p2 := v2.InterfaceData()[1]
5836
5837 if p1 == 0 {
5838 t.Errorf("got p1=%v. want=not-%v", p1, nil)
5839 }
5840
5841 if p2 == 0 {
5842 t.Errorf("got p2=%v. want=not-%v", p2, nil)
5843 }
5844 }
5845 }
5846
5847 type StructI int
5848
5849 func (i StructI) Get() int { return int(i) }
5850
5851 type StructIPtr int
5852
5853 func (i *StructIPtr) Get() int { return int(*i) }
5854 func (i *StructIPtr) Set(v int) { *(*int)(i) = v }
5855
5856 type SettableStruct struct {
5857 SettableField int
5858 }
5859
5860 func (p *SettableStruct) Set(v int) { p.SettableField = v }
5861
5862 type SettablePointer struct {
5863 SettableField *int
5864 }
5865
5866 func (p *SettablePointer) Set(v int) { *p.SettableField = v }
5867
5868 func TestStructOfWithInterface(t *testing.T) {
5869 const want = 42
5870 type Iface interface {
5871 Get() int
5872 }
5873 type IfaceSet interface {
5874 Set(int)
5875 }
5876 tests := []struct {
5877 name string
5878 typ Type
5879 val Value
5880 impl bool
5881 }{
5882 {
5883 name: "StructI",
5884 typ: TypeOf(StructI(want)),
5885 val: ValueOf(StructI(want)),
5886 impl: true,
5887 },
5888 {
5889 name: "StructI",
5890 typ: PointerTo(TypeOf(StructI(want))),
5891 val: ValueOf(func() any {
5892 v := StructI(want)
5893 return &v
5894 }()),
5895 impl: true,
5896 },
5897 {
5898 name: "StructIPtr",
5899 typ: PointerTo(TypeOf(StructIPtr(want))),
5900 val: ValueOf(func() any {
5901 v := StructIPtr(want)
5902 return &v
5903 }()),
5904 impl: true,
5905 },
5906 {
5907 name: "StructIPtr",
5908 typ: TypeOf(StructIPtr(want)),
5909 val: ValueOf(StructIPtr(want)),
5910 impl: false,
5911 },
5912
5913
5914
5915
5916
5917 }
5918
5919 for i, table := range tests {
5920 for j := 0; j < 2; j++ {
5921 var fields []StructField
5922 if j == 1 {
5923 fields = append(fields, StructField{
5924 Name: "Dummy",
5925 PkgPath: "",
5926 Type: TypeOf(int(0)),
5927 })
5928 }
5929 fields = append(fields, StructField{
5930 Name: table.name,
5931 Anonymous: true,
5932 PkgPath: "",
5933 Type: table.typ,
5934 })
5935
5936
5937
5938
5939
5940
5941
5942 if j == 1 && table.impl {
5943 func() {
5944 defer func() {
5945 if err := recover(); err == nil {
5946 t.Errorf("test-%d-%d did not panic", i, j)
5947 }
5948 }()
5949 _ = StructOf(fields)
5950 }()
5951 continue
5952 }
5953
5954 rt := StructOf(fields)
5955 rv := New(rt).Elem()
5956 rv.Field(j).Set(table.val)
5957
5958 if _, ok := rv.Interface().(Iface); ok != table.impl {
5959 if table.impl {
5960 t.Errorf("test-%d-%d: type=%v fails to implement Iface.\n", i, j, table.typ)
5961 } else {
5962 t.Errorf("test-%d-%d: type=%v should NOT implement Iface\n", i, j, table.typ)
5963 }
5964 continue
5965 }
5966
5967 if !table.impl {
5968 continue
5969 }
5970
5971 v := rv.Interface().(Iface).Get()
5972 if v != want {
5973 t.Errorf("test-%d-%d: x.Get()=%v. want=%v\n", i, j, v, want)
5974 }
5975
5976 fct := rv.MethodByName("Get")
5977 out := fct.Call(nil)
5978 if !DeepEqual(out[0].Interface(), want) {
5979 t.Errorf("test-%d-%d: x.Get()=%v. want=%v\n", i, j, out[0].Interface(), want)
5980 }
5981 }
5982 }
5983
5984
5985 fields := []StructField{{
5986 Name: "StructIPtr",
5987 Anonymous: true,
5988 Type: PointerTo(TypeOf(StructIPtr(want))),
5989 }}
5990 rt := StructOf(fields)
5991 rv := New(rt).Elem()
5992
5993 shouldPanic("", func() {
5994 rv.Interface().(IfaceSet).Set(want)
5995 })
5996
5997
5998
5999 fields = []StructField{{
6000 Name: "SettableStruct",
6001 Anonymous: true,
6002 Type: PointerTo(TypeOf(SettableStruct{})),
6003 }}
6004 rt = StructOf(fields)
6005 rv = New(rt).Elem()
6006
6007 shouldPanic("", func() {
6008 rv.Interface().(IfaceSet).Set(want)
6009 })
6010
6011
6012
6013
6014 fields = []StructField{
6015 {
6016 Name: "SettableStruct",
6017 Anonymous: true,
6018 Type: PointerTo(TypeOf(SettableStruct{})),
6019 },
6020 {
6021 Name: "EmptyStruct",
6022 Anonymous: true,
6023 Type: StructOf(nil),
6024 },
6025 }
6026
6027
6028
6029 shouldPanic("", func() {
6030 StructOf(fields)
6031 })
6032
6033
6034
6035 fields = []StructField{
6036 {
6037 Name: "SettablePointer",
6038 Anonymous: true,
6039 Type: TypeOf(SettablePointer{}),
6040 },
6041 {
6042 Name: "EmptyStruct",
6043 Anonymous: true,
6044 Type: StructOf(nil),
6045 },
6046 }
6047
6048
6049
6050 shouldPanic("", func() {
6051 StructOf(fields)
6052 })
6053 }
6054
6055 func TestStructOfTooManyFields(t *testing.T) {
6056
6057 tt := StructOf([]StructField{
6058 {Name: "Time", Type: TypeOf(time.Time{}), Anonymous: true},
6059 })
6060
6061 if _, present := tt.MethodByName("After"); !present {
6062 t.Errorf("Expected method `After` to be found")
6063 }
6064 }
6065
6066 func TestStructOfDifferentPkgPath(t *testing.T) {
6067 fields := []StructField{
6068 {
6069 Name: "f1",
6070 PkgPath: "p1",
6071 Type: TypeOf(int(0)),
6072 },
6073 {
6074 Name: "f2",
6075 PkgPath: "p2",
6076 Type: TypeOf(int(0)),
6077 },
6078 }
6079 shouldPanic("different PkgPath", func() {
6080 StructOf(fields)
6081 })
6082 }
6083
6084 func TestStructOfTooLarge(t *testing.T) {
6085 t1 := TypeOf(byte(0))
6086 t2 := TypeOf(int16(0))
6087 t4 := TypeOf(int32(0))
6088 t0 := ArrayOf(0, t1)
6089
6090
6091 bigType := StructOf([]StructField{
6092 {Name: "F1", Type: ArrayOf(int(^uintptr(0)>>1), t1)},
6093 {Name: "F2", Type: ArrayOf(int(^uintptr(0)>>1-1), t1)},
6094 })
6095
6096 type test struct {
6097 shouldPanic bool
6098 fields []StructField
6099 }
6100
6101 tests := [...]test{
6102 {
6103 shouldPanic: false,
6104 fields: []StructField{
6105 {Name: "F1", Type: bigType},
6106 {Name: "F2", Type: ArrayOf(2, t1)},
6107 },
6108 },
6109 {
6110 shouldPanic: true,
6111 fields: []StructField{
6112 {Name: "F1", Type: bigType},
6113 {Name: "F2", Type: ArrayOf(3, t1)},
6114 },
6115 },
6116 {
6117 shouldPanic: true,
6118 fields: []StructField{
6119 {Name: "F1", Type: bigType},
6120 {Name: "F2", Type: t4},
6121 },
6122 },
6123 {
6124 shouldPanic: true,
6125 fields: []StructField{
6126 {Name: "F1", Type: bigType},
6127 {Name: "F2", Type: ArrayOf(2, t1)},
6128 {Name: "F3", Type: t0},
6129 },
6130 },
6131 {
6132 shouldPanic: true,
6133 fields: []StructField{
6134 {Name: "F1", Type: t2},
6135 {Name: "F2", Type: bigType},
6136 },
6137 },
6138 }
6139
6140 for i, tt := range tests {
6141 func() {
6142 defer func() {
6143 err := recover()
6144 if !tt.shouldPanic {
6145 if err != nil {
6146 t.Errorf("test %d should not panic, got %s", i, err)
6147 }
6148 return
6149 }
6150 if err == nil {
6151 t.Errorf("test %d expected to panic", i)
6152 return
6153 }
6154 s := fmt.Sprintf("%s", err)
6155 if s != "reflect.StructOf: struct size would exceed virtual address space" {
6156 t.Errorf("test %d wrong panic message: %s", i, s)
6157 return
6158 }
6159 }()
6160 _ = StructOf(tt.fields)
6161 }()
6162 }
6163 }
6164
6165 func TestStructOfAnonymous(t *testing.T) {
6166 var s any = struct{ D1 }{}
6167 f := TypeOf(s).Field(0)
6168 ds := StructOf([]StructField{f})
6169 st := TypeOf(s)
6170 dt := New(ds).Elem()
6171 if st != dt.Type() {
6172 t.Errorf("StructOf returned %s, want %s", dt.Type(), st)
6173 }
6174
6175
6176 _ = dt.Interface().(struct{ D1 })
6177 }
6178
6179 func TestChanOf(t *testing.T) {
6180
6181 type T string
6182 ct := ChanOf(BothDir, TypeOf(T("")))
6183 v := MakeChan(ct, 2)
6184 runtime.GC()
6185 v.Send(ValueOf(T("hello")))
6186 runtime.GC()
6187 v.Send(ValueOf(T("world")))
6188 runtime.GC()
6189
6190 sv1, _ := v.Recv()
6191 sv2, _ := v.Recv()
6192 s1 := sv1.String()
6193 s2 := sv2.String()
6194 if s1 != "hello" || s2 != "world" {
6195 t.Errorf("constructed chan: have %q, %q, want %q, %q", s1, s2, "hello", "world")
6196 }
6197
6198
6199 type T1 int
6200 checkSameType(t, ChanOf(BothDir, TypeOf(T1(1))), (chan T1)(nil))
6201
6202
6203 var left chan<- chan T
6204 var right chan (<-chan T)
6205 tLeft := ChanOf(SendDir, ChanOf(BothDir, TypeOf(T(""))))
6206 tRight := ChanOf(BothDir, ChanOf(RecvDir, TypeOf(T(""))))
6207 if tLeft != TypeOf(left) {
6208 t.Errorf("chan<-chan: have %s, want %T", tLeft, left)
6209 }
6210 if tRight != TypeOf(right) {
6211 t.Errorf("chan<-chan: have %s, want %T", tRight, right)
6212 }
6213 }
6214
6215 func TestChanOfDir(t *testing.T) {
6216
6217 type T string
6218 crt := ChanOf(RecvDir, TypeOf(T("")))
6219 cst := ChanOf(SendDir, TypeOf(T("")))
6220
6221
6222 type T1 int
6223 checkSameType(t, ChanOf(RecvDir, TypeOf(T1(1))), (<-chan T1)(nil))
6224 checkSameType(t, ChanOf(SendDir, TypeOf(T1(1))), (chan<- T1)(nil))
6225
6226
6227 if crt.ChanDir().String() != "<-chan" {
6228 t.Errorf("chan dir: have %q, want %q", crt.ChanDir().String(), "<-chan")
6229 }
6230 if cst.ChanDir().String() != "chan<-" {
6231 t.Errorf("chan dir: have %q, want %q", cst.ChanDir().String(), "chan<-")
6232 }
6233 }
6234
6235 func TestChanOfGC(t *testing.T) {
6236 type T *uintptr
6237 tt := TypeOf(T(nil))
6238 ct := ChanOf(BothDir, tt)
6239
6240
6241
6242
6243 const n = 100
6244 var x []any
6245 for i := 0; i < n; i++ {
6246 v := MakeChan(ct, n)
6247 for j := 0; j < n; j++ {
6248 p := new(uintptr)
6249 *p = uintptr(i*n + j)
6250 v.Send(ValueOf(p).Convert(tt))
6251 }
6252 pv := New(ct)
6253 pv.Elem().Set(v)
6254 x = append(x, pv.Interface())
6255 }
6256 runtime.GC()
6257
6258 for i, xi := range x {
6259 v := ValueOf(xi).Elem()
6260 for j := 0; j < n; j++ {
6261 pv, _ := v.Recv()
6262 k := pv.Elem().Interface()
6263 if k != uintptr(i*n+j) {
6264 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
6265 }
6266 }
6267 }
6268 }
6269
6270 func TestMapOf(t *testing.T) {
6271
6272 type K string
6273 type V float64
6274
6275 v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
6276 runtime.GC()
6277 v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
6278 runtime.GC()
6279
6280 s := fmt.Sprint(v.Interface())
6281 want := "map[a:1]"
6282 if s != want {
6283 t.Errorf("constructed map = %s, want %s", s, want)
6284 }
6285
6286
6287 checkSameType(t, MapOf(TypeOf(V(0)), TypeOf(K(""))), map[V]K(nil))
6288
6289
6290 shouldPanic("invalid key type", func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
6291 }
6292
6293 func TestMapOfGCKeys(t *testing.T) {
6294 type T *uintptr
6295 tt := TypeOf(T(nil))
6296 mt := MapOf(tt, TypeOf(false))
6297
6298
6299
6300
6301 const n = 100
6302 var x []any
6303 for i := 0; i < n; i++ {
6304 v := MakeMap(mt)
6305 for j := 0; j < n; j++ {
6306 p := new(uintptr)
6307 *p = uintptr(i*n + j)
6308 v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
6309 }
6310 pv := New(mt)
6311 pv.Elem().Set(v)
6312 x = append(x, pv.Interface())
6313 }
6314 runtime.GC()
6315
6316 for i, xi := range x {
6317 v := ValueOf(xi).Elem()
6318 var out []int
6319 for _, kv := range v.MapKeys() {
6320 out = append(out, int(kv.Elem().Interface().(uintptr)))
6321 }
6322 slices.Sort(out)
6323 for j, k := range out {
6324 if k != i*n+j {
6325 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
6326 }
6327 }
6328 }
6329 }
6330
6331
6332 func TestMapOfGCBigKey(t *testing.T) {
6333 type KV struct {
6334 i int64
6335 j int64
6336 }
6337
6338 kvTyp := TypeFor[KV]()
6339 mt := MapOf(kvTyp, kvTyp)
6340
6341 const n = 100
6342 m := MakeMap(mt)
6343 for i := 0; i < n; i++ {
6344 kv := KV{int64(i), int64(i + 1)}
6345 m.SetMapIndex(ValueOf(kv), ValueOf(kv))
6346 }
6347
6348 for i := 0; i < n; i++ {
6349 kv := KV{int64(i), int64(i + 1)}
6350 elem := m.MapIndex(ValueOf(kv)).Interface().(KV)
6351 if elem != kv {
6352 t.Errorf("lost m[%v] = %v, want %v", kv, elem, kv)
6353 }
6354 }
6355 }
6356
6357 func TestMapOfGCValues(t *testing.T) {
6358 type T *uintptr
6359 tt := TypeOf(T(nil))
6360 mt := MapOf(TypeOf(1), tt)
6361
6362
6363
6364
6365 const n = 100
6366 var x []any
6367 for i := 0; i < n; i++ {
6368 v := MakeMap(mt)
6369 for j := 0; j < n; j++ {
6370 p := new(uintptr)
6371 *p = uintptr(i*n + j)
6372 v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
6373 }
6374 pv := New(mt)
6375 pv.Elem().Set(v)
6376 x = append(x, pv.Interface())
6377 }
6378 runtime.GC()
6379
6380 for i, xi := range x {
6381 v := ValueOf(xi).Elem()
6382 for j := 0; j < n; j++ {
6383 k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
6384 if k != uintptr(i*n+j) {
6385 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
6386 }
6387 }
6388 }
6389 }
6390
6391 func TestTypelinksSorted(t *testing.T) {
6392 var last string
6393 for i, n := range TypeLinks() {
6394 if n < last {
6395 t.Errorf("typelinks not sorted: %q [%d] > %q [%d]", last, i-1, n, i)
6396 }
6397 last = n
6398 }
6399 }
6400
6401 func TestFuncOf(t *testing.T) {
6402
6403 type K string
6404 type V float64
6405
6406 fn := func(args []Value) []Value {
6407 if len(args) != 1 {
6408 t.Errorf("args == %v, want exactly one arg", args)
6409 } else if args[0].Type() != TypeOf(K("")) {
6410 t.Errorf("args[0] is type %v, want %v", args[0].Type(), TypeOf(K("")))
6411 } else if args[0].String() != "gopher" {
6412 t.Errorf("args[0] = %q, want %q", args[0].String(), "gopher")
6413 }
6414 return []Value{ValueOf(V(3.14))}
6415 }
6416 v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
6417
6418 outs := v.Call([]Value{ValueOf(K("gopher"))})
6419 if len(outs) != 1 {
6420 t.Fatalf("v.Call returned %v, want exactly one result", outs)
6421 } else if outs[0].Type() != TypeOf(V(0)) {
6422 t.Fatalf("c.Call[0] is type %v, want %v", outs[0].Type(), TypeOf(V(0)))
6423 }
6424 f := outs[0].Float()
6425 if f != 3.14 {
6426 t.Errorf("constructed func returned %f, want %f", f, 3.14)
6427 }
6428
6429
6430 type T1 int
6431 testCases := []struct {
6432 in, out []Type
6433 variadic bool
6434 want any
6435 }{
6436 {in: []Type{TypeOf(T1(0))}, want: (func(T1))(nil)},
6437 {in: []Type{TypeOf(int(0))}, want: (func(int))(nil)},
6438 {in: []Type{SliceOf(TypeOf(int(0)))}, variadic: true, want: (func(...int))(nil)},
6439 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false)}, want: (func(int) bool)(nil)},
6440 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
6441 }
6442 for _, tt := range testCases {
6443 checkSameType(t, FuncOf(tt.in, tt.out, tt.variadic), tt.want)
6444 }
6445
6446
6447 FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
6448 shouldPanic("must be slice", func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
6449 shouldPanic("must be slice", func() { FuncOf(nil, nil, true) })
6450
6451
6452 var in []Type
6453 for i := 0; i < 51; i++ {
6454 in = append(in, TypeOf(1))
6455 }
6456 FuncOf(in, nil, false)
6457 }
6458
6459 type R0 struct {
6460 *R1
6461 *R2
6462 *R3
6463 *R4
6464 }
6465
6466 type R1 struct {
6467 *R5
6468 *R6
6469 *R7
6470 *R8
6471 }
6472
6473 type R2 R1
6474 type R3 R1
6475 type R4 R1
6476
6477 type R5 struct {
6478 *R9
6479 *R10
6480 *R11
6481 *R12
6482 }
6483
6484 type R6 R5
6485 type R7 R5
6486 type R8 R5
6487
6488 type R9 struct {
6489 *R13
6490 *R14
6491 *R15
6492 *R16
6493 }
6494
6495 type R10 R9
6496 type R11 R9
6497 type R12 R9
6498
6499 type R13 struct {
6500 *R17
6501 *R18
6502 *R19
6503 *R20
6504 }
6505
6506 type R14 R13
6507 type R15 R13
6508 type R16 R13
6509
6510 type R17 struct {
6511 *R21
6512 *R22
6513 *R23
6514 *R24
6515 }
6516
6517 type R18 R17
6518 type R19 R17
6519 type R20 R17
6520
6521 type R21 struct {
6522 X int
6523 }
6524
6525 type R22 R21
6526 type R23 R21
6527 type R24 R21
6528
6529 func TestEmbed(t *testing.T) {
6530 typ := TypeOf(R0{})
6531 f, ok := typ.FieldByName("X")
6532 if ok {
6533 t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
6534 }
6535 }
6536
6537 func TestAllocsInterfaceBig(t *testing.T) {
6538 if testing.Short() {
6539 t.Skip("skipping malloc count in short mode")
6540 }
6541 v := ValueOf(S{})
6542 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
6543 t.Error("allocs:", allocs)
6544 }
6545 }
6546
6547 func TestAllocsInterfaceSmall(t *testing.T) {
6548 if testing.Short() {
6549 t.Skip("skipping malloc count in short mode")
6550 }
6551 v := ValueOf(int64(0))
6552 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
6553 t.Error("allocs:", allocs)
6554 }
6555 }
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599 type exhaustive struct {
6600 r *rand.Rand
6601 pos int
6602 last []choice
6603 }
6604
6605 type choice struct {
6606 off int
6607 n int
6608 max int
6609 }
6610
6611 func (x *exhaustive) Next() bool {
6612 if x.r == nil {
6613 x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
6614 }
6615 x.pos = 0
6616 if x.last == nil {
6617 x.last = []choice{}
6618 return true
6619 }
6620 for i := len(x.last) - 1; i >= 0; i-- {
6621 c := &x.last[i]
6622 if c.n+1 < c.max {
6623 c.n++
6624 x.last = x.last[:i+1]
6625 return true
6626 }
6627 }
6628 return false
6629 }
6630
6631 func (x *exhaustive) Choose(max int) int {
6632 if x.pos >= len(x.last) {
6633 x.last = append(x.last, choice{x.r.Intn(max), 0, max})
6634 }
6635 c := &x.last[x.pos]
6636 x.pos++
6637 if c.max != max {
6638 panic("inconsistent use of exhaustive tester")
6639 }
6640 return (c.n + c.off) % max
6641 }
6642
6643 func (x *exhaustive) Maybe() bool {
6644 return x.Choose(2) == 1
6645 }
6646
6647 func GCFunc(args []Value) []Value {
6648 runtime.GC()
6649 return []Value{}
6650 }
6651
6652 func TestReflectFuncTraceback(t *testing.T) {
6653 f := MakeFunc(TypeOf(func() {}), GCFunc)
6654 f.Call([]Value{})
6655 }
6656
6657 func TestReflectMethodTraceback(t *testing.T) {
6658 p := Point{3, 4}
6659 m := ValueOf(p).MethodByName("GCMethod")
6660 i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
6661 if i != 8 {
6662 t.Errorf("Call returned %d; want 8", i)
6663 }
6664 }
6665
6666 func TestSmallZero(t *testing.T) {
6667 type T [10]byte
6668 typ := TypeOf(T{})
6669 if allocs := testing.AllocsPerRun(100, func() { Zero(typ) }); allocs > 0 {
6670 t.Errorf("Creating small zero values caused %f allocs, want 0", allocs)
6671 }
6672 }
6673
6674 func TestBigZero(t *testing.T) {
6675 const size = 1 << 10
6676 var v [size]byte
6677 z := Zero(ValueOf(v).Type()).Interface().([size]byte)
6678 for i := 0; i < size; i++ {
6679 if z[i] != 0 {
6680 t.Fatalf("Zero object not all zero, index %d", i)
6681 }
6682 }
6683 }
6684
6685 func TestZeroSet(t *testing.T) {
6686 type T [16]byte
6687 type S struct {
6688 a uint64
6689 T T
6690 b uint64
6691 }
6692 v := S{
6693 a: 0xaaaaaaaaaaaaaaaa,
6694 T: T{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9},
6695 b: 0xbbbbbbbbbbbbbbbb,
6696 }
6697 ValueOf(&v).Elem().Field(1).Set(Zero(TypeOf(T{})))
6698 if v != (S{
6699 a: 0xaaaaaaaaaaaaaaaa,
6700 b: 0xbbbbbbbbbbbbbbbb,
6701 }) {
6702 t.Fatalf("Setting a field to a Zero value didn't work")
6703 }
6704 }
6705
6706 func TestFieldByIndexNil(t *testing.T) {
6707 type P struct {
6708 F int
6709 }
6710 type T struct {
6711 *P
6712 }
6713 v := ValueOf(T{})
6714
6715 v.FieldByName("P")
6716
6717 defer func() {
6718 if err := recover(); err == nil {
6719 t.Fatalf("no error")
6720 } else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
6721 t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
6722 }
6723 }()
6724 v.FieldByName("F")
6725
6726 t.Fatalf("did not panic")
6727 }
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770 type Outer struct {
6771 *Inner
6772 R io.Reader
6773 }
6774
6775 type Inner struct {
6776 X *Outer
6777 P1 uintptr
6778 P2 uintptr
6779 }
6780
6781 func (pi *Inner) M() {
6782
6783
6784
6785 pi.X.Inner = nil
6786
6787
6788
6789
6790
6791
6792 pi.P1 = 1
6793 pi.P2 = uintptr(unsafe.Pointer(pi))
6794 }
6795
6796 func TestCallMethodJump(t *testing.T) {
6797
6798
6799
6800 *CallGC = true
6801
6802 p := &Outer{Inner: new(Inner)}
6803 p.Inner.X = p
6804 ValueOf(p).Method(0).Call(nil)
6805
6806
6807 *CallGC = false
6808 }
6809
6810 func TestCallArgLive(t *testing.T) {
6811 type T struct{ X, Y *string }
6812
6813 F := func(t T) { *t.X = "ok" }
6814
6815
6816
6817 *CallGC = true
6818
6819 x := new(string)
6820 runtime.SetFinalizer(x, func(p *string) {
6821 if *p != "ok" {
6822 t.Errorf("x dead prematurely")
6823 }
6824 })
6825 v := T{x, nil}
6826
6827 ValueOf(F).Call([]Value{ValueOf(v)})
6828
6829
6830 *CallGC = false
6831 }
6832
6833 func TestMakeFuncStackCopy(t *testing.T) {
6834 target := func(in []Value) []Value {
6835 runtime.GC()
6836 useStack(16)
6837 return []Value{ValueOf(9)}
6838 }
6839
6840 var concrete func(*int, int) int
6841 fn := MakeFunc(ValueOf(concrete).Type(), target)
6842 ValueOf(&concrete).Elem().Set(fn)
6843 x := concrete(nil, 7)
6844 if x != 9 {
6845 t.Errorf("have %d want 9", x)
6846 }
6847 }
6848
6849
6850 func useStack(n int) {
6851 if n == 0 {
6852 return
6853 }
6854 var b [1024]byte
6855 useStack(n - 1 + int(b[99]))
6856 }
6857
6858 type Impl struct{}
6859
6860 func (Impl) F() {}
6861
6862 func TestValueString(t *testing.T) {
6863 rv := ValueOf(Impl{})
6864 if rv.String() != "<reflect_test.Impl Value>" {
6865 t.Errorf("ValueOf(Impl{}).String() = %q, want %q", rv.String(), "<reflect_test.Impl Value>")
6866 }
6867
6868 method := rv.Method(0)
6869 if method.String() != "<func() Value>" {
6870 t.Errorf("ValueOf(Impl{}).Method(0).String() = %q, want %q", method.String(), "<func() Value>")
6871 }
6872 }
6873
6874 func TestInvalid(t *testing.T) {
6875
6876 type T struct{ v any }
6877
6878 v := ValueOf(T{}).Field(0)
6879 if v.IsValid() != true || v.Kind() != Interface {
6880 t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
6881 }
6882 v = v.Elem()
6883 if v.IsValid() != false || v.Kind() != Invalid {
6884 t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
6885 }
6886 }
6887
6888
6889 func TestLarge(t *testing.T) {
6890 fv := ValueOf(func([256]*byte) {})
6891 fv.Call([]Value{ValueOf([256]*byte{})})
6892 }
6893
6894 func fieldIndexRecover(t Type, i int) (recovered any) {
6895 defer func() {
6896 recovered = recover()
6897 }()
6898
6899 t.Field(i)
6900 return
6901 }
6902
6903
6904 func TestTypeFieldOutOfRangePanic(t *testing.T) {
6905 typ := TypeOf(struct{ X int }{10})
6906 testIndices := [...]struct {
6907 i int
6908 mustPanic bool
6909 }{
6910 0: {-2, true},
6911 1: {0, false},
6912 2: {1, true},
6913 3: {1 << 10, true},
6914 }
6915 for i, tt := range testIndices {
6916 recoveredErr := fieldIndexRecover(typ, tt.i)
6917 if tt.mustPanic {
6918 if recoveredErr == nil {
6919 t.Errorf("#%d: fieldIndex %d expected to panic", i, tt.i)
6920 }
6921 } else {
6922 if recoveredErr != nil {
6923 t.Errorf("#%d: got err=%v, expected no panic", i, recoveredErr)
6924 }
6925 }
6926 }
6927 }
6928
6929 func TestTypeFieldReadOnly(t *testing.T) {
6930 if runtime.GOOS == "js" || runtime.GOOS == "wasip1" {
6931
6932
6933 t.Skip("test does not fault on GOOS=js")
6934 }
6935
6936
6937
6938
6939
6940 typ := TypeFor[struct{ f int }]()
6941 f := typ.Field(0)
6942 defer debug.SetPanicOnFault(debug.SetPanicOnFault(true))
6943 shouldPanic("", func() {
6944 f.Index[0] = 1
6945 })
6946 }
6947
6948
6949 func TestCallGC(t *testing.T) {
6950 f := func(a, b, c, d, e string) {
6951 }
6952 g := func(in []Value) []Value {
6953 runtime.GC()
6954 return nil
6955 }
6956 typ := ValueOf(f).Type()
6957 f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string))
6958 f2("four", "five5", "six666", "seven77", "eight888")
6959 }
6960
6961
6962 func TestKeepFuncLive(t *testing.T) {
6963
6964
6965 typ := TypeOf(func(i int) {})
6966 var f, g func(in []Value) []Value
6967 f = func(in []Value) []Value {
6968 clobber()
6969 i := int(in[0].Int())
6970 if i > 0 {
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981 MakeFunc(typ, g).Interface().(func(i int))(i - 1)
6982 }
6983 return nil
6984 }
6985 g = func(in []Value) []Value {
6986 clobber()
6987 i := int(in[0].Int())
6988 MakeFunc(typ, f).Interface().(func(i int))(i)
6989 return nil
6990 }
6991 MakeFunc(typ, f).Call([]Value{ValueOf(10)})
6992 }
6993
6994 type UnExportedFirst int
6995
6996 func (i UnExportedFirst) ΦExported() {}
6997 func (i UnExportedFirst) unexported() {}
6998
6999
7000 func TestMethodByNameUnExportedFirst(t *testing.T) {
7001 defer func() {
7002 if recover() != nil {
7003 t.Errorf("should not panic")
7004 }
7005 }()
7006 typ := TypeOf(UnExportedFirst(0))
7007 m, _ := typ.MethodByName("ΦExported")
7008 if m.Name != "ΦExported" {
7009 t.Errorf("got %s, expected ΦExported", m.Name)
7010 }
7011 }
7012
7013
7014 type KeepMethodLive struct{}
7015
7016 func (k KeepMethodLive) Method1(i int) {
7017 clobber()
7018 if i > 0 {
7019 ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1)
7020 }
7021 }
7022
7023 func (k KeepMethodLive) Method2(i int) {
7024 clobber()
7025 ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i)
7026 }
7027
7028 func TestKeepMethodLive(t *testing.T) {
7029
7030
7031 KeepMethodLive{}.Method1(10)
7032 }
7033
7034
7035 func clobber() {
7036 runtime.GC()
7037 for i := 1; i < 32; i++ {
7038 for j := 0; j < 10; j++ {
7039 obj := make([]*byte, i)
7040 sink = obj
7041 }
7042 }
7043 runtime.GC()
7044 }
7045
7046 func TestFuncLayout(t *testing.T) {
7047 align := func(x uintptr) uintptr {
7048 return (x + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
7049 }
7050 var r []byte
7051 if goarch.PtrSize == 4 {
7052 r = []byte{0, 0, 0, 1}
7053 } else {
7054 r = []byte{0, 0, 1}
7055 }
7056
7057 type S struct {
7058 a, b uintptr
7059 c, d *byte
7060 }
7061
7062 type test struct {
7063 rcvr, typ Type
7064 size, argsize, retOffset uintptr
7065 stack, gc, inRegs, outRegs []byte
7066 intRegs, floatRegs int
7067 floatRegSize uintptr
7068 }
7069 tests := []test{
7070 {
7071 typ: ValueOf(func(a, b string) string { return "" }).Type(),
7072 size: 6 * goarch.PtrSize,
7073 argsize: 4 * goarch.PtrSize,
7074 retOffset: 4 * goarch.PtrSize,
7075 stack: []byte{1, 0, 1, 0, 1},
7076 gc: []byte{1, 0, 1, 0, 1},
7077 },
7078 {
7079 typ: ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
7080 size: align(align(3*4) + goarch.PtrSize + 2),
7081 argsize: align(3*4) + goarch.PtrSize + 2,
7082 retOffset: align(align(3*4) + goarch.PtrSize + 2),
7083 stack: r,
7084 gc: r,
7085 },
7086 {
7087 typ: ValueOf(func(a map[int]int, b uintptr, c any) {}).Type(),
7088 size: 4 * goarch.PtrSize,
7089 argsize: 4 * goarch.PtrSize,
7090 retOffset: 4 * goarch.PtrSize,
7091 stack: []byte{1, 0, 1, 1},
7092 gc: []byte{1, 0, 1, 1},
7093 },
7094 {
7095 typ: ValueOf(func(a S) {}).Type(),
7096 size: 4 * goarch.PtrSize,
7097 argsize: 4 * goarch.PtrSize,
7098 retOffset: 4 * goarch.PtrSize,
7099 stack: []byte{0, 0, 1, 1},
7100 gc: []byte{0, 0, 1, 1},
7101 },
7102 {
7103 rcvr: ValueOf((*byte)(nil)).Type(),
7104 typ: ValueOf(func(a uintptr, b *int) {}).Type(),
7105 size: 3 * goarch.PtrSize,
7106 argsize: 3 * goarch.PtrSize,
7107 retOffset: 3 * goarch.PtrSize,
7108 stack: []byte{1, 0, 1},
7109 gc: []byte{1, 0, 1},
7110 },
7111 {
7112 typ: ValueOf(func(a uintptr) {}).Type(),
7113 size: goarch.PtrSize,
7114 argsize: goarch.PtrSize,
7115 retOffset: goarch.PtrSize,
7116 stack: []byte{},
7117 gc: []byte{},
7118 },
7119 {
7120 typ: ValueOf(func() uintptr { return 0 }).Type(),
7121 size: goarch.PtrSize,
7122 argsize: 0,
7123 retOffset: 0,
7124 stack: []byte{},
7125 gc: []byte{},
7126 },
7127 {
7128 rcvr: ValueOf(uintptr(0)).Type(),
7129 typ: ValueOf(func(a uintptr) {}).Type(),
7130 size: 2 * goarch.PtrSize,
7131 argsize: 2 * goarch.PtrSize,
7132 retOffset: 2 * goarch.PtrSize,
7133 stack: []byte{1},
7134 gc: []byte{1},
7135
7136
7137
7138 },
7139
7140 }
7141 for _, lt := range tests {
7142 name := lt.typ.String()
7143 if lt.rcvr != nil {
7144 name = lt.rcvr.String() + "." + name
7145 }
7146 t.Run(name, func(t *testing.T) {
7147 defer SetArgRegs(SetArgRegs(lt.intRegs, lt.floatRegs, lt.floatRegSize))
7148
7149 typ, argsize, retOffset, stack, gc, inRegs, outRegs, ptrs := FuncLayout(lt.typ, lt.rcvr)
7150 if typ.Size() != lt.size {
7151 t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.typ, lt.rcvr, typ.Size(), lt.size)
7152 }
7153 if argsize != lt.argsize {
7154 t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.typ, lt.rcvr, argsize, lt.argsize)
7155 }
7156 if retOffset != lt.retOffset {
7157 t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.typ, lt.rcvr, retOffset, lt.retOffset)
7158 }
7159 if !bytes.Equal(stack, lt.stack) {
7160 t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.typ, lt.rcvr, stack, lt.stack)
7161 }
7162 if !bytes.Equal(gc, lt.gc) {
7163 t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.typ, lt.rcvr, gc, lt.gc)
7164 }
7165 if !bytes.Equal(inRegs, lt.inRegs) {
7166 t.Errorf("funcLayout(%v, %v).inRegs=%v, want %v", lt.typ, lt.rcvr, inRegs, lt.inRegs)
7167 }
7168 if !bytes.Equal(outRegs, lt.outRegs) {
7169 t.Errorf("funcLayout(%v, %v).outRegs=%v, want %v", lt.typ, lt.rcvr, outRegs, lt.outRegs)
7170 }
7171 if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
7172 t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.typ, lt.rcvr, ptrs, !ptrs)
7173 }
7174 })
7175 }
7176 }
7177
7178
7179 func trimBitmap(b []byte) []byte {
7180 for len(b) > 0 && b[len(b)-1] == 0 {
7181 b = b[:len(b)-1]
7182 }
7183 return b
7184 }
7185
7186 func verifyGCBits(t *testing.T, typ Type, bits []byte) {
7187 heapBits := GCBits(New(typ).Interface())
7188
7189
7190
7191 bits = trimBitmap(bits)
7192
7193 if bytes.HasPrefix(heapBits, bits) {
7194
7195
7196
7197
7198
7199
7200
7201 return
7202 }
7203 _, _, line, _ := runtime.Caller(1)
7204 t.Errorf("line %d: heapBits incorrect for %v\nhave %v\nwant %v", line, typ, heapBits, bits)
7205 }
7206
7207 func verifyGCBitsSlice(t *testing.T, typ Type, cap int, bits []byte) {
7208
7209
7210
7211
7212 val := MakeSlice(typ, 0, cap)
7213 data := NewAt(typ.Elem(), val.UnsafePointer())
7214 heapBits := GCBits(data.Interface())
7215
7216
7217 bits = trimBitmap(rep(cap, bits))
7218 if bytes.Equal(heapBits, bits) {
7219 return
7220 }
7221 if len(heapBits) > len(bits) && bytes.Equal(heapBits[:len(bits)], bits) {
7222
7223 return
7224 }
7225 _, _, line, _ := runtime.Caller(1)
7226 t.Errorf("line %d: heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", line, typ, cap, heapBits, bits)
7227 }
7228
7229
7230
7231
7232 type Xscalar struct{ x uintptr }
7233 type Xptr struct{ x *byte }
7234 type Xptrscalar struct {
7235 *byte
7236 uintptr
7237 }
7238 type Xscalarptr struct {
7239 uintptr
7240 *byte
7241 }
7242 type Xbigptrscalar struct {
7243 _ [100]*byte
7244 _ [100]uintptr
7245 }
7246
7247 var Tscalar, Tint64, Tptr, Tscalarptr, Tptrscalar, Tbigptrscalar Type
7248
7249 func init() {
7250
7251
7252
7253
7254
7255
7256
7257 type Scalar struct{ x uintptr }
7258 type Ptr struct{ x *byte }
7259 type Ptrscalar struct {
7260 *byte
7261 uintptr
7262 }
7263 type Scalarptr struct {
7264 uintptr
7265 *byte
7266 }
7267 type Bigptrscalar struct {
7268 _ [100]*byte
7269 _ [100]uintptr
7270 }
7271 type Int64 int64
7272 Tscalar = TypeOf(Scalar{})
7273 Tint64 = TypeOf(Int64(0))
7274 Tptr = TypeOf(Ptr{})
7275 Tscalarptr = TypeOf(Scalarptr{})
7276 Tptrscalar = TypeOf(Ptrscalar{})
7277 Tbigptrscalar = TypeOf(Bigptrscalar{})
7278 }
7279
7280 var empty = []byte{}
7281
7282 func TestGCBits(t *testing.T) {
7283 verifyGCBits(t, TypeOf((*byte)(nil)), []byte{1})
7284
7285 verifyGCBits(t, TypeOf(Xscalar{}), empty)
7286 verifyGCBits(t, Tscalar, empty)
7287 verifyGCBits(t, TypeOf(Xptr{}), lit(1))
7288 verifyGCBits(t, Tptr, lit(1))
7289 verifyGCBits(t, TypeOf(Xscalarptr{}), lit(0, 1))
7290 verifyGCBits(t, Tscalarptr, lit(0, 1))
7291 verifyGCBits(t, TypeOf(Xptrscalar{}), lit(1))
7292 verifyGCBits(t, Tptrscalar, lit(1))
7293
7294 verifyGCBits(t, TypeOf([0]Xptr{}), empty)
7295 verifyGCBits(t, ArrayOf(0, Tptr), empty)
7296 verifyGCBits(t, TypeOf([1]Xptrscalar{}), lit(1))
7297 verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
7298 verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
7299 verifyGCBits(t, ArrayOf(2, Tscalar), empty)
7300 verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
7301 verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
7302 verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
7303 verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
7304 verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
7305 verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
7306 verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
7307 verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
7308 verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
7309 verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
7310 verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
7311 verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
7312 verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
7313 verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
7314 verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
7315 verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
7316 verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
7317 verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
7318 verifyGCBits(t, TypeOf([4]Xbigptrscalar{}), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
7319 verifyGCBits(t, ArrayOf(4, Tbigptrscalar), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
7320
7321 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 0, empty)
7322 verifyGCBitsSlice(t, SliceOf(Tptr), 0, empty)
7323 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 1, lit(1))
7324 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 1, lit(1))
7325 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 2, lit(0))
7326 verifyGCBitsSlice(t, SliceOf(Tscalar), 2, lit(0))
7327 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 10000, lit(0))
7328 verifyGCBitsSlice(t, SliceOf(Tscalar), 10000, lit(0))
7329 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 2, lit(1))
7330 verifyGCBitsSlice(t, SliceOf(Tptr), 2, lit(1))
7331 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 10000, lit(1))
7332 verifyGCBitsSlice(t, SliceOf(Tptr), 10000, lit(1))
7333 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 2, lit(0, 1))
7334 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 2, lit(0, 1))
7335 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 10000, lit(0, 1))
7336 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 10000, lit(0, 1))
7337 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 2, lit(1, 0))
7338 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 2, lit(1, 0))
7339 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 10000, lit(1, 0))
7340 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 10000, lit(1, 0))
7341 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 1, rep(10000, lit(1, 0)))
7342 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 1, rep(10000, lit(1, 0)))
7343 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 2, rep(10000, lit(1, 0)))
7344 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 2, rep(10000, lit(1, 0)))
7345 verifyGCBitsSlice(t, TypeOf([]Xbigptrscalar{}), 4, join(rep(100, lit(1)), rep(100, lit(0))))
7346 verifyGCBitsSlice(t, SliceOf(Tbigptrscalar), 4, join(rep(100, lit(1)), rep(100, lit(0))))
7347
7348 verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
7349 verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
7350
7351 verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
7352 verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
7353
7354 verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
7355 verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
7356
7357 verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
7358 verifyGCBits(t, PointerTo(ArrayOf(10000, Tscalar)), lit(1))
7359
7360 verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
7361 verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
7362
7363
7364
7365 }
7366
7367 func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) }
7368 func join(b ...[]byte) []byte { return bytes.Join(b, nil) }
7369 func lit(x ...byte) []byte { return x }
7370
7371 func TestTypeOfTypeOf(t *testing.T) {
7372
7373
7374
7375 check := func(name string, typ Type) {
7376 if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
7377 t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
7378 }
7379 }
7380
7381 type T struct{ int }
7382 check("TypeOf", TypeOf(T{}))
7383
7384 check("ArrayOf", ArrayOf(10, TypeOf(T{})))
7385 check("ChanOf", ChanOf(BothDir, TypeOf(T{})))
7386 check("FuncOf", FuncOf([]Type{TypeOf(T{})}, nil, false))
7387 check("MapOf", MapOf(TypeOf(T{}), TypeOf(T{})))
7388 check("PtrTo", PointerTo(TypeOf(T{})))
7389 check("SliceOf", SliceOf(TypeOf(T{})))
7390 }
7391
7392 type XM struct{ _ bool }
7393
7394 func (*XM) String() string { return "" }
7395
7396 func TestPtrToMethods(t *testing.T) {
7397 var y struct{ XM }
7398 yp := New(TypeOf(y)).Interface()
7399 _, ok := yp.(fmt.Stringer)
7400 if !ok {
7401 t.Fatal("does not implement Stringer, but should")
7402 }
7403 }
7404
7405 func TestMapAlloc(t *testing.T) {
7406 if asan.Enabled {
7407 t.Skip("test allocates more with -asan; see #70079")
7408 }
7409 m := ValueOf(make(map[int]int, 10))
7410 k := ValueOf(5)
7411 v := ValueOf(7)
7412 allocs := testing.AllocsPerRun(100, func() {
7413 m.SetMapIndex(k, v)
7414 })
7415 if allocs > 0.5 {
7416 t.Errorf("allocs per map assignment: want 0 got %f", allocs)
7417 }
7418
7419 const size = 1000
7420 tmp := 0
7421 val := ValueOf(&tmp).Elem()
7422 allocs = testing.AllocsPerRun(100, func() {
7423 mv := MakeMapWithSize(TypeOf(map[int]int{}), size)
7424
7425 for i := 0; i < size/2; i++ {
7426 val.SetInt(int64(i))
7427 mv.SetMapIndex(val, val)
7428 }
7429 })
7430 if allocs > 10 {
7431 t.Errorf("allocs per map assignment: want at most 10 got %f", allocs)
7432 }
7433
7434
7435
7436 }
7437
7438 func TestChanAlloc(t *testing.T) {
7439 if asan.Enabled {
7440 t.Skip("test allocates more with -asan; see #70079")
7441 }
7442
7443
7444 c := ValueOf(make(chan *int, 1))
7445 v := ValueOf(new(int))
7446 allocs := testing.AllocsPerRun(100, func() {
7447 c.Send(v)
7448 _, _ = c.Recv()
7449 })
7450 if allocs < 0.5 || allocs > 1.5 {
7451 t.Errorf("allocs per chan send/recv: want 1 got %f", allocs)
7452 }
7453
7454
7455
7456 }
7457
7458 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
7459
7460 type nameTest struct {
7461 v any
7462 want string
7463 }
7464
7465 var nameTests = []nameTest{
7466 {(*int32)(nil), "int32"},
7467 {(*D1)(nil), "D1"},
7468 {(*[]D1)(nil), ""},
7469 {(*chan D1)(nil), ""},
7470 {(*func() D1)(nil), ""},
7471 {(*<-chan D1)(nil), ""},
7472 {(*chan<- D1)(nil), ""},
7473 {(*any)(nil), ""},
7474 {(*interface {
7475 F()
7476 })(nil), ""},
7477 {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
7478 }
7479
7480 func TestNames(t *testing.T) {
7481 for _, test := range nameTests {
7482 typ := TypeOf(test.v).Elem()
7483 if got := typ.Name(); got != test.want {
7484 t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
7485 }
7486 }
7487 }
7488
7489 func TestExported(t *testing.T) {
7490 type ΦExported struct{}
7491 type φUnexported struct{}
7492 type BigP *big
7493 type P int
7494 type p *P
7495 type P2 p
7496 type p3 p
7497
7498 type exportTest struct {
7499 v any
7500 want bool
7501 }
7502 exportTests := []exportTest{
7503 {D1{}, true},
7504 {(*D1)(nil), true},
7505 {big{}, false},
7506 {(*big)(nil), false},
7507 {(BigP)(nil), true},
7508 {(*BigP)(nil), true},
7509 {ΦExported{}, true},
7510 {φUnexported{}, false},
7511 {P(0), true},
7512 {(p)(nil), false},
7513 {(P2)(nil), true},
7514 {(p3)(nil), false},
7515 }
7516
7517 for i, test := range exportTests {
7518 typ := TypeOf(test.v)
7519 if got := IsExported(typ); got != test.want {
7520 t.Errorf("%d: %s exported=%v, want %v", i, typ.Name(), got, test.want)
7521 }
7522 }
7523 }
7524
7525 func TestTypeStrings(t *testing.T) {
7526 type stringTest struct {
7527 typ Type
7528 want string
7529 }
7530 stringTests := []stringTest{
7531 {TypeOf(func(int) {}), "func(int)"},
7532 {FuncOf([]Type{TypeOf(int(0))}, nil, false), "func(int)"},
7533 {TypeOf(XM{}), "reflect_test.XM"},
7534 {TypeOf(new(XM)), "*reflect_test.XM"},
7535 {TypeOf(new(XM).String), "func() string"},
7536 {TypeOf(new(XM)).Method(0).Type, "func(*reflect_test.XM) string"},
7537 {ChanOf(3, TypeOf(XM{})), "chan reflect_test.XM"},
7538 {MapOf(TypeOf(int(0)), TypeOf(XM{})), "map[int]reflect_test.XM"},
7539 {ArrayOf(3, TypeOf(XM{})), "[3]reflect_test.XM"},
7540 {ArrayOf(3, TypeOf(struct{}{})), "[3]struct {}"},
7541 }
7542
7543 for i, test := range stringTests {
7544 if got, want := test.typ.String(), test.want; got != want {
7545 t.Errorf("type %d String()=%q, want %q", i, got, want)
7546 }
7547 }
7548 }
7549
7550 func TestOffsetLock(t *testing.T) {
7551 var wg sync.WaitGroup
7552 for i := 0; i < 4; i++ {
7553 wg.Add(1)
7554 go func() {
7555 for j := 0; j < 50; j++ {
7556 ResolveReflectName(fmt.Sprintf("OffsetLockName:%d:%d", i, j))
7557 }
7558 wg.Done()
7559 }()
7560 }
7561 wg.Wait()
7562 }
7563
7564 func TestSwapper(t *testing.T) {
7565 type I int
7566 var a, b, c I
7567 type pair struct {
7568 x, y int
7569 }
7570 type pairPtr struct {
7571 x, y int
7572 p *I
7573 }
7574 type S string
7575
7576 tests := []struct {
7577 in any
7578 i, j int
7579 want any
7580 }{
7581 {
7582 in: []int{1, 20, 300},
7583 i: 0,
7584 j: 2,
7585 want: []int{300, 20, 1},
7586 },
7587 {
7588 in: []uintptr{1, 20, 300},
7589 i: 0,
7590 j: 2,
7591 want: []uintptr{300, 20, 1},
7592 },
7593 {
7594 in: []int16{1, 20, 300},
7595 i: 0,
7596 j: 2,
7597 want: []int16{300, 20, 1},
7598 },
7599 {
7600 in: []int8{1, 20, 100},
7601 i: 0,
7602 j: 2,
7603 want: []int8{100, 20, 1},
7604 },
7605 {
7606 in: []*I{&a, &b, &c},
7607 i: 0,
7608 j: 2,
7609 want: []*I{&c, &b, &a},
7610 },
7611 {
7612 in: []string{"eric", "sergey", "larry"},
7613 i: 0,
7614 j: 2,
7615 want: []string{"larry", "sergey", "eric"},
7616 },
7617 {
7618 in: []S{"eric", "sergey", "larry"},
7619 i: 0,
7620 j: 2,
7621 want: []S{"larry", "sergey", "eric"},
7622 },
7623 {
7624 in: []pair{{1, 2}, {3, 4}, {5, 6}},
7625 i: 0,
7626 j: 2,
7627 want: []pair{{5, 6}, {3, 4}, {1, 2}},
7628 },
7629 {
7630 in: []pairPtr{{1, 2, &a}, {3, 4, &b}, {5, 6, &c}},
7631 i: 0,
7632 j: 2,
7633 want: []pairPtr{{5, 6, &c}, {3, 4, &b}, {1, 2, &a}},
7634 },
7635 }
7636
7637 for i, tt := range tests {
7638 inStr := fmt.Sprint(tt.in)
7639 Swapper(tt.in)(tt.i, tt.j)
7640 if !DeepEqual(tt.in, tt.want) {
7641 t.Errorf("%d. swapping %v and %v of %v = %v; want %v", i, tt.i, tt.j, inStr, tt.in, tt.want)
7642 }
7643 }
7644 }
7645
7646
7647
7648
7649
7650
7651 func TestUnaddressableField(t *testing.T) {
7652 var b Buffer
7653 var localBuffer struct {
7654 buf []byte
7655 }
7656 lv := ValueOf(&localBuffer).Elem()
7657 rv := ValueOf(b)
7658 shouldPanic("Set", func() {
7659 lv.Set(rv)
7660 })
7661 }
7662
7663 type Tint int
7664
7665 type Tint2 = Tint
7666
7667 type Talias1 struct {
7668 byte
7669 uint8
7670 int
7671 int32
7672 rune
7673 }
7674
7675 type Talias2 struct {
7676 Tint
7677 Tint2
7678 }
7679
7680 func TestAliasNames(t *testing.T) {
7681 t1 := Talias1{byte: 1, uint8: 2, int: 3, int32: 4, rune: 5}
7682 out := fmt.Sprintf("%#v", t1)
7683 want := "reflect_test.Talias1{byte:0x1, uint8:0x2, int:3, int32:4, rune:5}"
7684 if out != want {
7685 t.Errorf("Talias1 print:\nhave: %s\nwant: %s", out, want)
7686 }
7687
7688 t2 := Talias2{Tint: 1, Tint2: 2}
7689 out = fmt.Sprintf("%#v", t2)
7690 want = "reflect_test.Talias2{Tint:1, Tint2:2}"
7691 if out != want {
7692 t.Errorf("Talias2 print:\nhave: %s\nwant: %s", out, want)
7693 }
7694 }
7695
7696 func TestIssue22031(t *testing.T) {
7697 type s []struct{ C int }
7698
7699 type t1 struct{ s }
7700 type t2 struct{ f s }
7701
7702 tests := []Value{
7703 ValueOf(t1{s{{}}}).Field(0).Index(0).Field(0),
7704 ValueOf(t2{s{{}}}).Field(0).Index(0).Field(0),
7705 }
7706
7707 for i, test := range tests {
7708 if test.CanSet() {
7709 t.Errorf("%d: CanSet: got true, want false", i)
7710 }
7711 }
7712 }
7713
7714 type NonExportedFirst int
7715
7716 func (i NonExportedFirst) ΦExported() {}
7717 func (i NonExportedFirst) nonexported() int { panic("wrong") }
7718
7719 func TestIssue22073(t *testing.T) {
7720 m := ValueOf(NonExportedFirst(0)).Method(0)
7721
7722 if got := m.Type().NumOut(); got != 0 {
7723 t.Errorf("NumOut: got %v, want 0", got)
7724 }
7725
7726
7727 m.Call(nil)
7728 }
7729
7730 func TestMapIterNonEmptyMap(t *testing.T) {
7731 m := map[string]int{"one": 1, "two": 2, "three": 3}
7732 iter := ValueOf(m).MapRange()
7733 if got, want := iterateToString(iter), `[one: 1, three: 3, two: 2]`; got != want {
7734 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7735 }
7736 }
7737
7738 func TestMapIterNilMap(t *testing.T) {
7739 var m map[string]int
7740 iter := ValueOf(m).MapRange()
7741 if got, want := iterateToString(iter), `[]`; got != want {
7742 t.Errorf("non-empty result iteratoring nil map: %s", got)
7743 }
7744 }
7745
7746 func TestMapIterReset(t *testing.T) {
7747 iter := new(MapIter)
7748
7749
7750 func() {
7751 defer func() { recover() }()
7752 iter.Next()
7753 t.Error("Next did not panic")
7754 }()
7755
7756
7757 m := map[string]int{"one": 1, "two": 2, "three": 3}
7758 iter.Reset(ValueOf(m))
7759 if got, want := iterateToString(iter), `[one: 1, three: 3, two: 2]`; got != want {
7760 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7761 }
7762
7763
7764 iter.Reset(Value{})
7765 func() {
7766 defer func() { recover() }()
7767 iter.Next()
7768 t.Error("Next did not panic")
7769 }()
7770
7771
7772 m2 := map[int]string{1: "one", 2: "two", 3: "three"}
7773 iter.Reset(ValueOf(m2))
7774 if got, want := iterateToString(iter), `[1: one, 2: two, 3: three]`; got != want {
7775 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7776 }
7777
7778
7779 m3 := map[uint64]uint64{
7780 1 << 0: 1 << 1,
7781 1 << 1: 1 << 2,
7782 1 << 2: 1 << 3,
7783 }
7784 kv := New(TypeOf(uint64(0))).Elem()
7785 for i := 0; i < 5; i++ {
7786 var seenk, seenv uint64
7787 iter.Reset(ValueOf(m3))
7788 for iter.Next() {
7789 kv.SetIterKey(iter)
7790 seenk ^= kv.Uint()
7791 kv.SetIterValue(iter)
7792 seenv ^= kv.Uint()
7793 }
7794 if seenk != 0b111 {
7795 t.Errorf("iteration yielded keys %b, want %b", seenk, 0b111)
7796 }
7797 if seenv != 0b1110 {
7798 t.Errorf("iteration yielded values %b, want %b", seenv, 0b1110)
7799 }
7800 }
7801
7802
7803
7804
7805
7806 n := int(testing.AllocsPerRun(10, func() {
7807 iter.Reset(ValueOf(m2))
7808 iter.Reset(Value{})
7809 }))
7810 if !asan.Enabled && n > 0 {
7811 t.Errorf("MapIter.Reset allocated %d times", n)
7812 }
7813 }
7814
7815 func TestMapIterSafety(t *testing.T) {
7816
7817 func() {
7818 defer func() { recover() }()
7819 new(MapIter).Key()
7820 t.Fatal("Key did not panic")
7821 }()
7822 func() {
7823 defer func() { recover() }()
7824 new(MapIter).Value()
7825 t.Fatal("Value did not panic")
7826 }()
7827 func() {
7828 defer func() { recover() }()
7829 new(MapIter).Next()
7830 t.Fatal("Next did not panic")
7831 }()
7832
7833
7834
7835 var m map[string]int
7836 iter := ValueOf(m).MapRange()
7837
7838 func() {
7839 defer func() { recover() }()
7840 iter.Key()
7841 t.Fatal("Key did not panic")
7842 }()
7843 func() {
7844 defer func() { recover() }()
7845 iter.Value()
7846 t.Fatal("Value did not panic")
7847 }()
7848
7849
7850
7851 iter.Next()
7852 func() {
7853 defer func() { recover() }()
7854 iter.Key()
7855 t.Fatal("Key did not panic")
7856 }()
7857 func() {
7858 defer func() { recover() }()
7859 iter.Value()
7860 t.Fatal("Value did not panic")
7861 }()
7862 func() {
7863 defer func() { recover() }()
7864 iter.Next()
7865 t.Fatal("Next did not panic")
7866 }()
7867 }
7868
7869 func TestMapIterNext(t *testing.T) {
7870
7871
7872 m := map[string]int{}
7873 iter := ValueOf(m).MapRange()
7874 m["one"] = 1
7875 if got, want := iterateToString(iter), `[one: 1]`; got != want {
7876 t.Errorf("iterator returned deleted elements: got %s, want %s", got, want)
7877 }
7878 }
7879
7880 func TestMapIterDelete0(t *testing.T) {
7881
7882 m := map[string]int{"one": 1, "two": 2, "three": 3}
7883 iter := ValueOf(m).MapRange()
7884 delete(m, "one")
7885 delete(m, "two")
7886 delete(m, "three")
7887 if got, want := iterateToString(iter), `[]`; got != want {
7888 t.Errorf("iterator returned deleted elements: got %s, want %s", got, want)
7889 }
7890 }
7891
7892 func TestMapIterDelete1(t *testing.T) {
7893
7894 m := map[string]int{"one": 1, "two": 2, "three": 3}
7895 iter := ValueOf(m).MapRange()
7896 var got []string
7897 for iter.Next() {
7898 got = append(got, fmt.Sprint(iter.Key(), iter.Value()))
7899 delete(m, "one")
7900 delete(m, "two")
7901 delete(m, "three")
7902 }
7903 if len(got) != 1 {
7904 t.Errorf("iterator returned wrong number of elements: got %d, want 1", len(got))
7905 }
7906 }
7907
7908
7909
7910 func iterateToString(it *MapIter) string {
7911 var got []string
7912 for it.Next() {
7913 line := fmt.Sprintf("%v: %v", it.Key(), it.Value())
7914 got = append(got, line)
7915 }
7916 slices.Sort(got)
7917 return "[" + strings.Join(got, ", ") + "]"
7918 }
7919
7920 func TestConvertibleTo(t *testing.T) {
7921 t1 := ValueOf(example1.MyStruct{}).Type()
7922 t2 := ValueOf(example2.MyStruct{}).Type()
7923
7924
7925 if t1.ConvertibleTo(t2) {
7926 t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t1, t2)
7927 }
7928
7929 t3 := ValueOf([]example1.MyStruct{}).Type()
7930 t4 := ValueOf([]example2.MyStruct{}).Type()
7931
7932 if t3.ConvertibleTo(t4) {
7933 t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t3, t4)
7934 }
7935 }
7936
7937 func TestSetIter(t *testing.T) {
7938 data := map[string]int{
7939 "foo": 1,
7940 "bar": 2,
7941 "baz": 3,
7942 }
7943
7944 m := ValueOf(data)
7945 i := m.MapRange()
7946 k := New(TypeOf("")).Elem()
7947 v := New(TypeOf(0)).Elem()
7948 shouldPanic("Value.SetIterKey called before Next", func() {
7949 k.SetIterKey(i)
7950 })
7951 shouldPanic("Value.SetIterValue called before Next", func() {
7952 v.SetIterValue(i)
7953 })
7954 data2 := map[string]int{}
7955 for i.Next() {
7956 k.SetIterKey(i)
7957 v.SetIterValue(i)
7958 data2[k.Interface().(string)] = v.Interface().(int)
7959 }
7960 if !DeepEqual(data, data2) {
7961 t.Errorf("maps not equal, got %v want %v", data2, data)
7962 }
7963 shouldPanic("Value.SetIterKey called on exhausted iterator", func() {
7964 k.SetIterKey(i)
7965 })
7966 shouldPanic("Value.SetIterValue called on exhausted iterator", func() {
7967 v.SetIterValue(i)
7968 })
7969
7970 i.Reset(m)
7971 i.Next()
7972 shouldPanic("Value.SetIterKey using unaddressable value", func() {
7973 ValueOf("").SetIterKey(i)
7974 })
7975 shouldPanic("Value.SetIterValue using unaddressable value", func() {
7976 ValueOf(0).SetIterValue(i)
7977 })
7978 shouldPanic("value of type string is not assignable to type int", func() {
7979 New(TypeOf(0)).Elem().SetIterKey(i)
7980 })
7981 shouldPanic("value of type int is not assignable to type string", func() {
7982 New(TypeOf("")).Elem().SetIterValue(i)
7983 })
7984
7985
7986 var x any
7987 y := ValueOf(&x).Elem()
7988 y.SetIterKey(i)
7989 if _, ok := data[x.(string)]; !ok {
7990 t.Errorf("got key %s which is not in map", x)
7991 }
7992 y.SetIterValue(i)
7993 if x.(int) < 1 || x.(int) > 3 {
7994 t.Errorf("got value %d which is not in map", x)
7995 }
7996
7997
7998 a := 88
7999 b := 99
8000 pp := map[*int]*int{
8001 &a: &b,
8002 }
8003 i = ValueOf(pp).MapRange()
8004 i.Next()
8005 y.SetIterKey(i)
8006 if got := *y.Interface().(*int); got != a {
8007 t.Errorf("pointer incorrect: got %d want %d", got, a)
8008 }
8009 y.SetIterValue(i)
8010 if got := *y.Interface().(*int); got != b {
8011 t.Errorf("pointer incorrect: got %d want %d", got, b)
8012 }
8013
8014
8015 m = ValueOf(struct{ m map[string]int }{data}).Field(0)
8016 for iter := m.MapRange(); iter.Next(); {
8017 shouldPanic("using value obtained using unexported field", func() {
8018 k.SetIterKey(iter)
8019 })
8020 shouldPanic("using value obtained using unexported field", func() {
8021 v.SetIterValue(iter)
8022 })
8023 }
8024 }
8025
8026 func TestMethodCallValueCodePtr(t *testing.T) {
8027 m := ValueOf(Point{}).Method(1)
8028 want := MethodValueCallCodePtr()
8029 if got := uintptr(m.UnsafePointer()); got != want {
8030 t.Errorf("methodValueCall code pointer mismatched, want: %v, got: %v", want, got)
8031 }
8032 if got := m.Pointer(); got != want {
8033 t.Errorf("methodValueCall code pointer mismatched, want: %v, got: %v", want, got)
8034 }
8035 }
8036
8037 type A struct{}
8038 type B[T any] struct{}
8039
8040 func TestIssue50208(t *testing.T) {
8041 want1 := "B[reflect_test.A]"
8042 if got := TypeOf(new(B[A])).Elem().Name(); got != want1 {
8043 t.Errorf("name of type parameter mismatched, want:%s, got:%s", want1, got)
8044 }
8045 want2 := "B[reflect_test.B[reflect_test.A]]"
8046 if got := TypeOf(new(B[B[A]])).Elem().Name(); got != want2 {
8047 t.Errorf("name of type parameter mismatched, want:%s, got:%s", want2, got)
8048 }
8049 }
8050
8051 func TestNegativeKindString(t *testing.T) {
8052 x := -1
8053 s := Kind(x).String()
8054 want := "kind-1"
8055 if s != want {
8056 t.Fatalf("Kind(-1).String() = %q, want %q", s, want)
8057 }
8058 }
8059
8060 type (
8061 namedBool bool
8062 namedBytes []byte
8063 )
8064
8065 func TestValue_Cap(t *testing.T) {
8066 a := &[3]int{1, 2, 3}
8067 v := ValueOf(a)
8068 if v.Cap() != cap(a) {
8069 t.Errorf("Cap = %d want %d", v.Cap(), cap(a))
8070 }
8071
8072 a = nil
8073 v = ValueOf(a)
8074 if v.Cap() != cap(a) {
8075 t.Errorf("Cap = %d want %d", v.Cap(), cap(a))
8076 }
8077
8078 getError := func(f func()) (errorStr string) {
8079 defer func() {
8080 e := recover()
8081 if str, ok := e.(string); ok {
8082 errorStr = str
8083 }
8084 }()
8085 f()
8086 return
8087 }
8088 e := getError(func() {
8089 var ptr *int
8090 ValueOf(ptr).Cap()
8091 })
8092 wantStr := "reflect: call of reflect.Value.Cap on ptr to non-array Value"
8093 if e != wantStr {
8094 t.Errorf("error is %q, want %q", e, wantStr)
8095 }
8096 }
8097
8098 func TestValue_Len(t *testing.T) {
8099 a := &[3]int{1, 2, 3}
8100 v := ValueOf(a)
8101 if v.Len() != len(a) {
8102 t.Errorf("Len = %d want %d", v.Len(), len(a))
8103 }
8104
8105 a = nil
8106 v = ValueOf(a)
8107 if v.Len() != len(a) {
8108 t.Errorf("Len = %d want %d", v.Len(), len(a))
8109 }
8110
8111 getError := func(f func()) (errorStr string) {
8112 defer func() {
8113 e := recover()
8114 if str, ok := e.(string); ok {
8115 errorStr = str
8116 }
8117 }()
8118 f()
8119 return
8120 }
8121 e := getError(func() {
8122 var ptr *int
8123 ValueOf(ptr).Len()
8124 })
8125 wantStr := "reflect: call of reflect.Value.Len on ptr to non-array Value"
8126 if e != wantStr {
8127 t.Errorf("error is %q, want %q", e, wantStr)
8128 }
8129 }
8130
8131 func TestValue_Comparable(t *testing.T) {
8132 var a int
8133 var s []int
8134 var i any = a
8135 var iNil any
8136 var iSlice any = s
8137 var iArrayFalse any = [2]any{1, map[int]int{}}
8138 var iArrayTrue any = [2]any{1, struct{ I any }{1}}
8139 var testcases = []struct {
8140 value Value
8141 comparable bool
8142 deref bool
8143 }{
8144 {
8145 ValueOf(&iNil),
8146 true,
8147 true,
8148 },
8149 {
8150 ValueOf(32),
8151 true,
8152 false,
8153 },
8154 {
8155 ValueOf(int8(1)),
8156 true,
8157 false,
8158 },
8159 {
8160 ValueOf(int16(1)),
8161 true,
8162 false,
8163 },
8164 {
8165 ValueOf(int32(1)),
8166 true,
8167 false,
8168 },
8169 {
8170 ValueOf(int64(1)),
8171 true,
8172 false,
8173 },
8174 {
8175 ValueOf(uint8(1)),
8176 true,
8177 false,
8178 },
8179 {
8180 ValueOf(uint16(1)),
8181 true,
8182 false,
8183 },
8184 {
8185 ValueOf(uint32(1)),
8186 true,
8187 false,
8188 },
8189 {
8190 ValueOf(uint64(1)),
8191 true,
8192 false,
8193 },
8194 {
8195 ValueOf(float32(1)),
8196 true,
8197 false,
8198 },
8199 {
8200 ValueOf(float64(1)),
8201 true,
8202 false,
8203 },
8204 {
8205 ValueOf(complex(float32(1), float32(1))),
8206 true,
8207 false,
8208 },
8209 {
8210 ValueOf(complex(float64(1), float64(1))),
8211 true,
8212 false,
8213 },
8214 {
8215 ValueOf("abc"),
8216 true,
8217 false,
8218 },
8219 {
8220 ValueOf(true),
8221 true,
8222 false,
8223 },
8224 {
8225 ValueOf(map[int]int{}),
8226 false,
8227 false,
8228 },
8229 {
8230 ValueOf([]int{}),
8231 false,
8232 false,
8233 },
8234 {
8235 Value{},
8236 false,
8237 false,
8238 },
8239 {
8240 ValueOf(&a),
8241 true,
8242 false,
8243 },
8244 {
8245 ValueOf(&s),
8246 true,
8247 false,
8248 },
8249 {
8250 ValueOf(&i),
8251 true,
8252 true,
8253 },
8254 {
8255 ValueOf(&iSlice),
8256 false,
8257 true,
8258 },
8259 {
8260 ValueOf([2]int{}),
8261 true,
8262 false,
8263 },
8264 {
8265 ValueOf([2]map[int]int{}),
8266 false,
8267 false,
8268 },
8269 {
8270 ValueOf([0]func(){}),
8271 false,
8272 false,
8273 },
8274 {
8275 ValueOf([2]struct{ I any }{{1}, {1}}),
8276 true,
8277 false,
8278 },
8279 {
8280 ValueOf([2]struct{ I any }{{[]int{}}, {1}}),
8281 false,
8282 false,
8283 },
8284 {
8285 ValueOf([2]any{1, struct{ I int }{1}}),
8286 true,
8287 false,
8288 },
8289 {
8290 ValueOf([2]any{[1]any{map[int]int{}}, struct{ I int }{1}}),
8291 false,
8292 false,
8293 },
8294 {
8295 ValueOf(&iArrayFalse),
8296 false,
8297 true,
8298 },
8299 {
8300 ValueOf(&iArrayTrue),
8301 true,
8302 true,
8303 },
8304 }
8305
8306 for _, cas := range testcases {
8307 v := cas.value
8308 if cas.deref {
8309 v = v.Elem()
8310 }
8311 got := v.Comparable()
8312 if got != cas.comparable {
8313 t.Errorf("%T.Comparable = %t, want %t", v, got, cas.comparable)
8314 }
8315 }
8316 }
8317
8318 type ValueEqualTest struct {
8319 v, u any
8320 eq bool
8321 vDeref, uDeref bool
8322 }
8323
8324 var equalI any = 1
8325 var equalSlice any = []int{1}
8326 var nilInterface any
8327 var mapInterface any = map[int]int{}
8328
8329 var valueEqualTests = []ValueEqualTest{
8330 {
8331 Value{}, Value{},
8332 true,
8333 false, false,
8334 },
8335 {
8336 true, true,
8337 true,
8338 false, false,
8339 },
8340 {
8341 1, 1,
8342 true,
8343 false, false,
8344 },
8345 {
8346 int8(1), int8(1),
8347 true,
8348 false, false,
8349 },
8350 {
8351 int16(1), int16(1),
8352 true,
8353 false, false,
8354 },
8355 {
8356 int32(1), int32(1),
8357 true,
8358 false, false,
8359 },
8360 {
8361 int64(1), int64(1),
8362 true,
8363 false, false,
8364 },
8365 {
8366 uint(1), uint(1),
8367 true,
8368 false, false,
8369 },
8370 {
8371 uint8(1), uint8(1),
8372 true,
8373 false, false,
8374 },
8375 {
8376 uint16(1), uint16(1),
8377 true,
8378 false, false,
8379 },
8380 {
8381 uint32(1), uint32(1),
8382 true,
8383 false, false,
8384 },
8385 {
8386 uint64(1), uint64(1),
8387 true,
8388 false, false,
8389 },
8390 {
8391 float32(1), float32(1),
8392 true,
8393 false, false,
8394 },
8395 {
8396 float64(1), float64(1),
8397 true,
8398 false, false,
8399 },
8400 {
8401 complex(1, 1), complex(1, 1),
8402 true,
8403 false, false,
8404 },
8405 {
8406 complex128(1 + 1i), complex128(1 + 1i),
8407 true,
8408 false, false,
8409 },
8410 {
8411 func() {}, nil,
8412 false,
8413 false, false,
8414 },
8415 {
8416 &equalI, 1,
8417 true,
8418 true, false,
8419 },
8420 {
8421 (chan int)(nil), nil,
8422 false,
8423 false, false,
8424 },
8425 {
8426 (chan int)(nil), (chan int)(nil),
8427 true,
8428 false, false,
8429 },
8430 {
8431 &equalI, &equalI,
8432 true,
8433 false, false,
8434 },
8435 {
8436 struct{ i int }{1}, struct{ i int }{1},
8437 true,
8438 false, false,
8439 },
8440 {
8441 struct{ i int }{1}, struct{ i int }{2},
8442 false,
8443 false, false,
8444 },
8445 {
8446 &nilInterface, &nilInterface,
8447 true,
8448 true, true,
8449 },
8450 {
8451 1, ValueOf(struct{ i int }{1}).Field(0),
8452 true,
8453 false, false,
8454 },
8455 }
8456
8457 func TestValue_Equal(t *testing.T) {
8458 for _, test := range valueEqualTests {
8459 var v, u Value
8460 if vv, ok := test.v.(Value); ok {
8461 v = vv
8462 } else {
8463 v = ValueOf(test.v)
8464 }
8465
8466 if uu, ok := test.u.(Value); ok {
8467 u = uu
8468 } else {
8469 u = ValueOf(test.u)
8470 }
8471 if test.vDeref {
8472 v = v.Elem()
8473 }
8474
8475 if test.uDeref {
8476 u = u.Elem()
8477 }
8478
8479 if r := v.Equal(u); r != test.eq {
8480 t.Errorf("%s == %s got %t, want %t", v.Type(), u.Type(), r, test.eq)
8481 }
8482 }
8483 }
8484
8485 func TestValue_EqualNonComparable(t *testing.T) {
8486 var invalid = Value{}
8487 var values = []Value{
8488
8489 ValueOf([]int(nil)),
8490 ValueOf(([]int{})),
8491
8492
8493 ValueOf(map[int]int(nil)),
8494 ValueOf((map[int]int{})),
8495
8496
8497 ValueOf(((func())(nil))),
8498 ValueOf(func() {}),
8499
8500
8501 ValueOf((NonComparableStruct{})),
8502
8503
8504 ValueOf([0]map[int]int{}),
8505 ValueOf([0]func(){}),
8506 ValueOf(([1]struct{ I any }{{[]int{}}})),
8507 ValueOf(([1]any{[1]any{map[int]int{}}})),
8508 }
8509 for _, value := range values {
8510
8511 shouldPanic("are not comparable", func() { value.Equal(value) })
8512
8513
8514 if r := value.Equal(invalid); r != false {
8515 t.Errorf("%s == invalid got %t, want false", value.Type(), r)
8516 }
8517 }
8518 }
8519
8520 func TestInitFuncTypes(t *testing.T) {
8521 n := 100
8522 var wg sync.WaitGroup
8523
8524 wg.Add(n)
8525 for i := 0; i < n; i++ {
8526 go func() {
8527 defer wg.Done()
8528 ipT := TypeOf(net.IP{})
8529 for range ipT.Methods() {
8530 }
8531 }()
8532 }
8533 wg.Wait()
8534 }
8535
8536 func TestClear(t *testing.T) {
8537 m := make(map[string]any, len(valueTests))
8538 for _, tt := range valueTests {
8539 m[tt.s] = tt.i
8540 }
8541 mapTestFn := func(v Value) bool { v.Clear(); return v.Len() == 0 }
8542
8543 s := make([]*pair, len(valueTests))
8544 for i := range s {
8545 s[i] = &valueTests[i]
8546 }
8547 sliceTestFn := func(v Value) bool {
8548 v.Clear()
8549 for i := 0; i < v.Len(); i++ {
8550 if !v.Index(i).IsZero() {
8551 return false
8552 }
8553 }
8554 return true
8555 }
8556
8557 panicTestFn := func(v Value) bool { shouldPanic("reflect.Value.Clear", func() { v.Clear() }); return true }
8558
8559 tests := []struct {
8560 name string
8561 value Value
8562 testFunc func(v Value) bool
8563 }{
8564 {"map", ValueOf(m), mapTestFn},
8565 {"slice no pointer", ValueOf([]int{1, 2, 3, 4, 5}), sliceTestFn},
8566 {"slice has pointer", ValueOf(s), sliceTestFn},
8567 {"non-map/slice", ValueOf(1), panicTestFn},
8568 }
8569
8570 for _, tc := range tests {
8571 t.Run(tc.name, func(t *testing.T) {
8572 t.Parallel()
8573 if !tc.testFunc(tc.value) {
8574 t.Errorf("unexpected result for value.Clear(): %v", tc.value)
8575 }
8576 })
8577 }
8578 }
8579
8580 func TestValuePointerAndUnsafePointer(t *testing.T) {
8581 ptr := new(int)
8582 ch := make(chan int)
8583 m := make(map[int]int)
8584 unsafePtr := unsafe.Pointer(ptr)
8585 slice := make([]int, 1)
8586 fn := func() {}
8587 s := "foo"
8588
8589 tests := []struct {
8590 name string
8591 val Value
8592 wantUnsafePointer unsafe.Pointer
8593 }{
8594 {"pointer", ValueOf(ptr), unsafe.Pointer(ptr)},
8595 {"channel", ValueOf(ch), *(*unsafe.Pointer)(unsafe.Pointer(&ch))},
8596 {"map", ValueOf(m), *(*unsafe.Pointer)(unsafe.Pointer(&m))},
8597 {"unsafe.Pointer", ValueOf(unsafePtr), unsafePtr},
8598 {"function", ValueOf(fn), **(**unsafe.Pointer)(unsafe.Pointer(&fn))},
8599 {"slice", ValueOf(slice), unsafe.Pointer(unsafe.SliceData(slice))},
8600 {"string", ValueOf(s), unsafe.Pointer(unsafe.StringData(s))},
8601 }
8602
8603 for _, tc := range tests {
8604 t.Run(tc.name, func(t *testing.T) {
8605 if got := tc.val.Pointer(); got != uintptr(tc.wantUnsafePointer) {
8606 t.Errorf("unexpected uintptr result, got %#x, want %#x", got, uintptr(tc.wantUnsafePointer))
8607 }
8608 if got := tc.val.UnsafePointer(); got != tc.wantUnsafePointer {
8609 t.Errorf("unexpected unsafe.Pointer result, got %#x, want %#x", got, tc.wantUnsafePointer)
8610 }
8611 })
8612 }
8613 }
8614
8615
8616 func TestSliceAt(t *testing.T) {
8617 const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
8618 var p [10]byte
8619
8620 typ := TypeOf(p[0])
8621
8622 s := SliceAt(typ, unsafe.Pointer(&p[0]), len(p))
8623 if s.Pointer() != uintptr(unsafe.Pointer(&p[0])) {
8624 t.Fatalf("unexpected underlying array: %d, want: %d", s.Pointer(), uintptr(unsafe.Pointer(&p[0])))
8625 }
8626 if s.Len() != len(p) || s.Cap() != len(p) {
8627 t.Fatalf("unexpected len or cap, len: %d, cap: %d, want: %d", s.Len(), s.Cap(), len(p))
8628 }
8629
8630 typ = TypeOf(0)
8631 if !SliceAt(typ, unsafe.Pointer((*int)(nil)), 0).IsNil() {
8632 t.Fatal("nil pointer with zero length must return nil")
8633 }
8634
8635
8636 shouldPanic("", func() { _ = SliceAt(typ, unsafe.Pointer((*int)(nil)), 1) })
8637
8638
8639 var neg int = -1
8640 shouldPanic("", func() { _ = SliceAt(TypeOf(byte(0)), unsafe.Pointer(&p[0]), neg) })
8641
8642
8643 n := uint64(0)
8644 shouldPanic("", func() { _ = SliceAt(TypeOf(n), unsafe.Pointer(&n), maxUintptr/8) })
8645 shouldPanic("", func() { _ = SliceAt(TypeOf(n), unsafe.Pointer(&n), maxUintptr/8+1) })
8646
8647
8648 last := (*byte)(unsafe.Pointer(^uintptr(0)))
8649
8650
8651
8652
8653 shouldPanic("", func() { _ = SliceAt(typ, unsafe.Pointer(last), 2) })
8654 }
8655
8656
8657
8658
8659
8660 func TestMapOfKeyUpdate(t *testing.T) {
8661 m := MakeMap(MapOf(TypeFor[float64](), TypeFor[bool]()))
8662
8663 zero := float64(0.0)
8664 negZero := math.Copysign(zero, -1.0)
8665
8666 m.SetMapIndex(ValueOf(zero), ValueOf(true))
8667 m.SetMapIndex(ValueOf(negZero), ValueOf(true))
8668
8669 if m.Len() != 1 {
8670 t.Errorf("map length got %d want 1", m.Len())
8671 }
8672
8673 iter := m.MapRange()
8674 for iter.Next() {
8675 k := iter.Key().Float()
8676 if math.Copysign(1.0, k) > 0 {
8677 t.Errorf("map key %f has positive sign", k)
8678 }
8679 }
8680 }
8681
8682
8683
8684
8685
8686
8687 func TestMapOfKeyPanic(t *testing.T) {
8688 defer func() {
8689 r := recover()
8690 if r == nil {
8691 t.Errorf("didn't panic")
8692 }
8693 }()
8694
8695 m := MakeMap(MapOf(TypeFor[any](), TypeFor[bool]()))
8696
8697 var slice []int
8698 m.MapIndex(ValueOf(slice))
8699 }
8700
8701 func TestTypeAssert(t *testing.T) {
8702 testTypeAssert(t, int(123456789), int(123456789), true)
8703 testTypeAssert(t, int(-123456789), int(-123456789), true)
8704 testTypeAssert(t, int32(123456789), int32(123456789), true)
8705 testTypeAssert(t, int8(-123), int8(-123), true)
8706 testTypeAssert(t, [2]int{1234, -5678}, [2]int{1234, -5678}, true)
8707 testTypeAssert(t, "test value", "test value", true)
8708 testTypeAssert(t, any("test value"), any("test value"), true)
8709
8710 v := 123456789
8711 testTypeAssert(t, &v, &v, true)
8712
8713 testTypeAssert(t, int(123), uint(0), false)
8714
8715 testTypeAssert[any](t, 1, 1, true)
8716 testTypeAssert[fmt.Stringer](t, 1, nil, false)
8717
8718 vv := testTypeWithMethod{"test"}
8719 testTypeAssert[any](t, vv, vv, true)
8720 testTypeAssert[any](t, &vv, &vv, true)
8721 testTypeAssert[fmt.Stringer](t, vv, vv, true)
8722 testTypeAssert[fmt.Stringer](t, &vv, &vv, true)
8723 testTypeAssert[interface{ A() }](t, vv, nil, false)
8724 testTypeAssert[interface{ A() }](t, &vv, nil, false)
8725 testTypeAssert(t, any(vv), any(vv), true)
8726 testTypeAssert(t, fmt.Stringer(vv), fmt.Stringer(vv), true)
8727
8728 testTypeAssert(t, fmt.Stringer(vv), any(vv), true)
8729 testTypeAssert(t, any(vv), fmt.Stringer(vv), true)
8730 testTypeAssert(t, fmt.Stringer(vv), interface{ M() }(vv), true)
8731 testTypeAssert(t, interface{ M() }(vv), fmt.Stringer(vv), true)
8732
8733 testTypeAssert(t, any(int(1)), int(1), true)
8734 testTypeAssert(t, any(int(1)), byte(0), false)
8735 testTypeAssert(t, fmt.Stringer(vv), vv, true)
8736
8737 testTypeAssert(t, any(nil), any(nil), false)
8738 testTypeAssert(t, any(nil), error(nil), false)
8739 testTypeAssert(t, error(nil), any(nil), false)
8740 testTypeAssert(t, error(nil), error(nil), false)
8741 }
8742
8743 func testTypeAssert[T comparable, V any](t *testing.T, val V, wantVal T, wantOk bool) {
8744 t.Helper()
8745
8746 v, ok := TypeAssert[T](ValueOf(&val).Elem())
8747 if v != wantVal || ok != wantOk {
8748 t.Errorf("TypeAssert[%v](%#v) = (%#v, %v); want = (%#v, %v)", TypeFor[T](), val, v, ok, wantVal, wantOk)
8749 }
8750
8751
8752 v2, ok2 := ValueOf(&val).Elem().Interface().(T)
8753 if v != v2 || ok != ok2 {
8754 t.Errorf("reflect.ValueOf(%#v).Interface().(%v) = (%#v, %v); want = (%#v, %v)", val, TypeFor[T](), v2, ok2, v, ok)
8755 }
8756 }
8757
8758 type testTypeWithMethod struct{ val string }
8759
8760 func (v testTypeWithMethod) String() string { return v.val }
8761 func (v testTypeWithMethod) M() {}
8762
8763 func TestTypeAssertMethod(t *testing.T) {
8764 method := ValueOf(&testTypeWithMethod{val: "test value"}).MethodByName("String")
8765 f, ok := TypeAssert[func() string](method)
8766 if !ok {
8767 t.Fatalf(`TypeAssert[func() string](method) = (,false); want = (,true)`)
8768 }
8769
8770 out := f()
8771 if out != "test value" {
8772 t.Fatalf(`TypeAssert[func() string](method)() = %q; want "test value"`, out)
8773 }
8774 }
8775
8776 func TestTypeAssertPanic(t *testing.T) {
8777 t.Run("zero val", func(t *testing.T) {
8778 defer func() { recover() }()
8779 TypeAssert[int](Value{})
8780 t.Fatalf("TypeAssert did not panic")
8781 })
8782 t.Run("read only", func(t *testing.T) {
8783 defer func() { recover() }()
8784 TypeAssert[int](ValueOf(&testTypeWithMethod{}).FieldByName("val"))
8785 t.Fatalf("TypeAssert did not panic")
8786 })
8787 }
8788
8789 func TestTypeAssertAllocs(t *testing.T) {
8790 if race.Enabled || asan.Enabled || msan.Enabled {
8791 t.Skip("instrumentation breaks this optimization")
8792 }
8793 typeAssertAllocs[[128]int](t, ValueOf([128]int{}), 0)
8794 typeAssertAllocs[any](t, ValueOf([128]int{}), 0)
8795
8796 val := 123
8797 typeAssertAllocs[any](t, ValueOf(val), 0)
8798 typeAssertAllocs[any](t, ValueOf(&val).Elem(), 1)
8799 typeAssertAllocs[int](t, ValueOf(val), 0)
8800 typeAssertAllocs[int](t, ValueOf(&val).Elem(), 0)
8801
8802 typeAssertAllocs[time.Time](t, ValueOf(new(time.Time)).Elem(), 0)
8803 typeAssertAllocs[time.Time](t, ValueOf(*new(time.Time)), 0)
8804
8805 type I interface{ foo() }
8806 typeAssertAllocs[I](t, ValueOf(new(string)).Elem(), 0)
8807 }
8808
8809 func typeAssertAllocs[T any](t *testing.T, val Value, wantAllocs int) {
8810 t.Helper()
8811 allocs := testing.AllocsPerRun(10, func() {
8812 TypeAssert[T](val)
8813 })
8814 if allocs != float64(wantAllocs) {
8815 t.Errorf("TypeAssert[%v](%v) unexpected amount of allocations = %v; want = %v", TypeFor[T](), val.Type(), allocs, wantAllocs)
8816 }
8817 }
8818
8819 func BenchmarkTypeAssert(b *testing.B) {
8820 benchmarkTypeAssert[int](b, ValueOf(int(1)))
8821 benchmarkTypeAssert[byte](b, ValueOf(int(1)))
8822
8823 benchmarkTypeAssert[fmt.Stringer](b, ValueOf(testTypeWithMethod{}))
8824 benchmarkTypeAssert[fmt.Stringer](b, ValueOf(&testTypeWithMethod{}))
8825 benchmarkTypeAssert[any](b, ValueOf(int(1)))
8826 benchmarkTypeAssert[any](b, ValueOf(testTypeWithMethod{}))
8827
8828 benchmarkTypeAssert[time.Time](b, ValueOf(*new(time.Time)))
8829
8830 benchmarkTypeAssert[func() string](b, ValueOf(time.Now()).MethodByName("String"))
8831 }
8832
8833 func benchmarkTypeAssert[T any](b *testing.B, val Value) {
8834 b.Run(fmt.Sprintf("TypeAssert[%v](%v)", TypeFor[T](), val.Type()), func(b *testing.B) {
8835 for b.Loop() {
8836 TypeAssert[T](val)
8837 }
8838 })
8839 }
8840
View as plain text