diff --git a/src/attr.rs b/src/attr.rs index 3460c18..5d5c9b7 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -49,8 +49,6 @@ pub struct InputClone { bounds: Option>, /// Whether the implementation should have an explicit `clone_from`. pub clone_from: bool, - /// Whether the `rustc_copy_clone_marker` was found. - pub rustc_copy_clone_marker: bool, } #[derive(Debug, Default)] @@ -58,8 +56,6 @@ pub struct InputClone { pub struct InputCopy { /// The `bound` attribute if present and the corresponding bounds. bounds: Option>, - /// Whether the input also derive `Clone` (ie. `derive(Clone)`, but not `derivative(Clone)`) - derives_clone: bool, } #[derive(Debug, Default)] @@ -215,50 +211,21 @@ impl Input { for_all_attr! { for (name, values) in attrs; "Clone" => { - let mut clone = input.clone.take().unwrap_or_default(); - - clone.rustc_copy_clone_marker = attrs - .iter() - .filter_map(|attr| attr.parse_meta().ok()) - .any(|meta| meta.name().to_string() == "rustc_copy_clone_marker"); - match_attributes! { + let Some(clone) = input.clone; for value in values; "bound" => try!(parse_bound(&mut clone.bounds, opt_string_to_str!(value))), "clone_from" => { clone.clone_from = try!(parse_boolean_meta_item(&opt_string_to_str!(value), true, "clone_from")); } } - - input.clone = Some(clone); } "Copy" => { - let mut copy = input.copy.take().unwrap_or_default(); - - for attr in attrs { - if let Ok(syn::Meta::List(syn::MetaList{ - ident: ref name, - nested: ref traits, - .. - })) = attr.parse_meta() { - fn is_clone(elem: &syn::NestedMeta) -> bool { - match *elem { - syn::NestedMeta::Meta(ref mi) => mi.name() == "Clone", - syn::NestedMeta::Literal(..) => false, - } - } - if name == "derive" && traits.iter().any(is_clone) { - copy.derives_clone = true; - } - } - } - match_attributes! { + let Some(copy) = input.copy; for value in values; "bound" => try!(parse_bound(&mut copy.bounds, opt_string_to_str!(value))), } - - input.copy = Some(copy); } "Debug" => { match_attributes! { @@ -325,10 +292,6 @@ impl Input { .map_or(None, |d| d.bounds.as_ref().map(Vec::as_slice)) } - pub fn derives_clone(&self) -> bool { - self.copy.as_ref().map_or(false, |d| d.derives_clone) - } - pub fn debug_bound(&self) -> Option<&[syn::WherePredicate]> { self.debug .as_ref() @@ -357,12 +320,6 @@ impl Input { .map_or(None, |d| d.bounds.as_ref().map(Vec::as_slice)) } - pub fn rustc_copy_clone_marker(&self) -> bool { - self.clone - .as_ref() - .map_or(false, |d| d.rustc_copy_clone_marker) - } - pub fn partial_eq_bound(&self) -> Option<&[syn::WherePredicate]> { self.partial_eq .as_ref() diff --git a/src/clone.rs b/src/clone.rs index d0f3183..971e8d0 100644 --- a/src/clone.rs +++ b/src/clone.rs @@ -7,13 +7,9 @@ use syn; use utils; /// Derive `Copy` for `input`. -pub fn derive_copy(input: &ast::Input) -> Result { +pub fn derive_copy(input: &ast::Input) -> proc_macro2::TokenStream { let name = &input.ident; - if input.attrs.derives_clone() { - return Err("`#[derivative(Copy)]` can't be used with `#[derive(Clone)]`".into()); - } - let copy_trait_path = copy_trait_path(); let generics = utils::build_impl_generics( input, @@ -24,10 +20,10 @@ pub fn derive_copy(input: &ast::Input) -> Result proc_macro2::TokenStream { ); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let is_copy = input.attrs.rustc_copy_clone_marker() || input.attrs.copy.is_some(); + let is_copy = input.attrs.copy.is_some(); if is_copy && input.generics.type_params().count() == 0 { quote! { #[allow(unused_qualifications)] diff --git a/src/lib.rs b/src/lib.rs index 5dfe20e..2107c38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,7 @@ fn derive_impls(input: &ast::Input) -> Result tokens.extend(clone::derive_clone(input)); } if input.attrs.copy.is_some() { - tokens.extend(clone::derive_copy(input)?); + tokens.extend(clone::derive_copy(input)); } if input.attrs.debug.is_some() { tokens.extend(debug::derive(input)); diff --git a/tests/compile-fail/derive-copy-clone.rs b/tests/compile-fail/derive-copy-clone.rs deleted file mode 100644 index 1e93367..0000000 --- a/tests/compile-fail/derive-copy-clone.rs +++ /dev/null @@ -1,12 +0,0 @@ -#[macro_use] -extern crate derivative; - -#[derive(Derivative)] -//~^ ERROR custom derive attribute panicked -//~| HELP `#[derivative(Copy)]` can't be used with `#[derive(Clone)]` -#[derivative(Copy)] -#[derive(Clone)] -struct OurTheir1; - -fn main() { -} diff --git a/tests/rustc-deriving-copyclone.rs b/tests/rustc-deriving-copyclone.rs index 45f2a14..d6374da 100644 --- a/tests/rustc-deriving-copyclone.rs +++ b/tests/rustc-deriving-copyclone.rs @@ -44,15 +44,6 @@ struct OurOur1(Liar); #[derivative(Clone, Copy)] struct OurOur2(Liar); -#[derive(Copy)] -#[derive(Derivative)] -#[derivative(Clone)] -struct TheirOur1(Liar); -#[derive(Copy)] -#[derive(Derivative)] -#[derivative(Clone)] -struct TheirOur2(Liar); - #[test] fn main() { let _ = TheirTheir(Liar).clone(); @@ -62,12 +53,4 @@ fn main() { assert!(!CLONED.load(Ordering::SeqCst), "OurOur1"); let _ = OurOur2(Liar).clone(); assert!(!CLONED.load(Ordering::SeqCst), "OurOur2"); - - // Ideally this would work the same, just testing that the behaviour does not change: - CLONED.store(false, Ordering::SeqCst); - let _ = TheirOur1(Liar).clone(); - assert!(CLONED.load(Ordering::SeqCst), "TheirOur1"); - CLONED.store(false, Ordering::SeqCst); - let _ = TheirOur2(Liar).clone(); - assert!(CLONED.load(Ordering::SeqCst), "TheirOur2"); }