reflect: move indirect values into interface when setting interfaces

Fixes #4040
Этот коммит содержится в:
Damian Gryski 2023-12-12 21:51:26 -08:00 коммит произвёл Ron Evans
родитель cc3e785692
коммит 5b8127fd4e
2 изменённых файлов: 29 добавлений и 0 удалений

Просмотреть файл

@ -1086,6 +1086,13 @@ func (v Value) Set(x Value) {
}
if v.typecode.Kind() == Interface && x.typecode.Kind() != Interface {
// move the value of x back into the interface, if possible
if x.isIndirect() && x.typecode.Size() <= unsafe.Sizeof(uintptr(0)) {
var value uintptr
memcpy(unsafe.Pointer(&value), x.value, x.typecode.Size())
x.value = unsafe.Pointer(value)
}
intf := composeInterface(unsafe.Pointer(x.typecode), x.value)
x = Value{
typecode: v.typecode,

Просмотреть файл

@ -624,6 +624,28 @@ func TestConvert(t *testing.T) {
}
}
func TestIssue4040(t *testing.T) {
var value interface{} = uint16(0)
// get the pointer to the interface value
inPtr := ValueOf(&value)
// dereference to get the actual value (an interface)
inElem := inPtr.Elem()
// create a new value of the same concrete type
uint16Type := TypeOf(uint16(0))
newUint16Value := New(uint16Type).Elem()
newUint16Value.Set(ValueOf(uint16(13)))
// set the new value to the interface
inElem.Set(newUint16Value)
if value.(uint16) != 13 {
t.Errorf("Failed to set interface value from uint16")
}
}
func equal[T comparable](a, b []T) bool {
if len(a) != len(b) {
return false