cgen: use overloaded eq op in auto eq method (#9475)

pull/9483/head
zakuro 2021-03-27 02:46:54 +09:00 committed by GitHub
parent 36cc4880a6
commit 6f5259571d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 22 deletions

View File

@ -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
}

View File

@ -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('*')

View File

@ -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 {