reflect: implement CanInterface and fix string Index()

This commit fixes two related issues:

 1. CanInterface was unimplemented. It now uses the same check as is
    used in Interface() itself.
    This issue led to https://github.com/tinygo-org/tinygo/issues/3033
 2. Allow making an interface out of a string char element.

Doing this in one commit (instead of two) because they are shown to be
correct with the same tests.
This commit is contained in:
Ayke van Laethem
2022-08-31 22:33:28 +02:00
committed by Ron Evans
parent edaf13f951
commit e955aa1941
3 changed files with 22 additions and 16 deletions
+5 -2
View File
@@ -168,8 +168,7 @@ func (v Value) IsValid() bool {
}
func (v Value) CanInterface() bool {
// No Value types of private data can be constructed at the moment.
return true
return v.isExported()
}
func (v Value) CanAddr() bool {
@@ -502,6 +501,9 @@ func (v Value) Index(i int) Value {
// Extract a character from a string.
// A string is never stored directly in the interface, but always as a
// pointer to the string value.
// Keeping valueFlagExported if set, but don't set valueFlagIndirect
// otherwise CanSet will return true for string elements (which is bad,
// strings are read-only).
s := *(*stringHeader)(v.value)
if uint(i) >= uint(s.len) {
panic("reflect: string index out of range")
@@ -509,6 +511,7 @@ func (v Value) Index(i int) Value {
return Value{
typecode: Uint8.basicType(),
value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Pointer(uintptr(s.data) + uintptr(i))))),
flags: v.flags & valueFlagExported,
}
case Array:
// Extract an element from the array.