reflect: move indirect values into interface when setting interfaces
Fixes #4040
Этот коммит содержится в:
родитель
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
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче