From fb81647d3bd538f924726bbf48e339d68e4599dd Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: Tue, 21 Mar 2023 12:03:36 +0100 Subject: [PATCH] Fix param type overwriting in type propagation logic --- checker/checker.go | 2 +- checker/checker_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/checker/checker.go b/checker/checker.go index 06371c62e..00025a33c 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -639,7 +639,7 @@ func (v *visitor) checkFunc(name string, fn reflect.Type, method bool, node *ast in = fn.In(i + fnInOffset) } - if isIntegerOrArithmeticOperation(arg) { + if isIntegerOrArithmeticOperation(arg) && (isInteger(in) || isFloat(in)) { t = in setTypeForIntegers(arg, t) } diff --git a/checker/checker_test.go b/checker/checker_test.go index eba6a1f81..f62b6d580 100644 --- a/checker/checker_test.go +++ b/checker/checker_test.go @@ -484,6 +484,11 @@ cannot use int to get an element from map[string]interface {} (1:10) invalid operation: + (mismatched types int and string) (1:13) | 1 /* one */ + "2" | ............^ + +FuncTyped(42) +cannot use int as argument (type string) to call FuncTyped (1:11) + | FuncTyped(42) + | ..........^ ` func TestCheck_error(t *testing.T) { @@ -893,3 +898,38 @@ func TestCheck_dont_panic_on_nil_arguments_for_builtins(t *testing.T) { }) } } + +func TestCheck_do_not_override_params_for_functions(t *testing.T) { + env := map[string]interface{}{ + "foo": func(p string) string { + return "foo" + }, + } + config := conf.New(env) + expr.Function( + "bar", + func(p ...interface{}) (interface{}, error) { + return p[0].(string), nil + }, + new(func(string) string), + )(config) + config.Check() + + t.Run("func from env", func(t *testing.T) { + tree, err := parser.Parse("foo(1)") + require.NoError(t, err) + + _, err = checker.Check(tree, config) + require.Error(t, err) + require.Contains(t, err.Error(), "cannot use int as argument") + }) + + t.Run("func from function", func(t *testing.T) { + tree, err := parser.Parse("bar(1)") + require.NoError(t, err) + + _, err = checker.Check(tree, config) + require.Error(t, err) + require.Contains(t, err.Error(), "cannot use int as argument") + }) +}