Skip to content

Commit e79e2ea

Browse files
committed
update
Change-Id: Id8d5f247884fbe189a4c778203ea7cf575b1a93a
1 parent e452d77 commit e79e2ea

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/reflect/all_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -8747,6 +8747,14 @@ func TestTypeAssertInterfaceTypes(t *testing.T) {
87478747
if v != fmt.Stringer(val) || !ok {
87488748
t.Errorf(`TypeAssert[fmt.Stringer](&testTypeWithMethod{"test"}) = (%v, %v); want = (&testTypeWithMethod{"test"}, true)`, v, ok)
87498749
}
8750+
8751+
if v, ok := TypeAssert[int](ValueOf(newPtr(any(1))).Elem()); v != 1 || !ok {
8752+
t.Errorf(`TypeAssert[int](ValueOf(newPtr(any(1))).Elem()) = (%v, %v); want = (1, true)`, v, ok)
8753+
}
8754+
8755+
if v, ok := TypeAssert[testTypeWithMethod](ValueOf(newPtr(fmt.Stringer(testTypeWithMethod{"test"}))).Elem()); v.val != "test" || !ok {
8756+
t.Errorf(`TypeAssert[testTypeWithMethod](newPtr(fmt.Stringer(testTypeWithMethod{"test"}))) = (%v, %v); want = (testTypeWithMethod{"test"}, true)`, v, ok)
8757+
}
87508758
}
87518759

87528760
type testTypeWithMethod struct {
@@ -8789,3 +8797,10 @@ func TestTypeAssertAllocs(t *testing.T) {
87898797
t.Errorf("unexpected amount of allocations = %v; want = 0", allocs)
87908798
}
87918799
}
8800+
8801+
func BenchmarkTypeAssertTime(b *testing.B) {
8802+
val := ValueOf(time.Now())
8803+
for b.Loop() {
8804+
TypeAssert[time.Time](val)
8805+
}
8806+
}

src/reflect/value.go

+17-2
Original file line numberDiff line numberDiff line change
@@ -1536,14 +1536,29 @@ func TypeAssert[T any](v Value) (T, bool) {
15361536
v, ok := packEface(v).(T)
15371537
return v, ok
15381538
}
1539+
1540+
// Special case: match the element inside the interface.
1541+
// TypeAssert[int](ValueOf(newPtr(any(0))).Elem()
1542+
if v.kind() == Interface {
1543+
// Empty interface has one layout, all interfaces with
1544+
// methods have a second layout.
1545+
if v.NumMethod() == 0 {
1546+
v, ok := (*(*any)(v.ptr)).(T)
1547+
return v, ok
1548+
}
1549+
v, ok := any(*(*interface {
1550+
M()
1551+
})(v.ptr)).(T)
1552+
return v, ok
1553+
}
1554+
15391555
var zero T
15401556
return zero, false
15411557
}
15421558

1543-
if v.typ().IsDirectIface() {
1559+
if v.flag&flagIndir == 0 {
15441560
return *(*T)(unsafe.Pointer(&v.ptr)), true
15451561
}
1546-
15471562
return *(*T)(v.ptr), true
15481563
}
15491564

0 commit comments

Comments
 (0)