traefik / yaegi

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

yaegi doesn't correctly resolve variable initialization dependencies going through function calls #1585

Open thehowl opened 1 year ago

thehowl commented 1 year ago

The following program sample.go triggers an unexpected result

// naming is important because of the way the files are sorted when reading the dir
// a.go
package xx

func initializerFunc(x string) string {
    return initializerMap[x]
}

// b.go
package xx

var a = initializerFunc("x")

// c.go
package xx

var initializerMap = map[string]string{
    "x": "y",
}

// b_test.go
package xx

import "testing"

func TestX(t *testing.T) {
    t.Logf(a)
    if a != "y" {
        panic("invalid")
    }
}

Expected result

$ go test -v  .
=== RUN   TestX
    b_test.go:6: y
--- PASS: TestX (0.00s)
PASS
ok      yaegi/tst       0.001s

Got

=== RUN   TestX
    value.go:586:
b_test.go:6:2: panic
--- FAIL: TestX (0.00s)
panic: invalid [recovered]
        panic: invalid [recovered]
        panic: invalid

goroutine 6 [running]:
testing.tRunner.func1.2({0xecb2a0, 0xc000011068})
        /usr/lib/go/src/testing/testing.go:1526 +0x24e
testing.tRunner.func1()
        /usr/lib/go/src/testing/testing.go:1529 +0x39f
panic({0xecb2a0, 0xc000011068})
        /usr/lib/go/src/runtime/panic.go:884 +0x213
github.com/traefik/yaegi/interp.runCfg.func1()
        /home/howl/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/run.go:205 +0x1a5
panic({0xecb2a0, 0xc000011068})
        /usr/lib/go/src/runtime/panic.go:884 +0x213
github.com/traefik/yaegi/interp._panic.func1(0xc0000d89a0?)
        /home/howl/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/run.go:910 +0x4c
github.com/traefik/yaegi/interp.runCfg(0xc000378280, 0xc0000d89a0, 0x0?, 0xeb8800?)
        /home/howl/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/run.go:213 +0x29d
github.com/traefik/yaegi/interp.genFunctionWrapper.func1.1({0xc000010ff0, 0x1, 0x1?})
        /home/howl/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/run.go:1024 +0x825
testing.tRunner(0xc0001991e0, 0xc00038d5c0)
        /usr/lib/go/src/testing/testing.go:1576 +0x10b
created by testing.(*T).Run
        /usr/lib/go/src/testing/testing.go:1629 +0x3ea

Yaegi Version

0.15.1

Additional Notes

Originally discovered by trying to run yaegi test on https://github.com/notnil/chess .

A caveat is that this bug's behaviour is dependent on the alphabetic ordering of the file. Doing mv c.go 0.go leads to the tests succeeding

$ yaegi test -v
=== RUN   TestX
    value.go:586: y
--- PASS: TestX (0.00s)
PASS