diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 7a63782ec3..0ebd108dfd 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -147,14 +147,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { match node.op { // .eq, .ne, .gt, .lt, .ge, .le, .and, .logical_or, .dot, .key_as, .right_shift {} .eq, .ne { - is_mismatch := - (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 { + 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_right_type_signed := right_type in ast.signed_integer_type_idxs if !is_left_type_signed && mut node.right is ast.IntegerLiteral { diff --git a/vlib/v/checker/tests/alias_array_possible_type_mismatch.out b/vlib/v/checker/tests/alias_array_possible_type_mismatch.out deleted file mode 100644 index f1298619d9..0000000000 --- a/vlib/v/checker/tests/alias_array_possible_type_mismatch.out +++ /dev/null @@ -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` diff --git a/vlib/v/checker/tests/alias_array_possible_type_mismatch.vv b/vlib/v/checker/tests/alias_array_possible_type_mismatch.vv deleted file mode 100644 index 5f8e6901f2..0000000000 --- a/vlib/v/checker/tests/alias_array_possible_type_mismatch.vv +++ /dev/null @@ -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) -} diff --git a/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out b/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out index dcdcf068aa..9895d7311b 100644 --- a/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out +++ b/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out @@ -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 11 | // the next line should produce at least a warning, or even an error, without an explicit cast: 12 | z := isym == ast.string_type | ~~~~~~~~~~~~~~~~~~~~~~~ 13 | println(typeof(isym).name) 14 | println(typeof(ast.string_type).name) -Details: left type: `&ast.TypeSymbol` vs right type: `ast.Type` diff --git a/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out b/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out index c141bf63e7..626302471a 100644 --- a/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out +++ b/vlib/v/checker/tests/eq_ne_op_wrong_type_err.out @@ -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` - 10 | + 10 | 11 | fn main() { 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) 15 | println(10 != Aaa{}) | ~~~~~~~~~~~ - 16 | + 16 | 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 - 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) +vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:29:10: error: infix expr: cannot use `Arr` (right expression) as `ArrAaa` 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) 29 | println(arr_aaa == arr) | ~~~~~~~~~~~~~~ 30 | println(arr == arr_aaa) 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: possible type mismatch of compared values of `==` operation +vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:30:10: error: infix expr: cannot use `ArrAaa` (right expression) as `Arr` 28 | arr_aaa := ArrAaa(arr) 29 | println(arr_aaa == arr) 30 | println(arr == arr_aaa) | ~~~~~~~~~~~~~~ 31 | println(arr_aaa != arr) 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: possible type mismatch of compared values of `!=` operation +vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:31:10: error: infix expr: cannot use `Arr` (right expression) as `ArrAaa` 29 | println(arr_aaa == arr) 30 | println(arr == arr_aaa) 31 | println(arr_aaa != arr) | ~~~~~~~~~~~~~~ 32 | println(arr != arr_aaa) 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: possible type mismatch of compared values of `!=` operation +vlib/v/checker/tests/eq_ne_op_wrong_type_err.vv:32:10: error: infix expr: cannot use `ArrAaa` (right expression) as `Arr` 30 | println(arr == arr_aaa) 31 | println(arr_aaa != arr) 32 | println(arr != arr_aaa) | ~~~~~~~~~~~~~~ - 33 | + 33 | 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` 32 | println(arr != arr_aaa) - 33 | + 33 | 34 | println(arr_aaa == [0]) | ~~~~~~~~~~~~~~ 35 | println([1] == arr_aaa) 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` - 33 | + 33 | 34 | println(arr_aaa == [0]) 35 | println([1] == arr_aaa) | ~~~~~~~~~~~~~~ diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index b527ec6cd0..e18b269313 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -148,13 +148,18 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { } g.expr(node.right) 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_] { if g.pref.translated && !g.is_builtin_mod { g.gen_plain_infix_expr(node) 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 { ptr_typ := g.equality_fn(left.typ) if node.op == .ne { @@ -289,7 +294,9 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) { g.expr(node.right) g.write(')') } - else {} + else { + g.gen_plain_infix_expr(node) + } } } else if left.unaliased.idx() in [ast.u32_type_idx, ast.u64_type_idx] && right.unaliased.is_signed() { diff --git a/vlib/v/tests/alias_compare_non_alias_test.v b/vlib/v/tests/alias_compare_non_alias_test.v new file mode 100644 index 0000000000..f017c30a12 --- /dev/null +++ b/vlib/v/tests/alias_compare_non_alias_test.v @@ -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 +}