Skip to content

Commit ec2ca38

Browse files
authored
checker, cgen: fix match expr with result (#15706)
1 parent 1738641 commit ec2ca38

File tree

4 files changed

+67
-8
lines changed

4 files changed

+67
-8
lines changed

vlib/v/checker/match.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
6161
expr_type := c.expr(stmt.expr)
6262
if first_iteration {
6363
if node.is_expr && (node.expected_type.has_flag(.optional)
64+
|| node.expected_type.has_flag(.result)
6465
|| c.table.type_kind(node.expected_type) in [.sum_type, .multi_return]) {
6566
ret_type = node.expected_type
6667
} else {

vlib/v/gen/c/cgen.v

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ mut:
116116
inside_map_index bool
117117
inside_opt_data bool
118118
inside_if_optional bool
119+
inside_if_result bool
119120
inside_match_optional bool
121+
inside_match_result bool
120122
inside_vweb_tmpl bool
121123
inside_return bool
122124
inside_struct_init bool
@@ -1592,6 +1594,29 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
15921594
g.writeln(' }, ($c.option_name*)(&$tmp_var), sizeof($styp));')
15931595
}
15941596
}
1597+
} else if g.inside_if_result || g.inside_match_result {
1598+
g.set_current_pos_as_last_stmt_pos()
1599+
g.skip_stmt_pos = true
1600+
if stmt is ast.ExprStmt {
1601+
if stmt.typ == ast.error_type_idx {
1602+
g.writeln('${tmp_var}.is_error = true;')
1603+
g.write('${tmp_var}.err = ')
1604+
g.expr(stmt.expr)
1605+
g.writeln(';')
1606+
} else {
1607+
mut styp := g.base_type(stmt.typ)
1608+
$if tinyc && x32 && windows {
1609+
if stmt.typ == ast.int_literal_type {
1610+
styp = 'int'
1611+
} else if stmt.typ == ast.float_literal_type {
1612+
styp = 'f64'
1613+
}
1614+
}
1615+
g.write('opt_ok2(&($styp[]) { ')
1616+
g.stmt(stmt)
1617+
g.writeln(' }, ($c.result_name*)(&$tmp_var), sizeof($styp));')
1618+
}
1619+
}
15951620
} else {
15961621
g.set_current_pos_as_last_stmt_pos()
15971622
g.skip_stmt_pos = true
@@ -1609,7 +1634,8 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
16091634
}
16101635
} else {
16111636
g.stmt(stmt)
1612-
if (g.inside_if_optional || g.inside_match_optional) && stmt is ast.ExprStmt {
1637+
if (g.inside_if_optional || g.inside_if_result || g.inside_match_optional
1638+
|| g.inside_match_result) && stmt is ast.ExprStmt {
16131639
g.writeln(';')
16141640
}
16151641
}
@@ -1796,7 +1822,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
17961822
// g.autofree_call_postgen()
17971823
// }
17981824
if g.inside_ternary == 0 && !g.inside_if_optional && !g.inside_match_optional
1799-
&& !node.is_expr && node.expr !is ast.IfExpr {
1825+
&& !g.inside_if_result && !g.inside_match_result && !node.is_expr
1826+
&& node.expr !is ast.IfExpr {
18001827
if node.expr is ast.MatchExpr {
18011828
g.writeln('')
18021829
} else {

vlib/v/gen/c/match.v

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool {
1212
if g.table.type_kind(node.return_type) == .sum_type {
1313
return true
1414
}
15-
if node.return_type.has_flag(.optional) {
15+
if node.return_type.has_flag(.optional) || node.return_type.has_flag(.result) {
1616
return true
1717
}
1818
if sym.kind == .multi_return {
@@ -52,12 +52,20 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
5252
if is_expr && !need_tmp_var {
5353
g.inside_ternary++
5454
}
55-
if is_expr && node.return_type.has_flag(.optional) {
56-
old := g.inside_match_optional
57-
defer {
58-
g.inside_match_optional = old
55+
if is_expr {
56+
if node.return_type.has_flag(.optional) {
57+
old := g.inside_match_optional
58+
defer {
59+
g.inside_match_optional = old
60+
}
61+
g.inside_match_optional = true
62+
} else if node.return_type.has_flag(.result) {
63+
old := g.inside_match_result
64+
defer {
65+
g.inside_match_result = old
66+
}
67+
g.inside_match_result = true
5968
}
60-
g.inside_match_optional = true
6169
}
6270
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral] {
6371
cond_var = g.expr_string(node.cond)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
fn foo(i int) ?bool {
2+
return match true {
3+
i == 0 { true }
4+
else { none }
5+
}
6+
}
7+
8+
fn bar(i int) !bool {
9+
return match true {
10+
i == 0 { true }
11+
else { error('') }
12+
}
13+
}
14+
15+
fn test_match_expr_with_result() {
16+
r1 := foo(0) or { false }
17+
println(r1)
18+
assert r1
19+
20+
r2 := bar(0) or { false }
21+
println(r2)
22+
assert r2
23+
}

0 commit comments

Comments
 (0)