interp: create real recursive types with unsafe type swapping

As the unsafe and pointer methods in `reflect` are to be depreciated, and seeing no replacement functions, it is now forced that some unsafe is needed to replace this as when and interface is dereferenced it is made unsettable by reflect.

With this in mind, this adds real recursive types by hot swapping the struct field type on the fly. This removes a lot of compensation code, simplifying all previous cases.

**Note:** While the struct field type is swapped for the real type, the type string is not changed. Due to this, unsafe will recreate the same type.
This commit is contained in:
Nicholas Wiersma
2021-08-30 18:38:12 +02:00
committed by GitHub
parent da922ce90b
commit 4af992bccb
6 changed files with 167 additions and 217 deletions

View File

@@ -0,0 +1,33 @@
package unsafe2_test
import (
"reflect"
"testing"
"github.com/traefik/yaegi/internal/unsafe2"
)
func TestSwapFieldType(t *testing.T) {
f := []reflect.StructField{
{
Name: "A",
Type: reflect.TypeOf(int(0)),
},
{
Name: "B",
Type: reflect.PtrTo(unsafe2.DummyType),
},
{
Name: "C",
Type: reflect.TypeOf(int64(0)),
},
}
typ := reflect.StructOf(f)
ntyp := reflect.PtrTo(typ)
unsafe2.SwapFieldType(typ, 1, ntyp)
if typ.Field(1).Type != ntyp {
t.Fatalf("unexpected field type: want %s; got %s", ntyp, typ.Field(1).Type)
}
}