github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/internal/reflectlite/all_test.go (about) 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 5 package reflectlite_test 6 7 import ( 8 "encoding/base64" 9 "fmt" 10 "internal/abi" 11 . "internal/reflectlite" 12 "math" 13 "reflect" 14 "runtime" 15 "testing" 16 "unsafe" 17 ) 18 19 func ToValue(v Value) reflect.Value { 20 return reflect.ValueOf(ToInterface(v)) 21 } 22 23 func TypeString(t Type) string { 24 return fmt.Sprintf("%T", ToInterface(Zero(t))) 25 } 26 27 type integer int 28 type T struct { 29 a int 30 b float64 31 c string 32 d *int 33 } 34 35 type pair struct { 36 i any 37 s string 38 } 39 40 func 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 47 var 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 172 var 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 220 func 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 227 func 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 234 func 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 240 func 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 284 func 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 367 var _i = 7 368 369 var 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 382 func 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 391 func 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 401 func 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 410 func 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 423 func 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 440 func 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 449 var 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 456 func 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 468 func 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 479 type big struct { 480 a, b, c, d, e int64 481 } 482 483 func 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 492 type Basic struct { 493 x int 494 y float32 495 } 496 497 type NotBasic Basic 498 499 type DeepEqualTest struct { 500 a, b any 501 eq bool 502 } 503 504 // Simple functions for DeepEqual tests. 505 var ( 506 fn1 func() // nil. 507 fn2 func() // nil. 508 fn3 = func() { fn1() } // Not nil. 509 ) 510 511 type self struct{} 512 513 type Loop *Loop 514 type Loopy any 515 516 var loop1, loop2 Loop 517 var loopy1, loopy2 Loopy 518 519 func init() { 520 loop1 = &loop2 521 loop2 = &loop1 522 523 loopy1 = &loopy2 524 loopy2 = &loopy1 525 } 526 527 var 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 593 func 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 610 func 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 617 func 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 624 func 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. 689 func Indirect(v Value) Value { 690 if v.Kind() != Ptr { 691 return v 692 } 693 return v.Elem() 694 } 695 696 func 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 703 type Point struct { 704 x, y int 705 } 706 707 // This will be index 0. 708 func (p Point) AnotherMethod(scale int) int { 709 return -1 710 } 711 712 // This will be index 1. 713 func (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. 719 func (p Point) GCMethod(k int) int { 720 runtime.GC() 721 return k + p.x 722 } 723 724 // This will be index 3. 725 func (p Point) NoArgs() { 726 // Exercise no-argument/no-result paths. 727 } 728 729 // This will be index 4. 730 func (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 741 type D1 struct { 742 d int 743 } 744 type D2 struct { 745 d int 746 } 747 748 func 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 790 func 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 807 func 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 830 func 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 916 func shouldPanic(f func()) { 917 defer func() { 918 if recover() == nil { 919 panic("did not panic") 920 } 921 }() 922 f() 923 } 924 925 type S struct { 926 i1 int64 927 i2 int64 928 } 929 930 func 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 941 func 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 955 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int 956 957 type nameTest struct { 958 v any 959 want string 960 } 961 962 type A struct{} 963 type B[T any] struct{} 964 965 var 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 982 func 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. 996 func 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 1008 type Tint int 1009 1010 type Tint2 = Tint 1011 1012 type Talias1 struct { 1013 byte 1014 uint8 1015 int 1016 int32 1017 rune 1018 } 1019 1020 type Talias2 struct { 1021 Tint 1022 Tint2 1023 } 1024 1025 func 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 }