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

interface conversion: interface {} is interp.valueInterface, not string when indexing map #1344

Closed
bailsman opened this issue Dec 26, 2021 · 0 comments · Fixed by #1397
Closed
Labels
area/core bug Something isn't working
Milestone

Comments

@bailsman
Copy link

The following program sample.go triggers an unexpected result

package main

import (
        "fmt"
)

func main() {
        var m = map[string]interface{}{"a": "a"}
        a, _ := m["a"]
        b := a.(string)
        fmt.Println(a, b)
}

Expected result

$ go run ./sample.go
a a

Got

$ yaegi ./sample.go
./sample.go:8:33: panic
run: interface conversion: interface {} is interp.valueInterface, not string
goroutine 1 [running]:
runtime/debug.Stack(0x1, 0xc0002ea800, 0x40)
        /usr/local/go/src/runtime/debug/stack.go:24 +0x9f
github.com/traefik/yaegi/interp.(*Interpreter).Execute.func1(0xc0001adaf8)
        /go/src/yaegi/interp/program.go:131 +0xc8
panic(0xe43620, 0xc00019efb0)
        /usr/local/go/src/runtime/panic.go:965 +0x1b9
github.com/traefik/yaegi/interp.runCfg.func1(0xc0000cabb0, 0xc0004078c0, 0x0)
        /go/src/yaegi/interp/run.go:193 +0x251
panic(0xe43620, 0xc00019efb0)
        /usr/local/go/src/runtime/panic.go:965 +0x1b9
github.com/traefik/yaegi/interp.typeAssert.func3(0xc0000cabb0, 0x0)
        /go/src/yaegi/interp/run.go:441 +0x76b
github.com/traefik/yaegi/interp.runCfg(0xc0004078c0, 0xc0000cabb0, 0xc0004067e0, 0x0)
        /go/src/yaegi/interp/run.go:201 +0xbe
github.com/traefik/yaegi/interp.(*Interpreter).run(0xc0000ed8c0, 0xc0004067e0, 0xc0000caa50)
        /go/src/yaegi/interp/run.go:120 +0x2d2
github.com/traefik/yaegi/interp.(*Interpreter).Execute(0xc0000ed8c0, 0xc00048c9c0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /go/src/yaegi/interp/program.go:157 +0x245
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc0000ed8c0, 0xc0002d4fa0, 0x91, 0x7ffe1ea59eb4, 0xb, 0x0, 0x92, 0x0, 0x0, 0x91, ...)
        /go/src/yaegi/interp/interp.go:615 +0xd3
github.com/traefik/yaegi/interp.(*Interpreter).EvalPath(0xc0000ed8c0, 0x7ffe1ea59eb4, 0xb, 0xc0002d4e00, 0x91, 0x0, 0x0, 0xc0001adc08)
        /go/src/yaegi/interp/interp.go:508 +0x13a
main.runFile(0xc0000ed8c0, 0x7ffe1ea59eb4, 0xb, 0x0, 0x1, 0x0)
        /go/src/yaegi/cmd/yaegi/run.go:153 +0xb1
main.run(0xc000032050, 0x1, 0x1, 0xc00000a501, 0xc000001680)
        /go/src/yaegi/cmd/yaegi/run.go:116 +0xa2a
main.main()
        /go/src/yaegi/cmd/yaegi/yaegi.go:144 +0x415

Yaegi Version

fbee2ba

Additional Notes

The following patch seems to fix the problem (at least for this instance):

diff --git a/interp/run.go b/interp/run.go
index 1295807..354f976 100644
--- a/interp/run.go
+++ b/interp/run.go
@@ -1843,11 +1843,7 @@ func getIndexMap2(n *node) {
                        n.exec = func(f *frame) bltn {
                                v := value0(f).MapIndex(mi)
                                if v.IsValid() {
-                                       if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
-                                               dest(f).Set(e)
-                                       } else {
-                                               dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
-                                       }
+                                       dest(f).Set(v.Elem())
                                }
                                if doStatus {
                                        value2(f).SetBool(v.IsValid())
@@ -1879,11 +1875,7 @@ func getIndexMap2(n *node) {
                        n.exec = func(f *frame) bltn {
                                v := value0(f).MapIndex(value1(f))
                                if v.IsValid() {
-                                       if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
-                                               dest(f).Set(e)
-                                       } else {
-                                               dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
-                                       }
+                                       dest(f).Set(v.Elem())
                                }
                                if doStatus {
                                        value2(f).SetBool(v.IsValid())

But note that this is more trial and error than me really understanding what's going on.

@mvertes mvertes added area/core bug Something isn't working labels Dec 29, 2021
@mvertes mvertes added this to the v0.11.x milestone Dec 29, 2021
mvertes added a commit to mvertes/yaegi that referenced this issue May 17, 2022
There should be no need now to wrap empty interfaces in order to
retrieve its value.

Fixes traefik#1344.
traefiker pushed a commit that referenced this issue May 19, 2022
There should be no need now to wrap empty interfaces in order to
retrieve its value.

Fixes #1344.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants