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

Can not import github.com/apache/thrift/lib/go/thrift #935

Open
vitrun opened this issue Nov 3, 2020 · 7 comments
Open

Can not import github.com/apache/thrift/lib/go/thrift #935

vitrun opened this issue Nov 3, 2020 · 7 comments
Labels
area/core bug Something isn't working

Comments

@vitrun
Copy link

vitrun commented Nov 3, 2020

The following program thrift_script.go triggers a panic:

package main

import (
	"context"
	"github.com/apache/thrift/lib/go/thrift"
)

func Invoke(ctx context.Context, iproto thrift.TProtocol, oproto thrift.TProtocol) error {
	return nil
}


func main() {
}

Expected result:

$ go run ./thrift_script.go
// output
// no output

Got:

$ yaegi -syscall -unsafe thrift_script.go
// output
run: reflect: embedded type with methods not implemented if there is more than one field
goroutine 1 [running]:
runtime/debug.Stack(0x1, 0xc00050fe00, 0x40)
        /usr/local/go/src/runtime/debug/stack.go:24 +0x9d
github.com/traefik/yaegi/interp.(*Interpreter).eval.func1(0xc001379c70)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/interp.go:480 +0xbc
panic(0x1951a20, 0x1c78fc0)
        /usr/local/go/src/runtime/panic.go:969 +0x166
reflect.StructOf(0xc000205520, 0x2, 0x2, 0x0, 0x0)
        /usr/local/go/src/reflect/type.go:2480 +0x312d
github.com/traefik/yaegi/interp.(*itype).refType(0xc000d6e1c0, 0xc0013781e8, 0x1a86700, 0x1, 0x22c2900)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/type.go:1445 +0x95c
github.com/traefik/yaegi/interp.(*itype).refType(0xc000d6f260, 0xc0013781e8, 0xc001378a00, 0xc0013782c8, 0x13401f1)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/type.go:1423 +0xcc0
github.com/traefik/yaegi/interp.(*itype).TypeOf(0xc000d6f260, 0xc000d6f260, 0x0)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/type.go:1457 +0x96
github.com/traefik/yaegi/interp.(*itype).frameType(0xc000d6f260, 0xc0013783d8, 0xe0f18bf4)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/type.go:1479 +0xed
github.com/traefik/yaegi/interp.(*scope).add(0xc000188000, 0xc000d6f260, 0xc0000392e0)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/scope.go:188 +0x49
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0004fcd00, 0xc0002ca000)
        /Users/bytedance/go/pkg/mod/github.com/traefik/yaegi@v0.9.4/interp/gta.go:83 +0x497
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004fcd00, 0xc001378bf8, 0x0)
...

Seems that it triggers an unsupported path of reflect.go

@mpl mpl added area/core bug Something isn't working labels Nov 3, 2020
@bailsman
Copy link

According to discussion in golang/go#15924 reflect.StructOf might be taught to create wrapper methods for "special cases that allow reusing the existing methods of embedded fields" which is exactly the special case that yaegi generally runs into.

@bailsman
Copy link

bailsman commented Apr 27, 2021

Recently I learned about the github.com/cosmos72/gomacro/xreflect package that works around many limitations in reflect.

Unsuccessfully, I tried using it to work around the "reflect: embedded type with methods not implemented if there is more than one field" error as follows. It has helped me import other packages that otherwise ran into similar errors, but no luck with thrift.

diff --git a/interp/type.go b/interp/type.go
index a2c9b6c..39dd51d 100644
--- a/interp/type.go
+++ b/interp/type.go
@@ -7,6 +7,7 @@ import (
        "reflect"
        "strconv"
        "sync"
+       "github.com/cosmos72/gomacro/xreflect"
 )

 // tcat defines interpreter type categories.
@@ -1494,7 +1495,7 @@ func (t *itype) refType(defined map[string]*itype, wrapRecursive bool) reflect.T
                if recursive && wrapRecursive {
                        t.rtype = interf
                } else {
-                       t.rtype = reflect.StructOf(fields)
+                       t.rtype = xStructOf(fields)
                }
        default:
                if z, _ := t.zero(); z.IsValid() {
@@ -1504,6 +1505,28 @@ func (t *itype) refType(defined map[string]*itype, wrapRecursive bool) reflect.T
        return t.rtype
 }

