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't compile function with slice as a parameter #725

Open
MEZk opened this issue Nov 6, 2024 · 3 comments
Open

Can't compile function with slice as a parameter #725

MEZk opened this issue Nov 6, 2024 · 3 comments
Labels

Comments

@MEZk
Copy link

MEZk commented Nov 6, 2024

The following code results in compilation error: cannot use []interface {} as argument (type []string) to call HasPhones (1:18)

package main

import (
	"github.com/expr-lang/expr"
)

type client struct {
}

func (c *client) HasPhones(phones []string) bool {
	return false
}

type env struct {
	Client *client
}

func main() {
	_, err := expr.Compile("Client.HasPhones([\"7\"])", expr.Env(env{}))
	if err != nil {
		panic(err)
	}
}

go 1.22.5
github.com/expr-lang/expr v1.16.9

I expect that the code can be compiled without errors.

@MEZk
Copy link
Author

MEZk commented Nov 6, 2024

I think the problem is in checker.go checkFunc:

if !t.AssignableTo(in) && t.Kind() != reflect.Interface {
  return v.error(arg, "cannot use %v as argument (type %v) to call %v ", t, in, name)
}

If t is an array (slice) of non interface types checker should check that all elements have the same type,

@MEZk
Copy link
Author

MEZk commented Nov 6, 2024

By the way, expr.Eval works OK:

func main() {
	_, err := expr.Eval("Client.HasPhones([\"7\"])", env{})
	if err != nil {
		panic(err)
	}
}

Same is for expr.Run – no problems:

func main() {
	p, err := expr.Compile("Client.HasPhones([\"7\"])")
	if err != nil {
		panic(err)
	}

	_, err = expr.Run(p, env{})
	if err != nil {
		panic(err)
	}
}

@antonmedv antonmedv added the bug label Nov 6, 2024
MEZk added a commit to MEZk/expr that referenced this issue Nov 7, 2024
@MEZk
Copy link
Author

MEZk commented Nov 7, 2024

Test case to prove problem MEZk@527303c .
Possible fix MEZk@413d52d (but I'm not sure, needs further investigation).

Concerns:

  • checkArguments receives arguments slice with only one argument: [true, "prefix"]
  • in variable inside checkArguments has type []string
  • argNature type is []interface {}

So if we know that argNature is an array and all elements of the array have the same type (see checker.ArrayNode) we can get the type of the array and compare the type with the first argument of the function – in to check the validity of arguments.

MEZk added a commit to MEZk/expr that referenced this issue Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants