From 5e98ea12c827ae23f6a25993c7bfc6669cbb19e8 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 17 Apr 2022 13:19:44 +0800 Subject: [PATCH] checker, cgen: fix error for if expr with generic sumtype (#14056) --- vlib/v/checker/if.v | 1 + vlib/v/gen/c/if.v | 8 +++++++- .../v/tests/if_expr_with_generic_sumtype_test.v | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/if_expr_with_generic_sumtype_test.v diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index f50fa265af..142d27ca62 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -204,6 +204,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } if node.is_expr && c.table.sym(former_expected_type).kind == .sum_type { + node.typ = former_expected_type continue } if is_noreturn_callexpr(last_expr.expr) { diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index bf1c31ca57..3b730b8a8c 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -74,7 +74,12 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { g.expr(branch.cond) g.write(' ? ') } + prev_expected_cast_type := g.expected_cast_type + if node.is_expr && g.table.sym(node.typ).kind == .sum_type { + g.expected_cast_type = node.typ + } g.stmts(branch.stmts) + g.expected_cast_type = prev_expected_cast_type } if node.branches.len == 1 { g.write(': 0') @@ -195,11 +200,12 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { } } if needs_tmp_var { + prev_expected_cast_type := g.expected_cast_type if node.is_expr && g.table.sym(node.typ).kind == .sum_type { g.expected_cast_type = node.typ } g.stmts_with_tmp_var(branch.stmts, tmp) - g.expected_cast_type = 0 + g.expected_cast_type = prev_expected_cast_type } else { // restore if_expr stmt header pos stmt_pos := g.nth_stmt_pos(0) diff --git a/vlib/v/tests/if_expr_with_generic_sumtype_test.v b/vlib/v/tests/if_expr_with_generic_sumtype_test.v new file mode 100644 index 0000000000..cd4677b598 --- /dev/null +++ b/vlib/v/tests/if_expr_with_generic_sumtype_test.v @@ -0,0 +1,17 @@ +type Opt = None | Some + +struct None {} + +struct Some { +mut: + value T +} + +fn operation(r int) Opt { + return if r > 0 { Some{r} } else { None{} } +} + +fn test_if_expr_with_generic_sumtype() { + op := operation(1) + assert Opt(Some{1}) == op +}