yaegi icon indicating copy to clipboard operation
yaegi copied to clipboard

panic: reflect.Set: value of type interface {} is not assignable to type XXX

Open ChaosNyaruko opened this issue 1 year ago • 0 comments

The following program sample.go triggers an unexpected result

import (
	"log"
	"reflect"

	"github.com/traefik/yaegi/interp"
)

func main() {
	var err error
	i := interp.New(interp.Options{})
	type Super struct {
	}
	imports := map[string]reflect.Value{
		"Super": reflect.ValueOf((*Super)(nil)),
	}
	_ = i.Use(interp.Exports{
		"fake.com/engine/proto/.": imports,
	})

	v, err := i.Eval(`
		import . "fake.com/engine/proto"

		func Playing1() func(any) (any) {
			return func(any) (any) {
				return Super{}
			}
		}
`)
	if err != nil {
		log.Fatal("compile playing1 err: %v", err)
	}
	if v, err = i.Eval("Playing1"); err != nil {
		log.Fatalf("get the closure generated by Playing1 err: %v", err)
	}
	vv := v.Call(nil)
	x := vv[0].Interface().(func(any) any)
	y := x(123)
	_ = y.(Super)
	log.Printf("finished")
}

Expected result

finished

Got

// I use the "compile" mode, so still go ./sample.go


panic: reflect.Set: value of type interface {} is not assignable to type main.Super

goroutine 1 [running]:
reflect.Value.assignTo({0x100bbe1a0?, 0x14000110ca0?, 0x140000295a8?}, {0x100b34f3b, 0xb}, 0x100bc48c0, 0x0)

Yaegi Version

0.16.1

Additional Notes

The behavior in the above case is really strange, I tried the following variants, they all worked..

  1. In the internal closure, if I add a parameter name, i.e.

from

return func (any) (any)

to

return func (a any) (any)

Then it works fine, I don't understand..

  1. If I remove the "import" part, and just use builtin type, it also worked. BUT when i add an an "anonymous" assignment, it breaks again..
v, err := i.Eval(`
		func Playing1() func(any) (any) {
			return func(any) (any) {
                               _ = 1 // without this statement, it works
				return 1
			}
		}
`)

ChaosNyaruko avatar Nov 06 '24 08:11 ChaosNyaruko