Procedural functionlike!() macros using only Macros 1.1
Did you think Macros 1.1 was only for custom derives? Think again.
Note: Requires stable Rust 1.15 or beta Rust 1.16. This library is currently affected by a regression in rustc, rust-lang/rust#39889, and does not work on the most recent nightlies. It works on stable and beta but not nightly. How times have changed, huh? A fix has been merged in rust-lang/rust#39419 and should be in the next nightly after March 1.
Defining procedural macros
Two crates are required to define a macro.
The declaration crate
This crate is allowed to contain other public things if you need, for example traits or functions or ordinary macros.
https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack
extern crate proc_macro_hack;
extern crate demo_hack_impl;
pub use *;
/// Add one to an expression.
proc_macro_expr_decl!;
/// A function that always returns 2.
proc_macro_item_decl!;
The implementation crate
This crate must contain nothing but procedural macros. Private helper functions and private modules are fine but nothing can be public.
https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack-impl
extern crate proc_macro_hack;
proc_macro_expr_impl!
proc_macro_item_impl!
Both crates depend on proc-macro-hack
:
[]
= "0.3"
Additionally, your implementation crate (but not your declaration crate) is a proc macro:
[]
= true
Using procedural macros
Users of your crate depend on your declaration crate (not your implementation crate), then use your procedural macros as though it were magic. They even get reasonable error messages if your procedural macro panics.
https://github.com/dtolnay/proc-macro-hack/tree/master/example
extern crate demo_hack;
two_fn!;
Limitations
- The input to your macro cannot contain dollar signs.
- Your macro must expand to either an expression or zero-or-more items, cannot sometimes be one or the other depending on input.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this hack by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.