mirror of
https://github.com/vlang/v.git
synced 2025-09-10 16:00:31 -04:00
checker: fix match expr with non last if expr (#15500)
This commit is contained in:
parent
98c6dad887
commit
196b5f8e3a
@ -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
|
// CTempVar is used in cgen only, to hold nodes for temporary variables
|
||||||
pub struct CTempVar {
|
pub struct CTempVar {
|
||||||
pub:
|
pub:
|
||||||
|
@ -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',
|
c.error('`$if_kind` expression requires an expression as the last statement of every branch',
|
||||||
branch.pos)
|
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 {
|
if mut branch.cond is ast.IfGuardExpr {
|
||||||
sym := c.table.sym(branch.cond.expr_type)
|
sym := c.table.sym(branch.cond.expr_type)
|
||||||
|
@ -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_mut_pos = token.Pos{}
|
||||||
c.smartcast_cond_pos = token.Pos{}
|
c.smartcast_cond_pos = token.Pos{}
|
||||||
if node.is_expr {
|
if node.is_expr {
|
||||||
if branch.stmts.len > 0 {
|
if branch.stmts.len == 0 && ret_type != ast.void_type {
|
||||||
// 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 {
|
|
||||||
c.error('`match` expression requires an expression as the last statement of every branch',
|
c.error('`match` expression requires an expression as the last statement of every branch',
|
||||||
branch.branch_pos)
|
branch.branch_pos)
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
20
vlib/v/tests/match_expr_with_non_last_if_expr_test.v
Normal file
20
vlib/v/tests/match_expr_with_non_last_if_expr_test.v
Normal 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'
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user