@@ -11,15 +11,8 @@ use std::iter;
11
11
use proc_macro2:: { Span , TokenStream } ;
12
12
use quote:: quote;
13
13
use syn:: {
14
- parse:: { Parse , ParseStream } ,
15
- parse_macro_input,
16
- punctuated:: Punctuated ,
17
- token:: Plus ,
18
- Error , FnArg , GenericParam , Ident , ItemTrait , Pat , PatType , Receiver , Result , ReturnType ,
19
- Signature , Token , TraitBound , TraitItem , TraitItemConst , TraitItemFn , TraitItemType , Type ,
20
- TypeGenerics , TypeImplTrait , TypeParam , TypeParamBound , WhereClause ,
14
+ parse:: { Parse , ParseStream } , parse_macro_input, parse_quote, punctuated:: Punctuated , token:: Plus , Error , FnArg , GenericParam , Ident , ItemTrait , Pat , PatIdent , PatType , Receiver , Result , ReturnType , Signature , Token , TraitBound , TraitItem , TraitItemConst , TraitItemFn , TraitItemType , Type , TypeGenerics , TypeImplTrait , TypeParam , TypeParamBound , TypeReference , WhereClause
21
15
} ;
22
- use syn:: { parse_quote, TypeReference } ;
23
16
24
17
struct Attrs {
25
18
variant : MakeVariant ,
@@ -154,10 +147,32 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
154
147
output : ReturnType :: Type ( syn:: parse2 ( quote ! { -> } ) . unwrap ( ) , Box :: new ( ty) ) ,
155
148
..sig. clone ( )
156
149
} ,
157
- fn_item
158
- . default
159
- . as_ref ( )
160
- . map ( |b| syn:: parse2 ( quote ! { { async move #b } } ) . unwrap ( ) ) ,
150
+ fn_item. default . as_ref ( ) . map ( |b| {
151
+ let items = sig. inputs . iter ( ) . map ( |i| match i {
152
+ FnArg :: Receiver ( Receiver { self_token, .. } ) => {
153
+ quote ! { let __self = #self_token; }
154
+ }
155
+ FnArg :: Typed ( PatType { pat, .. } ) => match pat. as_ref ( ) {
156
+ Pat :: Ident ( PatIdent { ident, .. } ) => quote ! { let #ident = #ident; } ,
157
+ _ => todo ! ( ) ,
158
+ } ,
159
+ } ) ;
160
+
161
+ struct ReplaceSelfVisitor ;
162
+ impl syn:: visit_mut:: VisitMut for ReplaceSelfVisitor {
163
+ fn visit_ident_mut ( & mut self , ident : & mut syn:: Ident ) {
164
+ if ident == "self" {
165
+ * ident = syn:: Ident :: new ( "__self" , ident. span ( ) ) ;
166
+ }
167
+ syn:: visit_mut:: visit_ident_mut ( self , ident) ;
168
+ }
169
+ }
170
+
171
+ let mut block = b. clone ( ) ;
172
+ syn:: visit_mut:: visit_block_mut ( & mut ReplaceSelfVisitor , & mut block) ;
173
+
174
+ parse_quote ! { { async move { #( #items) * #block} } }
175
+ } ) ,
161
176
)
162
177
} else {
163
178
match & sig. output {
0 commit comments