From 6f5259571df04b8def0ae9cb32dd4455b03b35b2 Mon Sep 17 00:00:00 2001 From: zakuro Date: Sat, 27 Mar 2021 02:46:54 +0900 Subject: [PATCH] cgen: use overloaded eq op in auto eq method (#9475) --- vlib/v/gen/c/auto_eq_methods.v | 12 +++++++++++- vlib/v/gen/c/cgen.v | 23 ++++++----------------- vlib/v/tests/struct_equality_test.v | 18 ++++++++++++++---- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index 9f5276cc77..3b158988d1 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -68,7 +68,18 @@ fn (mut g Gen) gen_struct_equality_fn(left table.Type) string { info := left_sym.struct_info() g.type_definitions.writeln('static bool ${ptr_typ}_struct_eq($ptr_typ a, $ptr_typ b); // auto') mut fn_builder := strings.new_builder(512) + defer { + g.auto_fn_definitions << fn_builder.str() + } fn_builder.writeln('static bool ${ptr_typ}_struct_eq($ptr_typ a, $ptr_typ b) {') + + // orverloaded + if left_sym.has_method('==') { + fn_builder.writeln('\treturn ${ptr_typ}__eq(a, b);') + fn_builder.writeln('}') + return ptr_typ + } + for field in info.fields { sym := g.table.get_type_symbol(field.typ) if sym.kind == .string { @@ -101,7 +112,6 @@ fn (mut g Gen) gen_struct_equality_fn(left table.Type) string { } fn_builder.writeln('\treturn true;') fn_builder.writeln('}') - g.auto_fn_definitions << fn_builder.str() return ptr_typ } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 282a7e4645..374383d8f1 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3301,7 +3301,6 @@ fn (mut g Gen) enum_expr(node ast.Expr) { } fn (mut g Gen) infix_gen_equality(node ast.InfixExpr, left_type table.Type, left_sym table.TypeSymbol, right_sym table.TypeSymbol) { - has_eq_overloaded := left_sym.has_method('==') if left_sym.kind != right_sym.kind { return } @@ -3396,22 +3395,12 @@ fn (mut g Gen) infix_gen_equality(node ast.InfixExpr, left_type table.Type, left g.write(')') } .struct_ { - if has_eq_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(') - } - } else { - // 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(') - } + // 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_equality_test.v b/vlib/v/tests/struct_equality_test.v index bc2229d832..61dbe26ce5 100644 --- a/vlib/v/tests/struct_equality_test.v +++ b/vlib/v/tests/struct_equality_test.v @@ -1,11 +1,21 @@ +struct Company { + name string + description string +} + +fn (lhs Company) == (rhs Company) bool { + return lhs.name == rhs.name +} + struct User { - name string - age int + name string + age int + company Company } fn test_struct_equality() { - mut usr1 := User{'sanath', 28} - mut usr2 := User{'sanath', 28} + mut usr1 := User{'sanath', 28, Company{'awesome company', 'we are awesome'}} + mut usr2 := User{'sanath', 28, Company{'awesome company', 'we are awesome too'}} if usr1 == usr2 { println('Same User') } else {