]> git.proxmox.com Git - rustc.git/blame - src/vendor/quote/README.md
New upstream version 1.30.0~beta.7+dfsg1
[rustc.git] / src / vendor / quote / README.md
CommitLineData
3b2f2976
XL
1Rust Quasi-Quoting
2==================
3
4[![Build Status](https://api.travis-ci.org/dtolnay/quote.svg?branch=master)](https://travis-ci.org/dtolnay/quote)
5[![Latest Version](https://img.shields.io/crates/v/quote.svg)](https://crates.io/crates/quote)
6[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/quote/)
7
0531ce1d
XL
8This crate provides the [`quote!`] macro for turning Rust syntax tree data
9structures into tokens of source code.
10
8faf50e0 11[`quote!`]: https://docs.rs/quote/0.6/quote/macro.quote.html
0531ce1d
XL
12
13Procedural macros in Rust receive a stream of tokens as input, execute arbitrary
14Rust code to determine how to manipulate those tokens, and produce a stream of
15tokens to hand back to the compiler to compile into the caller's crate.
16Quasi-quoting is a solution to one piece of that -- producing tokens to return
17to the compiler.
18
19The idea of quasi-quoting is that we write *code* that we treat as *data*.
20Within the `quote!` macro, we can write what looks like code to our text editor
21or IDE. We get all the benefits of the editor's brace matching, syntax
22highlighting, indentation, and maybe autocompletion. But rather than compiling
23that as code into the current crate, we can treat it as data, pass it around,
24mutate it, and eventually hand it back to the compiler as tokens to compile into
25the macro caller's crate.
26
27This crate is motivated by the procedural macro use case, but is a
28general-purpose Rust quasi-quoting library and is not specific to procedural
29macros.
30
31*Version requirement: Quote supports any compiler version back to Rust's very
32first support for procedural macros in Rust 1.15.0.*
3b2f2976 33
8faf50e0
XL
34[*Release notes*](https://github.com/dtolnay/quote/releases)
35
3b2f2976
XL
36```toml
37[dependencies]
8faf50e0 38quote = "0.6"
3b2f2976
XL
39```
40
41```rust
42#[macro_use]
43extern crate quote;
44```
45
3b2f2976
XL
46## Syntax
47
0531ce1d 48The quote crate provides a [`quote!`] macro within which you can write Rust code
8faf50e0
XL
49that gets packaged into a [`TokenStream`] and can be treated as data. You should
50think of `TokenStream` as representing a fragment of Rust source code. This type
51can be returned directly back to the compiler by a procedural macro to get
52compiled into the caller's crate.
0531ce1d 53
8faf50e0 54[`TokenStream`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.TokenStream.html
3b2f2976
XL
55
56Within the `quote!` macro, interpolation is done with `#var`. Any type
0531ce1d
XL
57implementing the [`quote::ToTokens`] trait can be interpolated. This includes
58most Rust primitive types as well as most of the syntax tree types from [`syn`].
59
8faf50e0 60[`quote::ToTokens`]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html
0531ce1d 61[`syn`]: https://github.com/dtolnay/syn
3b2f2976
XL
62
63```rust
64let tokens = quote! {
65 struct SerializeWith #generics #where_clause {
66 value: &'a #field_ty,
67 phantom: ::std::marker::PhantomData<#item_ty>,
68 }
69
70 impl #generics serde::Serialize for SerializeWith #generics #where_clause {
b7449926 71 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
8faf50e0
XL
72 where
73 S: serde::Serializer,
3b2f2976 74 {
b7449926 75 #path(self.value, serializer)
3b2f2976
XL
76 }
77 }
78
79 SerializeWith {
80 value: #value,
81 phantom: ::std::marker::PhantomData::<#item_ty>,
82 }
83};
84```
85
0531ce1d 86## Repetition
3b2f2976 87
0531ce1d
XL
88Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This
89iterates through the elements of any variable interpolated within the repetition
90and inserts a copy of the repetition body for each one. The variables in an
91interpolation may be anything that implements `IntoIterator`, including `Vec` or
92a pre-existing iterator.
3b2f2976 93
0531ce1d
XL
94- `#(#var)*` — no separators
95- `#(#var),*` — the character before the asterisk is used as a separator
96- `#( struct #var; )*` — the repetition can contain other things
97- `#( #k => println!("{}", #v), )*` — even multiple interpolations
3b2f2976 98
0531ce1d
XL
99Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter
100does not produce a trailing comma. This matches the behavior of delimiters in
101`macro_rules!`.
102
103## Hygiene
104
105Any interpolated tokens preserve the `Span` information provided by their
106`ToTokens` implementation. Tokens that originate within a `quote!` invocation
8faf50e0 107are spanned with [`Span::call_site()`].
0531ce1d 108
8faf50e0 109[`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site
0531ce1d
XL
110
111A different span can be provided explicitly through the [`quote_spanned!`]
112macro.
113
8faf50e0
XL
114[`quote_spanned!`]: https://docs.rs/quote/0.6/quote/macro.quote_spanned.html
115
116### Limitations
117
118- A non-repeating variable may not be interpolated inside of a repeating block
119 ([#7]).
120- The same variable may not be interpolated more than once inside of a repeating
121 block ([#8]).
122
123[#7]: https://github.com/dtolnay/quote/issues/7
124[#8]: https://github.com/dtolnay/quote/issues/8
0531ce1d
XL
125
126### Recursion limit
3b2f2976
XL
127
128The `quote!` macro relies on deep recursion so some large invocations may fail
129with "recursion limit reached" when you compile. If it fails, bump up the
130recursion limit by adding `#![recursion_limit = "128"]` to your crate. An even
131higher limit may be necessary for especially large invocations. You don't need
132this unless the compiler tells you that you need it.
133
134## License
135
136Licensed under either of
137
138 * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
139 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
140
141at your option.
142
143### Contribution
144
145Unless you explicitly state otherwise, any contribution intentionally submitted
146for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
147be dual licensed as above, without any additional terms or conditions.