about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorKeegan McAllister <kmcallister@mozilla.com>2014-09-04 11:26:39 -0700
committerKeegan McAllister <kmcallister@mozilla.com>2014-10-01 13:21:52 -0700
commit4ced7a9637c10196883733fa81ac67d02269a76e (patch)
treea174488beab341ba22049ca0a61a5934c33c628a /src/doc
parentc8bdba77fca16ebf5ad6c63a37a8dd8fd2afda8e (diff)
downloadrust-4ced7a9637c10196883733fa81ac67d02269a76e.tar.gz
rust-4ced7a9637c10196883733fa81ac67d02269a76e.zip
Add some notes about macro scoping
Diffstat (limited to 'src/doc')
-rw-r--r--src/doc/guide-macros.md60
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