Skip to content

Commit 83c22e1

Browse files
committed
update
Change-Id: Id8d5f247884fbe189a4c778203ea7cf575b1a93a
1 parent 31a7a18 commit 83c22e1

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
@@ -1539,14 +1539,29 @@ func TypeAssert[T any](v Value) (T, bool) {
15391539
v, ok := packEface(v).(T)
15401540
return v, ok
15411541
}
1542+
1543+
// Special case: match the element inside the interface.
1544+
// TypeAssert[int](ValueOf(newPtr(any(0))).Elem()
1545+
if v.kind() == Interface {
1546+
// Empty interface has one layout, all interfaces with
1547+
// methods have a second layout.
1548+
if v.NumMethod() == 0 {
1549+
v, ok := (*(*any)(v.ptr)).(T)
1550+
return v, ok
1551+
}
1552+
v, ok := any(*(*interface {
1553+
M()
1554+
})(v.ptr)).(T)
1555+
return v, ok
1556+
}
1557+
15421558
var zero T
15431559
return zero, false
15441560
}
15451561

1546-
if v.typ().IsDirectIface() {
1562+
if v.flag&flagIndir == 0 {
15471563
return *(*T)(unsafe.Pointer(&v.ptr)), true
15481564
}
1549-
15501565
return *(*T)(v.ptr), true
15511566
}
15521567

0 commit comments

Comments
 (0)