traefik/yaegi

CFG post-order panic: ... incomplete type (on Windows)

saurabh-io opened this issue · 1 comments

The following program sample.go triggers an unexpected result

1) Project Structure
C:\projects\go_projects\yaegi_test

yaegi_test
  - hello.go
  - go.mod
  - lib\src\mymodule\mavapi


2) lib\src\mymodule\mavapi\mav_api.go
package mavapi

type ApiError struct {
	XErr string `json:"error,omitempty"`
	Desc string `json:"error_description,omitempty"`
}

type IdpApiResp[T any] struct {
	HttpStatus int      `json:"httpStatus"`
	Body       *T       `json:"body,omitempty"`
	ErrSource  string   `json:"errSource,omitempty"`
	SomeError  ApiError `json:"error,omitempty"`
}

3) hello.go

package main

import (
	"mymodule/mavapi"
	"fmt"
)

func main() {
	fmt.Println("Hello world")
	x := mavapi.IdpApiResp[string]{
		HttpStatus: 0,
		Body:       new(string),
		ErrSource:  "",
		SomeError:  mavapi.ApiError{},
	}
	fmt.Println(x)
}


4) Run from windows command line
cd C:\projects\go_projects\yaegi_test>
set GOPATH=C:\projects\go_projects\yaegi_test\lib
yaegi hello.go

Expected result

C:\projects\go_projects\yaegi_test>go run hello.go
Hello world
{0 0xc00008a030  { }}

Got

C:\projects\go_projects\yaegi_test>yaegi hello.go

panic: C:\projects\go_projects\yaegi_test\lib\src\yyyy\someapi\mav_api.go:18:13: incomplete type ApiError [recovered]
        panic: hello.go:10:7: CFG post-order panic: C:\projects\go_projects\yaegi_test\lib\src\yyy\someapi\mav_api.go:18:13: incomplete type ApiError

goroutine 1 [running]:
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2.1()
        C:/Users/xxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/cfg.go:601 +0x74
panic({0x14ba5c0?, 0xc0000a4cd8?})
        C:/go/src/runtime/panic.go:770 +0x132
github.com/traefik/yaegi/interp.(*itype).refType(0xc000319400?, 0x16c3a68?)
        C:/Users/xxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/type.go:2047 +0x172c
github.com/traefik/yaegi/interp.(*itype).TypeOf(...)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/type.go:2196
github.com/traefik/yaegi/interp.isInterface(0xc000319400)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/type.go:2410 +0x37
github.com/traefik/yaegi/interp.(*itype).equals(0xc0003103c0, 0xc000319400)
        C:/Users/xxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/type.go:1527 +0x45
github.com/traefik/yaegi/interp.(*itype).assignableTo(0xc0003103c0, 0xc000319400)
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/type.go:1453 +0x25
github.com/traefik/yaegi/interp.typecheck.assignment({0xc0000cf0c0?}, 0xc0002ee280, 0x9?, {0x14f9c8c, 0xe})
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/typecheck.go:57 +0x1bd
github.com/traefik/yaegi/interp.typecheck.structLitExpr({0xc0000cf0c8?}, {0xc0000b5bc8, 0x4, 0x10?}, 0xc000319180)
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/typecheck.go:399 +0x1df
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2(0xc0002eca00)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/cfg.go:1392 +0x1512
github.com/traefik/yaegi/interp.(*node).Walk(0xc0002eca00, 0xc0000cf980, 0xc0000cf928)
        C:/Users/xxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:294 +0x9e
github.com/traefik/yaegi/interp.(*node).Walk(0xc0002ec780, 0xc0000cf980, 0xc0000cf928)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc0001f3e00, 0xc0000cf980, 0xc0000cf928)
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc0001f3680, 0xc0000cf980, 0xc0000cf928)
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc0001f2dc0, 0xc0000cf980, 0xc0000cf928)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).cfg(0xc000112908, 0xc0001f2dc0, 0xc0001343f0, {0xc0000b3710, 0x4}, {0xc0000b3710, 0x4})
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/cfg.go:62 +0x29a
github.com/traefik/yaegi/interp.(*Interpreter).CompileAST(0xc000112908, {0x16b5e08?, 0xc0000ab860?})
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/program.go:97 +0x14d
github.com/traefik/yaegi/interp.(*Interpreter).compileSrc(0xc000112908, {0xc00008a500?, 0x100?}, {0xc0000b2088?, 0xc0000a2400?}, 0x0?)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/program.go:64 +0xaa
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc000112908, {0xc00008a500?, 0x100?}, {0xc0000b2088?, 0xc0000a2400?}, 0x0?)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:556 +0x25
github.com/traefik/yaegi/interp.(*Interpreter).EvalPath(0xc000112908, {0xc0000b2088, 0x8})
        C:/Users/xxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:514 +0xa6
