cgen: allow `==` to be user defined if `!=` is auto generated and vice versa (#8286)
							parent
							
								
									39e5f6e9df
								
							
						
					
					
						commit
						8a59ffb4b7
					
				| 
						 | 
				
			
			@ -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('*')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue