From c0f8f129c08f8350ba479fe52dfe569722320134 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Sat, 11 Mar 2023 15:49:19 -0800 Subject: [PATCH] reflect: convert map elements to an interface, if needed --- src/reflect/value.go | 9 +++++++++ src/reflect/value_test.go | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/reflect/value.go b/src/reflect/value.go index d2546960..5c4fffc4 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -1370,6 +1370,15 @@ func (v Value) SetMapIndex(key, elem Value) { panic("reflect.Value.SetMapIndex: incompatible types for value") } + // make elem an interface if it needs to be converted + if v.typecode.elem().Kind() == Interface && elem.typecode.Kind() != Interface { + intf := composeInterface(unsafe.Pointer(elem.typecode), elem.value) + elem = Value{ + typecode: v.typecode.elem(), + value: unsafe.Pointer(&intf), + } + } + if key.Kind() == String { if del { hashmapStringDelete(v.pointer(), *(*string)(key.value)) diff --git a/src/reflect/value_test.go b/src/reflect/value_test.go index 81533713..18bb9afe 100644 --- a/src/reflect/value_test.go +++ b/src/reflect/value_test.go @@ -192,6 +192,24 @@ func TestTinyMap(t *testing.T) { } } +func TestMapInterfaceElem(t *testing.T) { + m := make(map[string]interface{}) + refm := ValueOf(m) + + four := ValueOf(4) + hello := ValueOf("hello") + + refm.SetMapIndex(hello, four) + + if v := refm.MapIndex(hello).Interface().(int); v != 4 { + t.Errorf("failed to get value assigned to interface via MapIndex") + } + + if v := m["hello"].(int); v != 4 { + t.Errorf("failed to get value assigned to interface via direct lookup") + } +} + func TestTinySlice(t *testing.T) { s := []int{0, 10, 20} refs := ValueOf(s)