1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: fix match expr with non last if expr (#15500)

This commit is contained in:
yuyi 2022-08-23 12:58:33 +08:00 committed by GitHub
parent 98c6dad887
commit 196b5f8e3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 21 additions and 98 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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'
}