From ff3b50eee885449b9fb7b9fe5cb752a2061233ec Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 12 Oct 2024 08:38:32 -0300 Subject: [PATCH 1/2] fix --- vlib/v/checker/if.v | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 08de2bce35f266..13b3aa0294c173 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -363,7 +363,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } else { // smartcast sumtypes and interfaces when using `is` - c.smartcast_if_conds(mut branch.cond, mut branch.scope) + c.smartcast_if_conds(mut branch.cond, mut branch.scope, node) if node_is_expr { c.stmts_ending_with_expression(mut branch.stmts, c.expected_or_type) } else { @@ -535,11 +535,11 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { return node.typ } -fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope) { +fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope, control_expr ast.Expr) { if mut node is ast.InfixExpr { if node.op == .and { - c.smartcast_if_conds(mut node.left, mut scope) - c.smartcast_if_conds(mut node.right, mut scope) + c.smartcast_if_conds(mut node.left, mut scope, control_expr) + c.smartcast_if_conds(mut node.right, mut scope, control_expr) } else if node.left is ast.Ident && node.op == .ne && node.right is ast.None { if node.left is ast.Ident && c.comptime.get_ct_type_var(node.left) == .smartcast { node.left_type = c.comptime.get_comptime_var_type(node.left) @@ -624,7 +624,26 @@ fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope) { } } } else if mut node is ast.Likely { - c.smartcast_if_conds(mut node.expr, mut scope) + c.smartcast_if_conds(mut node.expr, mut scope, control_expr) + } else if control_expr is ast.IfExpr && mut node is ast.NodeError { // IfExpr else branch + if control_expr.branches.len != 2 { + return + } + mut first_cond := control_expr.branches[0].cond + // handles unwrapping on if var == none { /**/ } else { /*unwrapped var*/ } + if mut first_cond is ast.InfixExpr { + if first_cond.left is ast.Ident && first_cond.op == .eq && first_cond.right is ast.None { + if first_cond.left is ast.Ident + && c.comptime.get_ct_type_var(first_cond.left) == .smartcast { + first_cond.left_type = c.comptime.get_comptime_var_type(first_cond.left) + c.smartcast(mut first_cond.left, first_cond.left_type, first_cond.left_type.clear_flag(.option), mut + scope, true) + } else { + c.smartcast(mut first_cond.left, first_cond.left_type, first_cond.left_type.clear_flag(.option), mut + scope, false) + } + } + } } } From 4c4e20994a5c4d248d15ee98255931502e8f02e5 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 12 Oct 2024 08:52:03 -0300 Subject: [PATCH 2/2] test --- .../tests/options/option_unwrap_ifexpr_test.v | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 vlib/v/tests/options/option_unwrap_ifexpr_test.v diff --git a/vlib/v/tests/options/option_unwrap_ifexpr_test.v b/vlib/v/tests/options/option_unwrap_ifexpr_test.v new file mode 100644 index 00000000000000..267f67c23c5121 --- /dev/null +++ b/vlib/v/tests/options/option_unwrap_ifexpr_test.v @@ -0,0 +1,28 @@ +type TestSmart = ?string | int + +fn test_simple_case() { + o := ?string('abc') + dump(o) + a := if o == none { + 'none' + } else { + '${o} exists' + } + dump(a) + assert a == 'abc exists' +} + +fn test_comptime_smartcast() { + t := TestSmart(?string('foobar')) + $for v in TestSmart.variants { + if t is v { + $if t is ?string { + if t == none { + panic('error') + } else { + assert t == 'foobar' + } + } + } + } +}