]> git.proxmox.com Git - rustc.git/blame - src/vendor/quote/src/lib.rs
New upstream version 1.31.0+dfsg1
[rustc.git] / src / vendor / quote / src / lib.rs
CommitLineData
0531ce1d
XL
1//! This crate provides the [`quote!`] macro for turning Rust syntax tree data
2//! structures into tokens of source code.
3//!
4//! [`quote!`]: macro.quote.html
5//!
6//! Procedural macros in Rust receive a stream of tokens as input, execute
7//! arbitrary Rust code to determine how to manipulate those tokens, and produce
8//! a stream of tokens to hand back to the compiler to compile into the caller's
9//! crate. Quasi-quoting is a solution to one piece of that -- producing tokens
10//! to return to the compiler.
11//!
12//! The idea of quasi-quoting is that we write *code* that we treat as *data*.
13//! Within the `quote!` macro, we can write what looks like code to our text
14//! editor or IDE. We get all the benefits of the editor's brace matching,
15//! syntax highlighting, indentation, and maybe autocompletion. But rather than
16//! compiling that as code into the current crate, we can treat it as data, pass
17//! it around, mutate it, and eventually hand it back to the compiler as tokens
18//! to compile into the macro caller's crate.
19//!
20//! This crate is motivated by the procedural macro use case, but is a
21//! general-purpose Rust quasi-quoting library and is not specific to procedural
22//! macros.
23//!
24//! *Version requirement: Quote supports any compiler version back to Rust's
25//! very first support for procedural macros in Rust 1.15.0.*
3b2f2976
XL
26//!
27//! ```toml
28//! [dependencies]
8faf50e0 29//! quote = "0.6"
3b2f2976
XL
30//! ```
31//!
0531ce1d 32//! ```
3b2f2976
XL
33//! #[macro_use]
34//! extern crate quote;
0531ce1d
XL
35//! #
36//! # fn main() {}
3b2f2976
XL
37//! ```
38//!
0531ce1d 39//! # Example
3b2f2976 40//!
0531ce1d
XL
41//! The following quasi-quoted block of code is something you might find in [a]
42//! procedural macro having to do with data structure serialization. The `#var`
43//! syntax performs interpolation of runtime variables into the quoted tokens.
44//! Check out the documentation of the [`quote!`] macro for more detail about
45//! the syntax. See also the [`quote_spanned!`] macro which is important for
46//! implementing hygienic procedural macros.
47//!
48//! [a]: https://serde.rs/
49//! [`quote_spanned!`]: macro.quote_spanned.html
50//!
51//! ```
52//! # #[macro_use]
53//! # extern crate quote;
54//! #
55//! # fn main() {
56//! # let generics = "";
57//! # let where_clause = "";
58//! # let field_ty = "";
59//! # let item_ty = "";
60//! # let path = "";
61//! # let value = "";
62//! #
3b2f2976
XL
63//! let tokens = quote! {
64//! struct SerializeWith #generics #where_clause {
65//! value: &'a #field_ty,
66//! phantom: ::std::marker::PhantomData<#item_ty>,
67//! }
68//!
69//! impl #generics serde::Serialize for SerializeWith #generics #where_clause {
b7449926 70//! fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
8faf50e0
XL
71//! where
72//! S: serde::Serializer,
3b2f2976 73//! {
b7449926 74//! #path(self.value, serializer)
3b2f2976
XL
75//! }
76//! }
77//!
78//! SerializeWith {
79//! value: #value,
80//! phantom: ::std::marker::PhantomData::<#item_ty>,
81//! }
82//! };
0531ce1d
XL
83//! #
84//! # }
3b2f2976
XL
85//! ```
86//!
0531ce1d 87//! ## Recursion limit
3b2f2976 88//!
0531ce1d
XL
89//! The `quote!` macro relies on deep recursion so some large invocations may
90//! fail with "recursion limit reached" when you compile. If it fails, bump up
91//! the recursion limit by adding `#![recursion_limit = "128"]` to your crate.
92//! An even higher limit may be necessary for especially large invocations.
93
94// Quote types in rustdoc of other crates get linked to here.
b7449926 95#![doc(html_root_url = "https://docs.rs/quote/0.6.8")]
0531ce1d 96
b7449926
XL
97#[cfg(all(
98 not(all(target_arch = "wasm32", target_os = "unknown")),
99 feature = "proc-macro"
100))]
0531ce1d 101extern crate proc_macro;
83c7162d 102extern crate proc_macro2;
3b2f2976 103
8faf50e0
XL
104mod ext;
105pub use ext::TokenStreamExt;
3b2f2976
XL
106
107mod to_tokens;
0531ce1d 108pub use to_tokens::ToTokens;
3b2f2976 109
0531ce1d
XL
110// Not public API.
111#[doc(hidden)]
112pub mod __rt {
b7449926 113 use ext::TokenStreamExt;
0531ce1d
XL
114 pub use proc_macro2::*;
115
b7449926
XL
116 fn is_ident_start(c: u8) -> bool {
117 (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_'
118 }
119
120 fn is_ident_continue(c: u8) -> bool {
121 (b'a' <= c && c <= b'z')
122 || (b'A' <= c && c <= b'Z')
123 || c == b'_'
124 || (b'0' <= c && c <= b'9')
125 }
126
127 fn is_ident(token: &str) -> bool {
128 if token.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
129 return false;
130 }
131
132 let mut bytes = token.bytes();
133 let first = bytes.next().unwrap();
134 if !is_ident_start(first) {
135 return false;
136 }
137 for ch in bytes {
138 if !is_ident_continue(ch) {
139 return false;
140 }
141 }
142 true
143 }
144
8faf50e0 145 pub fn parse(tokens: &mut TokenStream, span: Span, s: &str) {
b7449926
XL
146 if is_ident(s) {
147 // Fast path, since idents are the most common token.
148 tokens.append(Ident::new(s, span));
149 } else {
150 let s: TokenStream = s.parse().expect("invalid token stream");
151 tokens.extend(s.into_iter().map(|mut t| {
152 t.set_span(span);
153 t
154 }));
155 }
156 }
157
158 macro_rules! push_punct {
159 ($name:ident $char1:tt) => {
160 pub fn $name(tokens: &mut TokenStream, span: Span) {
161 let mut punct = Punct::new($char1, Spacing::Alone);
162 punct.set_span(span);
163 tokens.append(punct);
164 }
165 };
166 ($name:ident $char1:tt $char2:tt) => {
167 pub fn $name(tokens: &mut TokenStream, span: Span) {
168 let mut punct = Punct::new($char1, Spacing::Joint);
169 punct.set_span(span);
170 tokens.append(punct);
171 let mut punct = Punct::new($char2, Spacing::Alone);
172 punct.set_span(span);
173 tokens.append(punct);
174 }
175 };
176 ($name:ident $char1:tt $char2:tt $char3:tt) => {
177 pub fn $name(tokens: &mut TokenStream, span: Span) {
178 let mut punct = Punct::new($char1, Spacing::Joint);
179 punct.set_span(span);
180 tokens.append(punct);
181 let mut punct = Punct::new($char2, Spacing::Joint);
182 punct.set_span(span);
183 tokens.append(punct);
184 let mut punct = Punct::new($char3, Spacing::Alone);
185 punct.set_span(span);
186 tokens.append(punct);
187 }
188 };
0531ce1d 189 }
b7449926
XL
190
191 push_punct!(push_add '+');
192 push_punct!(push_add_eq '+' '=');
193 push_punct!(push_and '&');
194 push_punct!(push_and_and '&' '&');
195 push_punct!(push_and_eq '&' '=');
196 push_punct!(push_at '@');
197 push_punct!(push_bang '!');
198 push_punct!(push_caret '^');
199 push_punct!(push_caret_eq '^' '=');
200 push_punct!(push_colon ':');
201 push_punct!(push_colon2 ':' ':');
202 push_punct!(push_comma ',');
203 push_punct!(push_div '/');
204 push_punct!(push_div_eq '/' '=');
205 push_punct!(push_dot '.');
206 push_punct!(push_dot2 '.' '.');
207 push_punct!(push_dot3 '.' '.' '.');
208 push_punct!(push_dot_dot_eq '.' '.' '=');
209 push_punct!(push_eq '=');
210 push_punct!(push_eq_eq '=' '=');
211 push_punct!(push_ge '>' '=');
212 push_punct!(push_gt '>');
213 push_punct!(push_le '<' '=');
214 push_punct!(push_lt '<');
215 push_punct!(push_mul_eq '*' '=');
216 push_punct!(push_ne '!' '=');
217 push_punct!(push_or '|');
218 push_punct!(push_or_eq '|' '=');
219 push_punct!(push_or_or '|' '|');
220 push_punct!(push_pound '#');
221 push_punct!(push_question '?');
222 push_punct!(push_rarrow '-' '>');
223 push_punct!(push_larrow '<' '-');
224 push_punct!(push_rem '%');
225 push_punct!(push_rem_eq '%' '=');
226 push_punct!(push_fat_arrow '=' '>');
227 push_punct!(push_semi ';');
228 push_punct!(push_shl '<' '<');
229 push_punct!(push_shl_eq '<' '<' '=');
230 push_punct!(push_shr '>' '>');
231 push_punct!(push_shr_eq '>' '>' '=');
232 push_punct!(push_star '*');
233 push_punct!(push_sub '-');
234 push_punct!(push_sub_eq '-' '=');
0531ce1d 235}
3b2f2976
XL
236
237/// The whole point.
0531ce1d
XL
238///
239/// Performs variable interpolation against the input and produces it as
8faf50e0 240/// [`TokenStream`]. For returning tokens to the compiler in a procedural macro, use
0531ce1d
XL
241/// `into()` to build a `TokenStream`.
242///
8faf50e0 243/// [`TokenStream`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.TokenStream.html
0531ce1d
XL
244///
245/// # Interpolation
246///
247/// Variable interpolation is done with `#var` (similar to `$var` in
248/// `macro_rules!` macros). This grabs the `var` variable that is currently in
b7449926
XL
249/// scope and inserts it in that location in the output tokens. Any type
250/// implementing the [`ToTokens`] trait can be interpolated. This includes most
251/// Rust primitive types as well as most of the syntax tree types from the [Syn]
252/// crate.
0531ce1d
XL
253///
254/// [`ToTokens`]: trait.ToTokens.html
b7449926 255/// [Syn]: https://github.com/dtolnay/syn
0531ce1d
XL
256///
257/// Repetition is done using `#(...)*` or `#(...),*` again similar to
258/// `macro_rules!`. This iterates through the elements of any variable
259/// interpolated within the repetition and inserts a copy of the repetition body
260/// for each one. The variables in an interpolation may be anything that
261/// implements `IntoIterator`, including `Vec` or a pre-existing iterator.
262///
263/// - `#(#var)*` — no separators
264/// - `#(#var),*` — the character before the asterisk is used as a separator
265/// - `#( struct #var; )*` — the repetition can contain other tokens
266/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
267///
268/// # Hygiene
269///
270/// Any interpolated tokens preserve the `Span` information provided by their
271/// `ToTokens` implementation. Tokens that originate within the `quote!`
83c7162d 272/// invocation are spanned with [`Span::call_site()`].
0531ce1d 273///
8faf50e0 274/// [`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site
0531ce1d
XL
275///
276/// A different span can be provided through the [`quote_spanned!`] macro.
277///
278/// [`quote_spanned!`]: macro.quote_spanned.html
279///
280/// # Example
281///
282/// ```
8faf50e0 283/// # #[cfg(any())]
0531ce1d 284/// extern crate proc_macro;
83c7162d 285/// # extern crate proc_macro2 as proc_macro;
0531ce1d
XL
286///
287/// #[macro_use]
288/// extern crate quote;
289///
290/// use proc_macro::TokenStream;
291///
292/// # const IGNORE_TOKENS: &'static str = stringify! {
293/// #[proc_macro_derive(HeapSize)]
294/// # };
295/// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
296/// // Parse the input and figure out what implementation to generate...
297/// # const IGNORE_TOKENS: &'static str = stringify! {
298/// let name = /* ... */;
299/// let expr = /* ... */;
300/// # };
301/// #
302/// # let name = 0;
303/// # let expr = 0;
304///
305/// let expanded = quote! {
306/// // The generated impl.
307/// impl ::heapsize::HeapSize for #name {
308/// fn heap_size_of_children(&self) -> usize {
309/// #expr
310/// }
311/// }
312/// };
313///
314/// // Hand the output tokens back to the compiler.
315/// expanded.into()
316/// }
317/// #
318/// # fn main() {}
319/// ```
b7449926 320#[macro_export(local_inner_macros)]
3b2f2976 321macro_rules! quote {
83c7162d 322 ($($tt:tt)*) => (quote_spanned!($crate::__rt::Span::call_site()=> $($tt)*));
0531ce1d 323}
3b2f2976 324
0531ce1d
XL
325/// Same as `quote!`, but applies a given span to all tokens originating within
326/// the macro invocation.
327///
328/// # Syntax
329///
330/// A span expression of type [`Span`], followed by `=>`, followed by the tokens
331/// to quote. The span expression should be brief -- use a variable for anything
332/// more than a few characters. There should be no space before the `=>` token.
333///
8faf50e0 334/// [`Span`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html
0531ce1d
XL
335///
336/// ```
337/// # #[macro_use]
338/// # extern crate quote;
339/// # extern crate proc_macro2;
340/// #
341/// # use proc_macro2::Span;
342/// #
343/// # fn main() {
344/// # const IGNORE_TOKENS: &'static str = stringify! {
345/// let span = /* ... */;
346/// # };
347/// # let span = Span::call_site();
348/// # let init = 0;
349///
350/// // On one line, use parentheses.
351/// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
352///
353/// // On multiple lines, place the span at the top and use braces.
354/// let tokens = quote_spanned! {span=>
355/// Box::into_raw(Box::new(#init))
356/// };
357/// # }
358/// ```
359///
83c7162d
XL
360/// The lack of space before the `=>` should look jarring to Rust programmers
361/// and this is intentional. The formatting is designed to be visibly
362/// off-balance and draw the eye a particular way, due to the span expression
363/// being evaluated in the context of the procedural macro and the remaining
364/// tokens being evaluated in the generated code.
365///
0531ce1d
XL
366/// # Hygiene
367///
368/// Any interpolated tokens preserve the `Span` information provided by their
369/// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
370/// invocation are spanned with the given span argument.
371///
372/// # Example
373///
374/// The following procedural macro code uses `quote_spanned!` to assert that a
375/// particular Rust type implements the [`Sync`] trait so that references can be
376/// safely shared between threads.
377///
378/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
379///
380/// ```
381/// # #[macro_use]
382/// # extern crate quote;
383/// # extern crate proc_macro2;
384/// #
8faf50e0
XL
385/// # use quote::{TokenStreamExt, ToTokens};
386/// # use proc_macro2::{Span, TokenStream};
0531ce1d
XL
387/// #
388/// # struct Type;
389/// #
390/// # impl Type {
391/// # fn span(&self) -> Span {
392/// # Span::call_site()
393/// # }
394/// # }
395/// #
396/// # impl ToTokens for Type {
8faf50e0 397/// # fn to_tokens(&self, _tokens: &mut TokenStream) {}
0531ce1d
XL
398/// # }
399/// #
400/// # fn main() {
401/// # let ty = Type;
83c7162d 402/// # let call_site = Span::call_site();
0531ce1d 403/// #
83c7162d 404/// let ty_span = ty.span();
0531ce1d
XL
405/// let assert_sync = quote_spanned! {ty_span=>
406/// struct _AssertSync where #ty: Sync;
407/// };
408/// # }
409/// ```
410///
411/// If the assertion fails, the user will see an error like the following. The
412/// input span of their type is hightlighted in the error.
413///
414/// ```text
415/// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
416/// --> src/main.rs:10:21
417/// |
418/// 10 | static ref PTR: *const () = &();
419/// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely
420/// ```
421///
422/// In this example it is important for the where-clause to be spanned with the
423/// line/column information of the user's input type so that error messages are
424/// placed appropriately by the compiler. But it is also incredibly important
425/// that `Sync` resolves at the macro definition site and not the macro call
426/// site. If we resolve `Sync` at the same span that the user's type is going to
427/// be resolved, then they could bypass our check by defining their own trait
428/// named `Sync` that is implemented for their type.
b7449926 429#[macro_export(local_inner_macros)]
0531ce1d
XL
430macro_rules! quote_spanned {
431 ($span:expr=> $($tt:tt)*) => {
3b2f2976 432 {
8faf50e0 433 let mut _s = $crate::__rt::TokenStream::new();
0531ce1d
XL
434 let _span = $span;
435 quote_each_token!(_s _span $($tt)*);
3b2f2976
XL
436 _s
437 }
438 };
439}
440
441// Extract the names of all #metavariables and pass them to the $finish macro.
442//
443// in: pounded_var_names!(then () a #b c #( #d )* #e)
444// out: then!(() b d e)
b7449926 445#[macro_export(local_inner_macros)]
3b2f2976
XL
446#[doc(hidden)]
447macro_rules! pounded_var_names {
448 ($finish:ident ($($found:ident)*) # ( $($inner:tt)* ) $($rest:tt)*) => {
449 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
450 };
451
452 ($finish:ident ($($found:ident)*) # [ $($inner:tt)* ] $($rest:tt)*) => {
453 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
454 };
455
456 ($finish:ident ($($found:ident)*) # { $($inner:tt)* } $($rest:tt)*) => {
457 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
458 };
459
460 ($finish:ident ($($found:ident)*) # $first:ident $($rest:tt)*) => {
461 pounded_var_names!($finish ($($found)* $first) $($rest)*)
462 };
463
464 ($finish:ident ($($found:ident)*) ( $($inner:tt)* ) $($rest:tt)*) => {
465 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
466 };
467
468 ($finish:ident ($($found:ident)*) [ $($inner:tt)* ] $($rest:tt)*) => {
469 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
470 };
471
472 ($finish:ident ($($found:ident)*) { $($inner:tt)* } $($rest:tt)*) => {
473 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
474 };
475
476 ($finish:ident ($($found:ident)*) $ignore:tt $($rest:tt)*) => {
477 pounded_var_names!($finish ($($found)*) $($rest)*)
478 };
479
480 ($finish:ident ($($found:ident)*)) => {
481 $finish!(() $($found)*)
482 };
483}
484
485// in: nested_tuples_pat!(() a b c d e)
486// out: ((((a b) c) d) e)
487//
488// in: nested_tuples_pat!(() a)
489// out: a
b7449926 490#[macro_export(local_inner_macros)]
3b2f2976
XL
491#[doc(hidden)]
492macro_rules! nested_tuples_pat {
493 (()) => {
494 &()
495 };
496
497 (() $first:ident $($rest:ident)*) => {
498 nested_tuples_pat!(($first) $($rest)*)
499 };
500
501 (($pat:pat) $first:ident $($rest:ident)*) => {
502 nested_tuples_pat!((($pat, $first)) $($rest)*)
503 };
504
505 (($done:pat)) => {
506 $done
507 };
508}
509
510// in: multi_zip_expr!(() a b c d e)
511// out: a.into_iter().zip(b).zip(c).zip(d).zip(e)
512//
513// in: multi_zip_iter!(() a)
514// out: a
b7449926 515#[macro_export(local_inner_macros)]
3b2f2976
XL
516#[doc(hidden)]
517macro_rules! multi_zip_expr {
518 (()) => {
519 &[]
520 };
521
522 (() $single:ident) => {
523 $single
524 };
525
526 (() $first:ident $($rest:ident)*) => {
527 multi_zip_expr!(($first.into_iter()) $($rest)*)
528 };
529
530 (($zips:expr) $first:ident $($rest:ident)*) => {
531 multi_zip_expr!(($zips.zip($first)) $($rest)*)
532 };
533
534 (($done:expr)) => {
535 $done
536 };
537}
538
b7449926 539#[macro_export(local_inner_macros)]
3b2f2976
XL
540#[doc(hidden)]
541macro_rules! quote_each_token {
0531ce1d 542 ($tokens:ident $span:ident) => {};
3b2f2976 543
0531ce1d
XL
544 ($tokens:ident $span:ident # ! $($rest:tt)*) => {
545 quote_each_token!($tokens $span #);
546 quote_each_token!($tokens $span !);
547 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
548 };
549
0531ce1d 550 ($tokens:ident $span:ident # ( $($inner:tt)* ) * $($rest:tt)*) => {
3b2f2976
XL
551 for pounded_var_names!(nested_tuples_pat () $($inner)*)
552 in pounded_var_names!(multi_zip_expr () $($inner)*) {
0531ce1d 553 quote_each_token!($tokens $span $($inner)*);
3b2f2976 554 }
0531ce1d 555 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
556 };
557
0531ce1d 558 ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt * $($rest:tt)*) => {
3b2f2976
XL
559 for (_i, pounded_var_names!(nested_tuples_pat () $($inner)*))
560 in pounded_var_names!(multi_zip_expr () $($inner)*).into_iter().enumerate() {
561 if _i > 0 {
0531ce1d 562 quote_each_token!($tokens $span $sep);
3b2f2976 563 }
0531ce1d 564 quote_each_token!($tokens $span $($inner)*);
3b2f2976 565 }
0531ce1d 566 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
567 };
568
0531ce1d
XL
569 ($tokens:ident $span:ident # [ $($inner:tt)* ] $($rest:tt)*) => {
570 quote_each_token!($tokens $span #);
8faf50e0 571 $tokens.extend({
83c7162d 572 let mut g = $crate::__rt::Group::new(
0531ce1d 573 $crate::__rt::Delimiter::Bracket,
b7449926 574 quote_spanned!($span=> $($inner)*),
83c7162d
XL
575 );
576 g.set_span($span);
8faf50e0 577 Some($crate::__rt::TokenTree::from(g))
83c7162d 578 });
0531ce1d 579 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
580 };
581
0531ce1d 582 ($tokens:ident $span:ident # $first:ident $($rest:tt)*) => {
3b2f2976 583 $crate::ToTokens::to_tokens(&$first, &mut $tokens);
0531ce1d 584 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
585 };
586
0531ce1d 587 ($tokens:ident $span:ident ( $($first:tt)* ) $($rest:tt)*) => {
8faf50e0 588 $tokens.extend({
83c7162d 589 let mut g = $crate::__rt::Group::new(
0531ce1d 590 $crate::__rt::Delimiter::Parenthesis,
b7449926 591 quote_spanned!($span=> $($first)*),
83c7162d
XL
592 );
593 g.set_span($span);
8faf50e0 594 Some($crate::__rt::TokenTree::from(g))
83c7162d 595 });
0531ce1d 596 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
597 };
598
0531ce1d 599 ($tokens:ident $span:ident [ $($first:tt)* ] $($rest:tt)*) => {
8faf50e0 600 $tokens.extend({
83c7162d 601 let mut g = $crate::__rt::Group::new(
0531ce1d 602 $crate::__rt::Delimiter::Bracket,
b7449926 603 quote_spanned!($span=> $($first)*),
83c7162d
XL
604 );
605 g.set_span($span);
8faf50e0 606 Some($crate::__rt::TokenTree::from(g))
83c7162d 607 });
0531ce1d 608 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
609 };
610
0531ce1d 611 ($tokens:ident $span:ident { $($first:tt)* } $($rest:tt)*) => {
8faf50e0 612 $tokens.extend({
83c7162d 613 let mut g = $crate::__rt::Group::new(
0531ce1d 614 $crate::__rt::Delimiter::Brace,
b7449926 615 quote_spanned!($span=> $($first)*),
83c7162d
XL
616 );
617 g.set_span($span);
8faf50e0 618 Some($crate::__rt::TokenTree::from(g))
83c7162d 619 });
0531ce1d 620 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
621 };
622
b7449926
XL
623 ($tokens:ident $span:ident + $($rest:tt)*) => {
624 $crate::__rt::push_add(&mut $tokens, $span);
625 quote_each_token!($tokens $span $($rest)*);
626 };
627
628 ($tokens:ident $span:ident += $($rest:tt)*) => {
629 $crate::__rt::push_add_eq(&mut $tokens, $span);
630 quote_each_token!($tokens $span $($rest)*);
631 };
632
633 ($tokens:ident $span:ident & $($rest:tt)*) => {
634 $crate::__rt::push_and(&mut $tokens, $span);
635 quote_each_token!($tokens $span $($rest)*);
636 };
637
638 ($tokens:ident $span:ident && $($rest:tt)*) => {
639 $crate::__rt::push_and_and(&mut $tokens, $span);
640 quote_each_token!($tokens $span $($rest)*);
641 };
642
643 ($tokens:ident $span:ident &= $($rest:tt)*) => {
644 $crate::__rt::push_and_eq(&mut $tokens, $span);
645 quote_each_token!($tokens $span $($rest)*);
646 };
647
648 ($tokens:ident $span:ident @ $($rest:tt)*) => {
649 $crate::__rt::push_at(&mut $tokens, $span);
650 quote_each_token!($tokens $span $($rest)*);
651 };
652
653 ($tokens:ident $span:ident ! $($rest:tt)*) => {
654 $crate::__rt::push_bang(&mut $tokens, $span);
655 quote_each_token!($tokens $span $($rest)*);
656 };
657
658 ($tokens:ident $span:ident ^ $($rest:tt)*) => {
659 $crate::__rt::push_caret(&mut $tokens, $span);
660 quote_each_token!($tokens $span $($rest)*);
661 };
662
663 ($tokens:ident $span:ident ^= $($rest:tt)*) => {
664 $crate::__rt::push_caret_eq(&mut $tokens, $span);
665 quote_each_token!($tokens $span $($rest)*);
666 };
667
668 ($tokens:ident $span:ident : $($rest:tt)*) => {
669 $crate::__rt::push_colon(&mut $tokens, $span);
670 quote_each_token!($tokens $span $($rest)*);
671 };
672
673 ($tokens:ident $span:ident :: $($rest:tt)*) => {
674 $crate::__rt::push_colon2(&mut $tokens, $span);
675 quote_each_token!($tokens $span $($rest)*);
676 };
677
678 ($tokens:ident $span:ident , $($rest:tt)*) => {
679 $crate::__rt::push_comma(&mut $tokens, $span);
680 quote_each_token!($tokens $span $($rest)*);
681 };
682
683 ($tokens:ident $span:ident / $($rest:tt)*) => {
684 $crate::__rt::push_div(&mut $tokens, $span);
685 quote_each_token!($tokens $span $($rest)*);
686 };
687
688 ($tokens:ident $span:ident /= $($rest:tt)*) => {
689 $crate::__rt::push_div_eq(&mut $tokens, $span);
690 quote_each_token!($tokens $span $($rest)*);
691 };
692
693 ($tokens:ident $span:ident . $($rest:tt)*) => {
694 $crate::__rt::push_dot(&mut $tokens, $span);
695 quote_each_token!($tokens $span $($rest)*);
696 };
697
698 ($tokens:ident $span:ident .. $($rest:tt)*) => {
699 $crate::__rt::push_dot2(&mut $tokens, $span);
700 quote_each_token!($tokens $span $($rest)*);
701 };
702
703 ($tokens:ident $span:ident ... $($rest:tt)*) => {
704 $crate::__rt::push_dot3(&mut $tokens, $span);
705 quote_each_token!($tokens $span $($rest)*);
706 };
707
708 ($tokens:ident $span:ident ..= $($rest:tt)*) => {
709 $crate::__rt::push_dot_dot_eq(&mut $tokens, $span);
710 quote_each_token!($tokens $span $($rest)*);
711 };
712
713 ($tokens:ident $span:ident = $($rest:tt)*) => {
714 $crate::__rt::push_eq(&mut $tokens, $span);
715 quote_each_token!($tokens $span $($rest)*);
716 };
717
718 ($tokens:ident $span:ident == $($rest:tt)*) => {
719 $crate::__rt::push_eq_eq(&mut $tokens, $span);
720 quote_each_token!($tokens $span $($rest)*);
721 };
722
723 ($tokens:ident $span:ident >= $($rest:tt)*) => {
724 $crate::__rt::push_ge(&mut $tokens, $span);
725 quote_each_token!($tokens $span $($rest)*);
726 };
727
728 ($tokens:ident $span:ident > $($rest:tt)*) => {
729 $crate::__rt::push_gt(&mut $tokens, $span);
730 quote_each_token!($tokens $span $($rest)*);
731 };
732
733 ($tokens:ident $span:ident <= $($rest:tt)*) => {
734 $crate::__rt::push_le(&mut $tokens, $span);
735 quote_each_token!($tokens $span $($rest)*);
736 };
737
738 ($tokens:ident $span:ident < $($rest:tt)*) => {
739 $crate::__rt::push_lt(&mut $tokens, $span);
740 quote_each_token!($tokens $span $($rest)*);
741 };
742
743 ($tokens:ident $span:ident *= $($rest:tt)*) => {
744 $crate::__rt::push_mul_eq(&mut $tokens, $span);
745 quote_each_token!($tokens $span $($rest)*);
746 };
747
748 ($tokens:ident $span:ident != $($rest:tt)*) => {
749 $crate::__rt::push_ne(&mut $tokens, $span);
750 quote_each_token!($tokens $span $($rest)*);
751 };
752
753 ($tokens:ident $span:ident | $($rest:tt)*) => {
754 $crate::__rt::push_or(&mut $tokens, $span);
755 quote_each_token!($tokens $span $($rest)*);
756 };
757
758 ($tokens:ident $span:ident |= $($rest:tt)*) => {
759 $crate::__rt::push_or_eq(&mut $tokens, $span);
760 quote_each_token!($tokens $span $($rest)*);
761 };
762
763 ($tokens:ident $span:ident || $($rest:tt)*) => {
764 $crate::__rt::push_or_or(&mut $tokens, $span);
765 quote_each_token!($tokens $span $($rest)*);
766 };
767
768 ($tokens:ident $span:ident # $($rest:tt)*) => {
769 $crate::__rt::push_pound(&mut $tokens, $span);
770 quote_each_token!($tokens $span $($rest)*);
771 };
772
773 ($tokens:ident $span:ident ? $($rest:tt)*) => {
774 $crate::__rt::push_question(&mut $tokens, $span);
775 quote_each_token!($tokens $span $($rest)*);
776 };
777
778 ($tokens:ident $span:ident -> $($rest:tt)*) => {
779 $crate::__rt::push_rarrow(&mut $tokens, $span);
780 quote_each_token!($tokens $span $($rest)*);
781 };
782
783 ($tokens:ident $span:ident <- $($rest:tt)*) => {
784 $crate::__rt::push_larrow(&mut $tokens, $span);
785 quote_each_token!($tokens $span $($rest)*);
786 };
787
788 ($tokens:ident $span:ident % $($rest:tt)*) => {
789 $crate::__rt::push_rem(&mut $tokens, $span);
790 quote_each_token!($tokens $span $($rest)*);
791 };
792
793 ($tokens:ident $span:ident %= $($rest:tt)*) => {
794 $crate::__rt::push_rem_eq(&mut $tokens, $span);
795 quote_each_token!($tokens $span $($rest)*);
796 };
797
798 ($tokens:ident $span:ident => $($rest:tt)*) => {
799 $crate::__rt::push_fat_arrow(&mut $tokens, $span);
800 quote_each_token!($tokens $span $($rest)*);
801 };
802
803 ($tokens:ident $span:ident ; $($rest:tt)*) => {
804 $crate::__rt::push_semi(&mut $tokens, $span);
805 quote_each_token!($tokens $span $($rest)*);
806 };
807
808 ($tokens:ident $span:ident << $($rest:tt)*) => {
809 $crate::__rt::push_shl(&mut $tokens, $span);
810 quote_each_token!($tokens $span $($rest)*);
811 };
812
813 ($tokens:ident $span:ident <<= $($rest:tt)*) => {
814 $crate::__rt::push_shl_eq(&mut $tokens, $span);
815 quote_each_token!($tokens $span $($rest)*);
816 };
817
818 ($tokens:ident $span:ident >> $($rest:tt)*) => {
819 $crate::__rt::push_shr(&mut $tokens, $span);
820 quote_each_token!($tokens $span $($rest)*);
821 };
822
823 ($tokens:ident $span:ident >>= $($rest:tt)*) => {
824 $crate::__rt::push_shr_eq(&mut $tokens, $span);
825 quote_each_token!($tokens $span $($rest)*);
826 };
827
828 ($tokens:ident $span:ident * $($rest:tt)*) => {
829 $crate::__rt::push_star(&mut $tokens, $span);
830 quote_each_token!($tokens $span $($rest)*);
831 };
832
833 ($tokens:ident $span:ident - $($rest:tt)*) => {
834 $crate::__rt::push_sub(&mut $tokens, $span);
835 quote_each_token!($tokens $span $($rest)*);
836 };
837
838 ($tokens:ident $span:ident -= $($rest:tt)*) => {
839 $crate::__rt::push_sub_eq(&mut $tokens, $span);
840 quote_each_token!($tokens $span $($rest)*);
841 };
842
0531ce1d 843 ($tokens:ident $span:ident $first:tt $($rest:tt)*) => {
b7449926 844 $crate::__rt::parse(&mut $tokens, $span, quote_stringify!($first));
0531ce1d 845 quote_each_token!($tokens $span $($rest)*);
3b2f2976
XL
846 };
847}
b7449926
XL
848
849// Unhygienically invoke whatever `stringify` the caller has in scope i.e. not a
850// local macro. The macros marked `local_inner_macros` above cannot invoke
851// `stringify` directly.
852#[macro_export]
853#[doc(hidden)]
854macro_rules! quote_stringify {
855 ($tt:tt) => {
856 stringify!($tt)
857 };
858}