diff --git a/src/doc/reference.md b/src/doc/reference.md index 31524579df7..781b40be768 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -731,15 +731,20 @@ Rust syntax is restricted in two ways: pairs when they occur at the beginning of, or immediately after, a `$(...)*`; requiring a distinctive token in front can solve the problem. -## Syntax extensions useful for the macro author +## Syntax extensions useful in macros + +* `stringify!` : turn the identifier argument into a string literal +* `concat!` : concatenates a comma-separated list of literals + +## Syntax extensions for macro debugging * `log_syntax!` : print out the arguments at compile time * `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging -* `stringify!` : turn the identifier argument into a string literal -* `concat!` : concatenates a comma-separated list of literals -* `concat_idents!` : create a new identifier by concatenating the arguments -The following attributes are used for quasiquoting in procedural macros: +## Quasiquoting + +The following syntax extensions are used for quasiquoting Rust syntax trees, +usually in [procedural macros](book/plugins.html#syntax-extensions): * `quote_expr!` * `quote_item!` @@ -748,6 +753,8 @@ The following attributes are used for quasiquoting in procedural macros: * `quote_tokens!` * `quote_ty!` +Documentation is very limited at the moment. + # Crates and source files Rust is a *compiled* language. Its semantics obey a *phase distinction* diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md index 9a4cc57a1f7..a226e4d0bf9 100644 --- a/src/doc/trpl/advanced-macros.md +++ b/src/doc/trpl/advanced-macros.md @@ -239,19 +239,11 @@ fn main() { Exercise: use macros to reduce duplication in the above definition of the `bct!` macro. -# A final note - -Macros, as currently implemented, are not for the faint of heart. Even -ordinary syntax errors can be more difficult to debug when they occur inside a -macro, and errors caused by parse problems in generated code can be very -tricky. Invoking the `log_syntax!` macro can help elucidate intermediate -states, invoking `trace_macros!(true)` will automatically print those -intermediate states out, and passing the flag `--pretty expanded` as a -command-line argument to the compiler will show the result of expansion. +# Procedural macros If Rust's macro system can't do what you need, you may want to write a [compiler plugin](plugins.html) instead. Compared to `macro_rules!` macros, this is significantly more work, the interfaces are much less stable, -and the warnings about debugging apply ten-fold. In exchange you get the +and bugs can be much harder to track down. In exchange you get the flexibility of running arbitrary Rust code within the compiler. Syntax extension plugins are sometimes called *procedural macros* for this reason. diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index cf12b4938e2..ce48a5aeda4 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -405,6 +405,25 @@ fn main() { } ``` +# Debugging macro code + +To see the results of expanding macros, run `rustc --pretty expanded`. The +output represents a whole crate, so you can also feed it back in to `rustc`, +which will sometimes produce better error messages than the original +compilation. Note that the `--pretty expanded` output may have a different +meaning if multiple variables of the same name (but different syntax contexts) +are in play in the same scope. In this case `--pretty expanded,hygiene` will +tell you about the syntax contexts. + +`rustc` provides two syntax extensions that help with macro debugging. For now, +they are unstable and require feature gates. + +* `log_syntax!(...)` will print its arguments to standard output, at compile + time, and "expand" to nothing. + +* `trace_macros!(true)` will enable a compiler message every time a macro is + expanded. Use `trace_macros!(false)` later in expansion to turn it off. + # Further reading The [advanced macros chapter][] goes into more detail about macro syntax. It diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md index 79502f3cd17..f609a0a918a 100644 --- a/src/doc/trpl/plugins.md +++ b/src/doc/trpl/plugins.md @@ -146,14 +146,7 @@ a more involved macro example, see ## Tips and tricks -To see the results of expanding syntax extensions, run -`rustc --pretty expanded`. The output represents a whole crate, so you -can also feed it back in to `rustc`, which will sometimes produce better -error messages than the original compilation. Note that the -`--pretty expanded` output may have a different meaning if multiple -variables of the same name (but different syntax contexts) are in play -in the same scope. In this case `--pretty expanded,hygiene` will tell -you about the syntax contexts. +Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable. You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into higher-level syntax elements like expressions: @@ -184,6 +177,11 @@ and return [`DummyResult`](../syntax/ext/base/struct.DummyResult.html), so that the compiler can continue and find further errors. +To print syntax fragments for debugging, you can use +[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together +with +[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions). + The example above produced an integer literal using [`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint). As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of