about summary refs log tree commit diff
path: root/src/doc/guide-macros.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/guide-macros.md')
-rw-r--r--src/doc/guide-macros.md155
1 files changed, 97 insertions, 58 deletions
diff --git a/src/doc/guide-macros.md b/src/doc/guide-macros.md
index 58af5917407..dc6d281307a 100644
--- a/src/doc/guide-macros.md
+++ b/src/doc/guide-macros.md
@@ -1,14 +1,5 @@
 % The Rust Macros Guide
 
-<div class="unstable-feature">
-<b>Warning:</b> There are currently various problems with invoking macros, how
-they interact with their environment, and how they are used outside of the
-location in which they are defined. Macro definitions are likely to change
-slightly in the future. For this reason, they are hidden behind the
-<code>macro_rules</code> <a href="reference.html#compiler-features">feature
-attribute</a>.
-</div>
-
 # Introduction
 
 Functions are the primary tool that programmers can use to build abstractions.
@@ -46,19 +37,18 @@ lightweight custom syntax extensions, themselves defined using the
 the pattern in the above code:
 
 ~~~~
-# #![feature(macro_rules)]
 # enum T { SpecialA(uint), SpecialB(uint) }
 # fn f() -> uint {
 # let input_1 = T::SpecialA(0);
 # let input_2 = T::SpecialA(0);
-macro_rules! early_return(
+macro_rules! early_return {
     ($inp:expr $sp:path) => ( // invoke it like `(input_5 SpecialE)`
         match $inp {
             $sp(x) => { return x; }
             _ => {}
         }
     );
-);
+}
 // ...
 early_return!(input_1 T::SpecialA);
 // ...
@@ -109,10 +99,10 @@ that could be invoked like: `my_macro!(i->(( 2+2 )))`.
 
 ## Invocation location
 
-A macro invocation may take the place of (and therefore expand to)
-an expression, an item, or a statement.
-The Rust parser will parse the macro invocation as a "placeholder"
-for whichever of those three nonterminals is appropriate for the location.
+A macro invocation may take the place of (and therefore expand to) an
+expression, item, statement, or pattern.  The Rust parser will parse the macro
+invocation as a "placeholder" for whichever syntactic form is appropriate for
+the location.
 
 At expansion time, the output of the macro will be parsed as whichever of the
 three nonterminals it stands in for. This means that a single macro might,
@@ -166,12 +156,11 @@ separator token (a comma-separated list could be written `$(...),*`), and `+`
 instead of `*` to mean "at least one".
 
 ~~~~
-# #![feature(macro_rules)]
 # enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)}
 # fn f() -> uint {
 # let input_1 = T::SpecialA(0);
 # let input_2 = T::SpecialA(0);
