From 196b5f8e3a9f06f0a27bcd5b97dd7a13a83d1bb6 Mon Sep 17 00:00:00 2001 From: yuyi Date: Tue, 23 Aug 2022 12:58:33 +0800 Subject: [PATCH] checker: fix match expr with non last if expr (#15500) --- vlib/v/ast/ast.v | 20 ----------- vlib/v/checker/if.v | 4 --- vlib/v/checker/match.v | 13 +------ vlib/v/checker/tests/if_match_expr.out | 35 ------------------- vlib/v/checker/tests/if_match_expr.vv | 27 -------------- .../match_expr_with_non_last_if_expr_test.v | 20 +++++++++++ 6 files changed, 21 insertions(+), 98 deletions(-) delete mode 100644 vlib/v/checker/tests/if_match_expr.out delete mode 100644 vlib/v/checker/tests/if_match_expr.vv create mode 100644 vlib/v/tests/match_expr_with_non_last_if_expr_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index c7c5a90a4d..08946d6a19 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1875,26 +1875,6 @@ pub fn (e &Expr) is_lockable() bool { } } -// check if stmt can be an expression in C -pub fn (stmt Stmt) check_c_expr() ? { - match stmt { - AssignStmt { - return - } - ForCStmt, ForInStmt, ForStmt { - return - } - ExprStmt { - if stmt.expr.is_expr() { - return - } - return error('unsupported statement (`$stmt.expr.type_name()`)') - } - else {} - } - return error('unsupported statement (`$stmt.type_name()`)') -} - // CTempVar is used in cgen only, to hold nodes for temporary variables pub struct CTempVar { pub: diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index b4528d0088..473ebaf3e4 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -238,10 +238,6 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { c.error('`$if_kind` expression requires an expression as the last statement of every branch', branch.pos) } - for st in branch.stmts { - // must not contain C statements - st.check_c_expr() or { c.error('`if` expression branch has $err.msg()', st.pos) } - } } if mut branch.cond is ast.IfGuardExpr { sym := c.table.sym(branch.cond.expr_type) diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 916b903079..1125f3afe9 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -46,18 +46,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { c.smartcast_mut_pos = token.Pos{} c.smartcast_cond_pos = token.Pos{} if node.is_expr { - if branch.stmts.len > 0 { - // ignore last statement - workaround - // currently the last statement in a match branch does not have an - // expected value set, so e.g. IfExpr.is_expr is not set. - // probably any mismatch will be caught by not producing a value instead - for st in branch.stmts[..branch.stmts.len - 1] { - // must not contain C statements - st.check_c_expr() or { - c.error('`match` expression branch has $err.msg()', st.pos) - } - } - } else if ret_type != ast.void_type { + if branch.stmts.len == 0 && ret_type != ast.void_type { c.error('`match` expression requires an expression as the last statement of every branch', branch.branch_pos) } diff --git a/vlib/v/checker/tests/if_match_expr.out b/vlib/v/checker/tests/if_match_expr.out deleted file mode 100644 index bb4dc85293..0000000000 --- a/vlib/v/checker/tests/if_match_expr.out +++ /dev/null @@ -1,35 +0,0 @@ -vlib/v/checker/tests/if_match_expr.vv:9:2: error: `if` expression branch has unsupported statement (`v.ast.Block`) - 7 | } else { - 8 | for {break} - 9 | {} - | ^ - 10 | match true {true {} else {}} // statement not expression - 11 | _ = match true {true {1} else {-1}} // OK -vlib/v/checker/tests/if_match_expr.vv:10:2: error: `if` expression branch has unsupported statement (`v.ast.MatchExpr`) - 8 | for {break} - 9 | {} - 10 | match true {true {} else {}} // statement not expression - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 11 | _ = match true {true {1} else {-1}} // OK - 12 | match true {true {1} else {-1}} // result -vlib/v/checker/tests/if_match_expr.vv:17:3: error: `match` expression branch has unsupported statement (`v.ast.IfExpr`) - 15 | _ = match true { - 16 | true { - 17 | if true {} // statement not expression - | ~~ - 18 | _ = if true {1} else {-1} // OK - 19 | if true {1} else {-1} // result -vlib/v/checker/tests/if_match_expr.vv:22:10: error: `match` expression branch has unsupported statement (`v.ast.AssertStmt`) - 20 | } - 21 | else { - 22 | assert true - | ~~~~ - 23 | match true {true {} else {}} // statement not expression - 24 | _ = match true {true {1} else {-1}} // OK -vlib/v/checker/tests/if_match_expr.vv:23:3: error: `match` expression branch has unsupported statement (`v.ast.MatchExpr`) - 21 | else { - 22 | assert true - 23 | match true {true {} else {}} // statement not expression - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 24 | _ = match true {true {1} else {-1}} // OK - 25 | match true {true {1} else {-1}} // result diff --git a/vlib/v/checker/tests/if_match_expr.vv b/vlib/v/checker/tests/if_match_expr.vv deleted file mode 100644 index 655f25afd2..0000000000 --- a/vlib/v/checker/tests/if_match_expr.vv +++ /dev/null @@ -1,27 +0,0 @@ -// only C expressions are allowed for each statement - -_ = if true { - if true {} // FIXME should error, if statement - _ = if true {1} else {-1} // OK - if true {1} else {-1} // result -} else { - for {break} - {} - match true {true {} else {}} // statement not expression - _ = match true {true {1} else {-1}} // OK - match true {true {1} else {-1}} // result -} - -_ = match true { - true { - if true {} // statement not expression - _ = if true {1} else {-1} // OK - if true {1} else {-1} // result - } - else { - assert true - match true {true {} else {}} // statement not expression - _ = match true {true {1} else {-1}} // OK - match true {true {1} else {-1}} // result - } -} diff --git a/vlib/v/tests/match_expr_with_non_last_if_expr_test.v b/vlib/v/tests/match_expr_with_non_last_if_expr_test.v new file mode 100644 index 0000000000..ea09dba3eb --- /dev/null +++ b/vlib/v/tests/match_expr_with_non_last_if_expr_test.v @@ -0,0 +1,20 @@ +fn test_match_expr_with_non_last_if_expr() { + out := match true { + true { + { + } + if true { + } else { + } + 'a' + } + else { + for { + break + } + 'b' + } + } + println(out) + assert out == 'a' +}