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