@@ -12,6 +12,12 @@ use syn::{
1212 WhereClause ,
1313} ;
1414
15+ macro_rules! parse_quote_spanned {
16+ ( $span: expr => $( $t: tt) * ) => (
17+ syn:: parse2( quote_spanned!( $span => $( $t) * ) ) . unwrap( )
18+ )
19+ }
20+
1521impl ToTokens for Item {
1622 fn to_tokens ( & self , tokens : & mut TokenStream ) {
1723 match self {
@@ -21,7 +27,7 @@ impl ToTokens for Item {
2127 }
2228}
2329
24- #[ derive( Clone , Copy ) ]
30+ #[ derive( Debug , Clone , Copy ) ]
2531enum Context < ' a > {
2632 Trait {
2733 generics : & ' a Generics ,
@@ -46,6 +52,13 @@ impl Context<'_> {
4652 }
4753 } )
4854 }
55+
56+ fn generics_span ( & self ) -> Span {
57+ match self {
58+ Context :: Trait { generics, .. } => generics. span ( ) ,
59+ Context :: Impl { impl_generics } => impl_generics. span ( ) ,
60+ }
61+ }
4962}
5063
5164type Supertraits = Punctuated < TypeParamBound , Token ! [ +] > ;
@@ -78,7 +91,7 @@ pub fn expand(input: &mut Item, is_local: bool) {
7891 }
7992 }
8093 Item :: Impl ( input) => {
81- let mut lifetimes = CollectLifetimes :: new ( "'impl" ) ;
94+ let mut lifetimes = CollectLifetimes :: new ( "'impl" , input . generics . span ( ) ) ;
8295 lifetimes. visit_type_mut ( & mut * input. self_ty ) ;
8396 lifetimes. visit_path_mut ( & mut input. trait_ . as_mut ( ) . unwrap ( ) . 1 ) ;
8497 let params = & input. generics . params ;
@@ -133,21 +146,18 @@ fn transform_sig(
133146 ReturnType :: Type ( _, ret) => quote ! ( #ret) ,
134147 } ;
135148
136- let mut lifetimes = CollectLifetimes :: new ( "'life" ) ;
149+ let default_span = sig. ident . span ( )
150+ . join ( sig. paren_token . span )
151+ . unwrap_or_else ( || sig. ident . span ( ) ) ;
152+
153+ let mut lifetimes = CollectLifetimes :: new ( "'life" , default_span) ;
137154 for arg in sig. inputs . iter_mut ( ) {
138155 match arg {
139156 FnArg :: Receiver ( arg) => lifetimes. visit_receiver_mut ( arg) ,
140157 FnArg :: Typed ( arg) => lifetimes. visit_type_mut ( & mut arg. ty ) ,
141158 }
142159 }
143160
144- let where_clause = sig
145- . generics
146- . where_clause
147- . get_or_insert_with ( || WhereClause {
148- where_token : Default :: default ( ) ,
149- predicates : Punctuated :: new ( ) ,
150- } ) ;
151161 for param in sig
152162 . generics
153163 . params
@@ -157,26 +167,31 @@ fn transform_sig(
157167 match param {
158168 GenericParam :: Type ( param) => {
159169 let param = & param. ident ;
160- where_clause
170+ let span = param. span ( ) ;
171+ where_clause_or_default ( & mut sig. generics . where_clause )
161172 . predicates
162- . push ( parse_quote ! ( #param: ' async_trait) ) ;
173+ . push ( parse_quote_spanned ! ( span => #param: ' async_trait) ) ;
163174 }
164175 GenericParam :: Lifetime ( param) => {
165176 let param = & param. lifetime ;
166- where_clause
177+ let span = param. span ( ) ;
178+ where_clause_or_default ( & mut sig. generics . where_clause )
167179 . predicates
168- . push ( parse_quote ! ( #param: ' async_trait) ) ;
180+ . push ( parse_quote_spanned ! ( span => #param: ' async_trait) ) ;
169181 }
170182 GenericParam :: Const ( _) => { }
171183 }
172184 }
185+
173186 for elided in lifetimes. elided {
174- sig. generics . params . push ( parse_quote ! ( #elided) ) ;
175- where_clause
187+ push_param ( & mut sig. generics , parse_quote ! ( #elided) ) ;
188+ where_clause_or_default ( & mut sig . generics . where_clause )
176189 . predicates
177- . push ( parse_quote ! ( #elided: ' async_trait) ) ;
190+ . push ( parse_quote_spanned ! ( elided . span ( ) => #elided: ' async_trait) ) ;
178191 }
179- sig. generics . params . push ( parse_quote ! ( ' async_trait) ) ;
192+
193+ push_param ( & mut sig. generics , parse_quote_spanned ! ( default_span => ' async_trait) ) ;
194+
180195 if has_self {
181196 let bound: Ident = match sig. inputs . iter ( ) . next ( ) {
182197 Some ( FnArg :: Receiver ( Receiver {
@@ -200,10 +215,11 @@ fn transform_sig(
200215 Context :: Trait { supertraits, .. } => !has_default || has_bound ( supertraits, & bound) ,
201216 Context :: Impl { .. } => true ,
202217 } ;
218+ let where_clause = where_clause_or_default ( & mut sig. generics . where_clause ) ;
203219 where_clause. predicates . push ( if assume_bound || is_local {
204- parse_quote ! ( Self : ' async_trait)
220+ parse_quote_spanned ! ( where_clause . span ( ) => Self : ' async_trait)
205221 } else {
206- parse_quote ! ( Self : :: core:: marker:: #bound + ' async_trait)
222+ parse_quote_spanned ! ( where_clause . span ( ) => Self : :: core:: marker:: #bound + ' async_trait)
207223 } ) ;
208224 }
209225
@@ -228,9 +244,9 @@ fn transform_sig(
228244 }
229245
230246 let bounds = if is_local {
231- quote ! ( ' async_trait)
247+ quote_spanned ! ( context . generics_span ( ) => ' async_trait)
232248 } else {
233- quote ! ( :: core:: marker:: Send + ' async_trait)
249+ quote_spanned ! ( context . generics_span ( ) => :: core:: marker:: Send + ' async_trait)
234250 } ;
235251
236252 sig. output = parse_quote ! {
@@ -333,3 +349,20 @@ fn has_bound(supertraits: &Supertraits, marker: &Ident) -> bool {
333349 }
334350 false
335351}
352+
353+ fn where_clause_or_default ( clause : & mut Option < WhereClause > ) -> & mut WhereClause {
354+ clause. get_or_insert_with ( || WhereClause {
355+ where_token : Default :: default ( ) ,
356+ predicates : Punctuated :: new ( ) ,
357+ } )
358+ }
359+
360+ fn push_param ( generics : & mut Generics , param : GenericParam ) {
361+ let span = param. span ( ) ;
362+ if generics. params . is_empty ( ) {
363+ generics. lt_token = parse_quote_spanned ! ( span => <) ;
364+ generics. gt_token = parse_quote_spanned ! ( span => >) ;
365+ }
366+
367+ generics. params . push ( param) ;
368+ }
0 commit comments