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