@@ -4,12 +4,13 @@ use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
4
4
use proc_macro2:: TokenStream ;
5
5
use quote:: { format_ident, quote, quote_spanned, ToTokens } ;
6
6
use std:: collections:: BTreeSet as Set ;
7
+ use std:: mem;
7
8
use syn:: punctuated:: Punctuated ;
8
9
use syn:: visit_mut:: { self , VisitMut } ;
9
10
use syn:: {
10
11
parse_quote, parse_quote_spanned, Attribute , Block , FnArg , GenericParam , Generics , Ident ,
11
- ImplItem , Lifetime , Pat , PatIdent , Receiver , ReturnType , Signature , Stmt , Token , TraitItem ,
12
- Type , TypeParamBound , TypePath , WhereClause ,
12
+ ImplItem , Lifetime , LifetimeDef , Pat , PatIdent , Receiver , ReturnType , Signature , Stmt , Token ,
13
+ TraitItem , Type , TypeParamBound , TypePath , WhereClause ,
13
14
} ;
14
15
15
16
impl ToTokens for Item {
@@ -34,17 +35,18 @@ enum Context<'a> {
34
35
}
35
36
36
37
impl Context < ' _ > {
37
- fn lifetimes < ' a > ( & ' a self , used : & ' a [ Lifetime ] ) -> impl Iterator < Item = & ' a GenericParam > {
38
+ fn lifetimes < ' a > ( & ' a self , used : & ' a [ Lifetime ] ) -> impl Iterator < Item = & ' a LifetimeDef > {
38
39
let generics = match self {
39
40
Context :: Trait { generics, .. } => generics,
40
41
Context :: Impl { impl_generics, .. } => impl_generics,
41
42
} ;
42
- generics. params . iter ( ) . filter ( move |param| {
43
+ generics. params . iter ( ) . filter_map ( move |param| {
43
44
if let GenericParam :: Lifetime ( param) = param {
44
- used. contains ( & param. lifetime )
45
- } else {
46
- false
45
+ if used. contains ( & param. lifetime ) {
46
+ return Some ( param ) ;
47
+ }
47
48
}
49
+ None
48
50
} )
49
51
}
50
52
}
@@ -178,31 +180,42 @@ fn transform_sig(
178
180
}
179
181
}
180
182
181
- for param in sig
182
- . generics
183
- . params
184
- . iter ( )
185
- . chain ( context. lifetimes ( & lifetimes. explicit ) )
186
- {
183
+ for param in & mut sig. generics . params {
187
184
match param {
188
185
GenericParam :: Type ( param) => {
189
- let param = & param. ident ;
190
- let span = param. span ( ) ;
186
+ let param_name = & param. ident ;
187
+ let span = match param. colon_token . take ( ) {
188
+ Some ( colon_token) => colon_token. span ,
189
+ None => param_name. span ( ) ,
190
+ } ;
191
+ let bounds = mem:: replace ( & mut param. bounds , Punctuated :: new ( ) ) ;
191
192
where_clause_or_default ( & mut sig. generics . where_clause )
192
193
. predicates
193
- . push ( parse_quote_spanned ! ( span=> #param : ' async_trait) ) ;
194
+ . push ( parse_quote_spanned ! ( span=> #param_name : ' async_trait + #bounds ) ) ;
194
195
}
195
196
GenericParam :: Lifetime ( param) => {
196
- let param = & param. lifetime ;
197
- let span = param. span ( ) ;
197
+ let param_name = & param. lifetime ;
198
+ let span = match param. colon_token . take ( ) {
199
+ Some ( colon_token) => colon_token. span ,
200
+ None => param_name. span ( ) ,
201
+ } ;
202
+ let bounds = mem:: replace ( & mut param. bounds , Punctuated :: new ( ) ) ;
198
203
where_clause_or_default ( & mut sig. generics . where_clause )
199
204
. predicates
200
- . push ( parse_quote_spanned ! ( span=> #param: ' async_trait) ) ;
205
+ . push ( parse_quote_spanned ! ( span=> #param: ' async_trait + #bounds ) ) ;
201
206
}
202
207
GenericParam :: Const ( _) => { }
203
208
}
204
209
}
205
210
211
+ for param in context. lifetimes ( & lifetimes. explicit ) {
212
+ let param = & param. lifetime ;
213
+ let span = param. span ( ) ;
214
+ where_clause_or_default ( & mut sig. generics . where_clause )
215
+ . predicates
216
+ . push ( parse_quote_spanned ! ( span=> #param: ' async_trait) ) ;
217
+ }
218
+
206
219
if sig. generics . lt_token . is_none ( ) {
207
220
sig. generics . lt_token = Some ( Token ! [ <] ( sig. ident . span ( ) ) ) ;
208
221
}
0 commit comments