From 884b842930aef6e8c45088a6d2b987fe887266ed Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 4 Oct 2024 15:01:22 +0800 Subject: [PATCH] checker: check fn return void fn call (no value) (fix #22389) (#22404) --- vlib/v/checker/checker.v | 4 ++- vlib/v/checker/match.v | 3 ++ .../tests/fn_return_void_fn_call_err.out | 7 +++++ .../tests/fn_return_void_fn_call_err.vv | 30 ++++++++++++++++++ .../fn_return_match_expr_with_result_test.v | 31 +++++++++++++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/fn_return_void_fn_call_err.out create mode 100644 vlib/v/checker/tests/fn_return_void_fn_call_err.vv create mode 100644 vlib/v/tests/fns/fn_return_match_expr_with_result_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 0cf0ad27b..968842e65 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2177,7 +2177,9 @@ fn (mut c Checker) stmt(mut node ast.Stmt) { } } } - c.check_expr_option_or_result_call(node.expr, or_typ) + if !c.inside_return { + c.check_expr_option_or_result_call(node.expr, or_typ) + } // TODO: This should work, even if it's prolly useless .-. // node.typ = c.check_expr_option_or_result_call(node.expr, ast.void_type) } diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 38c14f7b4..930442e62 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -275,6 +275,9 @@ fn (mut c Checker) check_match_branch_last_stmt(last_stmt ast.ExprStmt, ret_type } c.error('return type mismatch, it should be `${ret_sym.name}`', last_stmt.pos) } + } else if expr_type == ast.void_type && ret_type.idx() == ast.void_type_idx + && ret_type.has_option_or_result() { + c.error('`${last_stmt.expr}` used as value', last_stmt.pos) } } diff --git a/vlib/v/checker/tests/fn_return_void_fn_call_err.out b/vlib/v/checker/tests/fn_return_void_fn_call_err.out new file mode 100644 index 000000000..269726290 --- /dev/null +++ b/vlib/v/checker/tests/fn_return_void_fn_call_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/fn_return_void_fn_call_err.vv:20:4: error: `install_from_github(unit, verbosity)!` used as value + 18 | return match source { + 19 | 'github' { + 20 | install_from_github(unit, verbosity)! + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 21 | } + 22 | else { diff --git a/vlib/v/checker/tests/fn_return_void_fn_call_err.vv b/vlib/v/checker/tests/fn_return_void_fn_call_err.vv new file mode 100644 index 000000000..aa410558d --- /dev/null +++ b/vlib/v/checker/tests/fn_return_void_fn_call_err.vv @@ -0,0 +1,30 @@ +fn main() { + install_command(['github:some/thing'], 1) or { panic(err) } +} + +pub fn install_command(args []string, verbosity int) ! { + if args.len == 0 { + return error('${@FN} requires an argument') + } + component := args[0] + if component.count(':') == 0 { + return install_command(['github:${component}'], verbosity) + } + source := component.all_before(':') + if source != 'github' { + return error('${@FN} unknown source `${source}`') + } + unit := component.all_after(':') + return match source { + 'github' { + install_from_github(unit, verbosity)! + } + else { + error('${@FN} unknown source `${source}`') + } + } +} + +fn install_from_github(unit string, verbosity int) ! { + dump(unit) +} diff --git a/vlib/v/tests/fns/fn_return_match_expr_with_result_test.v b/vlib/v/tests/fns/fn_return_match_expr_with_result_test.v new file mode 100644 index 000000000..e349331f1 --- /dev/null +++ b/vlib/v/tests/fns/fn_return_match_expr_with_result_test.v @@ -0,0 +1,31 @@ +fn test_fn_return_match_expr_with_result() { + install_command(['github:some/thing'], 1) or { panic(err) } + assert true +} + +pub fn install_command(args []string, verbosity int) ! { + if args.len == 0 { + return error('${@FN} requires an argument') + } + component := args[0] + if component.count(':') == 0 { + return install_command(['github:${component}'], verbosity) + } + source := component.all_before(':') + if source != 'github' { + return error('${@FN} unknown source `${source}`') + } + unit := component.all_after(':') + return match source { + 'github' { + install_from_github(unit, verbosity) + } + else { + error('${@FN} unknown source `${source}`') + } + } +} + +fn install_from_github(unit string, verbosity int) ! { + dump(unit) +} -- 2.39.5