1
0
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:
yuyi 2022-09-09 02:24:16 +08:00 committed by GitHub
parent 1738641567
commit ec2ca38adb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 8 deletions

View File

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

View File

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

View File

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

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