4 |
5 |
6 | Warning: Plugins are an advanced, unstable feature! For many details,
7 | the only available documentation is the libsyntax and librustc API docs, or even the source
10 | code itself. These internal compiler APIs are also subject to change at any
11 | time.
12 |
13 |
14 |
15 | For defining new syntax it is often much easier to use Rust's built-in macro system.
17 |
18 |
19 |
20 | The code in this document uses language features not covered in the Rust
21 | Guide. See the Reference Manual for more
22 | information.
23 |
24 |
25 |
26 |
27 | # Introduction
28 |
29 | `rustc` can load compiler plugins, which are user-provided libraries that
30 | extend the compiler's behavior with new syntax extensions, lint checks, etc.
31 |
32 | A plugin is a dynamic library crate with a designated *registrar* function that
33 | registers extensions with `rustc`. Other crates can load these extensions using
34 | the crate attribute `#![plugin(...)]`. See the
35 | [`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
36 | mechanics of defining and loading a plugin.
37 |
38 | If present, arguments passed as `#![plugin(foo(... args ...))]` are not
39 | interpreted by rustc itself. They are provided to the plugin through the
40 | `Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
41 |
42 | In the vast majority of cases, a plugin should *only* be used through
43 | `#![plugin]` and not through an `extern crate` item. Linking a plugin would
44 | pull in all of libsyntax and librustc as dependencies of your crate. This is
45 | generally unwanted unless you are building another plugin. The
46 | `plugin_as_library` lint checks these guidelines.
47 |
48 | The usual practice is to put compiler plugins in their own crate, separate from
49 | any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
50 | of a library.
51 |
52 | # Syntax extensions
53 |
54 | Plugins can extend Rust's syntax in various ways. One kind of syntax extension
55 | is the procedural macro. These are invoked the same way as [ordinary
56 | macros](macros.html), but the expansion is performed by arbitrary Rust
57 | code that manipulates [syntax trees](../syntax/ast/index.html) at
58 | compile time.
59 |
60 | Let's write a plugin
61 | [`roman_numerals.rs`](https://github.com/rust-lang/rust/tree/master/src/test/auxiliary/roman_numerals.rs)
62 | that implements Roman numeral integer literals.
63 |
64 | ```ignore
65 | #![crate_type="dylib"]
66 | #![feature(plugin_registrar, rustc_private)]
67 |
68 | extern crate syntax;
69 | extern crate rustc;
70 |
71 | use syntax::codemap::Span;
72 | use syntax::parse::token;
73 | use syntax::ast::{TokenTree, TtToken};
74 | use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
75 | use syntax::ext::build::AstBuilder; // trait for expr_usize
76 | use rustc::plugin::Registry;
77 |
78 | fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
79 | -> Box