From 0afb41f7e1b66387918f6ef8f5c90231a14280da Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 22 Mar 2023 19:49:02 -0300 Subject: [PATCH] checker: fix missing type mismatch with ptr types (#17695) --- vlib/v/checker/assign.v | 3 +++ vlib/v/checker/checker.v | 1 + vlib/v/checker/if.v | 7 +++++++ vlib/v/checker/tests/if_diff_expected_type_err.out | 7 +++++++ vlib/v/checker/tests/if_diff_expected_type_err.vv | 9 +++++++++ 5 files changed, 27 insertions(+) create mode 100644 vlib/v/checker/tests/if_diff_expected_type_err.out create mode 100644 vlib/v/checker/tests/if_diff_expected_type_err.vv diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 336540de37..ed1b865d90 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -7,9 +7,12 @@ import v.pref // TODO 600 line function fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { + prev_inside_assign := c.inside_assign + c.inside_assign = true c.expected_type = ast.none_type // TODO a hack to make `x := if ... work` defer { c.expected_type = ast.void_type + c.inside_assign = prev_inside_assign } is_decl := node.op == .decl_assign right_first := node.right[0] diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 06bb7b3012..61a34a52cc 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -113,6 +113,7 @@ mut: inside_println_arg bool inside_decl_rhs bool inside_if_guard bool // true inside the guard condition of `if x := opt() {}` + inside_assign bool is_index_assign bool comptime_call_pos int // needed for correctly checking use before decl for templates goto_labels map[string]ast.GotoLabel // to check for unused goto labels diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 6049186248..8fdb52a91d 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -319,6 +319,13 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(stmt.typ)}`', 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) + } } } else if !node.is_comptime { c.error('`${if_kind}` expression requires an expression as the last statement of every branch', diff --git a/vlib/v/checker/tests/if_diff_expected_type_err.out b/vlib/v/checker/tests/if_diff_expected_type_err.out new file mode 100644 index 0000000000..54ade22fdb --- /dev/null +++ b/vlib/v/checker/tests/if_diff_expected_type_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/if_diff_expected_type_err.vv:7:11: error: mismatched types `&[]rune` and `[]rune` + 5 | + 6 | fn main() { + 7 | runes := if true { &some_runes } else { some_other_runes } + | ~~ + 8 | println(runes) + 9 | } diff --git a/vlib/v/checker/tests/if_diff_expected_type_err.vv b/vlib/v/checker/tests/if_diff_expected_type_err.vv new file mode 100644 index 0000000000..963e46bcb9 --- /dev/null +++ b/vlib/v/checker/tests/if_diff_expected_type_err.vv @@ -0,0 +1,9 @@ +const ( + some_runes = [`a`, `b`, `c`] + some_other_runes = [`c`, `b`, `a`] +) + +fn main() { + runes := if true { &some_runes } else { some_other_runes } + println(runes) +} \ No newline at end of file