• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/H03-May-2022-2723

src/H03-May-2022-1,045790

tests/H03-May-2022-6346

.cargo-checksum.jsonH A D03-May-202289 11

.cargo_vcs_info.jsonH A D28-Oct-202074 65

.gitignoreH A D25-Apr-201918 32

Cargo.tomlH A D28-Oct-20201.2 KiB4537

Cargo.toml.orig-cargoH A D28-Oct-2020716 2823

LICENSE-APACHEH A D25-Apr-201910.6 KiB202169

LICENSE-MITH A D25-Apr-20191 KiB2622

README.mdH A D27-Oct-20206.5 KiB156115

build.rsH A D27-Oct-20201.1 KiB3222

README.md

1Procedural macros in expression position
2========================================
3
4[<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)
5[<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)
6[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-proc--macro--hack-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/proc-macro-hack)
7[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/proc-macro-hack/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/proc-macro-hack/actions?query=branch%3Amaster)
8
9<table><tr><td><hr>
10<b>Note:</b> <i>As of Rust 1.45 this crate is superseded by native support for
11#[proc_macro] in expression position. Only consider using this crate if you care
12about supporting compilers between 1.31 and 1.45.</i>
13<hr></td></tr></table>
14
15Since Rust 1.30, the language supports user-defined function-like procedural
16macros. However these can only be invoked in item position, not in statements or
17expressions.
18
19This crate implements an alternative type of procedural macro that can be
20invoked in statement or expression position.
21
22This approach works with any Rust version 1.31+.
23
24## Defining procedural macros
25
26Two crates are required to define a procedural macro.
27
28### The implementation crate
29
30This crate must contain nothing but procedural macros. Private helper
31functions and private modules are fine but nothing can be public.
32
33[&raquo; example of an implementation crate][demo-hack-impl]
34
35Just like you would use a #\[proc_macro\] attribute to define a natively
36supported procedural macro, use proc-macro-hack's #\[proc_macro_hack\]
37attribute to define a procedural macro that works in expression position.
38The function signature is the same as for ordinary function-like procedural
39macros.
40
41```rust
42use proc_macro::TokenStream;
43use proc_macro_hack::proc_macro_hack;
44use quote::quote;
45use syn::{parse_macro_input, Expr};
46
47#[proc_macro_hack]
48pub fn add_one(input: TokenStream) -> TokenStream {
49    let expr = parse_macro_input!(input as Expr);
50    TokenStream::from(quote! {
51        1 + (#expr)
52    })
53}
54```
55
56### The declaration crate
57
58This crate is allowed to contain other public things if you need, for
59example traits or functions or ordinary macros.
60
61[&raquo; example of a declaration crate][demo-hack]
62
63Within the declaration crate there needs to be a re-export of your
64procedural macro from the implementation crate. The re-export also carries a
65\#\[proc_macro_hack\] attribute.
66
67```rust
68use proc_macro_hack::proc_macro_hack;
69
70/// Add one to an expression.
71///
72/// (Documentation goes here on the re-export, not in the other crate.)
73#[proc_macro_hack]
74pub use demo_hack_impl::add_one;
75```
76
77Both crates depend on `proc-macro-hack`:
78
79```toml
80[dependencies]
81proc-macro-hack = "0.5"
82```
83
84Additionally, your implementation crate (but not your declaration crate) is
85a proc macro crate:
86
87```toml
88[lib]
89proc-macro = true
90```
91
92## Using procedural macros
93
94Users of your crate depend on your declaration crate (not your
95implementation crate), then use your procedural macros as usual.
96
97[&raquo; example of a downstream crate][example]
98
99```rust
100use demo_hack::add_one;
101
102fn main() {
103    let two = 2;
104    let nine = add_one!(two) + add_one!(2 + 3);
105    println!("nine = {}", nine);
106}
107```
108
109[demo-hack-impl]: https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack-impl
110[demo-hack]: https://github.com/dtolnay/proc-macro-hack/tree/master/demo-hack
111[example]: https://github.com/dtolnay/proc-macro-hack/tree/master/example
112
113## Limitations
114
115- Only proc macros in expression position are supported. Proc macros in pattern
116  position ([#20]) are not supported.
117
118- By default, nested invocations are not supported i.e. the code emitted by a
119  proc-macro-hack macro invocation cannot contain recursive calls to the same
120  proc-macro-hack macro nor calls to any other proc-macro-hack macros. Use
121  [`proc-macro-nested`] if you require support for nested invocations.
122
123- By default, hygiene is structured such that the expanded code can't refer to
124  local variables other than those passed by name somewhere in the macro input.
125  If your macro must refer to *local* variables that don't get named in the
126  macro input, use `#[proc_macro_hack(fake_call_site)]` on the re-export in your
127  declaration crate. *Most macros won't need this.*
128
129- On compilers that are new enough to natively support proc macros in expression
130  position, proc-macro-hack does not automatically use that support, since the
131  hygiene can be subtly different between the two implementations. To opt in to
132  compiling your macro to native `#[proc_macro]` on sufficiently new compilers,
133  use `#[proc_macro_hack(only_hack_old_rustc)]` on the re-export in your
134  declaration crate.
135
136[#10]: https://github.com/dtolnay/proc-macro-hack/issues/10
137[#20]: https://github.com/dtolnay/proc-macro-hack/issues/20
138[`proc-macro-nested`]: https://docs.rs/proc-macro-nested
139
140<br>
141
142#### License
143
144<sup>
145Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
1462.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
147</sup>
148
149<br>
150
151<sub>
152Unless you explicitly state otherwise, any contribution intentionally submitted
153for inclusion in this hack by you, as defined in the Apache-2.0 license, shall
154be dual licensed as above, without any additional terms or conditions.
155</sub>
156