From 0f3a395ca2849eeb63c7dc6cb3ec6ddcbe255229 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 9 Sep 2022 16:29:21 +0800 Subject: [PATCH] checker, cgen: fix if expr with result (#15709) --- vlib/v/checker/if.v | 2 +- vlib/v/gen/c/if.v | 6 +++++- vlib/v/tests/if_expr_with_result_test.v | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/if_expr_with_result_test.v diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index d36437bf4e1503..2af8b14868a9f5 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -188,7 +188,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } c.expected_type = former_expected_type - if c.expected_type.has_flag(.optional) { + if c.expected_type.has_flag(.optional) || c.expected_type.has_flag(.result) { if node.typ == ast.void_type { node.is_expr = true node.typ = c.expected_type diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index 6a05c72ed8bd91..9b2136901464cb 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -7,7 +7,7 @@ import v.ast fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool { if node.is_expr && g.inside_ternary == 0 { - if g.is_autofree || node.typ.has_flag(.optional) { + if g.is_autofree || node.typ.has_flag(.optional) || node.typ.has_flag(.result) { return true } for branch in node.branches { @@ -142,6 +142,8 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { if needs_tmp_var { if node.typ.has_flag(.optional) { g.inside_if_optional = true + } else if node.typ.has_flag(.result) { + g.inside_if_result = true } styp := g.typ(node.typ) cur_line = g.go_before_stmt(0) @@ -325,5 +327,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { } if node.typ.has_flag(.optional) { g.inside_if_optional = false + } else if node.typ.has_flag(.result) { + g.inside_if_result = false } } diff --git a/vlib/v/tests/if_expr_with_result_test.v b/vlib/v/tests/if_expr_with_result_test.v new file mode 100644 index 00000000000000..83eaddbb2606f9 --- /dev/null +++ b/vlib/v/tests/if_expr_with_result_test.v @@ -0,0 +1,17 @@ +fn foo(i int) ?bool { + return if i == 0 { true } else { none } +} + +fn bar(i int) !bool { + return if i == 0 { true } else { error('') } +} + +fn test_if_expr_with_result() { + r1 := foo(0) or { false } + println(r1) + assert r1 + + r2 := bar(0) or { false } + println(r2) + assert r2 +}