diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 729306d07f..e3b85930d9 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -413,6 +413,12 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type { } pub fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type { + // Check whether the inner function definition is before the call + if var := node.scope.find_var(node.name) { + if var.expr is ast.AnonFn && var.pos.pos > node.pos.pos { + c.error('unknown function: $node.name', node.pos) + } + } // TODO merge logic from method_call and fn_call // First check everything that applies to both fns and methods old_inside_fn_arg := c.inside_fn_arg diff --git a/vlib/v/checker/tests/inner_functions_call_before_define.out b/vlib/v/checker/tests/inner_functions_call_before_define.out new file mode 100644 index 0000000000..1d0e092b54 --- /dev/null +++ b/vlib/v/checker/tests/inner_functions_call_before_define.out @@ -0,0 +1,13 @@ +vlib/v/checker/tests/inner_functions_call_before_define.vv:2:7: error: unknown function: f + 1 | fn main() { + 2 | _ := f() + | ~~~ + 3 | go f() + 4 | +vlib/v/checker/tests/inner_functions_call_before_define.vv:3:5: error: unknown function: f + 1 | fn main() { + 2 | _ := f() + 3 | go f() + | ~~~ + 4 | + 5 | f := fn () string { return "hello" } diff --git a/vlib/v/checker/tests/inner_functions_call_before_define.vv b/vlib/v/checker/tests/inner_functions_call_before_define.vv new file mode 100644 index 0000000000..7e2044497e --- /dev/null +++ b/vlib/v/checker/tests/inner_functions_call_before_define.vv @@ -0,0 +1,7 @@ +fn main() { + _ := f() + go f() + + f := fn () string { return "hello" } + _ := f() // avoid warnings +}