main.runFile(0xc000112908, {0xc0000b2088, 0x8}, 0x0)
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/cmd/yaegi/run.go:153 +0xd7
main.run({0xc0000ae3b0, 0x1, 0x1})
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/cmd/yaegi/run.go:116 +0xb65
main.main()
        C:/Users/xxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/cmd/yaegi/yaegi.go:144 +0x2d7

C:\projects\go_projects\yaegi_test>

Yaegi Version

v0.16.1, v0.15.1

Additional Notes

C:\projects\go_projects\yaegi_test>go version
go version go1.22.4 windows/amd64

Have only tested this on windows.

An additional finding. If move the ApiError struct definition after the IdpApiResp definition, I get a similar but different error.
`package someapi

type IdpApiResp[T any] struct {
HttpStatus int json:"httpStatus"
Body *T json:"body,omitempty"
ErrSource string json:"errSource,omitempty"
SomeError ApiError json:"error,omitempty"
}

type ApiError struct {
XErr string json:"error,omitempty"
Desc string json:"error_description,omitempty"
}
`

yaegi hello.go

`C:\projects\go_projects\yaegi_test>yaegi hello.go
panic: C:\projects\go_projects\yaegi_test\lib\src\byyy\someapi\mav_api.go:3:24: incomplete type IdpApiResp[string] [recovered]
panic: hello.go:10:7: CFG post-order panic: C:\projects\go_projects\yaegi_test\lib\src\byyy\someapi\mav_api.go:3:24: incomplete type IdpApiResp[string]

goroutine 1 [running]:
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2.1()
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/cfg.go:601 +0x74
panic({0x14ba5c0?, 0xc000008c00?})
C:/go/src/runtime/panic.go:770 +0x132
github.com/traefik/yaegi/interp.(*itype).frameType(0x0?)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/type.go:2202 +0x1bb
github.com/traefik/yaegi/interp.(*scope).add(0xc000146480, 0xc000079948?)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/scope.go:210 +0x72
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2(0xc000334b40)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/cfg.go:1408 +0x1565
github.com/traefik/yaegi/interp.(*node).Walk(0xc000334b40, 0xc000127980, 0xc000127928)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:294 +0x9e
github.com/traefik/yaegi/interp.(*node).Walk(0xc0003348c0, 0xc000127980, 0xc000127928)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc000334000, 0xc000127980, 0xc000127928)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc00023b7c0, 0xc000127980, 0xc000127928)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc00023af00, 0xc000127980, 0xc000127928)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).cfg(0xc000162908, 0xc00023af00, 0xc000146480, {0xc00000b770, 0x4}, {0xc00000b770, 0x4})
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/cfg.go:62 +0x29a
github.com/traefik/yaegi/interp.(*Interpreter).CompileAST(0xc000162908, {0x16b5e08?, 0xc00010d9a0?})
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/program.go:97 +0x14d
github.com/traefik/yaegi/interp.(*Interpreter).compileSrc(0xc000162908, {0xc0001445a0?, 0x102?}, {0xc00000a0e8?, 0xc000074400?}, 0xa0?)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/program.go:64 +0xaa
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc000162908, {0xc0001445a0?, 0x102?}, {0xc00000a0e8?, 0xc000074400?}, 0x60?)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:556 +0x25
github.com/traefik/yaegi/interp.(*Interpreter).EvalPath(0xc000162908, {0xc00000a0e8, 0x8})
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/interp/interp.go:514 +0xa6
main.runFile(0xc000162908, {0xc00000a0e8, 0x8}, 0x0)
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/cmd/yaegi/run.go:153 +0xd7
main.run({0xc0000783d0, 0x1, 0x1})
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/cmd/yaegi/run.go:116 +0xb65
main.main()
C:/Users/xxxxxxxx/go/pkg/mod/github.com/traefik/yaegi@v0.15.1/cmd/yaegi/yaegi.go:144 +0x2d7

C:\projects\go_projects\yaegi_test>`