From ac32d2a803b1c6f1c50fff77f5b91e7baf40e07b Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 16 Jun 2023 17:06:00 +0800 Subject: [PATCH] checker, cgen: fix if/match expr with `continue` or `break` in a branch (#18466) --- vlib/v/checker/if.v | 2 +- vlib/v/checker/match.v | 2 +- vlib/v/gen/c/cgen.v | 2 +- vlib/v/gen/c/if.v | 2 ++ vlib/v/gen/c/match.v | 2 ++ .../if_expr_with_continue_in_branch_test.v | 17 +++++++++++++++++ 6 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/if_expr_with_continue_in_branch_test.v diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index ed3054622207da..ff332940802408 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -414,7 +414,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { node.pos) } } - } else if !node.is_comptime && stmt !is ast.Return { + } else if !node.is_comptime && stmt !in [ast.Return, ast.BranchStmt] { c.error('`${if_kind}` expression requires an expression as the last statement of every branch', branch.pos) } diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 6f467f8aa581a3..4c339cc4a38719 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -90,7 +90,7 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { c.check_match_branch_last_stmt(stmt, ret_type, expr_type) } } - } else if stmt !is ast.Return { + } else if stmt !in [ast.Return, ast.BranchStmt] { if node.is_expr && ret_type != ast.void_type { c.error('`match` expression requires an expression as the last statement of every branch', stmt.pos) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 00c6a4b1cc2875..bd2af478d24556 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1802,7 +1802,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool { g.set_current_pos_as_last_stmt_pos() g.skip_stmt_pos = true mut is_noreturn := false - if stmt is ast.Return { + if stmt in [ast.Return, ast.BranchStmt] { is_noreturn = true } else if stmt is ast.ExprStmt { is_noreturn = is_noreturn_callexpr(stmt.expr) diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index 530a44ef2924ca..d348bcfc0b90ed 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -25,6 +25,8 @@ fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool { } } else if branch.stmts[0] is ast.Return { return true + } else if branch.stmts[0] is ast.BranchStmt { + return true } } } diff --git a/vlib/v/gen/c/match.v b/vlib/v/gen/c/match.v index 490d6b6193e441..df2f3f1ab548a5 100644 --- a/vlib/v/gen/c/match.v +++ b/vlib/v/gen/c/match.v @@ -29,6 +29,8 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool { } } else if branch.stmts[0] is ast.Return { return true + } else if branch.stmts[0] is ast.BranchStmt { + return true } } } diff --git a/vlib/v/tests/if_expr_with_continue_in_branch_test.v b/vlib/v/tests/if_expr_with_continue_in_branch_test.v new file mode 100644 index 00000000000000..2dd96f1644e2e1 --- /dev/null +++ b/vlib/v/tests/if_expr_with_continue_in_branch_test.v @@ -0,0 +1,17 @@ +fn test_if_expr_with_continue_in_branch() { + mut result := []int{} + for i in 0 .. 10 { + s := if i < 2 { + 100 + i + } else { + continue + } + + println(s) + result << s + } + println(result) + assert result.len == 2 + assert result[0] == 100 + assert result[1] == 101 +}