diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index a74d4b420..2f9e6db3e 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -758,8 +758,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { } // Do not swap for builtin functions. if !isBuiltin { - if typ, ok := c.typeOf(n.Fun).(*types.Signature); ok && typ.Variadic() { - // pack variadic args into an array + typ, ok := c.typeOf(n.Fun).(*types.Signature) + if ok && typ.Variadic() && !n.Ellipsis.IsValid() { + // pack variadic args into an array only if last argument is not of form `...` varSize := len(n.Args) - typ.Params().Len() + 1 c.emitReverse(varSize) emit.Int(c.prog.BinWriter, int64(varSize)) diff --git a/pkg/compiler/function_call_test.go b/pkg/compiler/function_call_test.go index 072542f58..d85bc29c8 100644 --- a/pkg/compiler/function_call_test.go +++ b/pkg/compiler/function_call_test.go @@ -186,7 +186,7 @@ func TestLocalsCount(t *testing.T) { } func TestVariadic(t *testing.T) { - src := `package foo + srcTmpl := `package foo func someFunc(a int, b ...int) int { sum := a for i := range b { @@ -195,9 +195,21 @@ func TestVariadic(t *testing.T) { return sum } func Main() int { - return someFunc(10, 1, 2, 3) + %s + return someFunc(10, %s) }` - eval(t, src, big.NewInt(4)) + t.Run("Elements", func(t *testing.T) { + src := fmt.Sprintf(srcTmpl, "", "1, 2, 3") + eval(t, src, big.NewInt(4)) + }) + t.Run("Slice", func(t *testing.T) { + src := fmt.Sprintf(srcTmpl, "a := []int{1, 2, 3}", "a...") + eval(t, src, big.NewInt(4)) + }) + t.Run("Literal", func(t *testing.T) { + src := fmt.Sprintf(srcTmpl, "", "[]int{1, 2, 3}...") + eval(t, src, big.NewInt(4)) + }) } func TestVariadicMethod(t *testing.T) {