mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
checker, cgen: fix the comparison of alias and non-alias values (#19112)
This commit is contained in:
parent
8714119590
commit
4355be8ef2
7 changed files with 42 additions and 111 deletions
|
@ -147,14 +147,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||||
match node.op {
|
match node.op {
|
||||||
// .eq, .ne, .gt, .lt, .ge, .le, .and, .logical_or, .dot, .key_as, .right_shift {}
|
// .eq, .ne, .gt, .lt, .ge, .le, .and, .logical_or, .dot, .key_as, .right_shift {}
|
||||||
.eq, .ne {
|
.eq, .ne {
|
||||||
is_mismatch :=
|
if left_type in ast.integer_type_idxs && right_type in ast.integer_type_idxs {
|
||||||
(left_sym.kind == .alias && right_sym.kind in [.struct_, .array, .sum_type])
|
|
||||||
|| (right_sym.kind == .alias && left_sym.kind in [.struct_, .array, .sum_type])
|
|
||||||
if is_mismatch {
|
|
||||||
c.add_error_detail('left type: `${c.table.type_to_str(left_type)}` vs right type: `${c.table.type_to_str(right_type)}`')
|
|
||||||
c.error('possible type mismatch of compared values of `${node.op}` operation',
|
|
||||||
left_right_pos)
|
|
||||||
} else if left_type in ast.integer_type_idxs && right_type in ast.integer_type_idxs {
|
|
||||||
is_left_type_signed := left_type in ast.signed_integer_type_idxs
|
is_left_type_signed := left_type in ast.signed_integer_type_idxs
|
||||||
is_right_type_signed := right_type in ast.signed_integer_type_idxs
|
is_right_type_signed := right_type in ast.signed_integer_type_idxs
|
||||||
if !is_left_type_signed && mut node.right is ast.IntegerLiteral {
|
if !is_left_type_signed && mut node.right is ast.IntegerLiteral {
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
vlib/v/checker/tests/alias_array_possible_type_mismatch.vv:11:7: error: possible type mismatch of compared values of `==` operation
|
|
||||||
9 | mut a := new_vector(12, 4.5, 6.7, 6)
|
|
||||||
10 | dump(a)
|
|
||||||
11 | x := a == []f64{}
|
|
||||||
| ~~~~~~~~~~~
|
|
||||||
12 | dump(x)
|
|
||||||
13 | }
|
|
||||||
Details: left type: `main.Vector` vs right type: `[]f64`
|
|
|
@ -1,13 +0,0 @@
|
||||||
type Vector = []f64
|
|
||||||
type Another = []f64
|
|
||||||
|
|
||||||
fn new_vector(x f64, y f64, z f64, w f64) Vector {
|
|
||||||
return Vector([x, y, z, w])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_alias_array_plus_overload() {
|
|
||||||
mut a := new_vector(12, 4.5, 6.7, 6)
|
|
||||||
dump(a)
|
|
||||||
x := a == []f64{}
|
|
||||||
dump(x)
|
|
||||||
}
|
|
|
@ -1,8 +1,7 @@
|
||||||
vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv:12:7: error: possible type mismatch of compared values of `==` operation
|
vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv:12:7: error: infix expr: cannot use `v.ast.Type` (right expression) as `v.ast.TypeSymbol`
|
||||||
10 | x := ityp == ast.string_type
|
10 | x := ityp == ast.string_type
|
||||||
11 | // the next line should produce at least a warning, or even an error, without an explicit cast:
|
11 | // the next line should produce at least a warning, or even an error, without an explicit cast:
|
||||||
12 | z := isym == ast.string_type
|
12 | z := isym == ast.string_type
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
13 | println(typeof(isym).name)
|
13 | println(typeof(isym).name)
|
||||||
14 | println(typeof(ast.string_type).name)
|
14 | println(typeof(ast.string_type).name)
|
||||||
Details: left type: `&ast.TypeSymbol` vs right type: `ast.Type`
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:12:10: error: infix expr: cannot use `int literal` (right expression) as `Aaa`
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:12:10: error: infix expr: cannot use `int literal` (right expression) as `Aaa`
|
||||||
10 |
|
10 |
|
||||||
11 | fn main() {
|
11 | fn main() {
|
||||||
12 | println(Aaa{} == 10)
|
12 | println(Aaa{} == 10)
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~~~~~~~
|
||||||
|
@ -24,113 +24,45 @@ vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:15:10: error: infix expr: cannot
|
||||||
14 | println(Aaa{} != 10)
|
14 | println(Aaa{} != 10)
|
||||||
15 | println(10 != Aaa{})
|
15 | println(10 != Aaa{})
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~~~~~~~
|
||||||
16 |
|
16 |
|
||||||
17 | println(Aaa{0} == AAaa{0})
|
17 | println(Aaa{0} == AAaa{0})
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:17:10: error: possible type mismatch of compared values of `==` operation
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:29:10: error: infix expr: cannot use `Arr` (right expression) as `ArrAaa`
|
||||||
15 | println(10 != Aaa{})
|
|
||||||
16 |
|
|
||||||
17 | println(Aaa{0} == AAaa{0})
|
|
||||||
| ~~~~~~~~~~~~~~~~~
|
|
||||||
18 | println(AAaa{0} == Aaa{0})
|
|
||||||
19 | println(AAaa{1} != Aaa{1})
|
|
||||||
Details: left type: `main.Aaa` vs right type: `main.AAaa`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:18:10: error: possible type mismatch of compared values of `==` operation
|
|
||||||
16 |
|
|
||||||
17 | println(Aaa{0} == AAaa{0})
|
|
||||||
18 | println(AAaa{0} == Aaa{0})
|
|
||||||
| ~~~~~~~~~~~~~~~~~
|
|
||||||
19 | println(AAaa{1} != Aaa{1})
|
|
||||||
20 | println(Aaa{1} != AAaa{1})
|
|
||||||
Details: left type: `main.AAaa` vs right type: `main.Aaa`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:19:10: error: possible type mismatch of compared values of `!=` operation
|
|
||||||
17 | println(Aaa{0} == AAaa{0})
|
|
||||||
18 | println(AAaa{0} == Aaa{0})
|
|
||||||
19 | println(AAaa{1} != Aaa{1})
|
|
||||||
| ~~~~~~~~~~~~~~~~~
|
|
||||||
20 | println(Aaa{1} != AAaa{1})
|
|
||||||
21 |
|
|
||||||
Details: left type: `main.AAaa` vs right type: `main.Aaa`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:20:10: error: possible type mismatch of compared values of `!=` operation
|
|
||||||
18 | println(AAaa{0} == Aaa{0})
|
|
||||||
19 | println(AAaa{1} != Aaa{1})
|
|
||||||
20 | println(Aaa{1} != AAaa{1})
|
|
||||||
| ~~~~~~~~~~~~~~~~~
|
|
||||||
21 |
|
|
||||||
22 | arr := Arr([0])
|
|
||||||
Details: left type: `main.Aaa` vs right type: `main.AAaa`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:23:10: error: possible type mismatch of compared values of `==` operation
|
|
||||||
21 |
|
|
||||||
22 | arr := Arr([0])
|
|
||||||
23 | println(arr == [0])
|
|
||||||
| ~~~~~~~~~~
|
|
||||||
24 | println([1] == arr)
|
|
||||||
25 | println(arr != [0])
|
|
||||||
Details: left type: `main.Arr` vs right type: `[]int`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:24:10: error: possible type mismatch of compared values of `==` operation
|
|
||||||
22 | arr := Arr([0])
|
|
||||||
23 | println(arr == [0])
|
|
||||||
24 | println([1] == arr)
|
|
||||||
| ~~~~~~~~~~
|
|
||||||
25 | println(arr != [0])
|
|
||||||
26 | println([1] != arr)
|
|
||||||
Details: left type: `[]int` vs right type: `main.Arr`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:25:10: error: possible type mismatch of compared values of `!=` operation
|
|
||||||
23 | println(arr == [0])
|
|
||||||
24 | println([1] == arr)
|
|
||||||
25 | println(arr != [0])
|
|
||||||
| ~~~~~~~~~~
|
|
||||||
26 | println([1] != arr)
|
|
||||||
27 |
|
27 |
|
||||||
Details: left type: `main.Arr` vs right type: `[]int`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:26:10: error: possible type mismatch of compared values of `!=` operation
|
|
||||||
24 | println([1] == arr)
|
|
||||||
25 | println(arr != [0])
|
|
||||||
26 | println([1] != arr)
|
|
||||||
| ~~~~~~~~~~
|
|
||||||
27 |
|
|
||||||
28 | arr_aaa := ArrAaa(arr)
|
|
||||||
Details: left type: `[]int` vs right type: `main.Arr`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:29:10: error: possible type mismatch of compared values of `==` operation
|
|
||||||
27 |
|
|
||||||
28 | arr_aaa := ArrAaa(arr)
|
28 | arr_aaa := ArrAaa(arr)
|
||||||
29 | println(arr_aaa == arr)
|
29 | println(arr_aaa == arr)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
30 | println(arr == arr_aaa)
|
30 | println(arr == arr_aaa)
|
||||||
31 | println(arr_aaa != arr)
|
31 | println(arr_aaa != arr)
|
||||||
Details: left type: `main.ArrAaa` vs right type: `main.Arr`
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:30:10: error: infix expr: cannot use `ArrAaa` (right expression) as `Arr`
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:30:10: error: possible type mismatch of compared values of `==` operation
|
|
||||||
28 | arr_aaa := ArrAaa(arr)
|
28 | arr_aaa := ArrAaa(arr)
|
||||||
29 | println(arr_aaa == arr)
|
29 | println(arr_aaa == arr)
|
||||||
30 | println(arr == arr_aaa)
|
30 | println(arr == arr_aaa)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
31 | println(arr_aaa != arr)
|
31 | println(arr_aaa != arr)
|
||||||
32 | println(arr != arr_aaa)
|
32 | println(arr != arr_aaa)
|
||||||
Details: left type: `main.Arr` vs right type: `main.ArrAaa`
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:31:10: error: infix expr: cannot use `Arr` (right expression) as `ArrAaa`
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:31:10: error: possible type mismatch of compared values of `!=` operation
|
|
||||||
29 | println(arr_aaa == arr)
|
29 | println(arr_aaa == arr)
|
||||||
30 | println(arr == arr_aaa)
|
30 | println(arr == arr_aaa)
|
||||||
31 | println(arr_aaa != arr)
|
31 | println(arr_aaa != arr)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
32 | println(arr != arr_aaa)
|
32 | println(arr != arr_aaa)
|
||||||
33 |
|
33 |
|
||||||
Details: left type: `main.ArrAaa` vs right type: `main.Arr`
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:32:10: error: infix expr: cannot use `ArrAaa` (right expression) as `Arr`
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:32:10: error: possible type mismatch of compared values of `!=` operation
|
|
||||||
30 | println(arr == arr_aaa)
|
30 | println(arr == arr_aaa)
|
||||||
31 | println(arr_aaa != arr)
|
31 | println(arr_aaa != arr)
|
||||||
32 | println(arr != arr_aaa)
|
32 | println(arr != arr_aaa)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
33 |
|
33 |
|
||||||
34 | println(arr_aaa == [0])
|
34 | println(arr_aaa == [0])
|
||||||
Details: left type: `main.Arr` vs right type: `main.ArrAaa`
|
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:34:10: error: infix expr: cannot use `[]int` (right expression) as `ArrAaa`
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:34:10: error: infix expr: cannot use `[]int` (right expression) as `ArrAaa`
|
||||||
32 | println(arr != arr_aaa)
|
32 | println(arr != arr_aaa)
|
||||||
33 |
|
33 |
|
||||||
34 | println(arr_aaa == [0])
|
34 | println(arr_aaa == [0])
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
35 | println([1] == arr_aaa)
|
35 | println([1] == arr_aaa)
|
||||||
36 | println(arr_aaa != [0])
|
36 | println(arr_aaa != [0])
|
||||||
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:35:10: error: infix expr: cannot use `ArrAaa` (right expression) as `[]int`
|
vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:35:10: error: infix expr: cannot use `ArrAaa` (right expression) as `[]int`
|
||||||
33 |
|
33 |
|
||||||
34 | println(arr_aaa == [0])
|
34 | println(arr_aaa == [0])
|
||||||
35 | println([1] == arr_aaa)
|
35 | println([1] == arr_aaa)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -148,13 +148,18 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
}
|
}
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
} else if left.typ.idx() == right.typ.idx()
|
} else if left.unaliased.idx() == right.unaliased.idx()
|
||||||
&& left.sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type, .interface_] {
|
&& left.sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type, .interface_] {
|
||||||
if g.pref.translated && !g.is_builtin_mod {
|
if g.pref.translated && !g.is_builtin_mod {
|
||||||
g.gen_plain_infix_expr(node)
|
g.gen_plain_infix_expr(node)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
match left.sym.kind {
|
kind := if left.sym.kind == .alias && right.sym.kind != .alias {
|
||||||
|
left.unaliased_sym.kind
|
||||||
|
} else {
|
||||||
|
left.sym.kind
|
||||||
|
}
|
||||||
|
match kind {
|
||||||
.alias {
|
.alias {
|
||||||
ptr_typ := g.equality_fn(left.typ)
|
ptr_typ := g.equality_fn(left.typ)
|
||||||
if node.op == .ne {
|
if node.op == .ne {
|
||||||
|
@ -289,7 +294,9 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
else {}
|
else {
|
||||||
|
g.gen_plain_infix_expr(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if left.unaliased.idx() in [ast.u32_type_idx, ast.u64_type_idx]
|
} else if left.unaliased.idx() in [ast.u32_type_idx, ast.u64_type_idx]
|
||||||
&& right.unaliased.is_signed() {
|
&& right.unaliased.is_signed() {
|
||||||
|
|
21
vlib/v/tests/alias_compare_non_alias_test.v
Normal file
21
vlib/v/tests/alias_compare_non_alias_test.v
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
struct Foo {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Foo1 = [2][2]int
|
||||||
|
type Foo2 = []int
|
||||||
|
type Foo3 = Foo
|
||||||
|
|
||||||
|
fn test_alias_compare_non_alias_value() {
|
||||||
|
f1 := Foo1([[1, 2]!, [3, 4]!]!)
|
||||||
|
assert f1 == [[1, 2]!, [3, 4]!]!
|
||||||
|
assert [[1, 2]!, [3, 4]!]! == f1
|
||||||
|
|
||||||
|
f2 := Foo2([1, 2, 3, 4])
|
||||||
|
assert f2 == [1, 2, 3, 4]
|
||||||
|
assert [1, 2, 3, 4] == f2
|
||||||
|
|
||||||
|
f3 := Foo3(Foo{'hello'})
|
||||||
|
assert f3 == Foo{'hello'}
|
||||||
|
assert Foo{'hello'} == f3
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue