1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package reflectlite_test
6
7import (
8	"encoding/base64"
9	"fmt"
10	"internal/abi"
11	. "internal/reflectlite"
12	"math"
13	"reflect"
14	"runtime"
15	"testing"
16	"unsafe"
17)
18
19func ToValue(v Value) reflect.Value {
20	return reflect.ValueOf(ToInterface(v))
21}
22
23func TypeString(t Type) string {
24	return fmt.Sprintf("%T", ToInterface(Zero(t)))
25}
26
27type integer int
28type T struct {
29	a int
30	b float64
31	c string
32	d *int
33}
34
35type pair struct {
36	i any
37	s string
38}
39
40func assert(t *testing.T, s, want string) {
41	t.Helper()
42	if s != want {
43		t.Errorf("have %#q want %#q", s, want)
44	}
45}
46
47var typeTests = []pair{
48	{struct{ x int }{}, "int"},
49	{struct{ x int8 }{}, "int8"},
50	{struct{ x int16 }{}, "int16"},
51	{struct{ x int32 }{}, "int32"},
52	{struct{ x int64 }{}, "int64"},
53	{struct{ x uint }{}, "uint"},
54	{struct{ x uint8 }{}, "uint8"},
55	{struct{ x uint16 }{}, "uint16"},
56	{struct{ x uint32 }{}, "uint32"},
57	{struct{ x uint64 }{}, "uint64"},
58	{struct{ x float32 }{}, "float32"},
59	{struct{ x float64 }{}, "float64"},
60	{struct{ x int8 }{}, "int8"},
61	{struct{ x (**int8) }{}, "**int8"},
62	{struct{ x (**integer) }{}, "**reflectlite_test.integer"},
63	{struct{ x ([32]int32) }{}, "[32]int32"},
64	{struct{ x ([]int8) }{}, "[]int8"},
65	{struct{ x (map[string]int32) }{}, "map[string]int32"},
66	{struct{ x (chan<- string) }{}, "chan<- string"},
67	{struct {
68		x struct {
69			c chan *int32
70			d float32
71		}
72	}{},
73		"struct { c chan *int32; d float32 }",
74	},
75	{struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
76	{struct {
77		x struct {
78			c func(chan *integer, *int8)
79		}
80	}{},
81		"struct { c func(chan *reflectlite_test.integer, *int8) }",
82	},
83	{struct {
84		x struct {
85			a int8
86			b int32
87		}
88	}{},
89		"struct { a int8; b int32 }",
90	},
91	{struct {
92		x struct {
93			a int8
94			b int8
95			c int32
96		}
97	}{},
98		"struct { a int8; b int8; c int32 }",
99	},
100	{struct {
101		x struct {
102			a int8
103			b int8
104			c int8
105			d int32
106		}
107	}{},
108		"struct { a int8; b int8; c int8; d int32 }",
109	},
110	{struct {
111		x struct {
112			a int8
113			b int8
114			c int8
115			d int8
116			e int32
117		}
118	}{},
119		"struct { a int8; b int8; c int8; d int8; e int32 }",
120	},
121	{struct {
122		x struct {
123			a int8
124			b int8
125			c int8
126			d int8
127			e int8
128			f int32
129		}
130	}{},
131		"struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
132	},
133	{struct {
134		x struct {
135			a int8 `reflect:"hi there"`
136		}
137	}{},
138		`struct { a int8 "reflect:\"hi there\"" }`,
139	},
140	{struct {
141		x struct {
142			a int8 `reflect:"hi \x00there\t\n\"\\"`
143		}
144	}{},
145		`struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
146	},
147	{struct {
148		x struct {
149			f func(args ...int)
150		}
151	}{},
152		"struct { f func(...int) }",
153	},
154	// {struct {
155	// 	x (interface {
156	// 		a(func(func(int) int) func(func(int)) int)
157	// 		b()
158	// 	})
159	// }{},
160	// 	"interface { reflectlite_test.a(func(func(int) int) func(func(int)) int); reflectlite_test.b() }",
161	// },
162	{struct {
163		x struct {
164			int32
165			int64
166		}
167	}{},
168		"struct { int32; int64 }",
169	},
170}
171
172var valueTests = []pair{
173	{new(int), "132"},
174	{new(int8), "8"},
175	{new(int16), "16"},
176	{new(int32), "32"},
177	{new(int64), "64"},
178	{new(uint), "132"},
179	{new(uint8), "8"},
180	{new(uint16), "16"},
181	{new(uint32), "32"},
182	{new(uint64), "64"},
183	{new(float32), "256.25"},
184	{new(float64), "512.125"},
185	{new(complex64), "532.125+10i"},
186	{new(complex128), "564.25+1i"},
187	{new(string), "stringy cheese"},
188	{new(bool), "true"},
189	{new(*int8), "*int8(0)"},
190	{new(**int8), "**int8(0)"},
191	{new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
192	{new(**integer), "**reflectlite_test.integer(0)"},
193	{new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
194	{new(chan<- string), "chan<- string"},
195	{new(func(a int8, b int32)), "func(int8, int32)(arg)"},
196	{new(struct {
197		c chan *int32
198		d float32
199	}),
200		"struct { c chan *int32; d float32 }{chan *int32, 0}",
201	},
202	{new(struct{ c func(chan *integer, *int8) }),
203		"struct { c func(chan *reflectlite_test.integer, *int8) }{func(chan *reflectlite_test.integer, *int8)(arg)}",
204	},
205	{new(struct {
206		a int8
207		b int32
208	}),
209		"struct { a int8; b int32 }{0, 0}",
210	},
211	{new(struct {
212		a int8
213		b int8
214		c int32
215	}),
216		"struct { a int8; b int8; c int32 }{0, 0, 0}",
217	},
218}
219
220func testType(t *testing.T, i int, typ Type, want string) {
221	s := TypeString(typ)
222	if s != want {
223		t.Errorf("#%d: have %#q, want %#q", i, s, want)
224	}
225}
226
227func testReflectType(t *testing.T, i int, typ Type, want string) {
228	s := TypeString(typ)
229	if s != want {
230		t.Errorf("#%d: have %#q, want %#q", i, s, want)
231	}
232}
233
234func TestTypes(t *testing.T) {
235	for i, tt := range typeTests {
236		testReflectType(t, i, Field(ValueOf(tt.i), 0).Type(), tt.s)
237	}
238}
239
240func TestSetValue(t *testing.T) {
241	for i, tt := range valueTests {
242		v := ValueOf(tt.i).Elem()
243		switch v.Kind() {
244		case abi.Int:
245			v.Set(ValueOf(int(132)))
246		case abi.Int8:
247			v.Set(ValueOf(int8(8)))
248		case abi.Int16:
249			v.Set(ValueOf(int16(16)))
250		case abi.Int32:
251			v.Set(ValueOf(int32(32)))
252		case abi.Int64:
253			v.Set(ValueOf(int64(64)))
254		case abi.Uint:
255			v.Set(ValueOf(uint(132)))
256		case abi.Uint8:
257			v.Set(ValueOf(uint8(8)))
258		case abi.Uint16:
259			v.Set(ValueOf(uint16(16)))
260		case abi.Uint32:
261			v.Set(ValueOf(uint32(32)))
262		case abi.Uint64:
263			v.Set(ValueOf(uint64(64)))
264		case abi.Float32:
265			v.Set(ValueOf(float32(256.25)))
266		case abi.Float64:
267			v.Set(ValueOf(512.125))
268		case abi.Complex64:
269			v.Set(ValueOf(complex64(532.125 + 10i)))
270		case abi.Complex128:
271			v.Set(ValueOf(complex128(564.25 + 1i)))
272		case abi.String:
273			v.Set(ValueOf("stringy cheese"))
274		case abi.Bool:
275			v.Set(ValueOf(true))
276		}
277		s := valueToString(v)
278		if s != tt.s {
279			t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
280		}
281	}
282}
283
284func TestCanSetField(t *testing.T) {
285	type embed struct{ x, X int }
286	type Embed struct{ x, X int }
287	type S1 struct {
288		embed
289		x, X int
290	}
291	type S2 struct {
292		*embed
293		x, X int
294	}
295	type S3 struct {
296		Embed
297		x, X int
298	}
299	type S4 struct {
300		*Embed
301		x, X int
302	}
303
304	type testCase struct {
305		index  []int
306		canSet bool
307	}
308	tests := []struct {
309		val   Value
310		cases []testCase
311	}{{
312		val: ValueOf(&S1{}),
313		cases: []testCase{
314			{[]int{0}, false},
315			{[]int{0, 0}, false},
316			{[]int{0, 1}, true},
317			{[]int{1}, false},
318			{[]int{2}, true},
319		},
320	}, {
321		val: ValueOf(&S2{embed: &embed{}}),
322		cases: []testCase{
323			{[]int{0}, false},
324			{[]int{0, 0}, false},
325			{[]int{0, 1}, true},
326			{[]int{1}, false},
327			{[]int{2}, true},
328		},
329	}, {
330		val: ValueOf(&S3{}),
331		cases: []testCase{
332			{[]int{0}, true},
333			{[]int{0, 0}, false},
334			{[]int{0, 1}, true},
335			{[]int{1}, false},
336			{[]int{2}, true},
337		},
338	}, {
339		val: ValueOf(&S4{Embed: &Embed{}}),
340		cases: []testCase{
341			{[]int{0}, true},
342			{[]int{0, 0}, false},
343			{[]int{0, 1}, true},
344			{[]int{1}, false},
345			{[]int{2}, true},
346		},
347	}}
348
349	for _, tt := range tests {
350		t.Run(tt.val.Type().Name(), func(t *testing.T) {
351			for _, tc := range tt.cases {
352				f := tt.val
353				for _, i := range tc.index {
354					if f.Kind() == Ptr {
355						f = f.Elem()
356					}
357					f = Field(f, i)
358				}
359				if got := f.CanSet(); got != tc.canSet {
360					t.Errorf("CanSet() = %v, want %v", got, tc.canSet)
361				}
362			}
363		})
364	}
365}
366
367var _i = 7
368
369var valueToStringTests = []pair{
370	{123, "123"},
371	{123.5, "123.5"},
372	{byte(123), "123"},
373	{"abc", "abc"},
374	{T{123, 456.75, "hello", &_i}, "reflectlite_test.T{123, 456.75, hello, *int(&7)}"},
375	{new(chan *T), "*chan *reflectlite_test.T(&chan *reflectlite_test.T)"},
376	{[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
377	{&[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})"},
378	{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
379	{&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
380}
381
382func TestValueToString(t *testing.T) {
383	for i, test := range valueToStringTests {
384		s := valueToString(ValueOf(test.i))
385		if s != test.s {
386			t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
387		}
388	}
389}
390
391func TestPtrSetNil(t *testing.T) {
392	var i int32 = 1234
393	ip := &i
394	vip := ValueOf(&ip)
395	vip.Elem().Set(Zero(vip.Elem().Type()))
396	if ip != nil {
397		t.Errorf("got non-nil (%d), want nil", *ip)
398	}
399}
400
401func TestMapSetNil(t *testing.T) {
402	m := make(map[string]int)
403	vm := ValueOf(&m)
404	vm.Elem().Set(Zero(vm.Elem().Type()))
405	if m != nil {
406		t.Errorf("got non-nil (%p), want nil", m)
407	}
408}
409
410func TestAll(t *testing.T) {
411	testType(t, 1, TypeOf((int8)(0)), "int8")
412	testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
413
414	typ := TypeOf((*struct {
415		c chan *int32
416		d float32
417	})(nil))
418	testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
419	etyp := typ.Elem()
420	testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
421}
422
423func TestInterfaceValue(t *testing.T) {
424	var inter struct {
425		E any
426	}
427	inter.E = 123.456
428	v1 := ValueOf(&inter)
429	v2 := Field(v1.Elem(), 0)
430	// assert(t, TypeString(v2.Type()), "interface {}")
431	v3 := v2.Elem()
432	assert(t, TypeString(v3.Type()), "float64")
433
434	i3 := ToInterface(v2)
435	if _, ok := i3.(float64); !ok {
436		t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
437	}
438}
439
440func TestFunctionValue(t *testing.T) {
441	var x any = func() {}
442	v := ValueOf(x)
443	if fmt.Sprint(ToInterface(v)) != fmt.Sprint(x) {
444		t.Fatalf("TestFunction returned wrong pointer")
445	}
446	assert(t, TypeString(v.Type()), "func()")
447}
448
449var appendTests = []struct {
450	orig, extra []int
451}{
452	{make([]int, 2, 4), []int{22}},
453	{make([]int, 2, 4), []int{22, 33, 44}},
454}
455
456func sameInts(x, y []int) bool {
457	if len(x) != len(y) {
458		return false
459	}
460	for i, xx := range x {
461		if xx != y[i] {
462			return false
463		}
464	}
465	return true
466}
467
468func TestBigUnnamedStruct(t *testing.T) {
469	b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
470	v := ValueOf(b)
471	b1 := ToInterface(v).(struct {
472		a, b, c, d int64
473	})
474	if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
475		t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
476	}
477}
478
479type big struct {
480	a, b, c, d, e int64
481}
482
483func TestBigStruct(t *testing.T) {
484	b := big{1, 2, 3, 4, 5}
485	v := ValueOf(b)
486	b1 := ToInterface(v).(big)
487	if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
488		t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
489	}
490}
491
492type Basic struct {
493	x int
494	y float32
495}
496
497type NotBasic Basic
498
499type DeepEqualTest struct {
500	a, b any
501	eq   bool
502}
503
504// Simple functions for DeepEqual tests.
505var (
506	fn1 func()             // nil.
507	fn2 func()             // nil.
508	fn3 = func() { fn1() } // Not nil.
509)
510
511type self struct{}
512
513type Loop *Loop
514type Loopy any
515
516var loop1, loop2 Loop
517var loopy1, loopy2 Loopy
518
519func init() {
520	loop1 = &loop2
521	loop2 = &loop1
522
523	loopy1 = &loopy2
524	loopy2 = &loopy1
525}
526
527var typeOfTests = []DeepEqualTest{
528	// Equalities
529	{nil, nil, true},
530	{1, 1, true},
531	{int32(1), int32(1), true},
532	{0.5, 0.5, true},
533	{float32(0.5), float32(0.5), true},
534	{"hello", "hello", true},
535	{make([]int, 10), make([]int, 10), true},
536	{&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
537	{Basic{1, 0.5}, Basic{1, 0.5}, true},
538	{error(nil), error(nil), true},
539	{map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
540	{fn1, fn2, true},
541
542	// Inequalities
543	{1, 2, false},
544	{int32(1), int32(2), false},
545	{0.5, 0.6, false},
546	{float32(0.5), float32(0.6), false},
547	{"hello", "hey", false},
548	{make([]int, 10), make([]int, 11), false},
549	{&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
550	{Basic{1, 0.5}, Basic{1, 0.6}, false},
551	{Basic{1, 0}, Basic{2, 0}, false},
552	{map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
553	{map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
554	{map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
555	{map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
556	{nil, 1, false},
557	{1, nil, false},
558	{fn1, fn3, false},
559	{fn3, fn3, false},
560	{[][]int{{1}}, [][]int{{2}}, false},
561	{math.NaN(), math.NaN(), false},
562	{&[1]float64{math.NaN()}, &[1]float64{math.NaN()}, false},
563	{&[1]float64{math.NaN()}, self{}, true},
564	{[]float64{math.NaN()}, []float64{math.NaN()}, false},
565	{[]float64{math.NaN()}, self{}, true},
566	{map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false},
567	{map[float64]float64{math.NaN(): 1}, self{}, true},
568
569	// Nil vs empty: not the same.
570	{[]int{}, []int(nil), false},
571	{[]int{}, []int{}, true},
572	{[]int(nil), []int(nil), true},
573	{map[int]int{}, map[int]int(nil), false},
574	{map[int]int{}, map[int]int{}, true},
575	{map[int]int(nil), map[int]int(nil), true},
576
577	// Mismatched types
578	{1, 1.0, false},
579	{int32(1), int64(1), false},
580	{0.5, "hello", false},
581	{[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
582	{&[3]any{1, 2, 4}, &[3]any{1, 2, "s"}, false},
583	{Basic{1, 0.5}, NotBasic{1, 0.5}, false},
584	{map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
585
586	// Possible loops.
587	{&loop1, &loop1, true},
588	{&loop1, &loop2, true},
589	{&loopy1, &loopy1, true},
590	{&loopy1, &loopy2, true},
591}
592
593func TestTypeOf(t *testing.T) {
594	// Special case for nil
595	if typ := TypeOf(nil); typ != nil {
596		t.Errorf("expected nil type for nil value; got %v", typ)
597	}
598	for _, test := range typeOfTests {
599		v := ValueOf(test.a)
600		if !v.IsValid() {
601			continue
602		}
603		typ := TypeOf(test.a)
604		if typ != v.Type() {
605			t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
606		}
607	}
608}
609
610func Nil(a any, t *testing.T) {
611	n := Field(ValueOf(a), 0)
612	if !n.IsNil() {
613		t.Errorf("%v should be nil", a)
614	}
615}
616
617func NotNil(a any, t *testing.T) {
618	n := Field(ValueOf(a), 0)
619	if n.IsNil() {
620		t.Errorf("value of type %v should not be nil", TypeString(ValueOf(a).Type()))
621	}
622}
623
624func TestIsNil(t *testing.T) {
625	// These implement IsNil.
626	// Wrap in extra struct to hide interface type.
627	doNil := []any{
628		struct{ x *int }{},
629		struct{ x any }{},
630		struct{ x map[string]int }{},
631		struct{ x func() bool }{},
632		struct{ x chan int }{},
633		struct{ x []string }{},
634		struct{ x unsafe.Pointer }{},
635	}
636	for _, ts := range doNil {
637		ty := TField(TypeOf(ts), 0)
638		v := Zero(ty)
639		v.IsNil() // panics if not okay to call
640	}
641
642	// Check the implementations
643	var pi struct {
644		x *int
645	}
646	Nil(pi, t)
647	pi.x = new(int)
648	NotNil(pi, t)
649
650	var si struct {
651		x []int
652	}
653	Nil(si, t)
654	si.x = make([]int, 10)
655	NotNil(si, t)
656
657	var ci struct {
658		x chan int
659	}
660	Nil(ci, t)
661	ci.x = make(chan int)
662	NotNil(ci, t)
663
664	var mi struct {
665		x map[int]int
666	}
667	Nil(mi, t)
668	mi.x = make(map[int]int)
669	NotNil(mi, t)
670
671	var ii struct {
672		x any
673	}
674	Nil(ii, t)
675	ii.x = 2
676	NotNil(ii, t)
677
678	var fi struct {
679		x func(t *testing.T)
680	}
681	Nil(fi, t)
682	fi.x = TestIsNil
683	NotNil(fi, t)
684}
685
686// Indirect returns the value that v points to.
687// If v is a nil pointer, Indirect returns a zero Value.
688// If v is not a pointer, Indirect returns v.
689func Indirect(v Value) Value {
690	if v.Kind() != Ptr {
691		return v
692	}
693	return v.Elem()
694}
695
696func TestNilPtrValueSub(t *testing.T) {
697	var pi *int
698	if pv := ValueOf(pi); pv.Elem().IsValid() {
699		t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
700	}
701}
702
703type Point struct {
704	x, y int
705}
706
707// This will be index 0.
708func (p Point) AnotherMethod(scale int) int {
709	return -1
710}
711
712// This will be index 1.
713func (p Point) Dist(scale int) int {
714	//println("Point.Dist", p.x, p.y, scale)
715	return p.x*p.x*scale + p.y*p.y*scale
716}
717
718// This will be index 2.
719func (p Point) GCMethod(k int) int {
720	runtime.GC()
721	return k + p.x
722}
723
724// This will be index 3.
725func (p Point) NoArgs() {
726	// Exercise no-argument/no-result paths.
727}
728
729// This will be index 4.
730func (p Point) TotalDist(points ...Point) int {
731	tot := 0
732	for _, q := range points {
733		dx := q.x - p.x
734		dy := q.y - p.y
735		tot += dx*dx + dy*dy // Should call Sqrt, but it's just a test.
736
737	}
738	return tot
739}
740
741type D1 struct {
742	d int
743}
744type D2 struct {
745	d int
746}
747
748func TestImportPath(t *testing.T) {
749	tests := []struct {
750		t    Type
751		path string
752	}{
753		{TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
754		{TypeOf(int(0)), ""},
755		{TypeOf(int8(0)), ""},
756		{TypeOf(int16(0)), ""},
757		{TypeOf(int32(0)), ""},
758		{TypeOf(int64(0)), ""},
759		{TypeOf(uint(0)), ""},
760		{TypeOf(uint8(0)), ""},
761		{TypeOf(uint16(0)), ""},
762		{TypeOf(uint32(0)), ""},
763		{TypeOf(uint64(0)), ""},
764		{TypeOf(uintptr(0)), ""},
765		{TypeOf(float32(0)), ""},
766		{TypeOf(float64(0)), ""},
767		{TypeOf(complex64(0)), ""},
768		{TypeOf(complex128(0)), ""},
769		{TypeOf(byte(0)), ""},
770		{TypeOf(rune(0)), ""},
771		{TypeOf([]byte(nil)), ""},
772		{TypeOf([]rune(nil)), ""},
773		{TypeOf(string("")), ""},
774		{TypeOf((*any)(nil)).Elem(), ""},
775		{TypeOf((*byte)(nil)), ""},
776		{TypeOf((*rune)(nil)), ""},
777		{TypeOf((*int64)(nil)), ""},
778		{TypeOf(map[string]int{}), ""},
779		{TypeOf((*error)(nil)).Elem(), ""},
780		{TypeOf((*Point)(nil)), ""},
781		{TypeOf((*Point)(nil)).Elem(), "internal/reflectlite_test"},
782	}
783	for _, test := range tests {
784		if path := test.t.PkgPath(); path != test.path {
785			t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
786		}
787	}
788}
789
790func noAlloc(t *testing.T, n int, f func(int)) {
791	if testing.Short() {
792		t.Skip("skipping malloc count in short mode")
793	}
794	if runtime.GOMAXPROCS(0) > 1 {
795		t.Skip("skipping; GOMAXPROCS>1")
796	}
797	i := -1
798	allocs := testing.AllocsPerRun(n, func() {
799		f(i)
800		i++
801	})
802	if allocs > 0 {
803		t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
804	}
805}
806
807func TestAllocations(t *testing.T) {
808	noAlloc(t, 100, func(j int) {
809		var i any
810		var v Value
811
812		i = []int{j, j, j}
813		v = ValueOf(i)
814		if v.Len() != 3 {
815			panic("wrong length")
816		}
817	})
818	noAlloc(t, 100, func(j int) {
819		var i any
820		var v Value
821
822		i = func(j int) int { return j }
823		v = ValueOf(i)
824		if ToInterface(v).(func(int) int)(j) != j {
825			panic("wrong result")
826		}
827	})
828}
829
830func TestSetPanic(t *testing.T) {
831	ok := func(f func()) { f() }
832	bad := shouldPanic
833	clear := func(v Value) { v.Set(Zero(v.Type())) }
834
835	type t0 struct {
836		W int
837	}
838
839	type t1 struct {
840		Y int
841		t0
842	}
843
844	type T2 struct {
845		Z       int
846		namedT0 t0
847	}
848
849	type T struct {
850		X int
851		t1
852		T2
853		NamedT1 t1
854		NamedT2 T2
855		namedT1 t1
856		namedT2 T2
857	}
858
859	// not addressable
860	v := ValueOf(T{})
861	bad(func() { clear(Field(v, 0)) })                     // .X
862	bad(func() { clear(Field(v, 1)) })                     // .t1
863	bad(func() { clear(Field(Field(v, 1), 0)) })           // .t1.Y
864	bad(func() { clear(Field(Field(v, 1), 1)) })           // .t1.t0
865	bad(func() { clear(Field(Field(Field(v, 1), 1), 0)) }) // .t1.t0.W
866	bad(func() { clear(Field(v, 2)) })                     // .T2
867	bad(func() { clear(Field(Field(v, 2), 0)) })           // .T2.Z
868	bad(func() { clear(Field(Field(v, 2), 1)) })           // .T2.namedT0
869	bad(func() { clear(Field(Field(Field(v, 2), 1), 0)) }) // .T2.namedT0.W
870	bad(func() { clear(Field(v, 3)) })                     // .NamedT1
871	bad(func() { clear(Field(Field(v, 3), 0)) })           // .NamedT1.Y
872	bad(func() { clear(Field(Field(v, 3), 1)) })           // .NamedT1.t0
873	bad(func() { clear(Field(Field(Field(v, 3), 1), 0)) }) // .NamedT1.t0.W
874	bad(func() { clear(Field(v, 4)) })                     // .NamedT2
875	bad(func() { clear(Field(Field(v, 4), 0)) })           // .NamedT2.Z
876	bad(func() { clear(Field(Field(v, 4), 1)) })           // .NamedT2.namedT0
877	bad(func() { clear(Field(Field(Field(v, 4), 1), 0)) }) // .NamedT2.namedT0.W
878	bad(func() { clear(Field(v, 5)) })                     // .namedT1
879	bad(func() { clear(Field(Field(v, 5), 0)) })           // .namedT1.Y
880	bad(func() { clear(Field(Field(v, 5), 1)) })           // .namedT1.t0
881	bad(func() { clear(Field(Field(Field(v, 5), 1), 0)) }) // .namedT1.t0.W
882	bad(func() { clear(Field(v, 6)) })                     // .namedT2
883	bad(func() { clear(Field(Field(v, 6), 0)) })           // .namedT2.Z
884	bad(func() { clear(Field(Field(v, 6), 1)) })           // .namedT2.namedT0
885	bad(func() { clear(Field(Field(Field(v, 6), 1), 0)) }) // .namedT2.namedT0.W
886
887	// addressable
888	v = ValueOf(&T{}).Elem()
889	ok(func() { clear(Field(v, 0)) })                      // .X
890	bad(func() { clear(Field(v, 1)) })                     // .t1
891	ok(func() { clear(Field(Field(v, 1), 0)) })            // .t1.Y
892	bad(func() { clear(Field(Field(v, 1), 1)) })           // .t1.t0
893	ok(func() { clear(Field(Field(Field(v, 1), 1), 0)) })  // .t1.t0.W
894	ok(func() { clear(Field(v, 2)) })                      // .T2
895	ok(func() { clear(Field(Field(v, 2), 0)) })            // .T2.Z
896	bad(func() { clear(Field(Field(v, 2), 1)) })           // .T2.namedT0
897	bad(func() { clear(Field(Field(Field(v, 2), 1), 0)) }) // .T2.namedT0.W
898	ok(func() { clear(Field(v, 3)) })                      // .NamedT1
899	ok(func() { clear(Field(Field(v, 3), 0)) })            // .NamedT1.Y
900	bad(func() { clear(Field(Field(v, 3), 1)) })           // .NamedT1.t0
901	ok(func() { clear(Field(Field(Field(v, 3), 1), 0)) })  // .NamedT1.t0.W
902	ok(func() { clear(Field(v, 4)) })                      // .NamedT2
903	ok(func() { clear(Field(Field(v, 4), 0)) })            // .NamedT2.Z
904	bad(func() { clear(Field(Field(v, 4), 1)) })           // .NamedT2.namedT0
905	bad(func() { clear(Field(Field(Field(v, 4), 1), 0)) }) // .NamedT2.namedT0.W
906	bad(func() { clear(Field(v, 5)) })                     // .namedT1
907	bad(func() { clear(Field(Field(v, 5), 0)) })           // .namedT1.Y
908	bad(func() { clear(Field(Field(v, 5), 1)) })           // .namedT1.t0
909	bad(func() { clear(Field(Field(Field(v, 5), 1), 0)) }) // .namedT1.t0.W
910	bad(func() { clear(Field(v, 6)) })                     // .namedT2
911	bad(func() { clear(Field(Field(v, 6), 0)) })           // .namedT2.Z
912	bad(func() { clear(Field(Field(v, 6), 1)) })           // .namedT2.namedT0
913	bad(func() { clear(Field(Field(Field(v, 6), 1), 0)) }) // .namedT2.namedT0.W
914}
915
916func shouldPanic(f func()) {
917	defer func() {
918		if recover() == nil {
919			panic("did not panic")
920		}
921	}()
922	f()
923}
924
925type S struct {
926	i1 int64
927	i2 int64
928}
929
930func TestBigZero(t *testing.T) {
931	const size = 1 << 10
932	var v [size]byte
933	z := ToInterface(Zero(ValueOf(v).Type())).([size]byte)
934	for i := 0; i < size; i++ {
935		if z[i] != 0 {
936			t.Fatalf("Zero object not all zero, index %d", i)
937		}
938	}
939}
940
941func TestInvalid(t *testing.T) {
942	// Used to have inconsistency between IsValid() and Kind() != Invalid.
943	type T struct{ v any }
944
945	v := Field(ValueOf(T{}), 0)
946	if v.IsValid() != true || v.Kind() != Interface {
947		t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
948	}
949	v = v.Elem()
950	if v.IsValid() != false || v.Kind() != abi.Invalid {
951		t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
952	}
953}
954
955type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
956
957type nameTest struct {
958	v    any
959	want string
960}
961
962type A struct{}
963type B[T any] struct{}
964
965var nameTests = []nameTest{
966	{(*int32)(nil), "int32"},
967	{(*D1)(nil), "D1"},
968	{(*[]D1)(nil), ""},
969	{(*chan D1)(nil), ""},
970	{(*func() D1)(nil), ""},
971	{(*<-chan D1)(nil), ""},
972	{(*chan<- D1)(nil), ""},
973	{(*any)(nil), ""},
974	{(*interface {
975		F()
976	})(nil), ""},
977	{(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
978	{(*B[A])(nil), "B[internal/reflectlite_test.A]"},
979	{(*B[B[A]])(nil), "B[internal/reflectlite_test.B[internal/reflectlite_test.A]]"},
980}
981
982func TestNames(t *testing.T) {
983	for _, test := range nameTests {
984		typ := TypeOf(test.v).Elem()
985		if got := typ.Name(); got != test.want {
986			t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
987		}
988	}
989}
990
991// TestUnaddressableField tests that the reflect package will not allow
992// a type from another package to be used as a named type with an
993// unexported field.
994//
995// This ensures that unexported fields cannot be modified by other packages.
996func TestUnaddressableField(t *testing.T) {
997	var b Buffer // type defined in reflect, a different package
998	var localBuffer struct {
999		buf []byte
1000	}
1001	lv := ValueOf(&localBuffer).Elem()
1002	rv := ValueOf(b)
1003	shouldPanic(func() {
1004		lv.Set(rv)
1005	})
1006}
1007
1008type Tint int
1009
1010type Tint2 = Tint
1011
1012type Talias1 struct {
1013	byte
1014	uint8
1015	int
1016	int32
1017	rune
1018}
1019
1020type Talias2 struct {
1021	Tint
1022	Tint2
1023}
1024
1025func TestAliasNames(t *testing.T) {
1026	t1 := Talias1{byte: 1, uint8: 2, int: 3, int32: 4, rune: 5}
1027	out := fmt.Sprintf("%#v", t1)
1028	want := "reflectlite_test.Talias1{byte:0x1, uint8:0x2, int:3, int32:4, rune:5}"
1029	if out != want {
1030		t.Errorf("Talias1 print:\nhave: %s\nwant: %s", out, want)
1031	}
1032
1033	t2 := Talias2{Tint: 1, Tint2: 2}
1034	out = fmt.Sprintf("%#v", t2)
1035	want = "reflectlite_test.Talias2{Tint:1, Tint2:2}"
1036	if out != want {
1037		t.Errorf("Talias2 print:\nhave: %s\nwant: %s", out, want)
1038	}
1039}
1040