99use std:: iter;
1010
1111use proc_macro2:: TokenStream ;
12- use quote:: { quote, ToTokens } ;
12+ use quote:: quote;
1313use 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
2323struct Attrs {
@@ -162,59 +162,29 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
162162
163163fn 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-
214184fn 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