Skip to content

Commit c696dd6

Browse files
glandiummcarton
authored andcommitted
Revert "Try detecting mixed derive/derivative with Clone and Copy"
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
1 parent 0d9930b commit c696dd6

File tree

5 files changed

+7
-83
lines changed

5 files changed

+7
-83
lines changed

src/attr.rs

+2-45
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,13 @@ pub struct InputClone {
4949
bounds: Option<Vec<syn::WherePredicate>>,
5050
/// Whether the implementation should have an explicit `clone_from`.
5151
pub clone_from: bool,
52-
/// Whether the `rustc_copy_clone_marker` was found.
53-
pub rustc_copy_clone_marker: bool,
5452
}
5553

5654
#[derive(Debug, Default)]
5755
/// Represent the `derivative(Clone(…))` attributes on an input.
5856
pub struct InputCopy {
5957
/// The `bound` attribute if present and the corresponding bounds.
6058
bounds: Option<Vec<syn::WherePredicate>>,
61-
/// Whether the input also derive `Clone` (ie. `derive(Clone)`, but not `derivative(Clone)`)
62-
derives_clone: bool,
6359
}
6460

6561
#[derive(Debug, Default)]
@@ -215,50 +211,21 @@ impl Input {
215211
for_all_attr! {
216212
for (name, values) in attrs;
217213
"Clone" => {
218-
let mut clone = input.clone.take().unwrap_or_default();
219-
220-
clone.rustc_copy_clone_marker = attrs
221-
.iter()
222-
.filter_map(|attr| attr.parse_meta().ok())
223-
.any(|meta| meta.name().to_string() == "rustc_copy_clone_marker");
224-
225214
match_attributes! {
215+
let Some(clone) = input.clone;
226216
for value in values;
227217
"bound" => try!(parse_bound(&mut clone.bounds, opt_string_to_str!(value))),
228218
"clone_from" => {
229219
clone.clone_from = try!(parse_boolean_meta_item(&opt_string_to_str!(value), true, "clone_from"));
230220
}
231221
}
232-
233-
input.clone = Some(clone);
234222
}
235223
"Copy" => {
236-
let mut copy = input.copy.take().unwrap_or_default();
237-
238-
for attr in attrs {
239-
if let Ok(syn::Meta::List(syn::MetaList{
240-
ident: ref name,
241-
nested: ref traits,
242-
..
243-
})) = attr.parse_meta() {
244-
fn is_clone(elem: &syn::NestedMeta) -> bool {
245-
match *elem {
246-
syn::NestedMeta::Meta(ref mi) => mi.name() == "Clone",
247-
syn::NestedMeta::Literal(..) => false,
248-
}
249-
}
250-
if name == "derive" && traits.iter().any(is_clone) {
251-
copy.derives_clone = true;
252-
}
253-
}
254-
}
255-
256224
match_attributes! {
225+
let Some(copy) = input.copy;
257226
for value in values;
258227
"bound" => try!(parse_bound(&mut copy.bounds, opt_string_to_str!(value))),
259228
}
260-
261-
input.copy = Some(copy);
262229
}
263230
"Debug" => {
264231
match_attributes! {
@@ -325,10 +292,6 @@ impl Input {
325292
.map_or(None, |d| d.bounds.as_ref().map(Vec::as_slice))
326293
}
327294

328-
pub fn derives_clone(&self) -> bool {
329-
self.copy.as_ref().map_or(false, |d| d.derives_clone)
330-
}
331-
332295
pub fn debug_bound(&self) -> Option<&[syn::WherePredicate]> {
333296
self.debug
334297
.as_ref()
@@ -357,12 +320,6 @@ impl Input {
357320
.map_or(None, |d| d.bounds.as_ref().map(Vec::as_slice))
358321
}
359322

360-
pub fn rustc_copy_clone_marker(&self) -> bool {
361-
self.clone
362-
.as_ref()
363-
.map_or(false, |d| d.rustc_copy_clone_marker)
364-
}
365-
366323
pub fn partial_eq_bound(&self) -> Option<&[syn::WherePredicate]> {
367324
self.partial_eq
368325
.as_ref()

src/clone.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@ use syn;
77
use utils;
88

99
/// Derive `Copy` for `input`.
10-
pub fn derive_copy(input: &ast::Input) -> Result<proc_macro2::TokenStream, String> {
10+
pub fn derive_copy(input: &ast::Input) -> proc_macro2::TokenStream {
1111
let name = &input.ident;
1212

13-
if input.attrs.derives_clone() {
14-
return Err("`#[derivative(Copy)]` can't be used with `#[derive(Clone)]`".into());
15-
}
16-
1713
let copy_trait_path = copy_trait_path();
1814
let generics = utils::build_impl_generics(
1915
input,
@@ -24,10 +20,10 @@ pub fn derive_copy(input: &ast::Input) -> Result<proc_macro2::TokenStream, Strin
2420
);
2521
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
2622

27-
Ok(quote! {
23+
quote! {
2824
#[allow(unused_qualifications)]
2925
impl #impl_generics #copy_trait_path for #name #ty_generics #where_clause {}
30-
})
26+
}
3127
}
3228

3329
/// Derive `Clone` for `input`.
@@ -44,7 +40,7 @@ pub fn derive_clone(input: &ast::Input) -> proc_macro2::TokenStream {
4440
);
4541
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
4642

47-
let is_copy = input.attrs.rustc_copy_clone_marker() || input.attrs.copy.is_some();
43+
let is_copy = input.attrs.copy.is_some();
4844
if is_copy && input.generics.type_params().count() == 0 {
4945
quote! {
5046
#[allow(unused_qualifications)]

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn derive_impls(input: &ast::Input) -> Result<proc_macro2::TokenStream, String>
2626
tokens.extend(clone::derive_clone(input));
2727
}
2828
if input.attrs.copy.is_some() {
29-
tokens.extend(clone::derive_copy(input)?);
29+
tokens.extend(clone::derive_copy(input));
3030
}
3131
if input.attrs.debug.is_some() {
3232
tokens.extend(debug::derive(input));

tests/compile-fail/derive-copy-clone.rs

-12
This file was deleted.

tests/rustc-deriving-copyclone.rs

-17
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,6 @@ struct OurOur1(Liar);
4444
#[derivative(Clone, Copy)]
4545
struct OurOur2(Liar);
4646

47-
#[derive(Copy)]
48-
#[derive(Derivative)]
49-
#[derivative(Clone)]
50-
struct TheirOur1(Liar);
51-
#[derive(Copy)]
52-
#[derive(Derivative)]
53-
#[derivative(Clone)]
54-
struct TheirOur2(Liar);
55-
5647
#[test]
5748
fn main() {
5849
let _ = TheirTheir(Liar).clone();
@@ -62,12 +53,4 @@ fn main() {
6253
assert!(!CLONED.load(Ordering::SeqCst), "OurOur1");
6354
let _ = OurOur2(Liar).clone();
6455
assert!(!CLONED.load(Ordering::SeqCst), "OurOur2");
65-
66-
// Ideally this would work the same, just testing that the behaviour does not change:
67-
CLONED.store(false, Ordering::SeqCst);
68-
let _ = TheirOur1(Liar).clone();
69-
assert!(CLONED.load(Ordering::SeqCst), "TheirOur1");
70-
CLONED.store(false, Ordering::SeqCst);
71-
let _ = TheirOur2(Liar).clone();
72-
assert!(CLONED.load(Ordering::SeqCst), "TheirOur2");
7356
}

0 commit comments

Comments
 (0)