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