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 not being interpreted #1227

Closed
jptosso opened this issue Aug 24, 2021 · 0 comments · Fixed by #1242
Closed

interface not being interpreted #1227

jptosso opened this issue Aug 24, 2021 · 0 comments · Fixed by #1242
Labels
area/core bug Something isn't working
Milestone

Comments

@jptosso
Copy link

jptosso commented Aug 24, 2021

The following program sample.go triggers an unexpected result

package xpath

import (
	"errors"
	"fmt"
	"math"
	"strconv"
	"strings"
	"sync"
	"unicode"
)

// Defined an interface of stringBuilder that compatible with
// strings.Builder(go 1.10) and bytes.Buffer(< go 1.10)
type stringBuilder interface {
	WriteRune(r rune) (n int, err error)
	WriteString(s string) (int, error)
	Reset()
	Grow(n int)
	String() string
}

var builderPool = sync.Pool{New: func() interface{} {
	return newStringBuilder()
}}
//...

Expected result

it should at least compile

Got

jptosso@Porco-Rosso  ~/go/coraza-traefik   master  /Users/jptosso/go/bin/yaegi test  
/Users/jptosso/go/src/github.com/jptosso/coraza-waf/vendor/github.com/antchfx/xpath/func.go:23:19: panic
panic: reflect.Set: value of type func(interface {}, string, interface {}, interface {}) bool is not assignable to type *interp.node [recovered]
	panic: reflect.Set: value of type func(interface {}, string, interface {}, interface {}) bool is not assignable to type *interp.node

goroutine 1 [running]:
github.com/traefik/yaegi/interp.runCfg.func1(0xc0003e4000, 0xc0017ab100, 0xc000b92e38)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/run.go:184 +0x253
panic(0x1a1e180, 0xc00179a5b0)
	/usr/local/Cellar/go/1.16.5/libexec/src/runtime/panic.go:965 +0x1b9
reflect.Value.assignTo(0xc0016b2b00, 0xc0005af670, 0x193, 0x1b5f588, 0xb, 0x1af92c0, 0x0, 0xc0016b2b00, 0xc0005af638, 0xc0016b2b00)
	/usr/local/Cellar/go/1.16.5/libexec/src/reflect/value.go:2451 +0x3f7
reflect.Value.Set(0x1af92c0, 0xc000a74e68, 0x196, 0xc0016b2b00, 0xc0005af670, 0x193)
	/usr/local/Cellar/go/1.16.5/libexec/src/reflect/value.go:1564 +0xbd
