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