7
7
extern crate proc_macro;
8
8
9
9
use proc_macro:: TokenStream ;
10
- use quote:: quote;
10
+ use quote:: { quote, quote_spanned} ;
11
+ use syn:: spanned:: Spanned ;
11
12
12
13
/// Defines the `instrument` function.
13
14
#[ proc_macro_attribute]
@@ -27,23 +28,25 @@ pub fn instrument(_attr: TokenStream, item: TokenStream) -> TokenStream {
27
28
let output = & input. decl . output ;
28
29
let body = & input. block . stmts ;
29
30
30
- let args: Vec < syn:: Pat > = inputs
31
- . pairs ( )
32
- . filter_map ( |pair| match pair. into_value ( ) {
33
- syn:: FnArg :: Captured ( arg) => Some ( arg. pat . clone ( ) ) ,
34
- _ => return None ,
35
- } )
36
- . collect ( ) ;
37
-
38
- let names: String = args
39
- . iter ( )
40
- . enumerate ( )
41
- . map ( |( i, _arg) | {
42
- let mut string = format ! ( ", arg_{:?}" , i) ;
43
- string. push_str ( "={:?}" ) ;
44
- string
45
- } )
46
- . collect ( ) ;
31
+ let mut names = String :: new ( ) ;
32
+ let mut args = Vec :: < syn:: Pat > :: new ( ) ;
33
+
34
+ for fn_arg in inputs {
35
+ if let syn:: FnArg :: Captured ( arg) = fn_arg {
36
+ let pat = arg. pat . clone ( ) ;
37
+
38
+ if let syn:: Pat :: Ident ( pat_ident) = & pat {
39
+ names. push_str ( & format ! ( ", {}={{:?}}" , pat_ident. ident) ) ;
40
+ } else {
41
+ let tokens = quote_spanned ! { fn_arg. span( ) =>
42
+ compile_error!( "instrumented functions need to name arguments" ) ;
43
+ } ;
44
+ return TokenStream :: from ( tokens) ;
45
+ }
46
+
47
+ args. push ( pat) ;
48
+ }
49
+ }
47
50
48
51
let result = quote ! {
49
52
#( #attrs) *
0 commit comments