Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ChaosNyaruko opened this issue Nov 6, 2024 · 0 comments

Comments

@ChaosNyaruko
Copy link

ChaosNyaruko commented Nov 6, 2024

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
			}
		}
`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant