Skip to content

Commit 708e019

Browse files
committed
clean up generics with split_for_impl
1 parent 09bd42a commit 708e019

File tree

1 file changed

+18
-48
lines changed

1 file changed

+18
-48
lines changed

trait-variant/src/variant.rs

+18-48
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
use std::iter;
1010

1111
use proc_macro2::TokenStream;
12-
use quote::{quote, ToTokens};
12+
use quote::quote;
1313
use syn::{
1414
parse::{Parse, ParseStream},
15-
parse_macro_input,
15+
parse_macro_input, parse_quote,
1616
punctuated::Punctuated,
17-
token::{Comma, Plus},
18-
Error, FnArg, GenericParam, Ident, ItemTrait, Lifetime, Pat, PatType, Result, ReturnType,
19-
Signature, Token, TraitBound, TraitItem, TraitItemConst, TraitItemFn, TraitItemType, Type,
20-
TypeImplTrait, TypeParamBound,
17+
token::Plus,
18+
Error, FnArg, Ident, ItemTrait, Pat, PatType, Result, ReturnType, Signature, Token, TraitBound,
19+
TraitItem, TraitItemConst, TraitItemFn, TraitItemType, Type, TypeGenerics, TypeImplTrait,
20+
TypeParamBound,
2121
};
2222

2323
struct Attrs {
@@ -162,59 +162,29 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
162162

163163
fn mk_blanket_impl(attrs: &Attrs, tr: &ItemTrait) -> TokenStream {
164164
let orig = &tr.ident;
165-
let generics = &tr.generics.params;
166-
let mut generic_names = tr
167-
.generics
168-
.params
169-
.iter()
170-
.map(|generic| match generic {
171-
GenericParam::Lifetime(lt) => GenericParamName::Lifetime(&lt.lifetime),
172-
GenericParam::Type(ty) => GenericParamName::Type(&ty.ident),
173-
GenericParam::Const(co) => GenericParamName::Const(&co.ident),
174-
})
175-
.collect::<Punctuated<_, Comma>>();
176-
let trailing_comma = if !generic_names.is_empty() {
177-
generic_names.push_punct(Comma::default());
178-
quote! { , }
179-
} else {
180-
quote! {}
181-
};
182165
let variant = &attrs.variant.name;
166+
let (_impl, orig_ty_generics, _where) = &tr.generics.split_for_impl();
183167
let items = tr
184168
.items
185169
.iter()
186-
.map(|item| blanket_impl_item(item, variant, &generic_names));
187-
let where_clauses = tr.generics.where_clause.as_ref().map(|wh| &wh.predicates);
170+
.map(|item| blanket_impl_item(item, variant, orig_ty_generics));
171+
let mut blanket_generics = tr.generics.to_owned();
172+
blanket_generics
173+
.params
174+
.push(parse_quote!(TraitVariantBlanketType: #variant #orig_ty_generics));
175+
let (blanket_impl_generics, _ty, blanket_where_clause) = &blanket_generics.split_for_impl();
188176
quote! {
189-
impl<#generics #trailing_comma TraitVariantBlanketType> #orig<#generic_names>
190-
for TraitVariantBlanketType
191-
where TraitVariantBlanketType: #variant<#generic_names>, #where_clauses
177+
impl #blanket_impl_generics #orig #orig_ty_generics for TraitVariantBlanketType #blanket_where_clause
192178
{
193179
#(#items)*
194180
}
195181
}
196182
}
197183

198-
enum GenericParamName<'s> {
199-
Lifetime(&'s Lifetime),
200-
Type(&'s Ident),
201-
Const(&'s Ident),
202-
}
203-
204-
impl ToTokens for GenericParamName<'_> {
205-
fn to_tokens(&self, tokens: &mut TokenStream) {
206-
match self {
207-
GenericParamName::Lifetime(lt) => lt.to_tokens(tokens),
208-
GenericParamName::Type(ty) => ty.to_tokens(tokens),
209-
GenericParamName::Const(co) => co.to_tokens(tokens),
210-
}
211-
}
212-
}
213-
214184
fn blanket_impl_item(
215185
item: &TraitItem,
216186
variant: &Ident,
217-
generic_names: &Punctuated<GenericParamName<'_>, Comma>,
187+
trait_ty_generics: &TypeGenerics<'_>,
218188
) -> TokenStream {
219189
// impl<T> IntFactory for T where T: SendIntFactory {
220190
// const NAME: &'static str = <Self as SendIntFactory>::NAME;
@@ -231,7 +201,7 @@ fn blanket_impl_item(
231201
..
232202
}) => {
233203
quote! {
234-
const #ident #generics: #ty = <Self as #variant<#generic_names>>::#ident;
204+
const #ident #generics: #ty = <Self as #variant #trait_ty_generics>::#ident;
235205
}
236206
}
237207
TraitItem::Fn(TraitItemFn { sig, .. }) => {
@@ -251,7 +221,7 @@ fn blanket_impl_item(
251221
};
252222
quote! {
253223
#sig {
254-
<Self as #variant<#generic_names>>::#ident(#(#args),*)#maybe_await
224+
<Self as #variant #trait_ty_generics>::#ident(#(#args),*)#maybe_await
255225
}
256226
}
257227
}
@@ -260,7 +230,7 @@ fn blanket_impl_item(
260230
}) => {
261231
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
262232
quote! {
263-
type #ident #impl_generics = <Self as #variant<#generic_names>>::#ident #ty_generics #where_clause;
233+
type #ident #impl_generics = <Self as #variant #trait_ty_generics>::#ident #ty_generics #where_clause;
264234
}
265235
}
266236
_ => Error::new_spanned(item, "unsupported item type").into_compile_error(),

0 commit comments

Comments
 (0)