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 done := make(chan bool, 1)
6202 go func() {
6203 select {
6204 case <-done:
6205 case <-time.After(5 * time.Second):
6206 panic("deadlock in TestChanOfGC")
6207 }
6208 }()
6209
6210 defer func() {
6211 done <- true
6212 }()
6213
6214 type T *uintptr
6215 tt := TypeOf(T(nil))
6216 ct := ChanOf(BothDir, tt)
6217
6218
6219
6220
6221 const n = 100
6222 var x []any
6223 for i := 0; i < n; i++ {
6224 v := MakeChan(ct, n)
6225 for j := 0; j < n; j++ {
6226 p := new(uintptr)
6227 *p = uintptr(i*n + j)
6228 v.Send(ValueOf(p).Convert(tt))
6229 }
6230 pv := New(ct)
6231 pv.Elem().Set(v)
6232 x = append(x, pv.Interface())
6233 }
6234 runtime.GC()
6235
6236 for i, xi := range x {
6237 v := ValueOf(xi).Elem()
6238 for j := 0; j < n; j++ {
6239 pv, _ := v.Recv()
6240 k := pv.Elem().Interface()
6241 if k != uintptr(i*n+j) {
6242 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
6243 }
6244 }
6245 }
6246 }
6247
6248 func TestMapOf(t *testing.T) {
6249
6250 type K string
6251 type V float64
6252
6253 v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
6254 runtime.GC()
6255 v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
6256 runtime.GC()
6257
6258 s := fmt.Sprint(v.Interface())
6259 want := "map[a:1]"
6260 if s != want {
6261 t.Errorf("constructed map = %s, want %s", s, want)
6262 }
6263
6264
6265 checkSameType(t, MapOf(TypeOf(V(0)), TypeOf(K(""))), map[V]K(nil))
6266
6267
6268 shouldPanic("invalid key type", func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
6269 }
6270
6271 func TestMapOfGCKeys(t *testing.T) {
6272 type T *uintptr
6273 tt := TypeOf(T(nil))
6274 mt := MapOf(tt, TypeOf(false))
6275
6276
6277
6278
6279 const n = 100
6280 var x []any
6281 for i := 0; i < n; i++ {
6282 v := MakeMap(mt)
6283 for j := 0; j < n; j++ {
6284 p := new(uintptr)
6285 *p = uintptr(i*n + j)
6286 v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
6287 }
6288 pv := New(mt)
6289 pv.Elem().Set(v)
6290 x = append(x, pv.Interface())
6291 }
6292 runtime.GC()
6293
6294 for i, xi := range x {
6295 v := ValueOf(xi).Elem()
6296 var out []int
6297 for _, kv := range v.MapKeys() {
6298 out = append(out, int(kv.Elem().Interface().(uintptr)))
6299 }
6300 slices.Sort(out)
6301 for j, k := range out {
6302 if k != i*n+j {
6303 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
6304 }
6305 }
6306 }
6307 }
6308
6309
6310 func TestMapOfGCBigKey(t *testing.T) {
6311 type KV struct {
6312 i int64
6313 j int64
6314 }
6315
6316 kvTyp := TypeFor[KV]()
6317 mt := MapOf(kvTyp, kvTyp)
6318
6319 const n = 100
6320 m := MakeMap(mt)
6321 for i := 0; i < n; i++ {
6322 kv := KV{int64(i), int64(i + 1)}
6323 m.SetMapIndex(ValueOf(kv), ValueOf(kv))
6324 }
6325
6326 for i := 0; i < n; i++ {
6327 kv := KV{int64(i), int64(i + 1)}
6328 elem := m.MapIndex(ValueOf(kv)).Interface().(KV)
6329 if elem != kv {
6330 t.Errorf("lost m[%v] = %v, want %v", kv, elem, kv)
6331 }
6332 }
6333 }
6334
6335 func TestMapOfGCValues(t *testing.T) {
6336 type T *uintptr
6337 tt := TypeOf(T(nil))
6338 mt := MapOf(TypeOf(1), tt)
6339
6340
6341
6342
6343 const n = 100
6344 var x []any
6345 for i := 0; i < n; i++ {
6346 v := MakeMap(mt)
6347 for j := 0; j < n; j++ {
6348 p := new(uintptr)
6349 *p = uintptr(i*n + j)
6350 v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
6351 }
6352 pv := New(mt)
6353 pv.Elem().Set(v)
6354 x = append(x, pv.Interface())
6355 }
6356 runtime.GC()
6357
6358 for i, xi := range x {
6359 v := ValueOf(xi).Elem()
6360 for j := 0; j < n; j++ {
6361 k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
6362 if k != uintptr(i*n+j) {
6363 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
6364 }
6365 }
6366 }
6367 }
6368
6369 func TestTypelinksSorted(t *testing.T) {
6370 var last string
6371 for i, n := range TypeLinks() {
6372 if n < last {
6373 t.Errorf("typelinks not sorted: %q [%d] > %q [%d]", last, i-1, n, i)
6374 }
6375 last = n
6376 }
6377 }
6378
6379 func TestFuncOf(t *testing.T) {
6380
6381 type K string
6382 type V float64
6383
6384 fn := func(args []Value) []Value {
6385 if len(args) != 1 {
6386 t.Errorf("args == %v, want exactly one arg", args)
6387 } else if args[0].Type() != TypeOf(K("")) {
6388 t.Errorf("args[0] is type %v, want %v", args[0].Type(), TypeOf(K("")))
6389 } else if args[0].String() != "gopher" {
6390 t.Errorf("args[0] = %q, want %q", args[0].String(), "gopher")
6391 }
6392 return []Value{ValueOf(V(3.14))}
6393 }
6394 v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
6395
6396 outs := v.Call([]Value{ValueOf(K("gopher"))})
6397 if len(outs) != 1 {
6398 t.Fatalf("v.Call returned %v, want exactly one result", outs)
6399 } else if outs[0].Type() != TypeOf(V(0)) {
6400 t.Fatalf("c.Call[0] is type %v, want %v", outs[0].Type(), TypeOf(V(0)))
6401 }
6402 f := outs[0].Float()
6403 if f != 3.14 {
6404 t.Errorf("constructed func returned %f, want %f", f, 3.14)
6405 }
6406
6407
6408 type T1 int
6409 testCases := []struct {
6410 in, out []Type
6411 variadic bool
6412 want any
6413 }{
6414 {in: []Type{TypeOf(T1(0))}, want: (func(T1))(nil)},
6415 {in: []Type{TypeOf(int(0))}, want: (func(int))(nil)},
6416 {in: []Type{SliceOf(TypeOf(int(0)))}, variadic: true, want: (func(...int))(nil)},
6417 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false)}, want: (func(int) bool)(nil)},
6418 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
6419 }
6420 for _, tt := range testCases {
6421 checkSameType(t, FuncOf(tt.in, tt.out, tt.variadic), tt.want)
6422 }
6423
6424
6425 FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
6426 shouldPanic("must be slice", func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
6427 shouldPanic("must be slice", func() { FuncOf(nil, nil, true) })
6428
6429
6430 var in []Type
6431 for i := 0; i < 51; i++ {
6432 in = append(in, TypeOf(1))
6433 }
6434 FuncOf(in, nil, false)
6435 }
6436
6437 type R0 struct {
6438 *R1
6439 *R2
6440 *R3
6441 *R4
6442 }
6443
6444 type R1 struct {
6445 *R5
6446 *R6
6447 *R7
6448 *R8
6449 }
6450
6451 type R2 R1
6452 type R3 R1
6453 type R4 R1
6454
6455 type R5 struct {
6456 *R9
6457 *R10
6458 *R11
6459 *R12
6460 }
6461
6462 type R6 R5
6463 type R7 R5
6464 type R8 R5
6465
6466 type R9 struct {
6467 *R13
6468 *R14
6469 *R15
6470 *R16
6471 }
6472
6473 type R10 R9
6474 type R11 R9
6475 type R12 R9
6476
6477 type R13 struct {
6478 *R17
6479 *R18
6480 *R19
6481 *R20
6482 }
6483
6484 type R14 R13
6485 type R15 R13
6486 type R16 R13
6487
6488 type R17 struct {
6489 *R21
6490 *R22
6491 *R23
6492 *R24
6493 }
6494
6495 type R18 R17
6496 type R19 R17
6497 type R20 R17
6498
6499 type R21 struct {
6500 X int
6501 }
6502
6503 type R22 R21
6504 type R23 R21
6505 type R24 R21
6506
6507 func TestEmbed(t *testing.T) {
6508 typ := TypeOf(R0{})
6509 f, ok := typ.FieldByName("X")
6510 if ok {
6511 t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
6512 }
6513 }
6514
6515 func TestAllocsInterfaceBig(t *testing.T) {
6516 if testing.Short() {
6517 t.Skip("skipping malloc count in short mode")
6518 }
6519 v := ValueOf(S{})
6520 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
6521 t.Error("allocs:", allocs)
6522 }
6523 }
6524
6525 func TestAllocsInterfaceSmall(t *testing.T) {
6526 if testing.Short() {
6527 t.Skip("skipping malloc count in short mode")
6528 }
6529 v := ValueOf(int64(0))
6530 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
6531 t.Error("allocs:", allocs)
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
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577 type exhaustive struct {
6578 r *rand.Rand
6579 pos int
6580 last []choice
6581 }
6582
6583 type choice struct {
6584 off int
6585 n int
6586 max int
6587 }
6588
6589 func (x *exhaustive) Next() bool {
6590 if x.r == nil {
6591 x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
6592 }
6593 x.pos = 0
6594 if x.last == nil {
6595 x.last = []choice{}
6596 return true
6597 }
6598 for i := len(x.last) - 1; i >= 0; i-- {
6599 c := &x.last[i]
6600 if c.n+1 < c.max {
6601 c.n++
6602 x.last = x.last[:i+1]
6603 return true
6604 }
6605 }
6606 return false
6607 }
6608
6609 func (x *exhaustive) Choose(max int) int {
6610 if x.pos >= len(x.last) {
6611 x.last = append(x.last, choice{x.r.Intn(max), 0, max})
6612 }
6613 c := &x.last[x.pos]
6614 x.pos++
6615 if c.max != max {
6616 panic("inconsistent use of exhaustive tester")
6617 }
6618 return (c.n + c.off) % max
6619 }
6620
6621 func (x *exhaustive) Maybe() bool {
6622 return x.Choose(2) == 1
6623 }
6624
6625 func GCFunc(args []Value) []Value {
6626 runtime.GC()
6627 return []Value{}
6628 }
6629
6630 func TestReflectFuncTraceback(t *testing.T) {
6631 f := MakeFunc(TypeOf(func() {}), GCFunc)
6632 f.Call([]Value{})
6633 }
6634
6635 func TestReflectMethodTraceback(t *testing.T) {
6636 p := Point{3, 4}
6637 m := ValueOf(p).MethodByName("GCMethod")
6638 i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
6639 if i != 8 {
6640 t.Errorf("Call returned %d; want 8", i)
6641 }
6642 }
6643
6644 func TestSmallZero(t *testing.T) {
6645 type T [10]byte
6646 typ := TypeOf(T{})
6647 if allocs := testing.AllocsPerRun(100, func() { Zero(typ) }); allocs > 0 {
6648 t.Errorf("Creating small zero values caused %f allocs, want 0", allocs)
6649 }
6650 }
6651
6652 func TestBigZero(t *testing.T) {
6653 const size = 1 << 10
6654 var v [size]byte
6655 z := Zero(ValueOf(v).Type()).Interface().([size]byte)
6656 for i := 0; i < size; i++ {
6657 if z[i] != 0 {
6658 t.Fatalf("Zero object not all zero, index %d", i)
6659 }
6660 }
6661 }
6662
6663 func TestZeroSet(t *testing.T) {
6664 type T [16]byte
6665 type S struct {
6666 a uint64
6667 T T
6668 b uint64
6669 }
6670 v := S{
6671 a: 0xaaaaaaaaaaaaaaaa,
6672 T: T{9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9},
6673 b: 0xbbbbbbbbbbbbbbbb,
6674 }
6675 ValueOf(&v).Elem().Field(1).Set(Zero(TypeOf(T{})))
6676 if v != (S{
6677 a: 0xaaaaaaaaaaaaaaaa,
6678 b: 0xbbbbbbbbbbbbbbbb,
6679 }) {
6680 t.Fatalf("Setting a field to a Zero value didn't work")
6681 }
6682 }
6683
6684 func TestFieldByIndexNil(t *testing.T) {
6685 type P struct {
6686 F int
6687 }
6688 type T struct {
6689 *P
6690 }
6691 v := ValueOf(T{})
6692
6693 v.FieldByName("P")
6694
6695 defer func() {
6696 if err := recover(); err == nil {
6697 t.Fatalf("no error")
6698 } else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
6699 t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
6700 }
6701 }()
6702 v.FieldByName("F")
6703
6704 t.Fatalf("did not panic")
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
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748 type Outer struct {
6749 *Inner
6750 R io.Reader
6751 }
6752
6753 type Inner struct {
6754 X *Outer
6755 P1 uintptr
6756 P2 uintptr
6757 }
6758
6759 func (pi *Inner) M() {
6760
6761
6762
6763 pi.X.Inner = nil
6764
6765
6766
6767
6768
6769
6770 pi.P1 = 1
6771 pi.P2 = uintptr(unsafe.Pointer(pi))
6772 }
6773
6774 func TestCallMethodJump(t *testing.T) {
6775
6776
6777
6778 *CallGC = true
6779
6780 p := &Outer{Inner: new(Inner)}
6781 p.Inner.X = p
6782 ValueOf(p).Method(0).Call(nil)
6783
6784
6785 *CallGC = false
6786 }
6787
6788 func TestCallArgLive(t *testing.T) {
6789 type T struct{ X, Y *string }
6790
6791 F := func(t T) { *t.X = "ok" }
6792
6793
6794
6795 *CallGC = true
6796
6797 x := new(string)
6798 runtime.SetFinalizer(x, func(p *string) {
6799 if *p != "ok" {
6800 t.Errorf("x dead prematurely")
6801 }
6802 })
6803 v := T{x, nil}
6804
6805 ValueOf(F).Call([]Value{ValueOf(v)})
6806
6807
6808 *CallGC = false
6809 }
6810
6811 func TestMakeFuncStackCopy(t *testing.T) {
6812 target := func(in []Value) []Value {
6813 runtime.GC()
6814 useStack(16)
6815 return []Value{ValueOf(9)}
6816 }
6817
6818 var concrete func(*int, int) int
6819 fn := MakeFunc(ValueOf(concrete).Type(), target)
6820 ValueOf(&concrete).Elem().Set(fn)
6821 x := concrete(nil, 7)
6822 if x != 9 {
6823 t.Errorf("have %#q want 9", x)
6824 }
6825 }
6826
6827
6828 func useStack(n int) {
6829 if n == 0 {
6830 return
6831 }
6832 var b [1024]byte
6833 useStack(n - 1 + int(b[99]))
6834 }
6835
6836 type Impl struct{}
6837
6838 func (Impl) F() {}
6839
6840 func TestValueString(t *testing.T) {
6841 rv := ValueOf(Impl{})
6842 if rv.String() != "<reflect_test.Impl Value>" {
6843 t.Errorf("ValueOf(Impl{}).String() = %q, want %q", rv.String(), "<reflect_test.Impl Value>")
6844 }
6845
6846 method := rv.Method(0)
6847 if method.String() != "<func() Value>" {
6848 t.Errorf("ValueOf(Impl{}).Method(0).String() = %q, want %q", method.String(), "<func() Value>")
6849 }
6850 }
6851
6852 func TestInvalid(t *testing.T) {
6853
6854 type T struct{ v any }
6855
6856 v := ValueOf(T{}).Field(0)
6857 if v.IsValid() != true || v.Kind() != Interface {
6858 t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
6859 }
6860 v = v.Elem()
6861 if v.IsValid() != false || v.Kind() != Invalid {
6862 t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
6863 }
6864 }
6865
6866
6867 func TestLarge(t *testing.T) {
6868 fv := ValueOf(func([256]*byte) {})
6869 fv.Call([]Value{ValueOf([256]*byte{})})
6870 }
6871
6872 func fieldIndexRecover(t Type, i int) (recovered any) {
6873 defer func() {
6874 recovered = recover()
6875 }()
6876
6877 t.Field(i)
6878 return
6879 }
6880
6881
6882 func TestTypeFieldOutOfRangePanic(t *testing.T) {
6883 typ := TypeOf(struct{ X int }{10})
6884 testIndices := [...]struct {
6885 i int
6886 mustPanic bool
6887 }{
6888 0: {-2, true},
6889 1: {0, false},
6890 2: {1, true},
6891 3: {1 << 10, true},
6892 }
6893 for i, tt := range testIndices {
6894 recoveredErr := fieldIndexRecover(typ, tt.i)
6895 if tt.mustPanic {
6896 if recoveredErr == nil {
6897 t.Errorf("#%d: fieldIndex %d expected to panic", i, tt.i)
6898 }
6899 } else {
6900 if recoveredErr != nil {
6901 t.Errorf("#%d: got err=%v, expected no panic", i, recoveredErr)
6902 }
6903 }
6904 }
6905 }
6906
6907 func TestTypeFieldReadOnly(t *testing.T) {
6908 if runtime.GOOS == "js" || runtime.GOOS == "wasip1" {
6909
6910
6911 t.Skip("test does not fault on GOOS=js")
6912 }
6913
6914
6915
6916
6917
6918 typ := TypeFor[struct{ f int }]()
6919 f := typ.Field(0)
6920 defer debug.SetPanicOnFault(debug.SetPanicOnFault(true))
6921 shouldPanic("", func() {
6922 f.Index[0] = 1
6923 })
6924 }
6925
6926
6927 func TestCallGC(t *testing.T) {
6928 f := func(a, b, c, d, e string) {
6929 }
6930 g := func(in []Value) []Value {
6931 runtime.GC()
6932 return nil
6933 }
6934 typ := ValueOf(f).Type()
6935 f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string))
6936 f2("four", "five5", "six666", "seven77", "eight888")
6937 }
6938
6939
6940 func TestKeepFuncLive(t *testing.T) {
6941
6942
6943 typ := TypeOf(func(i int) {})
6944 var f, g func(in []Value) []Value
6945 f = func(in []Value) []Value {
6946 clobber()
6947 i := int(in[0].Int())
6948 if i > 0 {
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959 MakeFunc(typ, g).Interface().(func(i int))(i - 1)
6960 }
6961 return nil
6962 }
6963 g = func(in []Value) []Value {
6964 clobber()
6965 i := int(in[0].Int())
6966 MakeFunc(typ, f).Interface().(func(i int))(i)
6967 return nil
6968 }
6969 MakeFunc(typ, f).Call([]Value{ValueOf(10)})
6970 }
6971
6972 type UnExportedFirst int
6973
6974 func (i UnExportedFirst) ΦExported() {}
6975 func (i UnExportedFirst) unexported() {}
6976
6977
6978 func TestMethodByNameUnExportedFirst(t *testing.T) {
6979 defer func() {
6980 if recover() != nil {
6981 t.Errorf("should not panic")
6982 }
6983 }()
6984 typ := TypeOf(UnExportedFirst(0))
6985 m, _ := typ.MethodByName("ΦExported")
6986 if m.Name != "ΦExported" {
6987 t.Errorf("got %s, expected ΦExported", m.Name)
6988 }
6989 }
6990
6991
6992 type KeepMethodLive struct{}
6993
6994 func (k KeepMethodLive) Method1(i int) {
6995 clobber()
6996 if i > 0 {
6997 ValueOf(k).MethodByName("Method2").Interface().(func(i int))(i - 1)
6998 }
6999 }
7000
7001 func (k KeepMethodLive) Method2(i int) {
7002 clobber()
7003 ValueOf(k).MethodByName("Method1").Interface().(func(i int))(i)
7004 }
7005
7006 func TestKeepMethodLive(t *testing.T) {
7007
7008
7009 KeepMethodLive{}.Method1(10)
7010 }
7011
7012
7013 func clobber() {
7014 runtime.GC()
7015 for i := 1; i < 32; i++ {
7016 for j := 0; j < 10; j++ {
7017 obj := make([]*byte, i)
7018 sink = obj
7019 }
7020 }
7021 runtime.GC()
7022 }
7023
7024 func TestFuncLayout(t *testing.T) {
7025 align := func(x uintptr) uintptr {
7026 return (x + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
7027 }
7028 var r []byte
7029 if goarch.PtrSize == 4 {
7030 r = []byte{0, 0, 0, 1}
7031 } else {
7032 r = []byte{0, 0, 1}
7033 }
7034
7035 type S struct {
7036 a, b uintptr
7037 c, d *byte
7038 }
7039
7040 type test struct {
7041 rcvr, typ Type
7042 size, argsize, retOffset uintptr
7043 stack, gc, inRegs, outRegs []byte
7044 intRegs, floatRegs int
7045 floatRegSize uintptr
7046 }
7047 tests := []test{
7048 {
7049 typ: ValueOf(func(a, b string) string { return "" }).Type(),
7050 size: 6 * goarch.PtrSize,
7051 argsize: 4 * goarch.PtrSize,
7052 retOffset: 4 * goarch.PtrSize,
7053 stack: []byte{1, 0, 1, 0, 1},
7054 gc: []byte{1, 0, 1, 0, 1},
7055 },
7056 {
7057 typ: ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
7058 size: align(align(3*4) + goarch.PtrSize + 2),
7059 argsize: align(3*4) + goarch.PtrSize + 2,
7060 retOffset: align(align(3*4) + goarch.PtrSize + 2),
7061 stack: r,
7062 gc: r,
7063 },
7064 {
7065 typ: ValueOf(func(a map[int]int, b uintptr, c any) {}).Type(),
7066 size: 4 * goarch.PtrSize,
7067 argsize: 4 * goarch.PtrSize,
7068 retOffset: 4 * goarch.PtrSize,
7069 stack: []byte{1, 0, 1, 1},
7070 gc: []byte{1, 0, 1, 1},
7071 },
7072 {
7073 typ: ValueOf(func(a S) {}).Type(),
7074 size: 4 * goarch.PtrSize,
7075 argsize: 4 * goarch.PtrSize,
7076 retOffset: 4 * goarch.PtrSize,
7077 stack: []byte{0, 0, 1, 1},
7078 gc: []byte{0, 0, 1, 1},
7079 },
7080 {
7081 rcvr: ValueOf((*byte)(nil)).Type(),
7082 typ: ValueOf(func(a uintptr, b *int) {}).Type(),
7083 size: 3 * goarch.PtrSize,
7084 argsize: 3 * goarch.PtrSize,
7085 retOffset: 3 * goarch.PtrSize,
7086 stack: []byte{1, 0, 1},
7087 gc: []byte{1, 0, 1},
7088 },
7089 {
7090 typ: ValueOf(func(a uintptr) {}).Type(),
7091 size: goarch.PtrSize,
7092 argsize: goarch.PtrSize,
7093 retOffset: goarch.PtrSize,
7094 stack: []byte{},
7095 gc: []byte{},
7096 },
7097 {
7098 typ: ValueOf(func() uintptr { return 0 }).Type(),
7099 size: goarch.PtrSize,
7100 argsize: 0,
7101 retOffset: 0,
7102 stack: []byte{},
7103 gc: []byte{},
7104 },
7105 {
7106 rcvr: ValueOf(uintptr(0)).Type(),
7107 typ: ValueOf(func(a uintptr) {}).Type(),
7108 size: 2 * goarch.PtrSize,
7109 argsize: 2 * goarch.PtrSize,
7110 retOffset: 2 * goarch.PtrSize,
7111 stack: []byte{1},
7112 gc: []byte{1},
7113
7114
7115
7116 },
7117
7118 }
7119 for _, lt := range tests {
7120 name := lt.typ.String()
7121 if lt.rcvr != nil {
7122 name = lt.rcvr.String() + "." + name
7123 }
7124 t.Run(name, func(t *testing.T) {
7125 defer SetArgRegs(SetArgRegs(lt.intRegs, lt.floatRegs, lt.floatRegSize))
7126
7127 typ, argsize, retOffset, stack, gc, inRegs, outRegs, ptrs := FuncLayout(lt.typ, lt.rcvr)
7128 if typ.Size() != lt.size {
7129 t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.typ, lt.rcvr, typ.Size(), lt.size)
7130 }
7131 if argsize != lt.argsize {
7132 t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.typ, lt.rcvr, argsize, lt.argsize)
7133 }
7134 if retOffset != lt.retOffset {
7135 t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.typ, lt.rcvr, retOffset, lt.retOffset)
7136 }
7137 if !bytes.Equal(stack, lt.stack) {
7138 t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.typ, lt.rcvr, stack, lt.stack)
7139 }
7140 if !bytes.Equal(gc, lt.gc) {
7141 t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.typ, lt.rcvr, gc, lt.gc)
7142 }
7143 if !bytes.Equal(inRegs, lt.inRegs) {
7144 t.Errorf("funcLayout(%v, %v).inRegs=%v, want %v", lt.typ, lt.rcvr, inRegs, lt.inRegs)
7145 }
7146 if !bytes.Equal(outRegs, lt.outRegs) {
7147 t.Errorf("funcLayout(%v, %v).outRegs=%v, want %v", lt.typ, lt.rcvr, outRegs, lt.outRegs)
7148 }
7149 if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
7150 t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.typ, lt.rcvr, ptrs, !ptrs)
7151 }
7152 })
7153 }
7154 }
7155
7156
7157 func trimBitmap(b []byte) []byte {
7158 for len(b) > 0 && b[len(b)-1] == 0 {
7159 b = b[:len(b)-1]
7160 }
7161 return b
7162 }
7163
7164 func verifyGCBits(t *testing.T, typ Type, bits []byte) {
7165 heapBits := GCBits(New(typ).Interface())
7166
7167
7168
7169 bits = trimBitmap(bits)
7170
7171 if bytes.HasPrefix(heapBits, bits) {
7172
7173
7174
7175
7176
7177
7178
7179 return
7180 }
7181 _, _, line, _ := runtime.Caller(1)
7182 t.Errorf("line %d: heapBits incorrect for %v\nhave %v\nwant %v", line, typ, heapBits, bits)
7183 }
7184
7185 func verifyGCBitsSlice(t *testing.T, typ Type, cap int, bits []byte) {
7186
7187
7188
7189
7190 val := MakeSlice(typ, 0, cap)
7191 data := NewAt(typ.Elem(), val.UnsafePointer())
7192 heapBits := GCBits(data.Interface())
7193
7194
7195 bits = trimBitmap(rep(cap, bits))
7196 if bytes.Equal(heapBits, bits) {
7197 return
7198 }
7199 if len(heapBits) > len(bits) && bytes.Equal(heapBits[:len(bits)], bits) {
7200
7201 return
7202 }
7203 _, _, line, _ := runtime.Caller(1)
7204 t.Errorf("line %d: heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", line, typ, cap, heapBits, bits)
7205 }
7206
7207
7208
7209
7210 type Xscalar struct{ x uintptr }
7211 type Xptr struct{ x *byte }
7212 type Xptrscalar struct {
7213 *byte
7214 uintptr
7215 }
7216 type Xscalarptr struct {
7217 uintptr
7218 *byte
7219 }
7220 type Xbigptrscalar struct {
7221 _ [100]*byte
7222 _ [100]uintptr
7223 }
7224
7225 var Tscalar, Tint64, Tptr, Tscalarptr, Tptrscalar, Tbigptrscalar Type
7226
7227 func init() {
7228
7229
7230
7231
7232
7233
7234
7235 type Scalar struct{ x uintptr }
7236 type Ptr struct{ x *byte }
7237 type Ptrscalar struct {
7238 *byte
7239 uintptr
7240 }
7241 type Scalarptr struct {
7242 uintptr
7243 *byte
7244 }
7245 type Bigptrscalar struct {
7246 _ [100]*byte
7247 _ [100]uintptr
7248 }
7249 type Int64 int64
7250 Tscalar = TypeOf(Scalar{})
7251 Tint64 = TypeOf(Int64(0))
7252 Tptr = TypeOf(Ptr{})
7253 Tscalarptr = TypeOf(Scalarptr{})
7254 Tptrscalar = TypeOf(Ptrscalar{})
7255 Tbigptrscalar = TypeOf(Bigptrscalar{})
7256 }
7257
7258 var empty = []byte{}
7259
7260 func TestGCBits(t *testing.T) {
7261 verifyGCBits(t, TypeOf((*byte)(nil)), []byte{1})
7262
7263 verifyGCBits(t, TypeOf(Xscalar{}), empty)
7264 verifyGCBits(t, Tscalar, empty)
7265 verifyGCBits(t, TypeOf(Xptr{}), lit(1))
7266 verifyGCBits(t, Tptr, lit(1))
7267 verifyGCBits(t, TypeOf(Xscalarptr{}), lit(0, 1))
7268 verifyGCBits(t, Tscalarptr, lit(0, 1))
7269 verifyGCBits(t, TypeOf(Xptrscalar{}), lit(1))
7270 verifyGCBits(t, Tptrscalar, lit(1))
7271
7272 verifyGCBits(t, TypeOf([0]Xptr{}), empty)
7273 verifyGCBits(t, ArrayOf(0, Tptr), empty)
7274 verifyGCBits(t, TypeOf([1]Xptrscalar{}), lit(1))
7275 verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
7276 verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
7277 verifyGCBits(t, ArrayOf(2, Tscalar), empty)
7278 verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
7279 verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
7280 verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
7281 verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
7282 verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
7283 verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
7284 verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
7285 verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
7286 verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
7287 verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
7288 verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
7289 verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
7290 verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
7291 verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
7292 verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
7293 verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
7294 verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
7295 verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
7296 verifyGCBits(t, TypeOf([4]Xbigptrscalar{}), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
7297 verifyGCBits(t, ArrayOf(4, Tbigptrscalar), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
7298
7299 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 0, empty)
7300 verifyGCBitsSlice(t, SliceOf(Tptr), 0, empty)
7301 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 1, lit(1))
7302 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 1, lit(1))
7303 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 2, lit(0))
7304 verifyGCBitsSlice(t, SliceOf(Tscalar), 2, lit(0))
7305 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 10000, lit(0))
7306 verifyGCBitsSlice(t, SliceOf(Tscalar), 10000, lit(0))
7307 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 2, lit(1))
7308 verifyGCBitsSlice(t, SliceOf(Tptr), 2, lit(1))
7309 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 10000, lit(1))
7310 verifyGCBitsSlice(t, SliceOf(Tptr), 10000, lit(1))
7311 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 2, lit(0, 1))
7312 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 2, lit(0, 1))
7313 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 10000, lit(0, 1))
7314 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 10000, lit(0, 1))
7315 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 2, lit(1, 0))
7316 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 2, lit(1, 0))
7317 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 10000, lit(1, 0))
7318 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 10000, lit(1, 0))
7319 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 1, rep(10000, lit(1, 0)))
7320 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 1, rep(10000, lit(1, 0)))
7321 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 2, rep(10000, lit(1, 0)))
7322 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 2, rep(10000, lit(1, 0)))
7323 verifyGCBitsSlice(t, TypeOf([]Xbigptrscalar{}), 4, join(rep(100, lit(1)), rep(100, lit(0))))
7324 verifyGCBitsSlice(t, SliceOf(Tbigptrscalar), 4, join(rep(100, lit(1)), rep(100, lit(0))))
7325
7326 verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
7327 verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
7328
7329 verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
7330 verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
7331
7332 verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
7333 verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
7334
7335 verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
7336 verifyGCBits(t, PointerTo(ArrayOf(10000, Tscalar)), lit(1))
7337
7338 verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
7339 verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
7340
7341
7342
7343 }
7344
7345 func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) }
7346 func join(b ...[]byte) []byte { return bytes.Join(b, nil) }
7347 func lit(x ...byte) []byte { return x }
7348
7349 func TestTypeOfTypeOf(t *testing.T) {
7350
7351
7352
7353 check := func(name string, typ Type) {
7354 if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
7355 t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
7356 }
7357 }
7358
7359 type T struct{ int }
7360 check("TypeOf", TypeOf(T{}))
7361
7362 check("ArrayOf", ArrayOf(10, TypeOf(T{})))
7363 check("ChanOf", ChanOf(BothDir, TypeOf(T{})))
7364 check("FuncOf", FuncOf([]Type{TypeOf(T{})}, nil, false))
7365 check("MapOf", MapOf(TypeOf(T{}), TypeOf(T{})))
7366 check("PtrTo", PointerTo(TypeOf(T{})))
7367 check("SliceOf", SliceOf(TypeOf(T{})))
7368 }
7369
7370 type XM struct{ _ bool }
7371
7372 func (*XM) String() string { return "" }
7373
7374 func TestPtrToMethods(t *testing.T) {
7375 var y struct{ XM }
7376 yp := New(TypeOf(y)).Interface()
7377 _, ok := yp.(fmt.Stringer)
7378 if !ok {
7379 t.Fatal("does not implement Stringer, but should")
7380 }
7381 }
7382
7383 func TestMapAlloc(t *testing.T) {
7384 if asan.Enabled {
7385 t.Skip("test allocates more with -asan; see #70079")
7386 }
7387 m := ValueOf(make(map[int]int, 10))
7388 k := ValueOf(5)
7389 v := ValueOf(7)
7390 allocs := testing.AllocsPerRun(100, func() {
7391 m.SetMapIndex(k, v)
7392 })
7393 if allocs > 0.5 {
7394 t.Errorf("allocs per map assignment: want 0 got %f", allocs)
7395 }
7396
7397 const size = 1000
7398 tmp := 0
7399 val := ValueOf(&tmp).Elem()
7400 allocs = testing.AllocsPerRun(100, func() {
7401 mv := MakeMapWithSize(TypeOf(map[int]int{}), size)
7402
7403 for i := 0; i < size/2; i++ {
7404 val.SetInt(int64(i))
7405 mv.SetMapIndex(val, val)
7406 }
7407 })
7408 if allocs > 10 {
7409 t.Errorf("allocs per map assignment: want at most 10 got %f", allocs)
7410 }
7411
7412
7413
7414 }
7415
7416 func TestChanAlloc(t *testing.T) {
7417 if asan.Enabled {
7418 t.Skip("test allocates more with -asan; see #70079")
7419 }
7420
7421
7422 c := ValueOf(make(chan *int, 1))
7423 v := ValueOf(new(int))
7424 allocs := testing.AllocsPerRun(100, func() {
7425 c.Send(v)
7426 _, _ = c.Recv()
7427 })
7428 if allocs < 0.5 || allocs > 1.5 {
7429 t.Errorf("allocs per chan send/recv: want 1 got %f", allocs)
7430 }
7431
7432
7433
7434 }
7435
7436 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
7437
7438 type nameTest struct {
7439 v any
7440 want string
7441 }
7442
7443 var nameTests = []nameTest{
7444 {(*int32)(nil), "int32"},
7445 {(*D1)(nil), "D1"},
7446 {(*[]D1)(nil), ""},
7447 {(*chan D1)(nil), ""},
7448 {(*func() D1)(nil), ""},
7449 {(*<-chan D1)(nil), ""},
7450 {(*chan<- D1)(nil), ""},
7451 {(*any)(nil), ""},
7452 {(*interface {
7453 F()
7454 })(nil), ""},
7455 {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
7456 }
7457
7458 func TestNames(t *testing.T) {
7459 for _, test := range nameTests {
7460 typ := TypeOf(test.v).Elem()
7461 if got := typ.Name(); got != test.want {
7462 t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
7463 }
7464 }
7465 }
7466
7467 func TestExported(t *testing.T) {
7468 type ΦExported struct{}
7469 type φUnexported struct{}
7470 type BigP *big
7471 type P int
7472 type p *P
7473 type P2 p
7474 type p3 p
7475
7476 type exportTest struct {
7477 v any
7478 want bool
7479 }
7480 exportTests := []exportTest{
7481 {D1{}, true},
7482 {(*D1)(nil), true},
7483 {big{}, false},
7484 {(*big)(nil), false},
7485 {(BigP)(nil), true},
7486 {(*BigP)(nil), true},
7487 {ΦExported{}, true},
7488 {φUnexported{}, false},
7489 {P(0), true},
7490 {(p)(nil), false},
7491 {(P2)(nil), true},
7492 {(p3)(nil), false},
7493 }
7494
7495 for i, test := range exportTests {
7496 typ := TypeOf(test.v)
7497 if got := IsExported(typ); got != test.want {
7498 t.Errorf("%d: %s exported=%v, want %v", i, typ.Name(), got, test.want)
7499 }
7500 }
7501 }
7502
7503 func TestTypeStrings(t *testing.T) {
7504 type stringTest struct {
7505 typ Type
7506 want string
7507 }
7508 stringTests := []stringTest{
7509 {TypeOf(func(int) {}), "func(int)"},
7510 {FuncOf([]Type{TypeOf(int(0))}, nil, false), "func(int)"},
7511 {TypeOf(XM{}), "reflect_test.XM"},
7512 {TypeOf(new(XM)), "*reflect_test.XM"},
7513 {TypeOf(new(XM).String), "func() string"},
7514 {TypeOf(new(XM)).Method(0).Type, "func(*reflect_test.XM) string"},
7515 {ChanOf(3, TypeOf(XM{})), "chan reflect_test.XM"},
7516 {MapOf(TypeOf(int(0)), TypeOf(XM{})), "map[int]reflect_test.XM"},
7517 {ArrayOf(3, TypeOf(XM{})), "[3]reflect_test.XM"},
7518 {ArrayOf(3, TypeOf(struct{}{})), "[3]struct {}"},
7519 }
7520
7521 for i, test := range stringTests {
7522 if got, want := test.typ.String(), test.want; got != want {
7523 t.Errorf("type %d String()=%q, want %q", i, got, want)
7524 }
7525 }
7526 }
7527
7528 func TestOffsetLock(t *testing.T) {
7529 var wg sync.WaitGroup
7530 for i := 0; i < 4; i++ {
7531 i := i
7532 wg.Add(1)
7533 go func() {
7534 for j := 0; j < 50; j++ {
7535 ResolveReflectName(fmt.Sprintf("OffsetLockName:%d:%d", i, j))
7536 }
7537 wg.Done()
7538 }()
7539 }
7540 wg.Wait()
7541 }
7542
7543 func TestSwapper(t *testing.T) {
7544 type I int
7545 var a, b, c I
7546 type pair struct {
7547 x, y int
7548 }
7549 type pairPtr struct {
7550 x, y int
7551 p *I
7552 }
7553 type S string
7554
7555 tests := []struct {
7556 in any
7557 i, j int
7558 want any
7559 }{
7560 {
7561 in: []int{1, 20, 300},
7562 i: 0,
7563 j: 2,
7564 want: []int{300, 20, 1},
7565 },
7566 {
7567 in: []uintptr{1, 20, 300},
7568 i: 0,
7569 j: 2,
7570 want: []uintptr{300, 20, 1},
7571 },
7572 {
7573 in: []int16{1, 20, 300},
7574 i: 0,
7575 j: 2,
7576 want: []int16{300, 20, 1},
7577 },
7578 {
7579 in: []int8{1, 20, 100},
7580 i: 0,
7581 j: 2,
7582 want: []int8{100, 20, 1},
7583 },
7584 {
7585 in: []*I{&a, &b, &c},
7586 i: 0,
7587 j: 2,
7588 want: []*I{&c, &b, &a},
7589 },
7590 {
7591 in: []string{"eric", "sergey", "larry"},
7592 i: 0,
7593 j: 2,
7594 want: []string{"larry", "sergey", "eric"},
7595 },
7596 {
7597 in: []S{"eric", "sergey", "larry"},
7598 i: 0,
7599 j: 2,
7600 want: []S{"larry", "sergey", "eric"},
7601 },
7602 {
7603 in: []pair{{1, 2}, {3, 4}, {5, 6}},
7604 i: 0,
7605 j: 2,
7606 want: []pair{{5, 6}, {3, 4}, {1, 2}},
7607 },
7608 {
7609 in: []pairPtr{{1, 2, &a}, {3, 4, &b}, {5, 6, &c}},
7610 i: 0,
7611 j: 2,
7612 want: []pairPtr{{5, 6, &c}, {3, 4, &b}, {1, 2, &a}},
7613 },
7614 }
7615
7616 for i, tt := range tests {
7617 inStr := fmt.Sprint(tt.in)
7618 Swapper(tt.in)(tt.i, tt.j)
7619 if !DeepEqual(tt.in, tt.want) {
7620 t.Errorf("%d. swapping %v and %v of %v = %v; want %v", i, tt.i, tt.j, inStr, tt.in, tt.want)
7621 }
7622 }
7623 }
7624
7625
7626
7627
7628
7629
7630 func TestUnaddressableField(t *testing.T) {
7631 var b Buffer
7632 var localBuffer struct {
7633 buf []byte
7634 }
7635 lv := ValueOf(&localBuffer).Elem()
7636 rv := ValueOf(b)
7637 shouldPanic("Set", func() {
7638 lv.Set(rv)
7639 })
7640 }
7641
7642 type Tint int
7643
7644 type Tint2 = Tint
7645
7646 type Talias1 struct {
7647 byte
7648 uint8
7649 int
7650 int32
7651 rune
7652 }
7653
7654 type Talias2 struct {
7655 Tint
7656 Tint2
7657 }
7658
7659 func TestAliasNames(t *testing.T) {
7660 t1 := Talias1{byte: 1, uint8: 2, int: 3, int32: 4, rune: 5}
7661 out := fmt.Sprintf("%#v", t1)
7662 want := "reflect_test.Talias1{byte:0x1, uint8:0x2, int:3, int32:4, rune:5}"
7663 if out != want {
7664 t.Errorf("Talias1 print:\nhave: %s\nwant: %s", out, want)
7665 }
7666
7667 t2 := Talias2{Tint: 1, Tint2: 2}
7668 out = fmt.Sprintf("%#v", t2)
7669 want = "reflect_test.Talias2{Tint:1, Tint2:2}"
7670 if out != want {
7671 t.Errorf("Talias2 print:\nhave: %s\nwant: %s", out, want)
7672 }
7673 }
7674
7675 func TestIssue22031(t *testing.T) {
7676 type s []struct{ C int }
7677
7678 type t1 struct{ s }
7679 type t2 struct{ f s }
7680
7681 tests := []Value{
7682 ValueOf(t1{s{{}}}).Field(0).Index(0).Field(0),
7683 ValueOf(t2{s{{}}}).Field(0).Index(0).Field(0),
7684 }
7685
7686 for i, test := range tests {
7687 if test.CanSet() {
7688 t.Errorf("%d: CanSet: got true, want false", i)
7689 }
7690 }
7691 }
7692
7693 type NonExportedFirst int
7694
7695 func (i NonExportedFirst) ΦExported() {}
7696 func (i NonExportedFirst) nonexported() int { panic("wrong") }
7697
7698 func TestIssue22073(t *testing.T) {
7699 m := ValueOf(NonExportedFirst(0)).Method(0)
7700
7701 if got := m.Type().NumOut(); got != 0 {
7702 t.Errorf("NumOut: got %v, want 0", got)
7703 }
7704
7705
7706 m.Call(nil)
7707 }
7708
7709 func TestMapIterNonEmptyMap(t *testing.T) {
7710 m := map[string]int{"one": 1, "two": 2, "three": 3}
7711 iter := ValueOf(m).MapRange()
7712 if got, want := iterateToString(iter), `[one: 1, three: 3, two: 2]`; got != want {
7713 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7714 }
7715 }
7716
7717 func TestMapIterNilMap(t *testing.T) {
7718 var m map[string]int
7719 iter := ValueOf(m).MapRange()
7720 if got, want := iterateToString(iter), `[]`; got != want {
7721 t.Errorf("non-empty result iteratoring nil map: %s", got)
7722 }
7723 }
7724
7725 func TestMapIterReset(t *testing.T) {
7726 iter := new(MapIter)
7727
7728
7729 func() {
7730 defer func() { recover() }()
7731 iter.Next()
7732 t.Error("Next did not panic")
7733 }()
7734
7735
7736 m := map[string]int{"one": 1, "two": 2, "three": 3}
7737 iter.Reset(ValueOf(m))
7738 if got, want := iterateToString(iter), `[one: 1, three: 3, two: 2]`; got != want {
7739 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7740 }
7741
7742
7743 iter.Reset(Value{})
7744 func() {
7745 defer func() { recover() }()
7746 iter.Next()
7747 t.Error("Next did not panic")
7748 }()
7749
7750
7751 m2 := map[int]string{1: "one", 2: "two", 3: "three"}
7752 iter.Reset(ValueOf(m2))
7753 if got, want := iterateToString(iter), `[1: one, 2: two, 3: three]`; got != want {
7754 t.Errorf("iterator returned %s (after sorting), want %s", got, want)
7755 }
7756
7757
7758 m3 := map[uint64]uint64{
7759 1 << 0: 1 << 1,
7760 1 << 1: 1 << 2,
7761 1 << 2: 1 << 3,
7762 }
7763 kv := New(TypeOf(uint64(0))).Elem()
7764 for i := 0; i < 5; i++ {
7765 var seenk, seenv uint64
7766 iter.Reset(ValueOf(m3))
7767 for iter.Next() {
7768 kv.SetIterKey(iter)
7769 seenk ^= kv.Uint()
7770 kv.SetIterValue(iter)
7771 seenv ^= kv.Uint()
7772 }
7773 if seenk != 0b111 {
7774 t.Errorf("iteration yielded keys %b, want %b", seenk, 0b111)
7775 }
7776 if seenv != 0b1110 {
7777 t.Errorf("iteration yielded values %b, want %b", seenv, 0b1110)
7778 }
7779 }
7780
7781
7782
7783
7784
7785 n := int(testing.AllocsPerRun(10, func() {
7786 iter.Reset(ValueOf(m2))
7787 iter.Reset(Value{})
7788 }))
7789 if !asan.Enabled && n > 0 {
7790 t.Errorf("MapIter.Reset allocated %d times", n)
7791 }
7792 }
7793
7794 func TestMapIterSafety(t *testing.T) {
7795
7796 func() {
7797 defer func() { recover() }()
7798 new(MapIter).Key()
7799 t.Fatal("Key did not panic")
7800 }()
7801 func() {
7802 defer func() { recover() }()
7803 new(MapIter).Value()
7804 t.Fatal("Value did not panic")
7805 }()
7806 func() {
7807 defer func() { recover() }()
7808 new(MapIter).Next()
7809 t.Fatal("Next did not panic")
7810 }()
7811
7812
7813
7814 var m map[string]int
7815 iter := ValueOf(m).MapRange()
7816
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
7828
7829
7830 iter.Next()
7831 func() {
7832 defer func() { recover() }()
7833 iter.Key()
7834 t.Fatal("Key did not panic")
7835 }()
7836 func() {
7837 defer func() { recover() }()
7838 iter.Value()
7839 t.Fatal("Value did not panic")
7840 }()
7841 func() {
7842 defer func() { recover() }()
7843 iter.Next()
7844 t.Fatal("Next did not panic")
7845 }()
7846 }
7847
7848 func TestMapIterNext(t *testing.T) {
7849
7850
7851 m := map[string]int{}
7852 iter := ValueOf(m).MapRange()
7853 m["one"] = 1
7854 if got, want := iterateToString(iter), `[one: 1]`; got != want {
7855 t.Errorf("iterator returned deleted elements: got %s, want %s", got, want)
7856 }
7857 }
7858
7859 func TestMapIterDelete0(t *testing.T) {
7860
7861 m := map[string]int{"one": 1, "two": 2, "three": 3}
7862 iter := ValueOf(m).MapRange()
7863 delete(m, "one")
7864 delete(m, "two")
7865 delete(m, "three")
7866 if got, want := iterateToString(iter), `[]`; got != want {
7867 t.Errorf("iterator returned deleted elements: got %s, want %s", got, want)
7868 }
7869 }
7870
7871 func TestMapIterDelete1(t *testing.T) {
7872
7873 m := map[string]int{"one": 1, "two": 2, "three": 3}
7874 iter := ValueOf(m).MapRange()
7875 var got []string
7876 for iter.Next() {
7877 got = append(got, fmt.Sprint(iter.Key(), iter.Value()))
7878 delete(m, "one")
7879 delete(m, "two")
7880 delete(m, "three")
7881 }
7882 if len(got) != 1 {
7883 t.Errorf("iterator returned wrong number of elements: got %d, want 1", len(got))
7884 }
7885 }
7886
7887
7888
7889 func iterateToString(it *MapIter) string {
7890 var got []string
7891 for it.Next() {
7892 line := fmt.Sprintf("%v: %v", it.Key(), it.Value())
7893 got = append(got, line)
7894 }
7895 slices.Sort(got)
7896 return "[" + strings.Join(got, ", ") + "]"
7897 }
7898
7899 func TestConvertibleTo(t *testing.T) {
7900 t1 := ValueOf(example1.MyStruct{}).Type()
7901 t2 := ValueOf(example2.MyStruct{}).Type()
7902
7903
7904 if t1.ConvertibleTo(t2) {
7905 t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t1, t2)
7906 }
7907
7908 t3 := ValueOf([]example1.MyStruct{}).Type()
7909 t4 := ValueOf([]example2.MyStruct{}).Type()
7910
7911 if t3.ConvertibleTo(t4) {
7912 t.Fatalf("(%s).ConvertibleTo(%s) = true, want false", t3, t4)
7913 }
7914 }
7915
7916 func TestSetIter(t *testing.T) {
7917 data := map[string]int{
7918 "foo": 1,
7919 "bar": 2,
7920 "baz": 3,
7921 }
7922
7923 m := ValueOf(data)
7924 i := m.MapRange()
7925 k := New(TypeOf("")).Elem()
7926 v := New(TypeOf(0)).Elem()
7927 shouldPanic("Value.SetIterKey called before Next", func() {
7928 k.SetIterKey(i)
7929 })
7930 shouldPanic("Value.SetIterValue called before Next", func() {
7931 v.SetIterValue(i)
7932 })
7933 data2 := map[string]int{}
7934 for i.Next() {
7935 k.SetIterKey(i)
7936 v.SetIterValue(i)
7937 data2[k.Interface().(string)] = v.Interface().(int)
7938 }
7939 if !DeepEqual(data, data2) {
7940 t.Errorf("maps not equal, got %v want %v", data2, data)
7941 }
7942 shouldPanic("Value.SetIterKey called on exhausted iterator", func() {
7943 k.SetIterKey(i)
7944 })
7945 shouldPanic("Value.SetIterValue called on exhausted iterator", func() {
7946 v.SetIterValue(i)
7947 })
7948
7949 i.Reset(m)
7950 i.Next()
7951 shouldPanic("Value.SetIterKey using unaddressable value", func() {
7952 ValueOf("").SetIterKey(i)
7953 })
7954 shouldPanic("Value.SetIterValue using unaddressable value", func() {
7955 ValueOf(0).SetIterValue(i)
7956 })
7957 shouldPanic("value of type string is not assignable to type int", func() {
7958 New(TypeOf(0)).Elem().SetIterKey(i)
7959 })
7960 shouldPanic("value of type int is not assignable to type string", func() {
7961 New(TypeOf("")).Elem().SetIterValue(i)
7962 })
7963
7964
7965 var x any
7966 y := ValueOf(&x).Elem()
7967 y.SetIterKey(i)
7968 if _, ok := data[x.(string)]; !ok {
7969 t.Errorf("got key %s which is not in map", x)
7970 }
7971 y.SetIterValue(i)
7972 if x.(int) < 1 || x.(int) > 3 {
7973 t.Errorf("got value %d which is not in map", x)
7974 }
7975
7976
7977 a := 88
7978 b := 99
7979 pp := map[*int]*int{
7980 &a: &b,
7981 }
7982 i = ValueOf(pp).MapRange()
7983 i.Next()
7984 y.SetIterKey(i)
7985 if got := *y.Interface().(*int); got != a {
7986 t.Errorf("pointer incorrect: got %d want %d", got, a)
7987 }
7988 y.SetIterValue(i)
7989 if got := *y.Interface().(*int); got != b {
7990 t.Errorf("pointer incorrect: got %d want %d", got, b)
7991 }
7992
7993
7994 m = ValueOf(struct{ m map[string]int }{data}).Field(0)
7995 for iter := m.MapRange(); iter.Next(); {
7996 shouldPanic("using value obtained using unexported field", func() {
7997 k.SetIterKey(iter)
7998 })
7999 shouldPanic("using value obtained using unexported field", func() {
8000 v.SetIterValue(iter)
8001 })
8002 }
8003 }
8004
8005 func TestMethodCallValueCodePtr(t *testing.T) {
8006 m := ValueOf(Point{}).Method(1)
8007 want := MethodValueCallCodePtr()
8008 if got := uintptr(m.UnsafePointer()); got != want {
8009 t.Errorf("methodValueCall code pointer mismatched, want: %v, got: %v", want, got)
8010 }
8011 if got := m.Pointer(); got != want {
8012 t.Errorf("methodValueCall code pointer mismatched, want: %v, got: %v", want, got)
8013 }
8014 }
8015
8016 type A struct{}
8017 type B[T any] struct{}
8018
8019 func TestIssue50208(t *testing.T) {
8020 want1 := "B[reflect_test.A]"
8021 if got := TypeOf(new(B[A])).Elem().Name(); got != want1 {
8022 t.Errorf("name of type parameter mismatched, want:%s, got:%s", want1, got)
8023 }
8024 want2 := "B[reflect_test.B[reflect_test.A]]"
8025 if got := TypeOf(new(B[B[A]])).Elem().Name(); got != want2 {
8026 t.Errorf("name of type parameter mismatched, want:%s, got:%s", want2, got)
8027 }
8028 }
8029
8030 func TestNegativeKindString(t *testing.T) {
8031 x := -1
8032 s := Kind(x).String()
8033 want := "kind-1"
8034 if s != want {
8035 t.Fatalf("Kind(-1).String() = %q, want %q", s, want)
8036 }
8037 }
8038
8039 type (
8040 namedBool bool
8041 namedBytes []byte
8042 )
8043
8044 func TestValue_Cap(t *testing.T) {
8045 a := &[3]int{1, 2, 3}
8046 v := ValueOf(a)
8047 if v.Cap() != cap(a) {
8048 t.Errorf("Cap = %d want %d", v.Cap(), cap(a))
8049 }
8050
8051 a = nil
8052 v = ValueOf(a)
8053 if v.Cap() != cap(a) {
8054 t.Errorf("Cap = %d want %d", v.Cap(), cap(a))
8055 }
8056
8057 getError := func(f func()) (errorStr string) {
8058 defer func() {
8059 e := recover()
8060 if str, ok := e.(string); ok {
8061 errorStr = str
8062 }
8063 }()
8064 f()
8065 return
8066 }
8067 e := getError(func() {
8068 var ptr *int
8069 ValueOf(ptr).Cap()
8070 })
8071 wantStr := "reflect: call of reflect.Value.Cap on ptr to non-array Value"
8072 if e != wantStr {
8073 t.Errorf("error is %q, want %q", e, wantStr)
8074 }
8075 }
8076
8077 func TestValue_Len(t *testing.T) {
8078 a := &[3]int{1, 2, 3}
8079 v := ValueOf(a)
8080 if v.Len() != len(a) {
8081 t.Errorf("Len = %d want %d", v.Len(), len(a))
8082 }
8083
8084 a = nil
8085 v = ValueOf(a)
8086 if v.Len() != len(a) {
8087 t.Errorf("Len = %d want %d", v.Len(), len(a))
8088 }
8089
8090 getError := func(f func()) (errorStr string) {
8091 defer func() {
8092 e := recover()
8093 if str, ok := e.(string); ok {
8094 errorStr = str
8095 }
8096 }()
8097 f()
8098 return
8099 }
8100 e := getError(func() {
8101 var ptr *int
8102 ValueOf(ptr).Len()
8103 })
8104 wantStr := "reflect: call of reflect.Value.Len on ptr to non-array Value"
8105 if e != wantStr {
8106 t.Errorf("error is %q, want %q", e, wantStr)
8107 }
8108 }
8109
8110 func TestValue_Comparable(t *testing.T) {
8111 var a int
8112 var s []int
8113 var i interface{} = a
8114 var iNil interface{}
8115 var iSlice interface{} = s
8116 var iArrayFalse interface{} = [2]interface{}{1, map[int]int{}}
8117 var iArrayTrue interface{} = [2]interface{}{1, struct{ I interface{} }{1}}
8118 var testcases = []struct {
8119 value Value
8120 comparable bool
8121 deref bool
8122 }{
8123 {
8124 ValueOf(&iNil),
8125 true,
8126 true,
8127 },
8128 {
8129 ValueOf(32),
8130 true,
8131 false,
8132 },
8133 {
8134 ValueOf(int8(1)),
8135 true,
8136 false,
8137 },
8138 {
8139 ValueOf(int16(1)),
8140 true,
8141 false,
8142 },
8143 {
8144 ValueOf(int32(1)),
8145 true,
8146 false,
8147 },
8148 {
8149 ValueOf(int64(1)),
8150 true,
8151 false,
8152 },
8153 {
8154 ValueOf(uint8(1)),
8155 true,
8156 false,
8157 },
8158 {
8159 ValueOf(uint16(1)),
8160 true,
8161 false,
8162 },
8163 {
8164 ValueOf(uint32(1)),
8165 true,
8166 false,
8167 },
8168 {
8169 ValueOf(uint64(1)),
8170 true,
8171 false,
8172 },
8173 {
8174 ValueOf(float32(1)),
8175 true,
8176 false,
8177 },
8178 {
8179 ValueOf(float64(1)),
8180 true,
8181 false,
8182 },
8183 {
8184 ValueOf(complex(float32(1), float32(1))),
8185 true,
8186 false,
8187 },
8188 {
8189 ValueOf(complex(float64(1), float64(1))),
8190 true,
8191 false,
8192 },
8193 {
8194 ValueOf("abc"),
8195 true,
8196 false,
8197 },
8198 {
8199 ValueOf(true),
8200 true,
8201 false,
8202 },
8203 {
8204 ValueOf(map[int]int{}),
8205 false,
8206 false,
8207 },
8208 {
8209 ValueOf([]int{}),
8210 false,
8211 false,
8212 },
8213 {
8214 Value{},
8215 false,
8216 false,
8217 },
8218 {
8219 ValueOf(&a),
8220 true,
8221 false,
8222 },
8223 {
8224 ValueOf(&s),
8225 true,
8226 false,
8227 },
8228 {
8229 ValueOf(&i),
8230 true,
8231 true,
8232 },
8233 {
8234 ValueOf(&iSlice),
8235 false,
8236 true,
8237 },
8238 {
8239 ValueOf([2]int{}),
8240 true,
8241 false,
8242 },
8243 {
8244 ValueOf([2]map[int]int{}),
8245 false,
8246 false,
8247 },
8248 {
8249 ValueOf([0]func(){}),
8250 false,
8251 false,
8252 },
8253 {
8254 ValueOf([2]struct{ I interface{} }{{1}, {1}}),
8255 true,
8256 false,
8257 },
8258 {
8259 ValueOf([2]struct{ I interface{} }{{[]int{}}, {1}}),
8260 false,
8261 false,
8262 },
8263 {
8264 ValueOf([2]interface{}{1, struct{ I int }{1}}),
8265 true,
8266 false,
8267 },
8268 {
8269 ValueOf([2]interface{}{[1]interface{}{map[int]int{}}, struct{ I int }{1}}),
8270 false,
8271 false,
8272 },
8273 {
8274 ValueOf(&iArrayFalse),
8275 false,
8276 true,
8277 },
8278 {
8279 ValueOf(&iArrayTrue),
8280 true,
8281 true,
8282 },
8283 }
8284
8285 for _, cas := range testcases {
8286 v := cas.value
8287 if cas.deref {
8288 v = v.Elem()
8289 }
8290 got := v.Comparable()
8291 if got != cas.comparable {
8292 t.Errorf("%T.Comparable = %t, want %t", v, got, cas.comparable)
8293 }
8294 }
8295 }
8296
8297 type ValueEqualTest struct {
8298 v, u any
8299 eq bool
8300 vDeref, uDeref bool
8301 }
8302
8303 var equalI interface{} = 1
8304 var equalSlice interface{} = []int{1}
8305 var nilInterface interface{}
8306 var mapInterface interface{} = map[int]int{}
8307
8308 var valueEqualTests = []ValueEqualTest{
8309 {
8310 Value{}, Value{},
8311 true,
8312 false, false,
8313 },
8314 {
8315 true, true,
8316 true,
8317 false, false,
8318 },
8319 {
8320 1, 1,
8321 true,
8322 false, false,
8323 },
8324 {
8325 int8(1), int8(1),
8326 true,
8327 false, false,
8328 },
8329 {
8330 int16(1), int16(1),
8331 true,
8332 false, false,
8333 },
8334 {
8335 int32(1), int32(1),
8336 true,
8337 false, false,
8338 },
8339 {
8340 int64(1), int64(1),
8341 true,
8342 false, false,
8343 },
8344 {
8345 uint(1), uint(1),
8346 true,
8347 false, false,
8348 },
8349 {
8350 uint8(1), uint8(1),
8351 true,
8352 false, false,
8353 },
8354 {
8355 uint16(1), uint16(1),
8356 true,
8357 false, false,
8358 },
8359 {
8360 uint32(1), uint32(1),
8361 true,
8362 false, false,
8363 },
8364 {
8365 uint64(1), uint64(1),
8366 true,
8367 false, false,
8368 },
8369 {
8370 float32(1), float32(1),
8371 true,
8372 false, false,
8373 },
8374 {
8375 float64(1), float64(1),
8376 true,
8377 false, false,
8378 },
8379 {
8380 complex(1, 1), complex(1, 1),
8381 true,
8382 false, false,
8383 },
8384 {
8385 complex128(1 + 1i), complex128(1 + 1i),
8386 true,
8387 false, false,
8388 },
8389 {
8390 func() {}, nil,
8391 false,
8392 false, false,
8393 },
8394 {
8395 &equalI, 1,
8396 true,
8397 true, false,
8398 },
8399 {
8400 (chan int)(nil), nil,
8401 false,
8402 false, false,
8403 },
8404 {
8405 (chan int)(nil), (chan int)(nil),
8406 true,
8407 false, false,
8408 },
8409 {
8410 &equalI, &equalI,
8411 true,
8412 false, false,
8413 },
8414 {
8415 struct{ i int }{1}, struct{ i int }{1},
8416 true,
8417 false, false,
8418 },
8419 {
8420 struct{ i int }{1}, struct{ i int }{2},
8421 false,
8422 false, false,
8423 },
8424 {
8425 &nilInterface, &nilInterface,
8426 true,
8427 true, true,
8428 },
8429 {
8430 1, ValueOf(struct{ i int }{1}).Field(0),
8431 true,
8432 false, false,
8433 },
8434 }
8435
8436 func TestValue_Equal(t *testing.T) {
8437 for _, test := range valueEqualTests {
8438 var v, u Value
8439 if vv, ok := test.v.(Value); ok {
8440 v = vv
8441 } else {
8442 v = ValueOf(test.v)
8443 }
8444
8445 if uu, ok := test.u.(Value); ok {
8446 u = uu
8447 } else {
8448 u = ValueOf(test.u)
8449 }
8450 if test.vDeref {
8451 v = v.Elem()
8452 }
8453
8454 if test.uDeref {
8455 u = u.Elem()
8456 }
8457
8458 if r := v.Equal(u); r != test.eq {
8459 t.Errorf("%s == %s got %t, want %t", v.Type(), u.Type(), r, test.eq)
8460 }
8461 }
8462 }
8463
8464 func TestValue_EqualNonComparable(t *testing.T) {
8465 var invalid = Value{}
8466 var values = []Value{
8467
8468 ValueOf([]int(nil)),
8469 ValueOf(([]int{})),
8470
8471
8472 ValueOf(map[int]int(nil)),
8473 ValueOf((map[int]int{})),
8474
8475
8476 ValueOf(((func())(nil))),
8477 ValueOf(func() {}),
8478
8479
8480 ValueOf((NonComparableStruct{})),
8481
8482
8483 ValueOf([0]map[int]int{}),
8484 ValueOf([0]func(){}),
8485 ValueOf(([1]struct{ I interface{} }{{[]int{}}})),
8486 ValueOf(([1]interface{}{[1]interface{}{map[int]int{}}})),
8487 }
8488 for _, value := range values {
8489
8490 shouldPanic("are not comparable", func() { value.Equal(value) })
8491
8492
8493 if r := value.Equal(invalid); r != false {
8494 t.Errorf("%s == invalid got %t, want false", value.Type(), r)
8495 }
8496 }
8497 }
8498
8499 func TestInitFuncTypes(t *testing.T) {
8500 n := 100
8501 var wg sync.WaitGroup
8502
8503 wg.Add(n)
8504 for i := 0; i < n; i++ {
8505 go func() {
8506 defer wg.Done()
8507 ipT := TypeOf(net.IP{})
8508 for i := 0; i < ipT.NumMethod(); i++ {
8509 _ = ipT.Method(i)
8510 }
8511 }()
8512 }
8513 wg.Wait()
8514 }
8515
8516 func TestClear(t *testing.T) {
8517 m := make(map[string]any, len(valueTests))
8518 for _, tt := range valueTests {
8519 m[tt.s] = tt.i
8520 }
8521 mapTestFn := func(v Value) bool { v.Clear(); return v.Len() == 0 }
8522
8523 s := make([]*pair, len(valueTests))
8524 for i := range s {
8525 s[i] = &valueTests[i]
8526 }
8527 sliceTestFn := func(v Value) bool {
8528 v.Clear()
8529 for i := 0; i < v.Len(); i++ {
8530 if !v.Index(i).IsZero() {
8531 return false
8532 }
8533 }
8534 return true
8535 }
8536
8537 panicTestFn := func(v Value) bool { shouldPanic("reflect.Value.Clear", func() { v.Clear() }); return true }
8538
8539 tests := []struct {
8540 name string
8541 value Value
8542 testFunc func(v Value) bool
8543 }{
8544 {"map", ValueOf(m), mapTestFn},
8545 {"slice no pointer", ValueOf([]int{1, 2, 3, 4, 5}), sliceTestFn},
8546 {"slice has pointer", ValueOf(s), sliceTestFn},
8547 {"non-map/slice", ValueOf(1), panicTestFn},
8548 }
8549
8550 for _, tc := range tests {
8551 tc := tc
8552 t.Run(tc.name, func(t *testing.T) {
8553 t.Parallel()
8554 if !tc.testFunc(tc.value) {
8555 t.Errorf("unexpected result for value.Clear(): %v", tc.value)
8556 }
8557 })
8558 }
8559 }
8560
8561 func TestValuePointerAndUnsafePointer(t *testing.T) {
8562 ptr := new(int)
8563 ch := make(chan int)
8564 m := make(map[int]int)
8565 unsafePtr := unsafe.Pointer(ptr)
8566 slice := make([]int, 1)
8567 fn := func() {}
8568 s := "foo"
8569
8570 tests := []struct {
8571 name string
8572 val Value
8573 wantUnsafePointer unsafe.Pointer
8574 }{
8575 {"pointer", ValueOf(ptr), unsafe.Pointer(ptr)},
8576 {"channel", ValueOf(ch), *(*unsafe.Pointer)(unsafe.Pointer(&ch))},
8577 {"map", ValueOf(m), *(*unsafe.Pointer)(unsafe.Pointer(&m))},
8578 {"unsafe.Pointer", ValueOf(unsafePtr), unsafePtr},
8579 {"function", ValueOf(fn), **(**unsafe.Pointer)(unsafe.Pointer(&fn))},
8580 {"slice", ValueOf(slice), unsafe.Pointer(unsafe.SliceData(slice))},
8581 {"string", ValueOf(s), unsafe.Pointer(unsafe.StringData(s))},
8582 }
8583
8584 for _, tc := range tests {
8585 tc := tc
8586 t.Run(tc.name, func(t *testing.T) {
8587 if got := tc.val.Pointer(); got != uintptr(tc.wantUnsafePointer) {
8588 t.Errorf("unexpected uintptr result, got %#x, want %#x", got, uintptr(tc.wantUnsafePointer))
8589 }
8590 if got := tc.val.UnsafePointer(); got != tc.wantUnsafePointer {
8591 t.Errorf("unexpected unsafe.Pointer result, got %#x, want %#x", got, tc.wantUnsafePointer)
8592 }
8593 })
8594 }
8595 }
8596
8597
8598 func TestSliceAt(t *testing.T) {
8599 const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
8600 var p [10]byte
8601
8602 typ := TypeOf(p[0])
8603
8604 s := SliceAt(typ, unsafe.Pointer(&p[0]), len(p))
8605 if s.Pointer() != uintptr(unsafe.Pointer(&p[0])) {
8606 t.Fatalf("unexpected underlying array: %d, want: %d", s.Pointer(), uintptr(unsafe.Pointer(&p[0])))
8607 }
8608 if s.Len() != len(p) || s.Cap() != len(p) {
8609 t.Fatalf("unexpected len or cap, len: %d, cap: %d, want: %d", s.Len(), s.Cap(), len(p))
8610 }
8611
8612 typ = TypeOf(0)
8613 if !SliceAt(typ, unsafe.Pointer((*int)(nil)), 0).IsNil() {
8614 t.Fatal("nil pointer with zero length must return nil")
8615 }
8616
8617
8618 shouldPanic("", func() { _ = SliceAt(typ, unsafe.Pointer((*int)(nil)), 1) })
8619
8620
8621 var neg int = -1
8622 shouldPanic("", func() { _ = SliceAt(TypeOf(byte(0)), unsafe.Pointer(&p[0]), neg) })
8623
8624
8625 n := uint64(0)
8626 shouldPanic("", func() { _ = SliceAt(TypeOf(n), unsafe.Pointer(&n), maxUintptr/8) })
8627 shouldPanic("", func() { _ = SliceAt(TypeOf(n), unsafe.Pointer(&n), maxUintptr/8+1) })
8628
8629
8630 last := (*byte)(unsafe.Pointer(^uintptr(0)))
8631
8632
8633
8634
8635 shouldPanic("", func() { _ = SliceAt(typ, unsafe.Pointer(last), 2) })
8636 }
8637
8638
8639
8640
8641
8642 func TestMapOfKeyUpdate(t *testing.T) {
8643 m := MakeMap(MapOf(TypeFor[float64](), TypeFor[bool]()))
8644
8645 zero := float64(0.0)
8646 negZero := math.Copysign(zero, -1.0)
8647
8648 m.SetMapIndex(ValueOf(zero), ValueOf(true))
8649 m.SetMapIndex(ValueOf(negZero), ValueOf(true))
8650
8651 if m.Len() != 1 {
8652 t.Errorf("map length got %d want 1", m.Len())
8653 }
8654
8655 iter := m.MapRange()
8656 for iter.Next() {
8657 k := iter.Key().Float()
8658 if math.Copysign(1.0, k) > 0 {
8659 t.Errorf("map key %f has positive sign", k)
8660 }
8661 }
8662 }
8663
8664
8665
8666
8667
8668
8669 func TestMapOfKeyPanic(t *testing.T) {
8670 defer func() {
8671 r := recover()
8672 if r == nil {
8673 t.Errorf("didn't panic")
8674 }
8675 }()
8676
8677 m := MakeMap(MapOf(TypeFor[any](), TypeFor[bool]()))
8678
8679 var slice []int
8680 m.MapIndex(ValueOf(slice))
8681 }
8682
8683 func TestTypeAssert(t *testing.T) {
8684 testTypeAssert(t, int(123456789), int(123456789), true)
8685 testTypeAssert(t, int(-123456789), int(-123456789), true)
8686 testTypeAssert(t, int32(123456789), int32(123456789), true)
8687 testTypeAssert(t, int8(-123), int8(-123), true)
8688 testTypeAssert(t, [2]int{1234, -5678}, [2]int{1234, -5678}, true)
8689 testTypeAssert(t, "test value", "test value", true)
8690 testTypeAssert(t, any("test value"), any("test value"), true)
8691
8692 v := 123456789
8693 testTypeAssert(t, &v, &v, true)
8694
8695 testTypeAssert(t, int(123), uint(0), false)
8696
8697 testTypeAssert[any](t, 1, 1, true)
8698 testTypeAssert[fmt.Stringer](t, 1, nil, false)
8699
8700 vv := testTypeWithMethod{"test"}
8701 testTypeAssert[any](t, vv, vv, true)
8702 testTypeAssert[any](t, &vv, &vv, true)
8703 testTypeAssert[fmt.Stringer](t, vv, vv, true)
8704 testTypeAssert[fmt.Stringer](t, &vv, &vv, true)
8705 testTypeAssert[interface{ A() }](t, vv, nil, false)
8706 testTypeAssert[interface{ A() }](t, &vv, nil, false)
8707 testTypeAssert(t, any(vv), any(vv), true)
8708 testTypeAssert(t, fmt.Stringer(vv), fmt.Stringer(vv), true)
8709
8710 testTypeAssert(t, fmt.Stringer(vv), any(vv), true)
8711 testTypeAssert(t, any(vv), fmt.Stringer(vv), true)
8712 testTypeAssert(t, fmt.Stringer(vv), interface{ M() }(vv), true)
8713 testTypeAssert(t, interface{ M() }(vv), fmt.Stringer(vv), true)
8714
8715 testTypeAssert(t, any(int(1)), int(1), true)
8716 testTypeAssert(t, any(int(1)), byte(0), false)
8717 testTypeAssert(t, fmt.Stringer(vv), vv, true)
8718
8719 testTypeAssert(t, any(nil), any(nil), false)
8720 testTypeAssert(t, any(nil), error(nil), false)
8721 testTypeAssert(t, error(nil), any(nil), false)
8722 testTypeAssert(t, error(nil), error(nil), false)
8723 }
8724
8725 func testTypeAssert[T comparable, V any](t *testing.T, val V, wantVal T, wantOk bool) {
8726 t.Helper()
8727
8728 v, ok := TypeAssert[T](ValueOf(&val).Elem())
8729 if v != wantVal || ok != wantOk {
8730 t.Errorf("TypeAssert[%v](%#v) = (%#v, %v); want = (%#v, %v)", TypeFor[T](), val, v, ok, wantVal, wantOk)
8731 }
8732
8733
8734 v2, ok2 := ValueOf(&val).Elem().Interface().(T)
8735 if v != v2 || ok != ok2 {
8736 t.Errorf("reflect.ValueOf(%#v).Interface().(%v) = (%#v, %v); want = (%#v, %v)", val, TypeFor[T](), v2, ok2, v, ok)
8737 }
8738 }
8739
8740 type testTypeWithMethod struct{ val string }
8741
8742 func (v testTypeWithMethod) String() string { return v.val }
8743 func (v testTypeWithMethod) M() {}
8744
8745 func TestTypeAssertMethod(t *testing.T) {
8746 method := ValueOf(&testTypeWithMethod{val: "test value"}).MethodByName("String")
8747 f, ok := TypeAssert[func() string](method)
8748 if !ok {
8749 t.Fatalf(`TypeAssert[func() string](method) = (,false); want = (,true)`)
8750 }
8751
8752 out := f()
8753 if out != "test value" {
8754 t.Fatalf(`TypeAssert[func() string](method)() = %q; want "test value"`, out)
8755 }
8756 }
8757
8758 func TestTypeAssertPanic(t *testing.T) {
8759 t.Run("zero val", func(t *testing.T) {
8760 defer func() { recover() }()
8761 TypeAssert[int](Value{})
8762 t.Fatalf("TypeAssert did not panic")
8763 })
8764 t.Run("read only", func(t *testing.T) {
8765 defer func() { recover() }()
8766 TypeAssert[int](ValueOf(&testTypeWithMethod{}).FieldByName("val"))
8767 t.Fatalf("TypeAssert did not panic")
8768 })
8769 }
8770
8771 func TestTypeAssertAllocs(t *testing.T) {
8772 if race.Enabled || asan.Enabled || msan.Enabled {
8773 t.Skip("instrumentation breaks this optimization")
8774 }
8775 typeAssertAllocs[[128]int](t, ValueOf([128]int{}), 0)
8776 typeAssertAllocs[any](t, ValueOf([128]int{}), 0)
8777
8778 val := 123
8779 typeAssertAllocs[any](t, ValueOf(val), 0)
8780 typeAssertAllocs[any](t, ValueOf(&val).Elem(), 1)
8781 typeAssertAllocs[int](t, ValueOf(val), 0)
8782 typeAssertAllocs[int](t, ValueOf(&val).Elem(), 0)
8783
8784 typeAssertAllocs[time.Time](t, ValueOf(new(time.Time)).Elem(), 0)
8785 typeAssertAllocs[time.Time](t, ValueOf(*new(time.Time)), 0)
8786 }
8787
8788 func typeAssertAllocs[T any](t *testing.T, val Value, wantAllocs int) {
8789 t.Helper()
8790 allocs := testing.AllocsPerRun(10, func() {
8791 TypeAssert[T](val)
8792 })
8793 if allocs != float64(wantAllocs) {
8794 t.Errorf("TypeAssert[%v](%v) unexpected amount of allocations = %v; want = %v", TypeFor[T](), val.Type(), allocs, wantAllocs)
8795 }
8796 }
8797
8798 func BenchmarkTypeAssert(b *testing.B) {
8799 benchmarkTypeAssert[int](b, ValueOf(int(1)))
8800 benchmarkTypeAssert[byte](b, ValueOf(int(1)))
8801
8802 benchmarkTypeAssert[fmt.Stringer](b, ValueOf(testTypeWithMethod{}))
8803 benchmarkTypeAssert[fmt.Stringer](b, ValueOf(&testTypeWithMethod{}))
8804 benchmarkTypeAssert[any](b, ValueOf(int(1)))
8805 benchmarkTypeAssert[any](b, ValueOf(testTypeWithMethod{}))
8806
8807 benchmarkTypeAssert[time.Time](b, ValueOf(*new(time.Time)))
8808
8809 benchmarkTypeAssert[func() string](b, ValueOf(time.Now()).MethodByName("String"))
8810 }
8811
8812 func benchmarkTypeAssert[T any](b *testing.B, val Value) {
8813 b.Run(fmt.Sprintf("TypeAssert[%v](%v)", TypeFor[T](), val.Type()), func(b *testing.B) {
8814 for b.Loop() {
8815 TypeAssert[T](val)
8816 }
8817 })
8818 }
8819
View as plain text