1An example of an attribute procedural macro. The `#[trace_var(...)]` attribute 2prints the value of the given variables each time they are reassigned. 3 4- [`trace-var/src/lib.rs`](trace-var/src/lib.rs) 5- [`example/src/main.rs`](example/src/main.rs) 6 7Consider the following factorial implementation. 8 9```rust 10#[trace_var(p, n)] 11fn factorial(mut n: u64) -> u64 { 12 let mut p = 1; 13 while n > 1 { 14 p *= n; 15 n -= 1; 16 } 17 p 18} 19``` 20 21Invoking this with `factorial(8)` prints all the values of `p` and `n` during 22the execution of the function. 23 24``` 25p = 1 26p = 8 27n = 7 28p = 56 29n = 6 30p = 336 31n = 5 32p = 1680 33n = 4 34p = 6720 35n = 3 36p = 20160 37n = 2 38p = 40320 39n = 1 40``` 41 42The procedural macro uses a syntax tree [`Fold`] to rewrite every `let` 43statement and assignment expression in the following way: 44 45[`Fold`]: https://docs.rs/syn/1.0/syn/fold/trait.Fold.html 46 47```rust 48// Before 49let VAR = INIT; 50 51// After 52let VAR = { let VAR = INIT; println!("VAR = {:?}", VAR); VAR }; 53``` 54 55```rust 56// Before 57VAR = INIT 58 59// After 60{ VAR = INIT; println!("VAR = {:?}", VAR); } 61``` 62