summaryrefslogtreecommitdiffstats
path: root/third_party/rust/proc-macro-hack/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/proc-macro-hack/README.md')
-rw-r--r--third_party/rust/proc-macro-hack/README.md155
1 files changed, 155 insertions, 0 deletions
diff --git a/third_party/rust/proc-macro-hack/README.md b/third_party/rust/proc-macro-hack/README.md
new file mode 100644
index 0000000000..b72b8ef9dd
--- /dev/null
+++ b/third_party/rust/proc-macro-hack/README.md
@@ -0,0 +1,155 @@
+Procedural macros in expression position
+========================================
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/proc--macro--hack-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/proc-macro-hack)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/proc-macro-hack.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/proc-macro-hack)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-proc--macro--hack-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/proc-macro-hack)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/proc-macro-hack/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/proc-macro-hack/actions?query=branch%3Amaster)
+
+<table><tr><td><hr>
+<b>Note:</b> <i>As of Rust 1.45 this crate is superseded by native support for
+#[proc_macro] in expression position. Only consider using this crate if you care
+about supporting compilers between 1.31 and 1.45.</i>
+<hr></td></tr></table>
+
+Since Rust 1.30, the language supports user-defined function-like procedural
+macros. However these can only be invoked in item position, not in statements or
+expressions.
+
+This crate implements an alternative type of procedural macro that can be
+invoked in statement or expression position.
+
+This approach works with any Rust version 1.31+.
+
+## Defining procedural macros
+
+Two crates are required to define a procedural macro.
+
+### The implementation crate
+
+This crate must contain nothing but procedural macros. Private helper
+functions and private modules are fine but nothing can be public.
+
+[&raquo; example of an implementation crate][demo-hack-impl]
+
+Just like you would use a #\[proc_macro\] attribute to define a natively
+supported procedural macro, use proc-macro-hack's #\[proc_macro_hack\]
+attribute to define a procedural macro that works in expression position.
+The function signature is the same as for ordinary function-like procedural
+macros.
+
+```rust
+use proc_macro::TokenStream;
+use proc_macro_hack::proc_macro_hack;
+use quote::quote;
+use syn::{parse_macro_input, Expr};
+
+#[proc_macro_hack]
+pub fn add_one(input: TokenStream) -> TokenStream {
+ let expr = parse_macro_input!(input as Expr);
+ TokenStream::from(quote! {
+ 1 + (#expr)
+ })
+}
+```
+
+### The declaration crate
+
+This crate is allowed to contain other public things if you need, for
+example traits or functions or ordinary macros.
+
+[&raquo; example of a declaration crate][demo-hack]
+
+Within the declaration crate there needs to be a re-export of your
+procedural macro from the implementation crate. The re-export also carries a
+\#\[proc_macro_hack\] attribute.
+
+```rust
+use proc_macro_hack::proc_macro_hack;
+
+/// Add one to an expression.
+///
+/// (Documentation goes here on the re-export, not in the other crate.)
+#[proc_macro_hack]
+pub use demo_hack_impl::add_one;
+```
+
+Both crates depend on `proc-macro-hack`:
+
+```toml
+[dependencies]
+proc-macro-hack = "0.5"
+```
+
+Additionally, your implementation crate (but not your declaration crate) is
+a proc macro crate:
+
+```toml
+[lib]
+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 usual.
+
+[&raquo; example of a downstream crate][example]
+
+```rust
+use demo_hack::add_one;
+
+fn main() {
+ let two = 2;
+ let nine = add_one!(two) + add_one!(2 + 3);
+ println!("nine = {}", nine);
+}
+```
+
+[demo-hack-impl]: https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack-impl
+[demo-hack]: https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack
+[example]: https://github.com/dtolnay/proc-macro-hack/tree/master/example
+
+## Limitations
+
+- Only proc macros in expression position are supported. Proc macros in pattern
+ position ([#20]) are not supported.
+
+- By default, nested invocations are not supported i.e. the code emitted by a
+ proc-macro-hack macro invocation cannot contain recursive calls to the same
+ proc-macro-hack macro nor calls to any other proc-macro-hack macros. Use
+ [`proc-macro-nested`] if you require support for nested invocations.
+
+- By default, hygiene is structured such that the expanded code can't refer to
+ local variables other than those passed by name somewhere in the macro input.
+ If your macro must refer to *local* variables that don't get named in the
+ macro input, use `#[proc_macro_hack(fake_call_site)]` on the re-export in your
+ declaration crate. *Most macros won't need this.*
+
+- On compilers that are new enough to natively support proc macros in expression
+ position, proc-macro-hack does not automatically use that support, since the
+ hygiene can be subtly different between the two implementations. To opt in to
+ compiling your macro to native `#[proc_macro]` on sufficiently new compilers,
+ use `#[proc_macro_hack(only_hack_old_rustc)]` on the re-export in your
+ declaration crate.
+
+[#10]: https://github.com/dtolnay/proc-macro-hack/issues/10
+[#20]: https://github.com/dtolnay/proc-macro-hack/issues/20
+[`proc-macro-nested`]: https://docs.rs/proc-macro-nested
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>