Skip to content

Commit 9a2286d

Browse files
committed
auto merge of #16995 : kmcallister/rust/plugin-tutorial, r=alexcrichton
@steveklabnik, are you interested in looking this over?
2 parents aa034cd + 3f0c483 commit 9a2286d

15 files changed

+473
-19
lines changed

configure

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,7 @@ do
921921
make_dir $h/test/doc-guide-pointers
922922
make_dir $h/test/doc-guide-container
923923
make_dir $h/test/doc-guide-tasks
924+
make_dir $h/test/doc-guide-plugin
924925
make_dir $h/test/doc-rust
925926
done
926927

mk/docs.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
######################################################################
2828
DOCS := index intro tutorial guide guide-ffi guide-macros guide-lifetimes \
2929
guide-tasks guide-container guide-pointers guide-testing \
30-
guide-runtime complement-bugreport \
30+
guide-runtime guide-plugin complement-bugreport \
3131
complement-lang-faq complement-design-faq complement-project-faq rust \
3232
rustdoc guide-unsafe guide-strings reference
3333

src/doc/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ something like:
3333
pandoc --from=markdown --to=html5 --number-sections -o reference.html reference.md
3434
~~~~
3535

36-
(rust.md being the Rust Reference Manual.)
36+
(reference.md being the Rust Reference Manual.)
3737

3838
The syntax for pandoc flavored markdown can be found at:
3939
http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown

src/doc/complement-design-faq.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ representation as a primitive. This allows using Rust `enum`s in FFI where C
3939
`enum`s are also used, for most use cases. The attribute can also be applied
4040
to `struct`s to get the same layout as a C struct would.
4141

42-
[repr]: http://doc.rust-lang.org/rust.html#miscellaneous-attributes
42+
[repr]: reference.html#miscellaneous-attributes
4343

4444
## There is no GC
4545

@@ -56,7 +56,7 @@ Types which are [`Sync`][sync] are thread-safe when multiple shared
5656
references to them are used concurrently. Types which are not `Sync` are not
5757
thread-safe, and thus when used in a global require unsafe code to use.
5858

59-
[sync]: http://doc.rust-lang.org/core/kinds/trait.Sync.html
59+
[sync]: core/kinds/trait.Sync.html
6060

6161
### If mutable static items that implement `Sync` are safe, why is taking &mut SHARABLE unsafe?
6262

@@ -139,8 +139,8 @@ and explicitly calling the `clone` method. Making user-defined copy operators
139139
explicit surfaces the underlying complexity, forcing the developer to opt-in
140140
to potentially expensive operations.
141141

142-
[copy]: http://doc.rust-lang.org/core/kinds/trait.Copy.html
143-
[clone]: http://doc.rust-lang.org/core/clone/trait.Clone.html
142+
[copy]: core/kinds/trait.Copy.html
143+
[clone]: core/clone/trait.Clone.html
144144

145145
## No move constructors
146146

src/doc/guide-macros.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
% The Rust Macros Guide
22

3+
<div class="unstable-feature">
4+
<b>Warning:</b> There are currently various problems with invoking macros, how
5+
they interact with their environment, and how they are used outside of the
6+
location in which they are defined. Macro definitions are likely to change
7+
slightly in the future. For this reason, they are hidden behind the
8+
<code>macro_rules</code> <a href="reference.html#compiler-features">feature
9+
attribute</a>.
10+
</div>
11+
312
# Introduction
413

514
Functions are the primary tool that programmers can use to build abstractions.
@@ -448,6 +457,66 @@ fn main() {
448457
The two `'x` names did not clash, which would have caused the loop
449458
to print "I am never printed" and to run forever.
450459

460+
# Scoping and macro import/export
461+
462+
Macros occupy a single global namespace. The interaction with Rust's system of
463+
modules and crates is somewhat complex.
464+
465+
Definition and expansion of macros both happen in a single depth-first,
466+
lexical-order traversal of a crate's source. So a macro defined at module scope
467+
is visible to any subsequent code in the same module, which includes the body
468+
of any subsequent child `mod` items.
469+
470+
If a module has the `macro_escape` attribute, its macros are also visible in
471+
its parent module after the child's `mod` item. If the parent also has
472+
`macro_escape` then the macros will be visible in the grandparent after the
473+
parent's `mod` item, and so forth.
474+
475+
Independent of `macro_escape`, the `macro_export` attribute controls visibility
476+
between crates. Any `macro_rules!` definition with the `macro_export`
477+
attribute will be visible to other crates that have loaded this crate with
478+
`phase(plugin)`. There is currently no way for the importing crate to control
479+
which macros are imported.
480+
481+
An example:
482+
483+
```rust
484+
# #![feature(macro_rules)]
485+
macro_rules! m1 (() => (()))
486+
487+
// visible here: m1
488+
489+
mod foo {
490+
// visible here: m1
491+
492+
#[macro_export]
493+
macro_rules! m2 (() => (()))
494+
495+
// visible here: m1, m2
496+
}
497+
498+
// visible here: m1
499+
500+
macro_rules! m3 (() => (()))
501+
502+
// visible here: m1, m3
503+
504+
#[macro_escape]
505+
mod bar {
506+
// visible here: m1, m3
507+
508+
macro_rules! m4 (() => (()))
509+
510+
// visible here: m1, m3, m4
511+
}
512+
513+
// visible here: m1, m3, m4
514+
# fn main() { }
515+
```
516+
517+
When this library is loaded with `#[phase(plugin)] extern crate`, only `m2`
518+
will be imported.
519+
451520
# A final note
452521

453522
Macros, as currently implemented, are not for the faint of heart. Even
@@ -457,3 +526,10 @@ tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
457526
states, invoking `trace_macros!(true)` will automatically print those
458527
intermediate states out, and passing the flag `--pretty expanded` as a
459528
command-line argument to the compiler will show the result of expansion.
529+
530+
If Rust's macro system can't do what you need, you may want to write a
531+
[compiler plugin](guide-plugin.html) instead. Compared to `macro_rules!`
532+
macros, this is significantly more work, the interfaces are much less stable,
533+
and the warnings about debugging apply ten-fold. In exchange you get the
534+
flexibility of running arbitrary Rust code within the compiler. Syntax
535+
extension plugins are sometimes called "procedural macros" for this reason.

0 commit comments

Comments
 (0)