+func xStructOf(fields []reflect.StructField) (t reflect.Type) {
+       // Handle reflect.StructOf panic by trying with xreflect
+       defer func() {
+               if r := recover(); r != nil {
+                       universe := xreflect.NewUniverse()
+                       var xfields []xreflect.StructField
+                       for _, field := range fields {
+                               xfield := xreflect.StructField{
+                                       Name:  field.Name,
+                                       Type: universe.FromReflectType(field.Type),
+                                       Tag: field.Tag,
+                                       Anonymous: field.Anonymous,
+                               }
+                               xfields = append(xfields, xfield)
+                       }
+                       t = universe.StructOf(xfields).ReflectType()
+               }
+       }()
+       t = reflect.StructOf(fields)
+       return
+}
+
 // TypeOf returns the reflection type of dynamic interpreter type t.
 func (t *itype) TypeOf() reflect.Type {
        return t.refType(map[string]*itype{}, false)

Unfortunately, running the sample program with this patch then runs into another error:

$ yaegi -syscall ./thrift_script.go
run: ./thrift_script.go:5:2: import "github.com/apache/thrift/lib/go/thrift" error: /go/src/workspace/src/vendor/github.com/apache/thrift/lib/go/thrift/binary_protocol.go:218:25: too many arguments

Note: I have absolutely no idea if this is the correct way to use xreflect.

@hongbo-miao
Copy link

hongbo-miao commented Jun 21, 2022

I got an error at traefik/traefik#9114

CFG post-order panic: reflect: embedded type with methods not implemented if there is more than one field

which might also related with this one.

@yoeluk
Copy link

yoeluk commented Jun 16, 2023

looks like this is the same issue... if I vendor aws-go-v2 SDK I get this

$ yaegi test -v .                                                                                                                                                                                                                      1202ms  Thu 20:51
panic: reflect: embedded type with methods not implemented if there is more than one field [recovered]
        panic: /Users/ygarciadiaz/projects/aws-sink/go/src/aws-sink/vendor/github.com/aws/smithy-go/transport/http/checksum_middleware.go:34:2: CFG post-order panic: reflect: embedded type with methods not implemented if there is more than one field

$ yaegi version
0.15.1

@lvijnck

This comment was marked as off-topic.

@v1sion
Copy link

v1sion commented Aug 31, 2023

Getting the same issue using aws-go-v2 SDK

panic: reflect: embedded type with methods not implemented if there is more than one field [recovered]
        panic: plugins-local/src/github.com/x/y/vendor/github.com/aws/smithy-go/transport/http/checksum_middleware.go:34:2: CFG post-order panic: reflect: embedded type with methods not implemented if there is more than one field

goroutine 1 [running]:
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2.1()
        github.com/traefik/yaegi@v0.15.1/interp/cfg.go:601 +0x78
panic({0x103b952c0, 0x1055b4f40})
        runtime/panic.go:890 +0x263
reflect.StructOf({0xc0010f9a00, 0x4, 0xc001b8c640?})
        reflect/type.go:2551 +0x2709
github.com/traefik/yaegi/interp.(*itype).refType(0xc001afab40?, 0x0?)
        github.com/traefik/yaegi@v0.15.1/interp/type.go:2151 +0xd2a
github.com/traefik/yaegi/interp.(*itype).TypeOf(...)
        github.com/traefik/yaegi@v0.15.1/interp/type.go:2196
github.com/traefik/yaegi/interp.(*itype).frameType(0x10?)
        github.com/traefik/yaegi@v0.15.1/interp/type.go:2223 +0x18a
github.com/traefik/yaegi/interp.(*itype).frameType(0x100017dd7?)
        github.com/traefik/yaegi@v0.15.1/interp/type.go:2221 +0x136
github.com/traefik/yaegi/interp.(*scope).add(0xc001ba2360, 0xc0018b91d8?)
        github.com/traefik/yaegi@v0.15.1/interp/scope.go:210 +0x7b
github.com/traefik/yaegi/interp.compDefineX(0xc001ba2360, 0xc001360f00)
        github.com/traefik/yaegi@v0.15.1/interp/cfg.go:2328 +0x6a8
github.com/traefik/yaegi/interp.(*Interpreter).cfg.func2(0xc001360f00)
        github.com/traefik/yaegi@v0.15.1/interp/cfg.go:840 +0x1993
github.com/traefik/yaegi/interp.(*node).Walk(0xc001360f00, 0xc0018b9cf0, 0xc0018b9d38)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:294 +0xad
github.com/traefik/yaegi/interp.(*node).Walk(0xc001360dc0, 0xc0018b9cf0, 0xc0018b9d38)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc00135db80, 0xc0018b9cf0, 0xc0018b9d38)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc001302b40, 0xc0018b9cf0, 0xc0018b9d38)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).cfg(0xc0014acd80, 0xc001302b40, 0xc001ba2360, {0xc0010eb681, 0x27}, {0xc00134c600, 0x4})
        github.com/traefik/yaegi@v0.15.1/interp/cfg.go:62 +0x2b4
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0014acd80, {0xc000fc0af0, 0x65}, {0xc0010eb681, 0x27}, 0x1)
        github.com/traefik/yaegi@v0.15.1/interp/src.go:125 +0xda9
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001651040)
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:273 +0x208d
github.com/traefik/yaegi/interp.(*node).Walk(0xc001651040, 0xc0018baad8, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:287 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc001650780, 0xc0018baad8, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc001650500, 0xc0018baad8, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0014acd80, 0xc001650500, {0xc000fc0af0, 0x65}, {0xc0010eb291, 0x24}, {0xc0015b12a0, 0x6})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0014acd80, {0xc000fc0690, 0x61}, {0xc0010eb291, 0x24}, 0x1)
        github.com/traefik/yaegi@v0.15.1/interp/src.go:108 +0x9a5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001637040)
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:273 +0x208d
github.com/traefik/yaegi/interp.(*node).Walk(0xc001637040, 0xc0018bb890, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:287 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc001636c80, 0xc0018bb890, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc001636a00, 0xc0018bb890, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0014acd80, 0xc001636a00, {0xc000fc0690, 0x61}, {0xc0010eadb1, 0x20}, {0xc0015b0f30, 0x3})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0014acd80, {0xc000fc03f0, 0x64}, {0xc0010eadb1, 0x20}, 0x1)
        github.com/traefik/yaegi@v0.15.1/interp/src.go:108 +0x9a5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001609b80)
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:273 +0x208d
github.com/traefik/yaegi/interp.(*node).Walk(0xc001609b80, 0xc0018bc648, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:287 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc0016097c0, 0xc0018bc648, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc001609540, 0xc0018bc648, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0014acd80, 0xc001609540, {0xc000fc03f0, 0x64}, {0xc0010ead21, 0x23}, {0xc0015b08d0, 0x6})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0014acd80, {0xc000084c80, 0x41}, {0xc0010ead21, 0x23}, 0x1)
        github.com/traefik/yaegi@v0.15.1/interp/src.go:108 +0x9a5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0015f8b40)
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:273 +0x208d
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015f8b40, 0xc0018bd400, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:287 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015f8500, 0xc0018bd400, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015f8280, 0xc0018bd400, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0014acd80, 0xc0015f8280, {0xc000084c80, 0x41}, {0xc000084aa1, 0x41}, {0xc0015b04e0, 0x3})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0014acd80, {0xc000eec200, 0x39}, {0xc000084aa1, 0x41}, 0x1)
        github.com/traefik/yaegi@v0.15.1/interp/src.go:108 +0x9a5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0015b6b40)
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:273 +0x208d
github.com/traefik/yaegi/interp.(*node).Walk(0xc0015b6b40, 0xc0018be1b8, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:287 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc000eb7900, 0xc0018be1b8, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc000eb7680, 0xc0018be1b8, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0014acd80, 0xc000eb7680, {0xc000eec200, 0x39}, {0xc000eb5f81, 0x39}, {0xc000ebc0c0, 0x1e})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0014acd80, {0xc0014a78e0, 0x4}, {0xc000eb5f81, 0x39}, 0x1)
        github.com/traefik/yaegi@v0.15.1/interp/src.go:108 +0x9a5
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc000eb7180)
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:273 +0x208d
github.com/traefik/yaegi/interp.(*node).Walk(0xc000eb7180, 0xc0018bef70, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:287 +0x34
github.com/traefik/yaegi/interp.(*node).Walk(0xc000eb6f00, 0xc0018bef70, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*node).Walk(0xc000eb6500, 0xc0018bef70, 0x0)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:291 +0x75
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0014acd80, 0xc000eb6500, {0xc0014a78e0, 0x4}, {0xc0014a78e0, 0x4}, {0xc0014a78e0, 0x4})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).gtaRetry(0xc0014acd80?, {0xc00120d150?, 0xc0014aabd0?, 0xc00120d098?}, {0xc0014a78e0, 0x4}, {0xc0014a78e0, 0x4})
        github.com/traefik/yaegi@v0.15.1/interp/gta.go:395 +0x15d
