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)
|
expr_type := c.expr(stmt.expr)
|
||||||
if first_iteration {
|
if first_iteration {
|
||||||
if node.is_expr && (node.expected_type.has_flag(.optional)
|
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]) {
|
|| c.table.type_kind(node.expected_type) in [.sum_type, .multi_return]) {
|
||||||
ret_type = node.expected_type
|
ret_type = node.expected_type
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -116,7 +116,9 @@ mut:
|
||||||
inside_map_index bool
|
inside_map_index bool
|
||||||
inside_opt_data bool
|
inside_opt_data bool
|
||||||
inside_if_optional bool
|
inside_if_optional bool
|
||||||
|
inside_if_result bool
|
||||||
inside_match_optional bool
|
inside_match_optional bool
|
||||||
|
inside_match_result bool
|
||||||
inside_vweb_tmpl bool
|
inside_vweb_tmpl bool
|
||||||
inside_return bool
|
inside_return bool
|
||||||
inside_struct_init 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));')
|
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 {
|
} else {
|
||||||
g.set_current_pos_as_last_stmt_pos()
|
g.set_current_pos_as_last_stmt_pos()
|
||||||
g.skip_stmt_pos = true
|
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 {
|
} else {
|
||||||
g.stmt(stmt)
|
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(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1796,7 +1822,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
// g.autofree_call_postgen()
|
// g.autofree_call_postgen()
|
||||||
// }
|
// }
|
||||||
if g.inside_ternary == 0 && !g.inside_if_optional && !g.inside_match_optional
|
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 {
|
if node.expr is ast.MatchExpr {
|
||||||
g.writeln('')
|
g.writeln('')
|
||||||
} else {
|
} 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 {
|
if g.table.type_kind(node.return_type) == .sum_type {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if node.return_type.has_flag(.optional) {
|
if node.return_type.has_flag(.optional) || node.return_type.has_flag(.result) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if sym.kind == .multi_return {
|
if sym.kind == .multi_return {
|
||||||
|
@ -52,12 +52,20 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
|
||||||
if is_expr && !need_tmp_var {
|
if is_expr && !need_tmp_var {
|
||||||
g.inside_ternary++
|
g.inside_ternary++
|
||||||
}
|
}
|
||||||
if is_expr && node.return_type.has_flag(.optional) {
|
if is_expr {
|
||||||
|
if node.return_type.has_flag(.optional) {
|
||||||
old := g.inside_match_optional
|
old := g.inside_match_optional
|
||||||
defer {
|
defer {
|
||||||
g.inside_match_optional = old
|
g.inside_match_optional = old
|
||||||
}
|
}
|
||||||
g.inside_match_optional = true
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral] {
|
if node.cond in [ast.Ident, ast.SelectorExpr, ast.IntegerLiteral, ast.StringLiteral, ast.FloatLiteral] {
|
||||||
cond_var = g.expr_string(node.cond)
|
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