Instrumenting Rust code with syntax extensions
Rust allows you to define your own syntax extensions such as custom item attributes that you can then annotate a function or a struct with. One interesting use case for doing so is code instrumentation. Say for a given function, you'd like to register all calls, time their execution and log return values. Doing so on a per-function basis would be tedious but if we defined a custom attribute trace_calls, we could then apply it on any function we want to instrument:
#[trace_calls(MyTrace)] fn my_function(x: uint) -> uint { x * 2 }
The attribute takes a single argument, which is the name of a type that implements a trait called FunctionCallTrace. Implementing that trait is all you need to do to define what you want to do on each function call. An example implementation would be logging each call with the time it took, like here.
Overall, meta programming of this sort in Rust has turned out to be a breeze, for a statically typed language. That is a combination of language features such as pattern matching that makes it easy to work with Rust's AST as well as quoting macros such as quote_stmt! which allows you to, instead of building up a part of the AST manually, dynamically produce Rust code at the parsing stage of your original program.













