diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7877ec2b45..e279e280ed 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -691,6 +691,7 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type { // look for function in format `mod.fn` or `fn` (main/builtin) mut f := table.Fn{} mut found := false + mut found_in_args := false // try prefix with current module as it would have never gotten prefixed if !fn_name.contains('.') && call_expr.mod !in ['builtin', 'main'] { name_prefixed := '${call_expr.mod}.$fn_name' @@ -717,6 +718,7 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type { info := vts.info as table.FnType f = info.func found = true + found_in_args = true } } } @@ -725,6 +727,12 @@ pub fn (mut c Checker) call_fn(call_expr mut ast.CallExpr) table.Type { c.error('unknown function: $fn_name', call_expr.pos) return table.void_type } + if !found_in_args && call_expr.mod in ['builtin', 'main'] { + scope := c.file.scope.innermost(call_expr.pos.pos) + if _ := scope.find_var(fn_name) { + c.error('ambiguous call to: `$fn_name`, may refer to fn `$fn_name` or variable `$fn_name`', call_expr.pos) + } + } call_expr.return_type = f.return_type if f.return_type == table.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines { call_expr.should_be_skipped = true diff --git a/vlib/v/checker/tests/ambiguous_function_call_a.out b/vlib/v/checker/tests/ambiguous_function_call_a.out new file mode 100644 index 0000000000..18be4473e2 --- /dev/null +++ b/vlib/v/checker/tests/ambiguous_function_call_a.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/ambiguous_function_call_a.v:2:2: error: ambiguous call to: `foo`, may refer to fn `foo` or variable `foo` + 1| fn foo(foo int) { + 2| foo(foo + 1) + ~~~~~~~~~~~~ + 3| } + 4| diff --git a/vlib/v/checker/tests/ambiguous_function_call_a.v b/vlib/v/checker/tests/ambiguous_function_call_a.v new file mode 100644 index 0000000000..e8ec08cdf7 --- /dev/null +++ b/vlib/v/checker/tests/ambiguous_function_call_a.v @@ -0,0 +1,7 @@ +fn foo(foo int) { + foo(foo + 1) +} + +fn main() { + foo(5) +} diff --git a/vlib/v/checker/tests/ambiguous_function_call_a.vv b/vlib/v/checker/tests/ambiguous_function_call_a.vv new file mode 100644 index 0000000000..e8ec08cdf7 --- /dev/null +++ b/vlib/v/checker/tests/ambiguous_function_call_a.vv @@ -0,0 +1,7 @@ +fn foo(foo int) { + foo(foo + 1) +} + +fn main() { + foo(5) +} diff --git a/vlib/v/checker/tests/ambiguous_function_call_b.out b/vlib/v/checker/tests/ambiguous_function_call_b.out new file mode 100644 index 0000000000..6d7417439e --- /dev/null +++ b/vlib/v/checker/tests/ambiguous_function_call_b.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/ambiguous_function_call_b.v:3:2: error: ambiguous call to: `foo`, may refer to fn `foo` or variable `foo` + 1| fn foo() { + 2| foo := 1 + 3| foo(foo) + ~~~~~~~~ + 4| } + 5| diff --git a/vlib/v/checker/tests/ambiguous_function_call_b.v b/vlib/v/checker/tests/ambiguous_function_call_b.v new file mode 100644 index 0000000000..c1dbab3b34 --- /dev/null +++ b/vlib/v/checker/tests/ambiguous_function_call_b.v @@ -0,0 +1,8 @@ +fn foo() { + foo := 1 + foo(foo) +} + +fn main() { + foo() +} diff --git a/vlib/v/checker/tests/ambiguous_function_call_b.vv b/vlib/v/checker/tests/ambiguous_function_call_b.vv new file mode 100644 index 0000000000..c1dbab3b34 --- /dev/null +++ b/vlib/v/checker/tests/ambiguous_function_call_b.vv @@ -0,0 +1,8 @@ +fn foo() { + foo := 1 + foo(foo) +} + +fn main() { + foo() +}