traefik / yaegi

Yaegi is Another Elegant Go Interpreter
https://pkg.go.dev/github.com/traefik/yaegi
Apache License 2.0
6.82k stars 342 forks source link

nil interface assertion panic #1578

Open laushunyu opened 1 year ago

laushunyu commented 1 year ago

The following program sample.go triggers an unexpected result

package main

import (
    "github.com/traefik/yaegi/interp"
    "github.com/traefik/yaegi/stdlib"
)

const src = `package main

import (
    "context"
    "fmt"
)

func main() {
    t, ok := context.Background().Value("yeagi").(fmt.Stringer)
    if ok {
        fmt.Println(t.String())
    }
}
`

func main() {
    i := interp.New(interp.Options{})
    if err := i.Use(stdlib.Symbols); err != nil {
        panic(err)
    }

    _, err := i.Eval(src)
    if err != nil {
        panic(err)
    }
}

Expected result

$ go run ./sample.go
// nothing happened

Got

$ yaegi ./sample.go
9:11: panic
panic: reflect: call of reflect.Value.Type on zero Value

goroutine 1 [running]:
main.main()
        /home/macoo/yeagi-test/sample.go:31 +0xbf

Yaegi Version

v0.15.1

Additional Notes

Comment of golang official package context Context.Value

    //  // FromContext returns the User value stored in ctx, if any.
    //  func FromContext(ctx context.Context) (*User, bool) {
    //      u, ok := ctx.Value(userKey).(*User)
    //      return u, ok
    //  }

When the ctx.Value(xxx) returned a nil interface, yaegi will panic at github.com/traefik/yaegi@v0.15.1/interp/use.go:98:

    // Otherwise return the direct "non-composed" interface.
    return w.Type().Elem()

Local var w is invalid.