Skip to content

Commit

Permalink
Fixed PartialEq and Eq bounds generation.
Browse files Browse the repository at this point in the history
Also added tests to catch these cases.

Issue mcarton#25
  • Loading branch information
azriel91 committed Oct 18, 2018
1 parent 442c695 commit 12e4bd1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
13 changes: 11 additions & 2 deletions src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use proc_macro2;

use ast;
use attr;
use matcher;
use syn;
use utils;
Expand All @@ -15,7 +16,7 @@ pub fn derive_eq(input: &ast::Input) -> proc_macro2::TokenStream {
let generics = utils::build_impl_generics(
input,
&eq_trait_path,
|attrs| attrs.eq_bound().is_none(),
needs_eq_bound,
|field| field.eq_bound(),
|input| input.eq_bound(),
);
Expand Down Expand Up @@ -79,7 +80,7 @@ pub fn derive_partial_eq(input: &ast::Input) -> Result<proc_macro2::TokenStream,
let generics = utils::build_impl_generics(
input,
&partial_eq_trait_path,
|attrs| attrs.partial_eq_bound().is_none(),
needs_partial_eq_bound,
|field| field.partial_eq_bound(),
|input| input.partial_eq_bound(),
);
Expand All @@ -97,6 +98,14 @@ pub fn derive_partial_eq(input: &ast::Input) -> Result<proc_macro2::TokenStream,
})
}

fn needs_partial_eq_bound(attrs: &attr::Field) -> bool {
!attrs.ignore_partial_eq() && attrs.partial_eq_bound().is_none()
}

fn needs_eq_bound(attrs: &attr::Field) -> bool {
!attrs.ignore_partial_eq() && attrs.eq_bound().is_none()
}

/// Return the path of the `Eq` trait, that is `::std::cmp::Eq`.
fn eq_trait_path() -> syn::Path {
parse_quote!(::std::cmp::Eq)
Expand Down
47 changes: 31 additions & 16 deletions tests/derive-partial-eq.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use std::marker::PhantomData;

#[macro_use]
extern crate derivative;

#[derive(Derivative)]
#[derivative(PartialEq)]
struct Foo {
foo: u8
foo: u8,
}

#[derive(Derivative)]
#[derivative(PartialEq="feature_allow_slow_enum")]
#[derivative(PartialEq = "feature_allow_slow_enum")]
enum Option<T> {
Some(T),
None,
Expand All @@ -17,8 +19,8 @@ enum Option<T> {
#[derive(Derivative)]
#[derivative(PartialEq)]
struct WithPtr<T: ?Sized> {
#[derivative(PartialEq(bound=""))]
foo: *const T
#[derivative(PartialEq(bound = ""))]
foo: *const T,
}

#[derive(Derivative)]
Expand All @@ -28,44 +30,48 @@ struct Empty;
#[derive(Derivative)]
#[derivative(PartialEq)]
struct AllIgnored {
#[derivative(PartialEq="ignore")]
#[derivative(PartialEq = "ignore")]
foo: u8,
}

#[derive(Derivative)]
#[derivative(PartialEq)]
struct OneIgnored {
#[derivative(PartialEq="ignore")]
#[derivative(PartialEq = "ignore")]
foo: u8,
bar: u8,
}

#[derive(Derivative)]
#[derivative(PartialEq)]
struct Parity(
#[derivative(PartialEq(compare_with="same_parity"))]
u8,
);
struct Parity(#[derivative(PartialEq(compare_with = "same_parity"))] u8);

fn same_parity(lhs: &u8, rhs: &u8) -> bool {
lhs % 2 == rhs % 2
}

#[derive(Derivative)]
#[derivative(PartialEq)]
struct Generic<T>(
#[derivative(PartialEq(compare_with="dummy_cmp", bound=""))]
T,
);
struct Generic<T>(#[derivative(PartialEq(compare_with = "dummy_cmp", bound = ""))] T);

fn dummy_cmp<T>(_: &T, _: &T) -> bool {
true
}

struct NonPartialEq;

#[derive(Derivative)]
#[derivative(PartialEq, Eq)]
struct GenericIgnore<T> {
f: u32,
#[derivative(PartialEq = "ignore")]
t: PhantomData<T>,
}

trait SomeTrait {}
struct SomeType {
#[allow(dead_code)]
foo: u8
foo: u8,
}
impl SomeTrait for SomeType {}

Expand Down Expand Up @@ -95,5 +101,14 @@ fn main() {
assert!(Parity(3) != Parity(42));
assert!(Parity(2) != Parity(7));

assert!(Generic(SomeType { foo: 0 }) == Generic(SomeType{ foo: 0 }));
assert!(Generic(SomeType { foo: 0 }) == Generic(SomeType { foo: 0 }));
assert!(
GenericIgnore {
f: 123,
t: PhantomData::<NonPartialEq>::default()
} == GenericIgnore {
f: 123,
t: PhantomData::<NonPartialEq>::default()
}
);
}

0 comments on commit 12e4bd1

Please sign in to comment.