github.com/traefik/yaegi/interp.arrayLit.func1(0xc0003e4000, 0xc00213a930)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/run.go:2338 +0x16e
github.com/traefik/yaegi/interp.runCfg(0xc0017ab100, 0xc0003e4000)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/run.go:190 +0x87
github.com/traefik/yaegi/interp.(*Interpreter).run(0xc0003e2000, 0xc001202500, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/run.go:121 +0x2b0
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0003e2000, 0xc000f2d710, 0x24, 0xc00168be21, 0x18, 0x1, 0xc001234b10, 0x3, 0x0, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:148 +0x9d4
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001408e00, 0xc001225c28)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:226 +0x13d0
github.com/traefik/yaegi/interp.(*node).Walk(0xc001408e00, 0xc000b93c28, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:233 +0xb5
github.com/traefik/yaegi/interp.(*node).Walk(0xc001408900, 0xc000b93c28, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:237 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc001408700, 0xc000b93c28, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:237 +0x66
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0003e2000, 0xc001408700, 0xc001189b80, 0x40, 0xc00168b7c1, 0x1b, 0x0, 0x1, 0xc001408700, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:21 +0x21f
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0003e2000, 0xc000b15530, 0x24, 0xc00168b7c1, 0x1b, 0x1, 0xc0013fea10, 0xc0012263a8, 0x13986c6, 0xc000263610)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:100 +0xf57
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc001238500, 0xc0012269a8)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:226 +0x13d0
github.com/traefik/yaegi/interp.(*node).Walk(0xc001238500, 0xc000b949a8, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:233 +0xb5
github.com/traefik/yaegi/interp.(*node).Walk(0xc001202c00, 0xc000b949a8, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:237 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc001202a00, 0xc000b949a8, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:237 +0x66
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0003e2000, 0xc001202a00, 0xc00168bdc0, 0x1d, 0xc000508081, 0x1d, 0x4, 0x8, 0xc001202a00, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:21 +0x21f
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0003e2000, 0xc000291dba, 0x1, 0xc000508081, 0x1d, 0xc0003e2001, 0xc0002848f0, 0xc0002a27c0, 0xd4, 0x119b333)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:100 +0xf57
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc00050ad00, 0xc0001a9728)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:226 +0x13d0
github.com/traefik/yaegi/interp.(*node).Walk(0xc00050ad00, 0xc000b95728, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:233 +0xb5
github.com/traefik/yaegi/interp.(*node).Walk(0xc00050a400, 0xc000b95728, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:237 +0x66
github.com/traefik/yaegi/interp.(*node).Walk(0xc00050a200, 0xc000b95728, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:237 +0x66
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc0003e2000, 0xc00050a200, 0xc000291dba, 0x1, 0xc00029196c, 0x2, 0x0, 0x1, 0xc00050a200, 0x0, ...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:21 +0x21f
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc0003e2000, 0x1cd6cd8, 0x1, 0xc00029196c, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:100 +0xf57
github.com/traefik/yaegi/interp.(*Interpreter).EvalTest(...)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:427
main.test(0xc000032060, 0x0, 0x0, 0xc00000a601, 0xc000001680)
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/cmd/yaegi/test.go:151 +0x106a
main.main()
	/Users/jptosso/go/pkg/mod/github.com/traefik/[email protected]/cmd/yaegi/yaegi.go:135 +0x505

It's some issue with sync.Pool{} which takes New(...) interface{} from repo github.com/antchfx/xpath (func.go)

Yaegi Version

devel (latest)

Additional Notes

I see Interfaces to be used from the pre-compiled code can not be added dynamically, as it is required to pre-compile interface wrappers. in the readme, is there any workaround or any way I can fix this?

Thank you

@mvertes mvertes added area/core bug Something isn't working labels Sep 6, 2021
@mvertes mvertes added this to the v0.10.x milestone Sep 6, 2021
traefiker pushed a commit that referenced this issue Sep 6, 2021
This test (assert2.go) display 2 separate issues:
1. assert2.go L28: Type assert tries to set an `interface{}` to a `valueInterface`. The typing here is complex, we have a valueT(strings.Builder) wrapped in a ptrT wrapped in a src iface wrapped in a valueT(interface{}). Type assert fails to realise that the `valueT` `interface{}` is wrapping the `valueInterface`.
2. assert2.go L29: `genValueBinMethodOnInterface` does not try and get the bin method, as the `typ.node` (`ptrT` or a `valueT`(`string.Builder`)) is set. In this case the src iface is called with a receiver argument. To fix this the method is looked for first if possible, and only if not found does it fall back to the `defaultGen`.

Fixes #1227
jptosso referenced this issue Sep 10, 2021
Make sure to keep always a single copy of incomplete type structures.
Remove remnants of recursive types processing.

Now `import "go.uber.org/zap"` works again (see #1172), fixing regressions
introduced by #1236.
@mvertes mvertes reopened this Sep 10, 2021
@mvertes mvertes closed this as completed Sep 10, 2021
Bai-Yingjie pushed a commit to godevsig/yaegi that referenced this issue Sep 12, 2021
This test (assert2.go) display 2 separate issues:
1. assert2.go L28: Type assert tries to set an `interface{}` to a `valueInterface`. The typing here is complex, we have a valueT(strings.Builder) wrapped in a ptrT wrapped in a src iface wrapped in a valueT(interface{}). Type assert fails to realise that the `valueT` `interface{}` is wrapping the `valueInterface`.
2. assert2.go L29: `genValueBinMethodOnInterface` does not try and get the bin method, as the `typ.node` (`ptrT` or a `valueT`(`string.Builder`)) is set. In this case the src iface is called with a receiver argument. To fix this the method is looked for first if possible, and only if not found does it fall back to the `defaultGen`.

Fixes traefik#1227
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