diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index ddd26a36c8..2a2c1d24e4 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -3171,13 +3171,42 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } g.expr(node.right) g.write(')') - } else if node.op in [.eq, .ne] && left_sym.kind == .struct_ && right_sym.kind == .struct_ - && has_eq_overloaded&& has_ne_overloaded { - ptr_typ := g.gen_struct_equality_fn(left_type) - if node.op == .eq { - g.write('${ptr_typ}_struct_eq(') - } else if node.op == .ne { - g.write('!${ptr_typ}_struct_eq(') + } else if node.op in [.eq, .ne] && left_sym.kind == .struct_ && right_sym.kind == .struct_ { + if has_eq_overloaded && !has_ne_overloaded { + // Define `!=` as negation of Autogenerated `==` + styp := g.typ(left_type) + if node.op == .eq { + g.write('!${styp}__ne(') + } else if node.op == .ne { + g.write('${styp}__ne(') + } + } + if !has_eq_overloaded && has_ne_overloaded { + // Define `==` as negation of Autogenerated `!=` + styp := g.typ(left_type) + if node.op == .ne { + g.write('!${styp}__eq(') + } else if node.op == .eq { + g.write('${styp}__eq(') + } + } + if !has_eq_overloaded && !has_ne_overloaded { + // Overload both User defined `==` and `!=` + styp := g.typ(left_type) + if node.op == .eq { + g.write('${styp}__eq(') + } else if node.op == .ne { + g.write('${styp}__ne(') + } + } + if has_eq_overloaded && has_ne_overloaded { + // Auto generate both `==` and `!=` + ptr_typ := g.gen_struct_equality_fn(left_type) + if node.op == .eq { + g.write('${ptr_typ}_struct_eq(') + } else if node.op == .ne { + g.write('!${ptr_typ}_struct_eq(') + } } if node.left_type.is_ptr() { g.write('*') diff --git a/vlib/v/tests/struct_eq_op_only_test.v b/vlib/v/tests/struct_eq_op_only_test.v new file mode 100644 index 0000000000..f03115e590 --- /dev/null +++ b/vlib/v/tests/struct_eq_op_only_test.v @@ -0,0 +1,15 @@ +struct User { + name string + num int +} + +fn (u User) == (u1 User) bool { + return u.name == u1.name +} + +fn test_eq_op() { + u1 := User{'Joe', 23} + u2 := User{'Joe', 24} + assert u1 == u2 + assert (u1 != u2) == false +} diff --git a/vlib/v/tests/sturct_ne_op_only_test.v b/vlib/v/tests/sturct_ne_op_only_test.v new file mode 100644 index 0000000000..5e35682366 --- /dev/null +++ b/vlib/v/tests/sturct_ne_op_only_test.v @@ -0,0 +1,15 @@ +struct User { + name string + num int +} + +fn (u User) != (u1 User) bool { + return u.num != u1.num +} + +fn test_eq_op() { + u1 := User{'Joe', 23} + u2 := User{'Joe', 24} + assert u1 != u2 + assert (u1 == u2) == false +}