From a975ce285ba0104014bef8208b0bda8af3e6bac5 Mon Sep 17 00:00:00 2001 From: CreeperFace <165158232+dy-tea@users.noreply.github.com> Date: Sun, 7 Dec 2025 09:55:28 +0000 Subject: [PATCH] checker: match type when auto deref occurs (fix #25913) (#25916) --- vlib/v/checker/infix.v | 35 ++++++++++++++++--- .../tests/for_mut_compare_rune_string_err.out | 7 ++++ .../tests/for_mut_compare_rune_string_err.vv | 8 +++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 vlib/v/checker/tests/for_mut_compare_rune_string_err.out create mode 100644 vlib/v/checker/tests/for_mut_compare_rune_string_err.vv diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 45565d969..462f226d9 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -868,9 +868,26 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { right_type = c.unwrap_generic(right_type) right_sym = c.table.sym(right_type) } - if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type)) - && !c.pref.translated && !c.file.is_translated && !node.left.is_auto_deref_var() - && !node.right.is_auto_deref_var() { + types_match := c.symmetric_check(left_type, right_type) + && c.symmetric_check(right_type, left_type) + mut types_match_after_deref := false + mut deref_left_type := left_type + mut deref_right_type := right_type + if !types_match && (node.left.is_auto_deref_var() || node.right.is_auto_deref_var()) { + deref_left_type = if node.left.is_auto_deref_var() { + left_type.deref() + } else { + left_type + } + deref_right_type = if node.right.is_auto_deref_var() { + right_type.deref() + } else { + right_type + } + types_match_after_deref = c.symmetric_check(deref_left_type, deref_right_type) + && c.symmetric_check(deref_right_type, deref_left_type) + } + if !types_match && !types_match_after_deref && !c.pref.translated && !c.file.is_translated { // for type-unresolved consts if left_type == ast.void_type || right_type == ast.void_type { return ast.void_type @@ -883,7 +900,17 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if node.right is ast.None && left_is_option { return ast.bool_type } - c.error('infix expr: cannot use `${right_sym.name}` (right expression) as `${left_sym.name}`', + error_left_sym := if node.left.is_auto_deref_var() { + c.table.sym(deref_left_type) + } else { + left_sym + } + error_right_sym := if node.right.is_auto_deref_var() { + c.table.sym(deref_right_type) + } else { + right_sym + } + c.error('infix expr: cannot use `${error_right_sym.name}` (right expression) as `${error_left_sym.name}`', left_right_pos) } else if left_type.is_ptr() { for_ptr_op := c.table.type_is_for_pointer_arithmetic(left_type) diff --git a/vlib/v/checker/tests/for_mut_compare_rune_string_err.out b/vlib/v/checker/tests/for_mut_compare_rune_string_err.out new file mode 100644 index 000000000..55d8ad51c --- /dev/null +++ b/vlib/v/checker/tests/for_mut_compare_rune_string_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/for_mut_compare_rune_string_err.vv:4:6: error: infix expr: cannot use `string` (right expression) as `rune` + 2 | s := 'Hello, World!' + 3 | for mut c in s.runes() { + 4 | if c == ' ' { + | ~~~~~~~~ + 5 | c = `x` + 6 | } diff --git a/vlib/v/checker/tests/for_mut_compare_rune_string_err.vv b/vlib/v/checker/tests/for_mut_compare_rune_string_err.vv new file mode 100644 index 000000000..8e37f0bba --- /dev/null +++ b/vlib/v/checker/tests/for_mut_compare_rune_string_err.vv @@ -0,0 +1,8 @@ +fn main() { + s := 'Hello, World!' + for mut c in s.runes() { + if c == ' ' { + c = `x` + } + } +} -- 2.39.5