github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/reflect/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 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{} // tests depend on T being comparable 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 // no inlining with the noopt builder 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 // Calling MapRange should not allocate even though it returns a *MapIter. 385 // The function is inlineable, so if the local usage does not escape 386 // the *MapIter, it can remain stack allocated. 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 // signed integer 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 // unsigned integer 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 // floating-point 419 {float32(256.25), [...]bool{false, false, true, false}}, 420 {float64(512.125), [...]bool{false, false, true, false}}, 421 // complex 422 {complex64(532.125 + 10i), [...]bool{false, false, false, true}}, 423 {complex128(564.25 + 1i), [...]bool{false, false, false, true}}, 424 // underlying 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 // not-acceptable 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 // -1 means Addr().Elem() of current value 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 // make sure tag strings are not part of element type 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 // Convert extra from []int to []Value. 832 e0 := make([]Value, len(test.extra)) 833 for j, e := range test.extra { 834 e0[j] = ValueOf(e) 835 } 836 // Convert extra from []int to *SliceValue. 837 e1 := ValueOf(test.extra) 838 839 // Test Append. 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 // Check that the orig and extra slices were not modified. 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 // Test AppendSlice. 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 // Check that the orig and extra slices were not modified. 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 // Test Append and AppendSlice with unexported value. 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 // Simple functions for DeepEqual tests. 1024 var ( 1025 fn1 func() // nil. 1026 fn2 func() // nil. 1027 fn3 = func() { fn1() } // Not nil. 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 // Equalities 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 // Inequalities 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 // Fun with floating point. 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 // Nil vs empty: not the same. 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 // Mismatched types 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 // Possible loops. 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 // Special case for nil 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" // Difference is here 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 // Check that DeepEqual can look at unexported fields. 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 // Check that structure alignment & offsets viewed through reflect agree with those 1299 // from the compiler itself. 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 // These implement IsNil. 1339 // Wrap in extra struct to hide interface type. 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() // panics if not okay to call 1353 } 1354 1355 // Check the implementations 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 // Booleans 1405 {true, false}, 1406 {false, true}, 1407 // Numeric types 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 // Array 1443 {Zero(TypeOf([5]string{})).Interface(), true}, 1444 {[5]string{}, true}, // comparable array 1445 {[5]string{"", "", "", "a", ""}, false}, // comparable array 1446 {[1]*int{}, true}, // direct pointer array 1447 {[1]*int{new(int)}, false}, // direct pointer array 1448 {[3][]int{}, true}, // incomparable array 1449 {[3][]int{{1}}, false}, // incomparable array 1450 {[1 << 12]byte{}, true}, 1451 {[1 << 12]byte{1}, false}, 1452 {[3]Value{}, true}, 1453 {[3]Value{{}, ValueOf(0), {}}, false}, 1454 // Chan 1455 {(chan string)(nil), true}, 1456 {make(chan string), false}, 1457 {time.After(1), false}, 1458 // Func 1459 {(func())(nil), true}, 1460 {New, false}, 1461 // Interface 1462 {New(TypeOf(new(error)).Elem()).Elem(), true}, 1463 {(io.Reader)(strings.NewReader("")), false}, 1464 // Map 1465 {(map[string]string)(nil), true}, 1466 {map[string]string{}, false}, 1467 {make(map[string]string), false}, 1468 // Pointer 1469 {(*func())(nil), true}, 1470 {(*int)(nil), true}, 1471 {new(int), false}, 1472 // Slice 1473 {[]string{}, false}, 1474 {([]string)(nil), true}, 1475 {make([]string, 0), false}, 1476 // Strings 1477 {"", true}, 1478 {"not-zero", false}, 1479 // Structs 1480 {T{}, true}, // comparable struct 1481 {T{123, 456.75, "hello", &_i}, false}, // comparable struct 1482 {struct{ p *int }{}, true}, // direct pointer struct 1483 {struct{ p *int }{new(int)}, false}, // direct pointer struct 1484 {struct{ s []int }{}, true}, // incomparable struct 1485 {struct{ s []int }{[]int{1}}, false}, // incomparable struct 1486 {struct{ Value }{}, true}, 1487 {struct{ Value }{ValueOf(0)}, false}, 1488 // UnsafePointer 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 // Check that returned Keys match keys in range. 1555 // These aren't required to be in the same order. 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 // Check that value lookup is correct. 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 // Copy into new map. 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 // Check that value for missing key is zero. 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 // Check big value too. 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 // Test that deletes from a nil map succeed. 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 // check both ways to allocate channels 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 // Send 1651 cv.Send(ValueOf(2)) 1652 if i := <-c; i != 2 { 1653 t.Errorf("reflect Send 2, native recv %d", i) 1654 } 1655 1656 // Recv 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 // TryRecv fail 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 // TryRecv success 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 // TrySend fail 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 // TrySend success 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 // Close 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 // check creation of unbuffered channel 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 // len/cap 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 // caseInfo describes a single case in a select test. 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 // Ready send. 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 // Ready recv. 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 // Blocking send. 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 // Let it execute? 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 // Blocking recv. 1817 if x.Maybe() { 1818 ch, val := newop(len(cases), 0) 1819 cases = append(cases, SelectCase{ 1820 Dir: SelectRecv, 1821 Chan: ch, 1822 }) 1823 // Let it execute? 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 // Zero Chan send. 1833 if x.Maybe() { 1834 // Maybe include value to send. 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 // Zero Chan receive. 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 // nil Chan send. 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 // nil Chan recv. 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 // closed Chan send. 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 // closed Chan recv. 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() // goroutine to help the select complete 1898 1899 // Add default? Must be last case here, but will permute. 1900 // Add the default if the select would otherwise 1901 // block forever, and maybe add it anyway. 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 // Select needs to communicate with another goroutine. 1928 cas := &info[helpers[x.Choose(len(helpers))]] 1929 helper = cas.helper 1930 cas.canSelect = true 1931 numCanSelect++ 1932 } 1933 1934 // Permute cases and case info. 1935 // Doing too much here makes the exhaustive loop 1936 // too exhausting, so just do two swaps. 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 // We wait before kicking off a goroutine to satisfy a blocked select. 1946 // The pause needs to be big enough to let the select block before 1947 // we run the helper, but if we lose that race once in a while it's okay: the 1948 // select will just proceed immediately. Not a big deal. 1949 // For short tests we can grow [sic] the timeout a bit without fear of taking too long 1950 pause := 10 * time.Microsecond 1951 if testing.Short() { 1952 pause = 100 * time.Microsecond 1953 } 1954 time.AfterFunc(pause, helper) 1955 } 1956 1957 // Run select. 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 // Should not panic 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 // Should panic 2028 _, _, _ = Select(sCases) 2029 } 2030 2031 func TestSelectNop(t *testing.T) { 2032 // "select { default: }" should always return the default case. 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 // selectWatch and the selectWatcher are a watchdog mechanism for running Select. 2040 // If the selectWatcher notices that the select has been blocked for >1 second, it prints 2041 // an error describing the select and panics the entire test binary. 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 // runSelect runs a single select test. 2062 // It returns the values returned by Select but also returns 2063 // a panic value if the Select panics. 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 // fmtSelect formats the information about a single select test. 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 // Difficult test for function call because of 2106 // implicit padding between arguments. 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 // Issue 21717: past-the-end pointer write in Call with 2195 // nonzero-sized frame and zero-sized return value. 2196 runtime.GC() 2197 var finalized uint32 2198 f := func() (emptyStruct, *[2]int64) { 2199 i := new([2]int64) // big enough to not be tinyalloc'd, so finalizer always runs when i dies 2200 runtime.SetFinalizer(i, func(*[2]int64) { atomic.StoreUint32(&finalized, 1) }) 2201 return emptyStruct{}, i 2202 } 2203 v := ValueOf(f).Call(nil)[0] // out[0] should not alias out[1]'s memory, so the finalizer should run. 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 // Call g with small arguments so that there is 2223 // something predictable (and different from the 2224 // correct results) in those positions on the stack. 2225 g := dummy 2226 g(1, 2, 3, two{4, 5}, 6, 7, 8) 2227 2228 // Call constructed function f. 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 // Test that variadic arguments are packed into a slice and passed as last arg 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 // Dummy type that implements io.WriteCloser 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 // reflect.Values returned from the wrapped function should be assignment-converted 2304 // to the types returned by the result of MakeFunc. 2305 2306 // Concrete types should be promotable to interfaces they implement. 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 // Super-interfaces should be promotable to simpler interfaces. 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 // Channels should be promotable to directional channels. 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 // Unnamed types should be promotable to named types. 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 // Type doesn't implement the required interface. 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 // Assigning to an interface with additional methods. 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 // Directional channels can't be assigned to bidirectional ones. 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 // Two named types which are otherwise identical. 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 // This will be index 0. 2381 func (p Point) AnotherMethod(scale int) int { 2382 return -1 2383 } 2384 2385 // This will be index 1. 2386 func (p Point) Dist(scale int) int { 2387 //println("Point.Dist", p.x, p.y, scale) 2388 return p.x*p.x*scale + p.y*p.y*scale 2389 } 2390 2391 // This will be index 2. 2392 func (p Point) GCMethod(k int) int { 2393 runtime.GC() 2394 return k + p.x 2395 } 2396 2397 // This will be index 3. 2398 func (p Point) NoArgs() { 2399 // Exercise no-argument/no-result paths. 2400 } 2401 2402 // This will be index 4. 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 // Should call Sqrt, but it's just a test. 2409 2410 } 2411 return tot 2412 } 2413 2414 // This will be index 5. 2415 func (p *Point) Int64Method(x int64) int64 { 2416 return x 2417 } 2418 2419 // This will be index 6. 2420 func (p *Point) Int32Method(x int32) int32 { 2421 return x 2422 } 2423 2424 func TestMethod(t *testing.T) { 2425 // Non-curried method of type. 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 // Curried method of value. 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 // Curried method of pointer. 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 // Curried method of interface value. 2525 // Have to wrap interface value in a struct to get at it. 2526 // Passing it to ValueOf directly would 2527 // access the underlying Point, not the interface. 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 // Check that method value have the same underlying code pointers. 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 // Curried method of value. 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 // Curried method of pointer. 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 // Curried method of pointer to pointer. 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 // Curried method of interface value. 2622 // Have to wrap interface value in a struct to get at it. 2623 // Passing it to ValueOf directly would 2624 // access the underlying Point, not the interface. 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 // For issue #33628: method args are not stored at the right offset 2649 // on amd64p32. 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 // Variadic method of type. 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 // Curried method of value. 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 // Reflect version of $GOROOT/test/method5.go 2731 2732 // Concrete types implementing M method. 2733 // Smaller than a word, word-sized, larger than a word. 2734 // Value and pointer receivers. 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 // Embedding via pointer. 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 // The X in S6 and S7 annihilate, but they also block the X in S8.S9. 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 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9. 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 // The X in S15.S11.S1 and S16.S11.S1 annihilate. 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 // Verify field depth and index. 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 // issue 21702 3153 *x // issue 21122 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}, // Exported 3180 {[]int{1}, "reflect_test", false, false}, // unexported 3181 {[]int{2}, "", true, true}, // OtherPkgFields 3182 {[]int{2, 0}, "", false, true}, // OtherExported 3183 {[]int{2, 1}, "reflect", false, false}, // otherUnexported 3184 {[]int{3}, "reflect_test", true, false}, // int 3185 {[]int{4}, "reflect_test", true, false}, // *x 3186 }) 3187 3188 type localOtherPkgFields OtherPkgFields 3189 typ = TypeOf(localOtherPkgFields{}) 3190 checkPkgPath("localOtherPkgFields", []pkgpathTest{ 3191 {[]int{0}, "", false, true}, // OtherExported 3192 {[]int{1}, "reflect", false, false}, // otherUnexported 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 // Test example from Type documentation. 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 // ok 3238 return 3239 } 3240 } 3241 } 3242 3243 // Failed 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 // This block of code means that the ptrToThis field of the 3348 // reflect data for *unsafe.Pointer is non zero, see 3349 // https://golang.org/issue/19003 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 // Again but take address of the ValueOf value. 3408 // Exercises generation of PtrTypes not present in the binary. 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 // Starting without pointer we should get changed value 3423 // in interface. 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 { // should be unchanged from last time 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 // Verify that taking the address of a type gives us a pointer 3442 // which we can convert back using the usual interface 3443 // notation. 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 // We can uncomment this when compiler escape analysis 3477 // is good enough to see that the integer assigned to i 3478 // does not escape and therefore need not be allocated. 3479 // 3480 // i = 42 + j 3481 // v = ValueOf(i) 3482 // if int(v.Int()) != 42+j { 3483 // panic("wrong int") 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) }) // smaller than len 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) }) // smaller than len 3629 shouldPanic("SetLen", func() { vs.SetLen(6) }) // bigger than cap 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 // Per issue #24746, it was decided that Bytes can be called on byte slices 3731 // that normally cannot be converted from per Go language semantics. 3732 type B byte 3733 type SB []B 3734 type AB [4]B 3735 ValueOf([]B{1, 2, 3, 4}).Bytes() // should not panic 3736 ValueOf(new([4]B)).Elem().Bytes() // should not panic 3737 ValueOf(SB{1, 2, 3, 4}).Bytes() // should not panic 3738 ValueOf(new(AB)).Elem().Bytes() // should not panic 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 // not addressable 3853 v := ValueOf(T{}) 3854 bad(func() { clear(v.Field(0)) }) // .X 3855 bad(func() { clear(v.Field(1)) }) // .t1 3856 bad(func() { clear(v.Field(1).Field(0)) }) // .t1.Y 3857 bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0 3858 bad(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W 3859 bad(func() { clear(v.Field(2)) }) // .T2 3860 bad(func() { clear(v.Field(2).Field(0)) }) // .T2.Z 3861 bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0 3862 bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W 3863 bad(func() { clear(v.Field(3)) }) // .NamedT1 3864 bad(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y 3865 bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0 3866 bad(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W 3867 bad(func() { clear(v.Field(4)) }) // .NamedT2 3868 bad(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z 3869 bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0 3870 bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W 3871 bad(func() { clear(v.Field(5)) }) // .namedT1 3872 bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y 3873 bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0 3874 bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W 3875 bad(func() { clear(v.Field(6)) }) // .namedT2 3876 bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z 3877 bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0 3878 bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W 3879 3880 // addressable 3881 v = ValueOf(&T{}).Elem() 3882 ok(func() { clear(v.Field(0)) }) // .X 3883 bad(func() { clear(v.Field(1)) }) // .t1 3884 ok(func() { clear(v.Field(1).Field(0)) }) // .t1.Y 3885 bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0 3886 ok(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W 3887 ok(func() { clear(v.Field(2)) }) // .T2 3888 ok(func() { clear(v.Field(2).Field(0)) }) // .T2.Z 3889 bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0 3890 bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W 3891 ok(func() { clear(v.Field(3)) }) // .NamedT1 3892 ok(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y 3893 bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0 3894 ok(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W 3895 ok(func() { clear(v.Field(4)) }) // .NamedT2 3896 ok(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z 3897 bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0 3898 bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W 3899 bad(func() { clear(v.Field(5)) }) // .namedT1 3900 bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y 3901 bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0 3902 bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W 3903 bad(func() { clear(v.Field(6)) }) // .namedT2 3904 bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z 3905 bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0 3906 bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W 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 // 0 3931 T1 // 1 3932 3933 NamedT0 t0 // 2 3934 NamedT1 T1 // 3 3935 NamedT2 T2 // 4 3936 3937 namedT0 t0 // 5 3938 namedT1 T1 // 6 3939 namedT2 T2 // 7 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)) }) // .t0.W 3949 badCall(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W 3950 badCall(func() { call(v.Field(0).Method(1)) }) // .t0.w 3951 badMethod(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w 3952 ok(func() { call(v.Field(1).Method(0)) }) // .T1.Y 3953 ok(func() { call(v.Field(1).Elem().Method(0)) }) // .T1.Y 3954 badCall(func() { call(v.Field(1).Method(1)) }) // .T1.y 3955 badMethod(func() { call(v.Field(1).Elem().Method(2)) }) // .T1.y 3956 3957 ok(func() { call(v.Field(2).Method(0)) }) // .NamedT0.W 3958 ok(func() { call(v.Field(2).Elem().Method(0)) }) // .NamedT0.W 3959 badCall(func() { call(v.Field(2).Method(1)) }) // .NamedT0.w 3960 badMethod(func() { call(v.Field(2).Elem().Method(2)) }) // .NamedT0.w 3961 3962 ok(func() { call(v.Field(3).Method(0)) }) // .NamedT1.Y 3963 ok(func() { call(v.Field(3).Elem().Method(0)) }) // .NamedT1.Y 3964 badCall(func() { call(v.Field(3).Method(1)) }) // .NamedT1.y 3965 badMethod(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y 3966 3967 ok(func() { call(v.Field(4).Field(0).Method(0)) }) // .NamedT2.T1.Y 3968 ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W 3969 badCall(func() { call(v.Field(4).Field(1).Method(0)) }) // .NamedT2.t0.W 3970 badCall(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W 3971 3972 badCall(func() { call(v.Field(5).Method(0)) }) // .namedT0.W 3973 badCall(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W 3974 badCall(func() { call(v.Field(5).Method(1)) }) // .namedT0.w 3975 badMethod(func() { call(v.Field(5).Elem().Method(2)) }) // .namedT0.w 3976 3977 badCall(func() { call(v.Field(6).Method(0)) }) // .namedT1.Y 3978 badCall(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.Y 3979 badCall(func() { call(v.Field(6).Method(0)) }) // .namedT1.y 3980 badCall(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.y 3981 3982 badCall(func() { call(v.Field(7).Field(0).Method(0)) }) // .namedT2.T1.Y 3983 badCall(func() { call(v.Field(7).Field(0).Elem().Method(0)) }) // .namedT2.T1.W 3984 badCall(func() { call(v.Field(7).Field(1).Method(0)) }) // .namedT2.t0.W 3985 badCall(func() { call(v.Field(7).Field(1).Elem().Method(0)) }) // .namedT2.t0.W 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 // numbers 4134 /* 4135 Edit .+1,/\*\//-1>cat >/tmp/x.go && go run /tmp/x.go 4136 4137 package main 4138 4139 import "fmt" 4140 4141 var numbers = []string{ 4142 "int8", "uint8", "int16", "uint16", 4143 "int32", "uint32", "int64", "uint64", 4144 "int", "uint", "uintptr", 4145 "float32", "float64", 4146 } 4147 4148 func main() { 4149 // all pairs but in an unusual order, 4150 // to emit all the int8, uint8 cases 4151 // before n grows too big. 4152 n := 1 4153 for i, f := range numbers { 4154 for _, g := range numbers[i:] { 4155 fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", f, n, g, n) 4156 n++ 4157 if f != g { 4158 fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", g, n, f, n) 4159 n++ 4160 } 4161 } 4162 } 4163 } 4164 */ 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 // truncation 4336 {V(float64(1.5)), V(int(1))}, 4337 4338 // complex 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 // string 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 // named string 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 // named []byte 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 // named []rune 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 // slice to array 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 // slice to array pointer 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 // named types and equal underlying types 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 // structs with different tags 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 // can convert *byte and *MyByte 4513 {V((*byte)(nil)), V((*MyByte)(nil))}, 4514 {V((*MyByte)(nil)), V((*byte)(nil))}, 4515 4516 // cannot convert mismatched array sizes 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 // cannot convert other instances 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 // other 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 // channels 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 // cannot convert other instances (channels) 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 // interfaces 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 // vout1 represents the in value converted to the in type. 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 // vout2 represents the in value converted to the out type. 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 // vout3 represents a new value of the out type, set to vout2. This makes 4640 // sure the converted value vout2 is really usable as a regular value. 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 // Assume that of all the types we saw during the tests, 4669 // if there wasn't an explicit entry for a conversion between 4670 // a pair of types, then it's not to be allowed. This checks for 4671 // things like 'int64' converting to '*int'. 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 // Converting a slice to non-empty array needs to return 4712 // a non-addressable copy of the original memory. 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 // Test to see if a store followed by a load of a signaling NaN 4732 // maintains the signaling bit. (This used to fail on the 387 port.) 4733 gFloat32 = math.Float32frombits(snan) 4734 runtime.Gosched() // make sure we don't optimize the store/load away 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 // Test reflect's conversion between float32s. See issue 36400. 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 // check construction and use of type not in binary 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))) // make it differ only by last element 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 // check that type already in binary is found 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 // Test hash 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 // Ensure passing in negative lengths panics. 5071 // See https://golang.org/issue/43603 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 // check construction and use of type not in binary 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 // check that type already in binary is found 5098 type T1 int 5099 checkSameType(t, SliceOf(TypeOf(T1(1))), []T1{}) 5100 } 5101 5102 func TestSliceOverflow(t *testing.T) { 5103 // check that MakeSlice panics when size of slice overflows uint 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 // invalid field name "1nvalid" 5151 shouldPanic("has invalid name", func() { 5152 StructOf([]StructField{ 5153 {Name: "Valid", Type: TypeOf("")}, 5154 {Name: "1nvalid", Type: TypeOf("")}, 5155 }) 5156 }) 5157 5158 // invalid field name "+" 5159 shouldPanic("has invalid name", func() { 5160 StructOf([]StructField{ 5161 {Name: "Val1d", Type: TypeOf("")}, 5162 {Name: "+", Type: TypeOf("")}, 5163 }) 5164 }) 5165 5166 // no field name 5167 shouldPanic("has no name", func() { 5168 StructOf([]StructField{ 5169 {Name: "", Type: TypeOf("")}, 5170 }) 5171 }) 5172 5173 // verify creation of a struct with valid struct fields 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 // check construction and use of type not in binary 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 // check the size, alignment and field offsets 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 // Check size and alignment with a trailing zero-sized field. 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 // check duplicate names 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 // check that type already in binary is found 5313 checkSameType(t, StructOf(fields[2:3]), struct{ Y uint64 }{}) 5314 5315 // gccgo used to fail this test. 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 // Test hash 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 // typ: TypeOf((*Iface)(nil)).Elem(), // FIXME(sbinet): fix method.ifn/tfn 5781 // val: ValueOf(StructI(want)), 5782 // impl: true, 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 // We currently do not correctly implement methods 5804 // for embedded fields other than the first. 5805 // Therefore, for now, we expect those methods 5806 // to not exist. See issues 15924 and 20824. 5807 // When those issues are fixed, this test of panic 5808 // should be removed. 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 // Test an embedded nil pointer with pointer methods. 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 // This should panic since the pointer is nil. 5860 shouldPanic("", func() { 5861 rv.Interface().(IfaceSet).Set(want) 5862 }) 5863 5864 // Test an embedded nil pointer to a struct with pointer methods. 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 // This should panic since the pointer is nil. 5874 shouldPanic("", func() { 5875 rv.Interface().(IfaceSet).Set(want) 5876 }) 5877 5878 // The behavior is different if there is a second field, 5879 // since now an interface value holds a pointer to the struct 5880 // rather than just holding a copy of the struct. 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 // With the current implementation this is expected to panic. 5894 // Ideally it should work and we should be able to see a panic 5895 // if we call the Set method. 5896 shouldPanic("", func() { 5897 StructOf(fields) 5898 }) 5899 5900 // Embed a field that can be stored directly in an interface, 5901 // with a second field. 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 // With the current implementation this is expected to panic. 5915 // Ideally it should work and we should be able to call the 5916 // Set and Get methods. 5917 shouldPanic("", func() { 5918 StructOf(fields) 5919 }) 5920 } 5921 5922 func TestStructOfTooManyFields(t *testing.T) { 5923 // Bug Fix: #25402 - this should not panic 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 // 2^64-3 sized type (or 2^32-3 on 32-bit archs) 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, // 2^64-1, ok 5971 fields: []StructField{ 5972 {Name: "F1", Type: bigType}, 5973 {Name: "F2", Type: ArrayOf(2, t1)}, 5974 }, 5975 }, 5976 { 5977 shouldPanic: true, // overflow in total size 5978 fields: []StructField{ 5979 {Name: "F1", Type: bigType}, 5980 {Name: "F2", Type: ArrayOf(3, t1)}, 5981 }, 5982 }, 5983 { 5984 shouldPanic: true, // overflow while aligning F2 5985 fields: []StructField{ 5986 {Name: "F1", Type: bigType}, 5987 {Name: "F2", Type: t4}, 5988 }, 5989 }, 5990 { 5991 shouldPanic: true, // overflow while adding trailing byte for zero-sized fields 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, // overflow while aligning total size 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 // check construction and use of type not in binary 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 // check that type already in binary is found 6052 type T1 int 6053 checkSameType(t, ChanOf(BothDir, TypeOf(T1(1))), (chan T1)(nil)) 6054 6055 // Check arrow token association in undefined chan types. 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 // check construction and use of type not in binary 6070 type T string 6071 crt := ChanOf(RecvDir, TypeOf(T(""))) 6072 cst := ChanOf(SendDir, TypeOf(T(""))) 6073 6074 // check that type already in binary is found 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 // check String form of ChanDir 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 // NOTE: The garbage collector handles allocated channels specially, 6107 // so we have to save pointers to channels in x; the pointer code will 6108 // use the gc info in the newly constructed chan type. 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 // check construction and use of type not in binary 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 // check that type already in binary is found 6153 checkSameType(t, MapOf(TypeOf(V(0)), TypeOf(K(""))), map[V]K(nil)) 6154 6155 // check that invalid key type panics 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 // NOTE: The garbage collector handles allocated maps specially, 6165 // so we have to save pointers to maps in x; the pointer code will 6166 // use the gc info in the newly constructed map type. 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 // NOTE: The garbage collector handles allocated maps specially, 6203 // so we have to save pointers to maps in x; the pointer code will 6204 // use the gc info in the newly constructed map type. 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 // check construction and use of type not in binary 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 // check that types already in binary are found 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 // check that variadic requires last element be a slice. 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 //testcase for #54669 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 // An exhaustive is a mechanism for writing exhaustive or stochastic tests. 6398 // The basic usage is: 6399 // 6400 // for x.Next() { 6401 // ... code using x.Maybe() or x.Choice(n) to create test cases ... 6402 // } 6403 // 6404 // Each iteration of the loop returns a different set of results, until all 6405 // possible result sets have been explored. It is okay for different code paths 6406 // to make different method call sequences on x, but there must be no 6407 // other source of non-determinism in the call sequences. 6408 // 6409 // When faced with a new decision, x chooses randomly. Future explorations 6410 // of that path will choose successive values for the result. Thus, stopping 6411 // the loop after a fixed number of iterations gives somewhat stochastic 6412 // testing. 6413 // 6414 // Example: 6415 // 6416 // for x.Next() { 6417 // v := make([]bool, x.Choose(4)) 6418 // for i := range v { 6419 // v[i] = x.Maybe() 6420 // } 6421 // fmt.Println(v) 6422 // } 6423 // 6424 // prints (in some order): 6425 // 6426 // [] 6427 // [false] 6428 // [true] 6429 // [false false] 6430 // [false true] 6431 // ... 6432 // [true true] 6433 // [false false false] 6434 // ... 6435 // [true true true] 6436 // [false false false false] 6437 // ... 6438 // [true true true true] 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") // should be fine 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") // should panic 6565 6566 t.Fatalf("did not panic") 6567 } 6568 6569 // Given 6570 // type Outer struct { 6571 // *Inner 6572 // ... 6573 // } 6574 // the compiler generates the implementation of (*Outer).M dispatching to the embedded Inner. 6575 // The implementation is logically: 6576 // func (p *Outer) M() { 6577 // (p.Inner).M() 6578 // } 6579 // but since the only change here is the replacement of one pointer receiver with another, 6580 // the actual generated code overwrites the original receiver with the p.Inner pointer and 6581 // then jumps to the M method expecting the *Inner receiver. 6582 // 6583 // During reflect.Value.Call, we create an argument frame and the associated data structures 6584 // to describe it to the garbage collector, populate the frame, call reflect.call to 6585 // run a function call using that frame, and then copy the results back out of the frame. 6586 // The reflect.call function does a memmove of the frame structure onto the 6587 // stack (to set up the inputs), runs the call, and the memmoves the stack back to 6588 // the frame structure (to preserve the outputs). 6589 // 6590 // Originally reflect.call did not distinguish inputs from outputs: both memmoves 6591 // were for the full stack frame. However, in the case where the called function was 6592 // one of these wrappers, the rewritten receiver is almost certainly a different type 6593 // than the original receiver. This is not a problem on the stack, where we use the 6594 // program counter to determine the type information and understand that 6595 // during (*Outer).M the receiver is an *Outer while during (*Inner).M the receiver in the same 6596 // memory word is now an *Inner. But in the statically typed argument frame created 6597 // by reflect, the receiver is always an *Outer. Copying the modified receiver pointer 6598 // off the stack into the frame will store an *Inner there, and then if a garbage collection 6599 // happens to scan that argument frame before it is discarded, it will scan the *Inner 6600 // memory as if it were an *Outer. If the two have different memory layouts, the 6601 // collection will interpret the memory incorrectly. 6602 // 6603 // One such possible incorrect interpretation is to treat two arbitrary memory words 6604 // (Inner.P1 and Inner.P2 below) as an interface (Outer.R below). Because interpreting 6605 // an interface requires dereferencing the itab word, the misinterpretation will try to 6606 // deference Inner.P1, causing a crash during garbage collection. 6607 // 6608 // This came up in a real program in issue 7725. 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 // Clear references to pi so that the only way the 6623 // garbage collection will find the pointer is in the 6624 // argument frame, typed as a *Outer. 6625 pi.X.Inner = nil 6626 6627 // Set up an interface value that will cause a crash. 6628 // P1 = 1 is a non-zero, so the interface looks non-nil. 6629 // P2 = pi ensures that the data word points into the 6630 // allocated heap; if not the collection skips the interface 6631 // value as irrelevant, without dereferencing P1. 6632 pi.P1 = 1 6633 pi.P2 = uintptr(unsafe.Pointer(pi)) 6634 } 6635 6636 func TestCallMethodJump(t *testing.T) { 6637 // In reflect.Value.Call, trigger a garbage collection after reflect.call 6638 // returns but before the args frame has been discarded. 6639 // This is a little clumsy but makes the failure repeatable. 6640 *CallGC = true 6641 6642 p := &Outer{Inner: new(Inner)} 6643 p.Inner.X = p 6644 ValueOf(p).Method(0).Call(nil) 6645 6646 // Stop garbage collecting during reflect.call. 6647 *CallGC = false 6648 } 6649 6650 func TestCallArgLive(t *testing.T) { 6651 type T struct{ X, Y *string } // pointerful aggregate 6652 6653 F := func(t T) { *t.X = "ok" } 6654 6655 // In reflect.Value.Call, trigger a garbage collection in reflect.call 6656 // between marshaling argument and the actual call. 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 // Stop garbage collecting during reflect.call. 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 // use about n KB of stack 6690 func useStack(n int) { 6691 if n == 0 { 6692 return 6693 } 6694 var b [1024]byte // makes frame about 1KB 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 // Used to have inconsistency between IsValid() and Kind() != Invalid. 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 // Issue 8917. 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 // Issue 15046. 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 // Issue 9179. 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 // Issue 18635 (function version). 6783 func TestKeepFuncLive(t *testing.T) { 6784 // Test that we keep makeFuncImpl live as long as it is 6785 // referenced on the stack. 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 // We can't use Value.Call here because 6793 // runtime.call* will keep the makeFuncImpl 6794 // alive. However, by converting it to an 6795 // interface value and calling that, 6796 // reflect.callReflect is the only thing that 6797 // can keep the makeFuncImpl live. 6798 // 6799 // Alternate between f and g so that if we do 6800 // reuse the memory prematurely it's more 6801 // likely to get obviously corrupted. 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 // Issue 21177 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 // Issue 18635 (method version). 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 // Test that we keep methodValue live as long as it is 6851 // referenced on the stack. 6852 KeepMethodLive{}.Method1(10) 6853 } 6854 6855 // clobber tries to clobber unreachable memory. 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 // pointer bitmap: 1 is pointer, 0 is scalar 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 // Note: this one is tricky, as the receiver is not a pointer. But we 6957 // pass the receiver by reference to the autogenerated pointer-receiver 6958 // version of the function. 6959 }, 6960 // TODO(mknyszek): Add tests for non-zero register count. 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 // trimBitmap removes trailing 0 elements from b and returns the result. 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 // Trim scalars at the end, as bits might end in zero, 7011 // e.g. with rep(2, lit(1, 0)). 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 // Creating a slice causes the runtime to repeat a bitmap, 7022 // which exercises a different path from making the compiler 7023 // repeat a bitmap for a small array or executing a repeat in 7024 // a GC program. 7025 val := MakeSlice(typ, 0, cap) 7026 data := NewAt(ArrayOf(cap, typ), val.UnsafePointer()) 7027 heapBits := GCBits(data.Interface()) 7028 // Repeat the bitmap for the slice size, trimming scalars in 7029 // the last element. 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 // Building blocks for types seen by the compiler (like [2]Xscalar). 7041 // The compiler will create the type structures for the derived types, 7042 // including their GC metadata. 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 // Building blocks for types constructed by reflect. 7061 // This code is in a separate block so that code below 7062 // cannot accidentally refer to these. 7063 // The compiler must NOT see types derived from these 7064 // (for example, [2]Scalar must NOT appear in the program), 7065 // or else reflect will use it instead of having to construct one. 7066 // The goal is to test the construction. 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 // Check that all the type constructors return concrete *rtype implementations. 7219 // It's difficult to test directly because the reflect package is only at arm's length. 7220 // The easiest thing to do is just call a function that crashes if it doesn't get an *rtype. 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 // Only adding half of the capacity to not trigger re-allocations due too many overloaded buckets. 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 // Empirical testing shows that with capacity hint single run will trigger 3 allocations and without 91. I set 7277 // the threshold to 10, to not make it overly brittle if something changes in the initial allocation of the 7278 // map, but to still catch a regression where we keep re-allocating in the hashmap as new entries are added. 7279 } 7280 7281 func TestChanAlloc(t *testing.T) { 7282 // Note: for a chan int, the return Value must be allocated, so we 7283 // use a chan *int instead. 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 // Note: there is one allocation in reflect.recv which seems to be 7294 // a limitation of escape analysis. If that is ever fixed the 7295 // allocs < 0.5 condition will trigger and this test should be fixed. 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 // TestUnaddressableField tests that the reflect package will not allow 7488 // a type from another package to be used as a named type with an 7489 // unexported field. 7490 // 7491 // This ensures that unexported fields cannot be modified by other packages. 7492 func TestUnaddressableField(t *testing.T) { 7493 var b Buffer // type defined in reflect, a different package 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 // Shouldn't panic. 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 // Use of zero iterator should panic. 7591 func() { 7592 defer func() { recover() }() 7593 iter.Next() 7594 t.Error("Next did not panic") 7595 }() 7596 7597 // Reset to new Map should work. 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 // Reset to Zero value should work, but iterating over it should panic. 7605 iter.Reset(Value{}) 7606 func() { 7607 defer func() { recover() }() 7608 iter.Next() 7609 t.Error("Next did not panic") 7610 }() 7611 7612 // Reset to a different Map with different types should work. 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 // Check that Reset, Next, and SetKey/SetValue play nicely together. 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 // Reset should not allocate. 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 // Using a zero MapIter causes a panic, but not a crash. 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 // Calling Key/Value on a MapIter before Next 7672 // causes a panic, but not a crash. 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 // Calling Next, Key, or Value on an exhausted iterator 7688 // causes a panic, but not a crash. 7689 iter.Next() // -> false 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 // The first call to Next should reflect any 7709 // insertions to the map since the iterator was created. 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 // Delete all elements before first iteration. 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 // Delete all elements after first iteration. 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 // iterateToString returns the set of elements 7747 // returned by an iterator in readable form. 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 // Shouldn't raise stack overflow 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 // Make sure assignment conversion works. 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 // Try some key/value types which are direct interfaces. 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 // Make sure we panic assigning from an unexported field. 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{} // ValueOf(nil) 8319 var values = []Value{ 8320 // Value of slice is non-comparable. 8321 ValueOf([]int(nil)), 8322 ValueOf(([]int{})), 8323 8324 // Value of map is non-comparable. 8325 ValueOf(map[int]int(nil)), 8326 ValueOf((map[int]int{})), 8327 8328 // Value of func is non-comparable. 8329 ValueOf(((func())(nil))), 8330 ValueOf(func() {}), 8331 8332 // Value of struct is non-comparable because of non-comparable elements. 8333 ValueOf((NonComparableStruct{})), 8334 8335 // Value of array is non-comparable because of non-comparable elements. 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 // Panic when reflect.Value.Equal using two valid non-comparable values. 8343 shouldPanic("are not comparable", func() { value.Equal(value) }) 8344 8345 // If one is non-comparable and the other is invalid, the expected result is always false. 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 }