Skip to content

Commit

Permalink
Revert "Try detecting mixed derive/derivative with Clone and `C…
Browse files Browse the repository at this point in the history
…opy`"

This reverts commit 4117fff.

As of rust 1.17, proc-macros don't get attributes other than their own
in the token stream they're fed.
See rust-lang/rust#39572
  • Loading branch information
glandium committed Jul 13, 2018
1 parent 162742a commit 4e04ccb
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 77 deletions.
40 changes: 2 additions & 38 deletions src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,13 @@ pub struct InputClone {
bounds: Option<Vec<syn::WherePredicate>>,
/// 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)]
/// Represent the `derivative(Clone(…))` attributes on an input.
pub struct InputCopy {
/// The `bound` attribute if present and the corresponding bounds.
bounds: Option<Vec<syn::WherePredicate>>,
/// Wether the input also derive `Clone` (ie. `derive(Clone)`, but not `derivative(Clone)`)
derives_clone: bool,
}

#[derive(Debug, Default)]
Expand Down Expand Up @@ -194,45 +190,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()
.any(|attr| attr.value.name() == "rustc_copy_clone_marker");

match_attributes! {
let Some(clone) = input.clone;
for value in values;
"bound" => try!(parse_bound(&mut clone.bounds, value)),
"clone_from" => {
clone.clone_from = try!(parse_boolean_meta_item(&value, true, "clone_from"));
}
}

input.clone = Some(clone);
}
"Copy" => {
let mut copy = input.copy.take().unwrap_or_default();

for attr in attrs {
if let syn::MetaItem::List(ref name, ref traits) = attr.value {
fn is_clone(elem: &syn::NestedMetaItem) -> bool {
match *elem {
syn::NestedMetaItem::MetaItem(ref mi) => mi.name() == "Clone",
syn::NestedMetaItem::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, value)),
}

input.copy = Some(copy);
}
"Debug" => {
match_attributes! {
Expand Down Expand Up @@ -295,10 +267,6 @@ impl Input {
self.copy.as_ref().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().map_or(None, |d| d.bounds.as_ref().map(Vec::as_slice))
}
Expand All @@ -319,10 +287,6 @@ impl Input {
self.hash.as_ref().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().map_or(None, |d| d.bounds.as_ref().map(Vec::as_slice))
}
Expand Down
13 changes: 4 additions & 9 deletions src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ use syn::{self, aster};
use utils;

/// Derive `Copy` for `input`.
pub fn derive_copy(input: &ast::Input) -> Result<quote::Tokens, String> {
pub fn derive_copy(input: &ast::Input) -> quote::Tokens {
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 impl_generics = utils::build_impl_generics(
input,
Expand All @@ -30,10 +26,10 @@ pub fn derive_copy(input: &ast::Input) -> Result<quote::Tokens, String> {
.build()
.build();

Ok(quote! {
quote! {
#[allow(unused_qualifications)]
impl #impl_generics #copy_trait_path for #ty #where_clause {}
})
}
}

/// Derive `Clone` for `input`.
Expand All @@ -57,8 +53,7 @@ pub fn derive_clone(input: &ast::Input) -> quote::Tokens {
.build()
.build();

let is_copy = input.attrs.rustc_copy_clone_marker() || input.attrs.copy.is_some();
if is_copy && input.generics.ty_params.is_empty() {
if input.attrs.copy.is_some() && input.generics.ty_params.is_empty() {
quote! {
#[allow(unused_qualifications)]
impl #impl_generics #clone_trait_path for #ty #where_clause {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn derive_impls(input: &ast::Input) -> Result<quote::Tokens, String> {
tokens.append(&clone::derive_clone(input).to_string());
}
if input.attrs.copy.is_some() {
tokens.append(&try!(clone::derive_copy(input)).to_string());
tokens.append(&clone::derive_copy(input).to_string());
}
if input.attrs.debug.is_some() {
tokens.append(&debug::derive(input).to_string());
Expand Down
12 changes: 0 additions & 12 deletions tests/compile-fail/derive-copy-clone.rs

This file was deleted.

17 changes: 0 additions & 17 deletions tests/rustc-deriving-copyclone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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");
}

0 comments on commit 4e04ccb

Please sign in to comment.