Warning: Plugins are an advanced, unstable feature! For many details,
the only available documentation is the libsyntax
and librustc
API docs, or even the source
code itself. These internal compiler APIs are also subject to change at any
time.
For defining new syntax it is often much easier to use Rust's built-in macro system.
The code in this document uses language features not covered in the Rust
Guide. See the Reference Manual for more
information.
# Introduction
`rustc` can load compiler plugins, which are user-provided libraries that
extend the compiler's behavior with new syntax extensions, lint checks, etc.
A plugin is a dynamic library crate with a designated "registrar" function that
registers extensions with `rustc`. Other crates can use these extensions by
loading the plugin crate with `#[phase(plugin)] extern crate`. See the
[`rustc::plugin`](rustc/plugin/index.html) documentation for more about the
mechanics of defining and loading a plugin.
# Syntax extensions
Plugins can extend Rust's syntax in various ways. One kind of syntax extension
is the procedural macro. These are invoked the same way as [ordinary
macros](guide-macros.html), but the expansion is performed by arbitrary Rust
code that manipulates [syntax trees](syntax/ast/index.html) at
compile time.
Let's write a plugin
[`roman_numerals.rs`](https://github.com/rust-lang/rust/tree/master/src/test/auxiliary/roman_numerals.rs)
that implements Roman numeral integer literals.
```ignore
#![crate_type="dylib"]
#![feature(plugin_registrar)]
extern crate syntax;
extern crate rustc;
use syntax::codemap::Span;
use syntax::parse::token::{IDENT, get_ident};
use syntax::ast::{TokenTree, TTToken};
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
use syntax::ext::build::AstBuilder; // trait for expr_uint
use rustc::plugin::Registry;
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
-> Box