From 1fd75ffbda1ff021289f2feb6a062434df68d8b7 Mon Sep 17 00:00:00 2001 From: Laurent Demailly Date: Tue, 23 Jul 2024 15:30:02 -0700 Subject: [PATCH] Getting DeepEqual to work with maps whose key is an interface (#4360) reflect: Getting DeepEqual to work with maps whose key is an interface --- src/reflect/all_test.go | 16 ++++++++++++++++ src/reflect/value.go | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 4c2fcc48be..8a3e09792e 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -1102,6 +1102,20 @@ func init() { cycleMap3["different"] = cycleMap3 } +type deepEqualInterface interface { + Foo() +} +type deepEqualConcrete struct { + int +} + +func (deepEqualConcrete) Foo() {} + +var ( + deepEqualConcrete1 = deepEqualConcrete{1} + deepEqualConcrete2 = deepEqualConcrete{2} +) + var deepEqualTests = []DeepEqualTest{ // Equalities {nil, nil, true}, @@ -1119,6 +1133,7 @@ var deepEqualTests = []DeepEqualTest{ {[]byte{1, 2, 3}, []byte{1, 2, 3}, true}, {[]MyByte{1, 2, 3}, []MyByte{1, 2, 3}, true}, {MyBytes{1, 2, 3}, MyBytes{1, 2, 3}, true}, + {map[deepEqualInterface]string{deepEqualConcrete1: "a"}, map[deepEqualInterface]string{deepEqualConcrete1: "a"}, true}, // Inequalities {1, 2, false}, @@ -1140,6 +1155,7 @@ var deepEqualTests = []DeepEqualTest{ {fn3, fn3, false}, {[][]int{{1}}, [][]int{{2}}, false}, {&structWithSelfPtr{p: &structWithSelfPtr{s: "a"}}, &structWithSelfPtr{p: &structWithSelfPtr{s: "b"}}, false}, + {map[deepEqualInterface]string{deepEqualConcrete1: "a"}, map[deepEqualInterface]string{deepEqualConcrete2: "a"}, false}, // Fun with floating point. {math.NaN(), math.NaN(), false}, diff --git a/src/reflect/value.go b/src/reflect/value.go index c8439ccef2..07553fbc5a 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -982,7 +982,9 @@ func (v Value) MapIndex(key Value) Value { vkey := v.typecode.key() // compare key type with actual key type of map - if !key.typecode.AssignableTo(vkey) { + // AssignableTo is not implemented for interfaces + // avoid: "reflect: unimplemented: AssignableTo with interface" + if vkey.Kind() != Interface && !key.typecode.AssignableTo(vkey) { // type error? panic("reflect.Value.MapIndex: incompatible types for key") }