diff --git a/src/bound.rs b/src/bound.rs index c79e276..37edbd9 100644 --- a/src/bound.rs +++ b/src/bound.rs @@ -112,12 +112,10 @@ where } impl<'ast> visit::Visit<'ast> for FindTyParams { fn visit_path(&mut self, path: &'ast syn::Path) { - if let Some(syn::punctuated::Pair::Punctuated(seg, _)) = path.segments.last() { - if seg.ident == "PhantomData" { - // Hardcoded exception, because `PhantomData` implements - // most traits whether or not `T` implements it. - return; - } + if is_phantom_data(path) { + // Hardcoded exception, because `PhantomData` implements + // most traits whether or not `T` implements it. + return; } if path.leading_colon.is_none() && path.segments.len() == 1 { let id = path.segments[0].ident.clone(); @@ -138,6 +136,13 @@ where .body .all_fields() .into_iter() + .filter(|field| { + if let syn::Type::Path(syn::TypePath { ref path, .. }) = field.ty { + !is_phantom_data(path) + } else { + true + } + }) .filter(|field| filter(&field.attrs)) .map(|field| &field.ty); @@ -164,3 +169,10 @@ where } cloned } + +fn is_phantom_data(path: &syn::Path) -> bool { + match path.segments.last() { + Some(syn::punctuated::Pair::End(seg)) if seg.ident == "PhantomData" => true, + _ => false, + } +} diff --git a/tests/derive-clone-generics.rs b/tests/derive-clone-generics.rs new file mode 100644 index 0000000..aa6bbb3 --- /dev/null +++ b/tests/derive-clone-generics.rs @@ -0,0 +1,26 @@ +#[macro_use] +extern crate derivative; + +use std::marker::PhantomData; + +struct NoClone; + +#[derive(Derivative)] +#[derivative(Clone, PartialEq)] +struct PhantomField { + foo: PhantomData, +} + +#[derive(Derivative)] +#[derivative(Clone, PartialEq)] +struct PhantomTuple { + foo: PhantomData<(T,)>, +} + +#[test] +fn main() { + let phantom_field = PhantomField:: { foo: Default::default() }; + let phantom_tuple = PhantomTuple:: { foo: Default::default() }; + assert!(phantom_field == phantom_field.clone()); + assert!(phantom_tuple == phantom_tuple.clone()); +} diff --git a/tests/derive-debug-generics.rs b/tests/derive-debug-generics.rs index 1b85b30..021a08e 100644 --- a/tests/derive-debug-generics.rs +++ b/tests/derive-debug-generics.rs @@ -1,6 +1,8 @@ #[macro_use] extern crate derivative; +use std::marker::PhantomData; + #[derive(Derivative)] #[derivative(Debug)] struct Foo { @@ -58,6 +60,18 @@ impl ToDebug for T { } } +#[derive(Derivative)] +#[derivative(Debug)] +struct PhantomField { + foo: PhantomData, +} + +#[derive(Derivative)] +#[derivative(Debug)] +struct PhantomTuple { + foo: PhantomData<(T,)>, +} + #[test] fn main() { assert_eq!(Foo { foo: 42, bar: NoDebug }.to_show(), "Foo { foo: 42 }".to_string()); @@ -69,4 +83,6 @@ fn main() { assert_eq!(F(NoDebug).to_show(), "F".to_string()); assert_eq!(G(42, NoDebug).to_show(), "G(42)".to_string()); assert_eq!(J(NoDebug).to_show(), "J".to_string()); + assert_eq!(&format!("{:?}", PhantomField:: { foo: Default::default() }), "PhantomField { foo: PhantomData }"); + assert_eq!(&format!("{:?}", PhantomTuple:: { foo: Default::default() }), "PhantomTuple { foo: PhantomData }"); }