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