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