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