From 87855990943cf01a070a78300968a3ff87b76126 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 29 May 2021 15:00:12 +0800 Subject: [PATCH] checker, cgen: fix optional with if expr (#10242) --- vlib/v/checker/checker.v | 11 +++++++++++ vlib/v/gen/c/cgen.v | 2 +- vlib/v/tests/option_if_expr_test.v | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/option_if_expr_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b0f0f8f581..8893835fdf 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5816,6 +5816,17 @@ pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type { pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { if_kind := if node.is_comptime { '\$if' } else { 'if' } + mut node_is_expr := false + if node.branches.len > 0 && node.has_else { + stmts := node.branches[0].stmts + if stmts.len > 0 && stmts[stmts.len - 1] is ast.ExprStmt + && (stmts[stmts.len - 1] as ast.ExprStmt).typ != ast.void_type { + node_is_expr = true + } + } + if c.expected_type == ast.void_type && node_is_expr { + c.expected_type = c.expected_or_type + } expr_required := c.expected_type != ast.void_type former_expected_type := c.expected_type node.typ = ast.void_type diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 76ceceeb5c..7ab40c2734 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5877,7 +5877,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty g.inside_opt_data = true g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_flag(.optional)) g.inside_opt_data = old_inside_opt_data - if g.inside_ternary == 0 && !(expr_stmt.expr is ast.IfExpr) { + if g.inside_ternary == 0 { g.writeln(';') } g.stmt_path_pos.delete_last() diff --git a/vlib/v/tests/option_if_expr_test.v b/vlib/v/tests/option_if_expr_test.v new file mode 100644 index 0000000000..cc4be3b1eb --- /dev/null +++ b/vlib/v/tests/option_if_expr_test.v @@ -0,0 +1,16 @@ +fn f() ?int { + return none +} + +fn test_option_if_expr() { + i := f() or { + if err is none { + int(0) + } else { + eprintln(err) + int(-1) + } + } + println(i) + assert i == 0 +}