From 73caa8dff5ff82eb4589f3c27e7e0b5cd3fd9b35 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 14 Feb 2024 18:22:55 -0300 Subject: [PATCH] checker: fix if branch option type mismatch (fix #20809) (#20830) --- vlib/v/checker/if.v | 15 ++++++++++++--- vlib/v/checker/tests/if_mismatch_option_err.out | 12 ++++++++++++ vlib/v/checker/tests/if_mismatch_option_err.vv | 9 +++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 vlib/v/checker/tests/if_mismatch_option_err.out create mode 100644 vlib/v/checker/tests/if_mismatch_option_err.vv diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index af48f98f1..56a90d9a0 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -467,10 +467,19 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { node.pos) } else { if c.inside_assign && node.is_expr && !node.typ.has_flag(.shared_f) - && stmt.typ.is_ptr() != node.typ.is_ptr() && stmt.typ != ast.voidptr_type { - c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(stmt.typ)}`', - node.pos) + if stmt.typ.is_ptr() != node.typ.is_ptr() { + c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(stmt.typ)}`', + node.pos) + } else if stmt.typ != ast.none_type { + if !node.typ.has_flag(.option) && stmt.typ.has_flag(.option) { + c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(stmt.typ)}`', + node.pos) + } else if !node.typ.has_flag(.result) && stmt.typ.has_flag(.result) { + c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(stmt.typ)}`', + node.pos) + } + } } } } else if !node.is_comptime && stmt !in [ast.Return, ast.BranchStmt] { diff --git a/vlib/v/checker/tests/if_mismatch_option_err.out b/vlib/v/checker/tests/if_mismatch_option_err.out new file mode 100644 index 000000000..00ea6a176 --- /dev/null +++ b/vlib/v/checker/tests/if_mismatch_option_err.out @@ -0,0 +1,12 @@ +vlib/v/checker/tests/if_mismatch_option_err.vv:8:2: warning: unused variable: `operation` + 6 | fn main() { + 7 | operation_name := 'get_area' + 8 | operation := if o := Operation.from(operation_name) { o } else { ?Operation(none) } + | ~~~~~~~~~ + 9 | } +vlib/v/checker/tests/if_mismatch_option_err.vv:8:15: error: mismatched types `Operation` and `?Operation` + 6 | fn main() { + 7 | operation_name := 'get_area' + 8 | operation := if o := Operation.from(operation_name) { o } else { ?Operation(none) } + | ~~ + 9 | } diff --git a/vlib/v/checker/tests/if_mismatch_option_err.vv b/vlib/v/checker/tests/if_mismatch_option_err.vv new file mode 100644 index 000000000..58f177eb2 --- /dev/null +++ b/vlib/v/checker/tests/if_mismatch_option_err.vv @@ -0,0 +1,9 @@ +enum Operation { + get_area + get_sector +} + +fn main() { + operation_name := 'get_area' + operation := if o := Operation.from(operation_name) { o } else { ?Operation(none) } +} \ No newline at end of file -- 2.39.5