diff options
| author | Keegan McAllister <kmcallister@mozilla.com> | 2014-09-04 11:26:39 -0700 |
|---|---|---|
| committer | Keegan McAllister <kmcallister@mozilla.com> | 2014-10-01 13:21:52 -0700 |
| commit | 4ced7a9637c10196883733fa81ac67d02269a76e (patch) | |
| tree | a174488beab341ba22049ca0a61a5934c33c628a /src/doc | |
| parent | c8bdba77fca16ebf5ad6c63a37a8dd8fd2afda8e (diff) | |
| download | rust-4ced7a9637c10196883733fa81ac67d02269a76e.tar.gz rust-4ced7a9637c10196883733fa81ac67d02269a76e.zip | |
Add some notes about macro scoping
Diffstat (limited to 'src/doc')
| -rw-r--r-- | src/doc/guide-macros.md | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/doc/guide-macros.md b/src/doc/guide-macros.md index 6d3825f8ecf..83571b60d3a 100644 --- a/src/doc/guide-macros.md +++ b/src/doc/guide-macros.md @@ -448,6 +448,66 @@ fn main() { The two `'x` names did not clash, which would have caused the loop to print "I am never printed" and to run forever. +# Scoping and macro import/export + +Macros occupy a single global namespace. The interaction with Rust's system of +modules and crates is somewhat complex. + +Definition and expansion of macros both happen in a single depth-first, +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. + +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. + +An example: + +```rust +# #![feature(macro_rules)] +macro_rules! m1 (() => (())) + +// visible here: m1 + +mod foo { + // visible here: m1 + + #[macro_export] + macro_rules! m2 (() => (())) + + // visible here: m1, m2 +} + +// visible here: m1 + +macro_rules! m3 (() => (())) + +// visible here: m1, m3 + +#[macro_escape] +mod bar { + // visible here: m1, m3 + + macro_rules! m4 (() => (())) + + // visible here: m1, m3, m4 +} + +// visible here: m1, m3, m4 +# fn main() { } +``` + +When this library is loaded with `#[phase(plugin)] extern crate`, only `m2` +will be imported. + # A final note Macros, as currently implemented, are not for the faint of heart. Even |
