Skip to content

Commit d83e17c

Browse files
committed
checker: match type when auto deref occurs
1 parent ecd0018 commit d83e17c

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

vlib/v/checker/infix.v

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -868,9 +868,26 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
868868
right_type = c.unwrap_generic(right_type)
869869
right_sym = c.table.sym(right_type)
870870
}
871-
if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type))
872-
&& !c.pref.translated && !c.file.is_translated && !node.left.is_auto_deref_var()
873-
&& !node.right.is_auto_deref_var() {
871+
types_match := c.symmetric_check(left_type, right_type)
872+
&& c.symmetric_check(right_type, left_type)
873+
mut types_match_after_deref := false
874+
mut deref_left_type := left_type
875+
mut deref_right_type := right_type
876+
if !types_match && (node.left.is_auto_deref_var() || node.right.is_auto_deref_var()) {
877+
deref_left_type = if node.left.is_auto_deref_var() {
878+
left_type.deref()
879+
} else {
880+
left_type
881+
}
882+
deref_right_type = if node.right.is_auto_deref_var() {
883+
right_type.deref()
884+
} else {
885+
right_type
886+
}
887+
types_match_after_deref = c.symmetric_check(deref_left_type, deref_right_type)
888+
&& c.symmetric_check(deref_right_type, deref_left_type)
889+
}
890+
if !types_match && !types_match_after_deref && !c.pref.translated && !c.file.is_translated {
874891
// for type-unresolved consts
875892
if left_type == ast.void_type || right_type == ast.void_type {
876893
return ast.void_type
@@ -883,7 +900,17 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
883900
if node.right is ast.None && left_is_option {
884901
return ast.bool_type
885902
}
886-
c.error('infix expr: cannot use `${right_sym.name}` (right expression) as `${left_sym.name}`',
903+
error_left_sym := if node.left.is_auto_deref_var() {
904+
c.table.sym(deref_left_type)
905+
} else {
906+
left_sym
907+
}
908+
error_right_sym := if node.right.is_auto_deref_var() {
909+
c.table.sym(deref_right_type)
910+
} else {
911+
right_sym
912+
}
913+
c.error('infix expr: cannot use `${error_right_sym.name}` (right expression) as `${error_left_sym.name}`',
887914
left_right_pos)
888915
} else if left_type.is_ptr() {
889916
for_ptr_op := c.table.type_is_for_pointer_arithmetic(left_type)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/checker/tests/for_mut_compare_rune_string_err.vv:4:6: error: infix expr: cannot use `string` (right expression) as `rune`
2+
2 | s := 'Hello, World!'
3+
3 | for mut c in s.runes() {
4+
4 | if c == ' ' {
5+
| ~~~~~~~~
6+
5 | c = `x`
7+
6 | }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
s := 'Hello, World!'
3+
for mut c in s.runes() {
4+
if c == ' ' {
5+
c = `x`
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)