mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker, cgen: fix match expr with result (#15706)
This commit is contained in:
parent
1738641567
commit
ec2ca38adb
@ -61,6 +61,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
||||
expr_type := c.expr(stmt.expr)
|
||||
if first_iteration {
|
||||
if node.is_expr && (node.expected_type.has_flag(.optional)
|
||||
|| node.expected_type.has_flag(.result)
|
||||
|| c.table.type_kind(node.expected_type) in [.sum_type, .multi_return]) {
|
||||
ret_type = node.expected_type
|
||||
} else {
|
||||
|
@ -116,7 +116,9 @@ mut:
|
||||
inside_map_index bool
|
||||
inside_opt_data bool
|
||||
inside_if_optional bool
|
||||
inside_if_result bool
|
||||
inside_match_optional bool
|
||||
inside_match_result bool
|
||||
inside_vweb_tmpl bool
|
||||
inside_return bool
|
||||
inside_struct_init bool
|
||||
@ -1592,6 +1594,29 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
|
||||
g.writeln(' }, ($c.option_name*)(&$tmp_var), sizeof($styp));')
|
||||
}
|
||||
}
|
||||
} else if g.inside_if_result || g.inside_match_result {
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
g.skip_stmt_pos = true
|
||||
if stmt is ast.ExprStmt {
|
||||
if stmt.typ == ast.error_type_idx {
|
||||
g.writeln('${tmp_var}.is_error = true;')
|
||||
g.write('${tmp_var}.err = ')
|
||||
g.expr(stmt.expr)
|
||||
g.writeln(';')
|
||||
} else {
|
||||
mut styp := g.base_type(stmt.typ)
|
||||
$if tinyc && x32 && windows {
|
||||
if stmt.typ == ast.int_literal_type {
|
||||
styp = 'int'
|
||||
} else if stmt.typ == ast.float_literal_type {
|
||||
styp = 'f64'
|
||||
}
|
||||
}
|
||||
g.write('opt_ok2(&($styp[]) { ')
|
||||
g.stmt(stmt)
|
||||
g.writeln(' }, ($c.result_name*)(&$tmp_var), sizeof($styp));')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
g.set_current_pos_as_last_stmt_pos()
|
||||
g.skip_stmt_pos = true
|
||||
@ -1609,7 +1634,8 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
|
||||
}
|
||||
} else {
|
||||
g.stmt(stmt)
|
||||
if (g.inside_if_optional || g.inside_match_optional) && stmt is ast.ExprStmt {
|
||||
if (g.inside_if_optional || g.inside_if_result || g.inside_match_optional
|
||||
|| g.inside_match_result) && stmt is ast.ExprStmt {
|
||||
g.writeln(';')
|
||||
}
|
||||
}
|
||||
@ -1796,7 +1822,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
// g.autofree_call_postgen()
|
||||
// }
|
||||
if g.inside_ternary == 0 && !g.inside_if_optional && !g.inside_match_optional
|
||||
&& !node.is_expr && node.expr !is ast.IfExpr {
|
||||
&& !g.inside_if_result && !g.inside_match_result && !node.is_expr
|
||||
&& node.expr !is ast.IfExpr {
|
||||
if node.expr is ast.MatchExpr {
|
||||
g.writeln('')
|
||||
} else {
|
||||
|
@ -12,7 +12,7 @@ fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool {
|
||||
if g.table.type_kind(node.return_type) == .sum_type {
|
||||
return true
|
||||
}
|
||||
if node.return_type.has_flag(.optional) {
|
||||
if node.return_type.has_flag(.optional) || node.return_type.has_flag(.result) {
|
||||
return true
|
||||
}
|
||||
if sym.kind == .multi_return {
|
||||
@ -52,12 +52,20 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
|
||||
if is_expr && !need_tmp_var {
|
||||
g.inside_ternary++
|
||||
}
|
||||
if is_expr && node.return_type.has_flag(.optional) {
|
||||
old := g.inside_match_optional
|
||||
defer {
|
||||
g.inside_match_optional = old
|
||||
if is_expr {
|
||||
if node.return_type.has_flag(.optional) {
|
||||
old := g.inside_match_optional
|
||||
defer {
|
||||
g.inside_match_optional = old
|
||||
}
|
||||
g.inside_match_optional = true
|
||||
} else if node.return_type.has_flag(.result) {
|
||||
old := g.inside_match_result
|
||||
defer {
|
||||
g.inside_match_result = old
|
||||
}
|
||||
g.inside_match_result = true
|
||||
}
|
||||
g.inside_match_optional = true
|
||||
}
|
||||
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral] {
|
||||
cond_var = g.expr_string(node.cond)
|
||||
|
23
vlib/v/tests/match_expr_with_result_test.v
Normal file
23
vlib/v/tests/match_expr_with_result_test.v
Normal file
@ -0,0 +1,23 @@
|
||||
fn foo(i int) ?bool {
|
||||
return match true {
|
||||
i == 0 { true }
|
||||
else { none }
|
||||
}
|
||||
}
|
||||
|
||||
fn bar(i int) !bool {
|
||||
return match true {
|
||||
i == 0 { true }
|
||||
else { error('') }
|
||||
}
|
||||
}
|
||||
|
||||
fn test_match_expr_with_result() {
|
||||
r1 := foo(0) or { false }
|
||||
println(r1)
|
||||
assert r1
|
||||
|
||||
r2 := bar(0) or { false }
|
||||
println(r2)
|
||||
assert r2
|
||||
}
|
Loading…
Reference in New Issue
Block a user