Skip to content

Commit 10eb844

Browse files
committed
improve auto bound
1 parent c927b41 commit 10eb844

File tree

4 files changed

+262
-212
lines changed

4 files changed

+262
-212
lines changed

src/trait_handlers/clone/clone_enum.rs

Lines changed: 119 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -66,80 +66,77 @@ impl TraitHandler for CloneEnumHandler {
6666
let contains_copy = false;
6767

6868
if contains_copy {
69-
bound = type_attribute.bound.into_where_predicates_by_generic_parameters(
70-
&ast.generics.params,
71-
&syn::parse2(quote!(::core::marker::Copy)).unwrap(),
72-
);
73-
7469
clone_token_stream.extend(quote!(*self));
75-
} else {
76-
let mut clone_types: Vec<&Type> = Vec::new();
70+
}
71+
72+
let mut clone_types: Vec<&Type> = Vec::new();
7773

78-
if variants.is_empty() {
74+
if variants.is_empty() {
75+
if !contains_copy {
7976
clone_token_stream.extend(quote!(unreachable!()));
8077
clone_from_token_stream.extend(quote!(let _ = source;));
81-
} else {
82-
let mut clone_variants_token_stream = proc_macro2::TokenStream::new();
83-
let mut clone_from_variants_token_stream = proc_macro2::TokenStream::new();
84-
85-
for (variant, variant_fields) in variants {
86-
let variant_ident = &variant.ident;
87-
88-
match &variant.fields {
89-
Fields::Unit => {
90-
clone_variants_token_stream.extend(quote! {
91-
Self::#variant_ident => Self::#variant_ident,
92-
});
93-
clone_from_variants_token_stream.extend(quote! {
94-
Self::#variant_ident => {
95-
if let Self::#variant_ident = source {
96-
// same
97-
} else {
98-
*self = ::core::clone::Clone::clone(source);
99-
}
100-
},
101-
});
102-
},
103-
Fields::Named(_) => {
104-
let mut pattern_token_stream = proc_macro2::TokenStream::new();
105-
let mut pattern2_token_stream = proc_macro2::TokenStream::new();
106-
let mut fields_token_stream = proc_macro2::TokenStream::new();
107-
let mut body_token_stream = proc_macro2::TokenStream::new();
108-
109-
for (field, field_attribute) in variant_fields {
110-
let field_name = field.ident.as_ref().unwrap();
111-
112-
pattern_token_stream.extend(quote!(#field_name,));
113-
114-
let field_name2: Ident =
115-
syn::parse_str(&format!("_{}", field_name)).unwrap();
116-
117-
pattern2_token_stream
118-
.extend(quote!(#field_name: #field_name2,));
119-
120-
if let Some(clone) = field_attribute.method.as_ref() {
121-
fields_token_stream.extend(quote! {
122-
#field_name: #clone(#field_name),
123-
});
124-
body_token_stream
125-
.extend(quote!(*#field_name = #clone(#field_name2);));
78+
}
79+
} else {
80+
let mut clone_variants_token_stream = proc_macro2::TokenStream::new();
81+
let mut clone_from_variants_token_stream = proc_macro2::TokenStream::new();
82+
83+
for (variant, variant_fields) in variants {
84+
let variant_ident = &variant.ident;
85+
86+
match &variant.fields {
87+
Fields::Unit => {
88+
clone_variants_token_stream.extend(quote! {
89+
Self::#variant_ident => Self::#variant_ident,
90+
});
91+
clone_from_variants_token_stream.extend(quote! {
92+
Self::#variant_ident => {
93+
if let Self::#variant_ident = source {
94+
// same
12695
} else {
127-
clone_types.push(&field.ty);
128-
129-
fields_token_stream.extend(quote! {
130-
#field_name: ::core::clone::Clone::clone(#field_name),
131-
});
132-
body_token_stream.extend(
133-
quote!( ::core::clone::Clone::clone_from(#field_name, #field_name2); ),
134-
);
96+
*self = ::core::clone::Clone::clone(source);
13597
}
98+
},
99+
});
100+
},
101+
Fields::Named(_) => {
102+
let mut pattern_token_stream = proc_macro2::TokenStream::new();
103+
let mut pattern2_token_stream = proc_macro2::TokenStream::new();
104+
let mut fields_token_stream = proc_macro2::TokenStream::new();
105+
let mut body_token_stream = proc_macro2::TokenStream::new();
106+
107+
for (field, field_attribute) in variant_fields {
108+
let field_name = field.ident.as_ref().unwrap();
109+
110+
pattern_token_stream.extend(quote!(#field_name,));
111+
112+
let field_name2: Ident =
113+
syn::parse_str(&format!("_{}", field_name)).unwrap();
114+
115+
pattern2_token_stream.extend(quote!(#field_name: #field_name2,));
116+
117+
if let Some(clone) = field_attribute.method.as_ref() {
118+
fields_token_stream.extend(quote! {
119+
#field_name: #clone(#field_name),
120+
});
121+
body_token_stream
122+
.extend(quote!(*#field_name = #clone(#field_name2);));
123+
} else {
124+
clone_types.push(&field.ty);
125+
126+
fields_token_stream.extend(quote! {
127+
#field_name: ::core::clone::Clone::clone(#field_name),
128+
});
129+
body_token_stream.extend(
130+
quote!( ::core::clone::Clone::clone_from(#field_name, #field_name2); ),
131+
);
136132
}
133+
}
137134

138-
clone_variants_token_stream.extend(quote! {
135+
clone_variants_token_stream.extend(quote! {
139136
Self::#variant_ident { #pattern_token_stream } => Self::#variant_ident { #fields_token_stream },
140137
});
141138

142-
clone_from_variants_token_stream.extend(quote! {
139+
clone_from_variants_token_stream.extend(quote! {
143140
Self::#variant_ident { #pattern_token_stream } => {
144141
if let Self::#variant_ident { #pattern2_token_stream } = source {
145142
#body_token_stream
@@ -148,47 +145,47 @@ impl TraitHandler for CloneEnumHandler {
148145
}
149146
},
150147
});
151-
},
152-
Fields::Unnamed(_) => {
153-
let mut pattern_token_stream = proc_macro2::TokenStream::new();
154-
let mut pattern2_token_stream = proc_macro2::TokenStream::new();
155-
let mut fields_token_stream = proc_macro2::TokenStream::new();
156-
let mut body_token_stream = proc_macro2::TokenStream::new();
157-
158-
for (index, (field, field_attribute)) in
159-
variant_fields.into_iter().enumerate()
160-
{
161-
let field_name: Ident =
162-
syn::parse_str(&format!("_{}", index)).unwrap();
163-
164-
pattern_token_stream.extend(quote!(#field_name,));
165-
166-
let field_name2: Ident =
167-
syn::parse_str(&format!("_{}", field_name)).unwrap();
168-
169-
pattern2_token_stream.extend(quote!(#field_name2,));
170-
171-
if let Some(clone) = field_attribute.method.as_ref() {
172-
fields_token_stream.extend(quote! (#clone(#field_name),));
173-
body_token_stream
174-
.extend(quote!(*#field_name = #clone(#field_name2);));
175-
} else {
176-
clone_types.push(&field.ty);
177-
178-
fields_token_stream.extend(
179-
quote! ( ::core::clone::Clone::clone(#field_name), ),
180-
);
181-
body_token_stream.extend(
182-
quote!( ::core::clone::Clone::clone_from(#field_name, #field_name2); ),
183-
);
184-
}
148+
},
149+
Fields::Unnamed(_) => {
150+
let mut pattern_token_stream = proc_macro2::TokenStream::new();
151+
let mut pattern2_token_stream = proc_macro2::TokenStream::new();
152+
let mut fields_token_stream = proc_macro2::TokenStream::new();
153+
let mut body_token_stream = proc_macro2::TokenStream::new();
154+
155+
for (index, (field, field_attribute)) in
156+
variant_fields.into_iter().enumerate()
157+
{
158+
let field_name: Ident =
159+
syn::parse_str(&format!("_{}", index)).unwrap();
160+
161+
pattern_token_stream.extend(quote!(#field_name,));
162+
163+
let field_name2: Ident =
164+
syn::parse_str(&format!("_{}", field_name)).unwrap();
165+
166+
pattern2_token_stream.extend(quote!(#field_name2,));
167+
168+
if let Some(clone) = field_attribute.method.as_ref() {
169+
fields_token_stream.extend(quote! (#clone(#field_name),));
170+
body_token_stream
171+
.extend(quote!(*#field_name = #clone(#field_name2);));
172+
} else {
173+
clone_types.push(&field.ty);
174+
175+
fields_token_stream.extend(
176+
quote! ( ::core::clone::Clone::clone(#field_name), ),
177+
);
178+
body_token_stream.extend(
179+
quote!( ::core::clone::Clone::clone_from(#field_name, #field_name2); ),
180+
);
185181
}
182+
}
186183

187-
clone_variants_token_stream.extend(quote! {
184+
clone_variants_token_stream.extend(quote! {
188185
Self::#variant_ident ( #pattern_token_stream ) => Self::#variant_ident ( #fields_token_stream ),
189186
});
190187

191-
clone_from_variants_token_stream.extend(quote! {
188+
clone_from_variants_token_stream.extend(quote! {
192189
Self::#variant_ident ( #pattern_token_stream ) => {
193190
if let Self::#variant_ident ( #pattern2_token_stream ) = source {
194191
#body_token_stream
@@ -197,10 +194,11 @@ impl TraitHandler for CloneEnumHandler {
197194
}
198195
},
199196
});
200-
},
201-
}
197+
},
202198
}
199+
}
203200

201+
if !contains_copy {
204202
clone_token_stream.extend(quote! {
205203
match self {
206204
#clone_variants_token_stream
@@ -213,15 +211,19 @@ impl TraitHandler for CloneEnumHandler {
213211
}
214212
});
215213
}
216-
217-
bound =
218-
type_attribute.bound.into_where_predicates_by_generic_parameters_check_types(
219-
&ast.generics.params,
220-
&syn::parse2(quote!(::core::clone::Clone)).unwrap(),
221-
&clone_types,
222-
Some((false, false)),
223-
);
224214
}
215+
216+
bound = type_attribute.bound.into_where_predicates_by_generic_parameters_check_types(
217+
&ast.generics.params,
218+
&syn::parse2(if contains_copy {
219+
quote!(::core::marker::Copy)
220+
} else {
221+
quote!(::core::clone::Clone)
222+
})
223+
.unwrap(),
224+
&clone_types,
225+
Some((false, false)),
226+
);
225227
}
226228

227229
let clone_from_fn_token_stream = if clone_from_token_stream.is_empty() {
@@ -256,6 +258,14 @@ impl TraitHandler for CloneEnumHandler {
256258
}
257259
});
258260

261+
#[cfg(feature = "Copy")]
262+
if traits.contains(&Trait::Copy) {
263+
token_stream.extend(quote! {
264+
impl #impl_generics ::core::marker::Copy for #ident #ty_generics #where_clause {
265+
}
266+
});
267+
}
268+
259269
Ok(())
260270
}
261271
}

0 commit comments

Comments
 (0)