-macro_rules! early_return(
+macro_rules! early_return {
     ($inp:expr, [ $($sp:path)|+ ]) => (
         match $inp {
             $(
@@ -180,7 +169,7 @@ macro_rules! early_return(
             _ => {}
         }
     )
-);
+}
 // ...
 early_return!(input_1, [T::SpecialA|T::SpecialC|T::SpecialD]);
 // ...
@@ -228,7 +217,6 @@ solves the problem.
 Now consider code like the following:
 
 ~~~~
-# #![feature(macro_rules)]
 # enum T1 { Good1(T2, uint), Bad1}
 # struct T2 { body: T3 }
 # enum T3 { Good2(uint), Bad2}
@@ -255,8 +243,7 @@ a match, but with a syntax that suits the problem better. The following macro
 can solve the problem:
 
 ~~~~
-# #![feature(macro_rules)]
-macro_rules! biased_match (
+macro_rules! biased_match {
     // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
     ( ($e:expr) ~ ($p:pat) else $err:stmt ;
       binds $bind_res:ident
@@ -275,7 +262,7 @@ macro_rules! biased_match (
             _ => { $err }
         };
     )
-);
+}
 
 # enum T1 { Good1(T2, uint), Bad1}
 # struct T2 { body: T3 }
@@ -297,13 +284,12 @@ like this, we might prefer to write a single macro invocation. The input
 pattern we want is clear:
 
 ~~~~
-# #![feature(macro_rules)]
 # fn main() {}
-# macro_rules! b(
+# macro_rules! b {
     ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
       binds $( $bind_res:ident ),*
     )
-# => (0));
+# => (0) }
 ~~~~
 
 However, it's not possible to directly expand to nested match statements. But
@@ -320,24 +306,22 @@ process the semicolon-terminated lines, one-by-one. So, we want the following
 input patterns:
 
 ~~~~
-# #![feature(macro_rules)]
-# macro_rules! b(
+# macro_rules! b {
     ( binds $( $bind_res:ident ),* )
-# => (0));
+# => (0) }
 # fn main() {}
 ~~~~
 
 ...and:
 
 ~~~~
-# #![feature(macro_rules)]
 # fn main() {}
-# macro_rules! b(
+# macro_rules! b {
     (    ($e     :expr) ~ ($p     :pat) else $err     :stmt ;
       $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
       binds  $( $bind_res:ident ),*
     )
-# => (0));
+# => (0) }
 ~~~~
 
 The resulting macro looks like this. Note that the separation into
@@ -345,10 +329,9 @@ The resulting macro looks like this. Note that the separation into
 piece of syntax (the `let`) which we only want to transcribe once.
 
 ~~~~
-# #![feature(macro_rules)]
 # fn main() {
 
-macro_rules! biased_match_rec (
+macro_rules! biased_match_rec {
     // Handle the first layer
     (   ($e     :expr) ~ ($p     :pat) else $err     :stmt ;
      $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
@@ -366,10 +349,10 @@ macro_rules! biased_match_rec (
     );
     // Produce the requested values
     ( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )
-);
+}
 
 // Wrap the whole thing in a `let`.
-macro_rules! biased_match (
+macro_rules! biased_match {
     // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
     ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
       binds $bind_res:ident
@@ -388,7 +371,7 @@ macro_rules! biased_match (
             binds $( $bind_res ),*
         );
     )
-);
+}
 
 
 # enum T1 { Good1(T2, uint), Bad1}
@@ -434,9 +417,7 @@ As an example, `loop` and `for-loop` labels (discussed in the lifetimes guide)
 will not clash. The following code will print "Hello!" only once:
 
 ~~~
-#![feature(macro_rules)]
-
-macro_rules! loop_x (
+macro_rules! loop_x {
     ($e: expr) => (
         // $e will not interact with this 'x
         'x: loop {
@@ -444,7 +425,7 @@ macro_rules! loop_x (
             $e
         }
     );
-);
+}
 
 fn main() {
     'x: loop {
@@ -467,22 +448,30 @@ lexical-order traversal of a crate's source. So a macro defined at module scope
 is visible to any subsequent code in the same module, which includes the body
 of any subsequent child `mod` items.
 
-If a module has the `macro_escape` attribute, its macros are also visible in
-its parent module after the child's `mod` item. If the parent also has
-`macro_escape` then the macros will be visible in the grandparent after the
-parent's `mod` item, and so forth.
+If a module has the `macro_use` attribute, its macros are also visible in its
+parent module after the child's `mod` item. If the parent also has `macro_use`
+then the macros will be visible in the grandparent after the parent's `mod`
+item, and so forth.
 
-Independent of `macro_escape`, the `macro_export` attribute controls visibility
-between crates.  Any `macro_rules!` definition with the `macro_export`
-attribute will be visible to other crates that have loaded this crate with
-`phase(plugin)`. There is currently no way for the importing crate to control
-which macros are imported.
+The `macro_use` attribute can also appear on `extern crate`.  In this context
+it controls which macros are loaded from the external crate, e.g.
+
+```rust,ignore
+#[macro_use(foo, bar)]
+extern crate baz;
+```
+
+If the attribute is given simply as `#[macro_use]`, all macros are loaded.  If
+there is no `#[macro_use]` attribute then no macros are loaded.  Only macros
+defined with the `#[macro_export]` attribute may be loaded.
+
+To load a crate's macros *without* linking it into the output, use `#[no_link]`
+as well.
 
 An example:
 
 ```rust
-# #![feature(macro_rules)]
-macro_rules! m1 (() => (()));
+macro_rules! m1 { () => (()) }
 
 // visible here: m1
 
@@ -490,22 +479,22 @@ mod foo {
     // visible here: m1
 
     #[macro_export]
-    macro_rules! m2 (() => (()));
+    macro_rules! m2 { () => (()) }
 
     // visible here: m1, m2
 }
 
 // visible here: m1
 
-macro_rules! m3 (() => (()));
+macro_rules! m3 { () => (()) }
 
 // visible here: m1, m3
 
-#[macro_escape]
+#[macro_use]
 mod bar {
     // visible here: m1, m3
 
-    macro_rules! m4 (() => (()));
+    macro_rules! m4 { () => (()) }
 
     // visible here: m1, m3, m4
 }
@@ -514,8 +503,58 @@ mod bar {
 # fn main() { }
 ```
 
-When this library is loaded with `#[phase(plugin)] extern crate`, only `m2`
-will be imported.
+When this library is loaded with `#[use_macros] extern crate`, only `m2` will
+be imported.
+
+The Rust Reference has a [listing of macro-related
+attributes](reference.html#macro--and-plugin-related-attributes).
+
+# The variable `$crate`
+
+A further difficulty occurs when a macro is used in multiple crates.  Say that
+`mylib` defines
+
+```rust
+pub fn increment(x: uint) -> uint {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! inc_a {
+    ($x:expr) => ( ::increment($x) )
+}
+
+#[macro_export]
+macro_rules! inc_b {
+    ($x:expr) => ( ::mylib::increment($x) )
+}
+# fn main() { }
+```
+
+`inc_a` only works within `mylib`, while `inc_b` only works outside the
+library.  Furthermore, `inc_b` will break if the user imports `mylib` under
+another name.
+
+Rust does not (yet) have a hygiene system for crate references, but it does
+provide a simple workaround for this problem.  Within a macro imported from a
+crate named `foo`, the special macro variable `$crate` will expand to `::foo`.
+By contrast, when a macro is defined and then used in the same crate, `$crate`
+will expand to nothing.  This means we can write
+
+```rust
+#[macro_export]
+macro_rules! inc {
+    ($x:expr) => ( $crate::increment($x) )
+}
+# fn main() { }
+```
+
+to define a single macro that works both inside and outside our library.  The
+function name will expand to either `::increment` or `::mylib::increment`.
+
+To keep this system simple and correct, `#[macro_use] extern crate ...` may
+only appear at the root of your crate, not inside `mod`.  This ensures that
+`$crate` is a single identifier.
 
 # A final note