github.com/traefik/yaegi/interp.(*Interpreter).CompileAST(0xc0014acd80, {0x1055ea140?, 0xc0014aabd0?})
        github.com/traefik/yaegi@v0.15.1/interp/program.go:92 +0x17f
github.com/traefik/yaegi/interp.(*Interpreter).compileSrc(0xc0014acd80, {0xc000084460?, 0x1?}, {0x0?, 0xc000084460?}, 0xf0?)
        github.com/traefik/yaegi@v0.15.1/interp/program.go:64 +0xb8
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc0014acd80, {0xc000084460?, 0xc00120d3c0?}, {0x0?, 0x1?}, 0x0?)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:556 +0x28
github.com/traefik/yaegi/interp.(*Interpreter).Eval(...)
        github.com/traefik/yaegi@v0.15.1/interp/interp.go:498
github.com/traefik/traefik/v2/pkg/plugins.NewBuilder(0x0, 0x0?, 0xc000912210?)
        github.com/traefik/traefik/v2/pkg/plugins/builder.go:104 +0xdc6
main.createPluginBuilder(0xc00084e080?)
        github.com/traefik/traefik/v2/cmd/traefik/plugins.go:18 +0x35
main.setupServer(0xc00084e080)
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:214 +0x537
main.runCmd(0xc00084e080)
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:117 +0x3e5
main.main.func1({0xc0003695e0?, 0xc000074050?, 0x0?})
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:62 +0x1f
github.com/traefik/paerser/cli.run(0xc00084e100, {0xc000074050?, 0x1, 0x1})
        github.com/traefik/paerser@v0.2.0/cli/commands.go:133 +0x269
github.com/traefik/paerser/cli.execute(0xc00084e100, {0xc000074040?, 0x2, 0x2}, 0xa0?)
        github.com/traefik/paerser@v0.2.0/cli/commands.go:67 +0x2cc
github.com/traefik/paerser/cli.Execute(...)
        github.com/traefik/paerser@v0.2.0/cli/commands.go:51
main.main()
        github.com/traefik/traefik/v2/cmd/traefik/traefik.go:78 +0x405
❯ traefik version
Version:      2.10.4
Codename:     cheddar
Go version:   go1.20.6
Built:        I don't remember exactly
OS/Arch:      darwin/amd64

@birdywings
Copy link

birdywings commented Jul 24, 2024

I still encounter the same issue when I import "github.com/bytedance/sonic" in my plugins.
panic: reflect: embedded type with methods not implemented if there is more than one field
there any solutions ?

❯ version

Traefik version: v2.9.9

Go version:   1.20.6

Yaegi version: v0.15.1

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

No branches or pull requests

8 participants