Auto merge of #12821 - SpecialMike:fix-partial-eq-default, r=Veykril

fix: Correctly generate default `PartialEq::ne`

Fixes #12779

For the `Generate default members` assist on the `PartialEq` trait, the assist will now give the default implementation instead of generating a function.
This commit is contained in:
bors 2022-07-20 06:20:21 +00:00
commit c001b9cb06
3 changed files with 33 additions and 1 deletions

View file

@ -1305,4 +1305,30 @@ impl Trait<u32> for Impl {
}"#, }"#,
); );
} }
#[test]
fn test_default_partial_eq() {
check_assist(
add_missing_default_members,
r#"
//- minicore: eq
struct SomeStruct {
data: usize,
field: (usize, usize),
}
impl PartialEq for SomeStruct {$0}
"#,
r#"
struct SomeStruct {
data: usize,
field: (usize, usize),
}
impl PartialEq for SomeStruct {
$0fn ne(&self, other: &Self) -> bool {
!self.eq(other)
}
}
"#,
);
}
} }

View file

@ -394,6 +394,9 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
/// Generate a `PartialEq` impl based on the fields and members of the target type. /// Generate a `PartialEq` impl based on the fields and members of the target type.
fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
if func.name().map_or(false, |name| name.text() == "ne") {
return None;
}
fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> { fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> {
match expr { match expr {
Some(expr) => Some(make::expr_bin_op(expr, BinaryOp::LogicOp(LogicOp::And), cmp)), Some(expr) => Some(make::expr_bin_op(expr, BinaryOp::LogicOp(LogicOp::And), cmp)),
@ -424,7 +427,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// generate this code `Self` for the time being. // generate this code `Self` for the time being.
let body = match adt { let body = match adt {
// `Hash` cannot be derived for unions, so no default impl can be provided. // `PartialEq` cannot be derived for unions, so no default impl can be provided.
ast::Adt::Union(_) => return None, ast::Adt::Union(_) => return None,
ast::Adt::Enum(enum_) => { ast::Adt::Enum(enum_) => {

View file

@ -354,6 +354,9 @@ pub mod cmp {
#[lang = "eq"] #[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> { pub trait PartialEq<Rhs: ?Sized = Self> {
fn eq(&self, other: &Rhs) -> bool; fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool {
!self.eq(other)
}
} }
pub trait Eq: PartialEq<Self> {} pub trait Eq: PartialEq<Self> {}