@@ -264,39 +264,45 @@ pub fn instrument(
264264 // the future instead of the wrapper
265265 if let Some ( internal_fun) = get_async_trait_info ( & input. block , input. sig . asyncness . is_some ( ) ) {
266266 // let's rewrite some statements!
267- let mut out_stmts = Vec :: with_capacity ( input. block . stmts . len ( ) ) ;
268- for stmt in & input. block . stmts {
269- if stmt == internal_fun. source_stmt {
270- match internal_fun. kind {
271- // async-trait <= 0.1.43
272- AsyncTraitKind :: Function ( fun) => {
273- out_stmts. push ( gen_function (
274- fun,
275- args,
276- instrumented_function_name,
277- internal_fun. self_type ,
278- ) ) ;
279- }
280- // async-trait >= 0.1.44
281- AsyncTraitKind :: Async ( async_expr) => {
282- // fallback if we couldn't find the '__async_trait' binding, might be
283- // useful for crates exhibiting the same behaviors as async-trait
284- let instrumented_block = gen_block (
285- & async_expr. block ,
286- & input. sig . inputs ,
287- true ,
288- args,
289- instrumented_function_name,
290- None ,
291- ) ;
292- let async_attrs = & async_expr. attrs ;
293- out_stmts. push ( quote ! {
294- Box :: pin( #( #async_attrs) * async move { #instrumented_block } )
295- } ) ;
267+ let mut out_stmts: Vec < TokenStream > = input
268+ . block
269+ . stmts
270+ . iter ( )
271+ . map ( |stmt| stmt. to_token_stream ( ) )
272+ . collect ( ) ;
273+
274+ if let Some ( ( iter, _stmt) ) = input
275+ . block
276+ . stmts
277+ . iter ( )
278+ . enumerate ( )
279+ . find ( |( _iter, stmt) | * stmt == internal_fun. source_stmt )
280+ {
281+ // instrument the future by rewriting the corresponding statement
282+ out_stmts[ iter] = match internal_fun. kind {
283+ // async-trait <= 0.1.43
284+ AsyncTraitKind :: Function ( fun) => gen_function (
285+ fun,
286+ args,
287+ instrumented_function_name. as_str ( ) ,
288+ internal_fun. self_type . as_ref ( ) ,
289+ ) ,
290+ // async-trait >= 0.1.44
291+ AsyncTraitKind :: Async ( async_expr) => {
292+ let instrumented_block = gen_block (
293+ & async_expr. block ,
294+ & input. sig . inputs ,
295+ true ,
296+ args,
297+ instrumented_function_name. as_str ( ) ,
298+ None ,
299+ ) ;
300+ let async_attrs = & async_expr. attrs ;
301+ quote ! {
302+ Box :: pin( #( #async_attrs) * async move { #instrumented_block } )
296303 }
297304 }
298- break ;
299- }
305+ } ;
300306 }
301307
302308 let vis = & input. vis ;
@@ -310,16 +316,16 @@ pub fn instrument(
310316 )
311317 . into ( )
312318 } else {
313- gen_function ( & input, args, instrumented_function_name, None ) . into ( )
319+ gen_function ( & input, args, instrumented_function_name. as_str ( ) , None ) . into ( )
314320 }
315321}
316322
317323/// Given an existing function, generate an instrumented version of that function
318324fn gen_function (
319325 input : & ItemFn ,
320326 args : InstrumentArgs ,
321- instrumented_function_name : String ,
322- self_type : Option < syn:: TypePath > ,
327+ instrumented_function_name : & str ,
328+ self_type : Option < & syn:: TypePath > ,
323329) -> proc_macro2:: TokenStream {
324330 // these are needed ahead of time, as ItemFn contains the function body _and_
325331 // isn't representable inside a quote!/quote_spanned! macro
@@ -377,8 +383,8 @@ fn gen_block(
377383 params : & Punctuated < FnArg , Token ! [ , ] > ,
378384 async_context : bool ,
379385 mut args : InstrumentArgs ,
380- instrumented_function_name : String ,
381- self_type : Option < syn:: TypePath > ,
386+ instrumented_function_name : & str ,
387+ self_type : Option < & syn:: TypePath > ,
382388) -> proc_macro2:: TokenStream {
383389 let err = args. err ;
384390
@@ -465,7 +471,7 @@ fn gen_block(
465471 // when async-trait <=0.1.43 is in use, replace instances
466472 // of the "Self" type inside the fields values
467473 if let Some ( self_type) = self_type {
468- replacer. types . push ( ( "Self" , self_type) ) ;
474+ replacer. types . push ( ( "Self" , self_type. clone ( ) ) ) ;
469475 }
470476
471477 for e in fields. iter_mut ( ) . filter_map ( |f| f. value . as_mut ( ) ) {
0 commit comments