quote/
lib.rs

1//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote)
2//!
3//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6//!
7//! <br>
8//!
9//! This crate provides the [`quote!`] macro for turning Rust syntax tree data
10//! structures into tokens of source code.
11//!
12//! [`quote!`]: macro.quote.html
13//!
14//! Procedural macros in Rust receive a stream of tokens as input, execute
15//! arbitrary Rust code to determine how to manipulate those tokens, and produce
16//! a stream of tokens to hand back to the compiler to compile into the caller's
17//! crate. Quasi-quoting is a solution to one piece of that &mdash; producing
18//! tokens to return to the compiler.
19//!
20//! The idea of quasi-quoting is that we write *code* that we treat as *data*.
21//! Within the `quote!` macro, we can write what looks like code to our text
22//! editor or IDE. We get all the benefits of the editor's brace matching,
23//! syntax highlighting, indentation, and maybe autocompletion. But rather than
24//! compiling that as code into the current crate, we can treat it as data, pass
25//! it around, mutate it, and eventually hand it back to the compiler as tokens
26//! to compile into the macro caller's crate.
27//!
28//! This crate is motivated by the procedural macro use case, but is a
29//! general-purpose Rust quasi-quoting library and is not specific to procedural
30//! macros.
31//!
32//! ```toml
33//! [dependencies]
34//! quote = "1.0"
35//! ```
36//!
37//! <br>
38//!
39//! # Example
40//!
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//! # use quote::quote;
53//! #
54//! # let generics = "";
55//! # let where_clause = "";
56//! # let field_ty = "";
57//! # let item_ty = "";
58//! # let path = "";
59//! # let value = "";
60//! #
61//! let tokens = quote! {
62//!     struct SerializeWith #generics #where_clause {
63//!         value: &'a #field_ty,
64//!         phantom: core::marker::PhantomData<#item_ty>,
65//!     }
66//!
67//!     impl #generics serde::Serialize for SerializeWith #generics #where_clause {
68//!         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69//!         where
70//!             S: serde::Serializer,
71//!         {
72//!             #path(self.value, serializer)
73//!         }
74//!     }
75//!
76//!     SerializeWith {
77//!         value: #value,
78//!         phantom: core::marker::PhantomData::<#item_ty>,
79//!     }
80//! };
81//! ```
82//!
83//! <br>
84//!
85//! # Non-macro code generators
86//!
87//! When using `quote` in a build.rs or main.rs and writing the output out to a
88//! file, consider having the code generator pass the tokens through
89//! [prettyplease] before writing. This way if an error occurs in the generated
90//! code it is convenient for a human to read and debug.
91//!
92//! [prettyplease]: https://github.com/dtolnay/prettyplease
93
94// Quote types in rustdoc of other crates get linked to here.
95#![doc(html_root_url = "https://docs.rs/quote/1.0.33")]
96#![allow(
97    clippy::doc_markdown,
98    clippy::missing_errors_doc,
99    clippy::missing_panics_doc,
100    clippy::module_name_repetitions,
101    // false positive https://github.com/rust-lang/rust-clippy/issues/6983
102    clippy::wrong_self_convention,
103)]
104
105extern crate alloc;
106
107#[cfg(feature = "proc-macro")]
108extern crate proc_macro;
109
110mod ext;
111mod format;
112mod ident_fragment;
113mod to_tokens;
114
115// Not public API.
116#[doc(hidden)]
117#[path = "runtime.rs"]
118pub mod __private;
119
120pub use crate::ext::TokenStreamExt;
121pub use crate::ident_fragment::IdentFragment;
122pub use crate::to_tokens::ToTokens;
123
124// Not public API.
125#[doc(hidden)]
126pub mod spanned;
127
128/// The whole point.
129///
130/// Performs variable interpolation against the input and produces it as
131/// [`proc_macro2::TokenStream`].
132///
133/// Note: for returning tokens to the compiler in a procedural macro, use
134/// `.into()` on the result to convert to [`proc_macro::TokenStream`].
135///
136/// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
137///
138/// <br>
139///
140/// # Interpolation
141///
142/// Variable interpolation is done with `#var` (similar to `$var` in
143/// `macro_rules!` macros). This grabs the `var` variable that is currently in
144/// scope and inserts it in that location in the output tokens. Any type
145/// implementing the [`ToTokens`] trait can be interpolated. This includes most
146/// Rust primitive types as well as most of the syntax tree types from the [Syn]
147/// crate.
148///
149/// [`ToTokens`]: trait.ToTokens.html
150/// [Syn]: https://github.com/dtolnay/syn
151///
152/// Repetition is done using `#(...)*` or `#(...),*` again similar to
153/// `macro_rules!`. This iterates through the elements of any variable
154/// interpolated within the repetition and inserts a copy of the repetition body
155/// for each one. The variables in an interpolation may be a `Vec`, slice,
156/// `BTreeSet`, or any `Iterator`.
157///
158/// - `#(#var)*` — no separators
159/// - `#(#var),*` — the character before the asterisk is used as a separator
160/// - `#( struct #var; )*` — the repetition can contain other tokens
161/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
162///
163/// <br>
164///
165/// # Hygiene
166///
167/// Any interpolated tokens preserve the `Span` information provided by their
168/// `ToTokens` implementation. Tokens that originate within the `quote!`
169/// invocation are spanned with [`Span::call_site()`].
170///
171/// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
172///
173/// A different span can be provided through the [`quote_spanned!`] macro.
174///
175/// [`quote_spanned!`]: macro.quote_spanned.html
176///
177/// <br>
178///
179/// # Return type
180///
181/// The macro evaluates to an expression of type `proc_macro2::TokenStream`.
182/// Meanwhile Rust procedural macros are expected to return the type
183/// `proc_macro::TokenStream`.
184///
185/// The difference between the two types is that `proc_macro` types are entirely
186/// specific to procedural macros and cannot ever exist in code outside of a
187/// procedural macro, while `proc_macro2` types may exist anywhere including
188/// tests and non-macro code like main.rs and build.rs. This is why even the
189/// procedural macro ecosystem is largely built around `proc_macro2`, because
190/// that ensures the libraries are unit testable and accessible in non-macro
191/// contexts.
192///
193/// There is a [`From`]-conversion in both directions so returning the output of
194/// `quote!` from a procedural macro usually looks like `tokens.into()` or
195/// `proc_macro::TokenStream::from(tokens)`.
196///
197/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
198///
199/// <br>
200///
201/// # Examples
202///
203/// ### Procedural macro
204///
205/// The structure of a basic procedural macro is as follows. Refer to the [Syn]
206/// crate for further useful guidance on using `quote!` as part of a procedural
207/// macro.
208///
209/// [Syn]: https://github.com/dtolnay/syn
210///
211/// ```
212/// # #[cfg(any())]
213/// extern crate proc_macro;
214/// # extern crate proc_macro2;
215///
216/// # #[cfg(any())]
217/// use proc_macro::TokenStream;
218/// # use proc_macro2::TokenStream;
219/// use quote::quote;
220///
221/// # const IGNORE_TOKENS: &'static str = stringify! {
222/// #[proc_macro_derive(HeapSize)]
223/// # };
224/// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
225///     // Parse the input and figure out what implementation to generate...
226///     # const IGNORE_TOKENS: &'static str = stringify! {
227///     let name = /* ... */;
228///     let expr = /* ... */;
229///     # };
230///     #
231///     # let name = 0;
232///     # let expr = 0;
233///
234///     let expanded = quote! {
235///         // The generated impl.
236///         impl heapsize::HeapSize for #name {
237///             fn heap_size_of_children(&self) -> usize {
238///                 #expr
239///             }
240///         }
241///     };
242///
243///     // Hand the output tokens back to the compiler.
244///     TokenStream::from(expanded)
245/// }
246/// ```
247///
248/// <p><br></p>
249///
250/// ### Combining quoted fragments
251///
252/// Usually you don't end up constructing an entire final `TokenStream` in one
253/// piece. Different parts may come from different helper functions. The tokens
254/// produced by `quote!` themselves implement `ToTokens` and so can be
255/// interpolated into later `quote!` invocations to build up a final result.
256///
257/// ```
258/// # use quote::quote;
259/// #
260/// let type_definition = quote! {...};
261/// let methods = quote! {...};
262///
263/// let tokens = quote! {
264///     #type_definition
265///     #methods
266/// };
267/// ```
268///
269/// <p><br></p>
270///
271/// ### Constructing identifiers
272///
273/// Suppose we have an identifier `ident` which came from somewhere in a macro
274/// input and we need to modify it in some way for the macro output. Let's
275/// consider prepending the identifier with an underscore.
276///
277/// Simply interpolating the identifier next to an underscore will not have the
278/// behavior of concatenating them. The underscore and the identifier will
279/// continue to be two separate tokens as if you had written `_ x`.
280///
281/// ```
282/// # use proc_macro2::{self as syn, Span};
283/// # use quote::quote;
284/// #
285/// # let ident = syn::Ident::new("i", Span::call_site());
286/// #
287/// // incorrect
288/// quote! {
289///     let mut _#ident = 0;
290/// }
291/// # ;
292/// ```
293///
294/// The solution is to build a new identifier token with the correct value. As
295/// this is such a common case, the [`format_ident!`] macro provides a
296/// convenient utility for doing so correctly.
297///
298/// ```
299/// # use proc_macro2::{Ident, Span};
300/// # use quote::{format_ident, quote};
301/// #
302/// # let ident = Ident::new("i", Span::call_site());
303/// #
304/// let varname = format_ident!("_{}", ident);
305/// quote! {
306///     let mut #varname = 0;
307/// }
308/// # ;
309/// ```
310///
311/// Alternatively, the APIs provided by Syn and proc-macro2 can be used to
312/// directly build the identifier. This is roughly equivalent to the above, but
313/// will not handle `ident` being a raw identifier.
314///
315/// ```
316/// # use proc_macro2::{self as syn, Span};
317/// # use quote::quote;
318/// #
319/// # let ident = syn::Ident::new("i", Span::call_site());
320/// #
321/// let concatenated = format!("_{}", ident);
322/// let varname = syn::Ident::new(&concatenated, ident.span());
323/// quote! {
324///     let mut #varname = 0;
325/// }
326/// # ;
327/// ```
328///
329/// <p><br></p>
330///
331/// ### Making method calls
332///
333/// Let's say our macro requires some type specified in the macro input to have
334/// a constructor called `new`. We have the type in a variable called
335/// `field_type` of type `syn::Type` and want to invoke the constructor.
336///
337/// ```
338/// # use quote::quote;
339/// #
340/// # let field_type = quote!(...);
341/// #
342/// // incorrect
343/// quote! {
344///     let value = #field_type::new();
345/// }
346/// # ;
347/// ```
348///
349/// This works only sometimes. If `field_type` is `String`, the expanded code
350/// contains `String::new()` which is fine. But if `field_type` is something
351/// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid
352/// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`
353/// but for macros often the following is more convenient.
354///
355/// ```
356/// # use quote::quote;
357/// #
358/// # let field_type = quote!(...);
359/// #
360/// quote! {
361///     let value = <#field_type>::new();
362/// }
363/// # ;
364/// ```
365///
366/// This expands to `<Vec<i32>>::new()` which behaves correctly.
367///
368/// A similar pattern is appropriate for trait methods.
369///
370/// ```
371/// # use quote::quote;
372/// #
373/// # let field_type = quote!(...);
374/// #
375/// quote! {
376///     let value = <#field_type as core::default::Default>::default();
377/// }
378/// # ;
379/// ```
380///
381/// <p><br></p>
382///
383/// ### Interpolating text inside of doc comments
384///
385/// Neither doc comments nor string literals get interpolation behavior in
386/// quote:
387///
388/// ```compile_fail
389/// quote! {
390///     /// try to interpolate: #ident
391///     ///
392///     /// ...
393/// }
394/// ```
395///
396/// ```compile_fail
397/// quote! {
398///     #[doc = "try to interpolate: #ident"]
399/// }
400/// ```
401///
402/// Instead the best way to build doc comments that involve variables is by
403/// formatting the doc string literal outside of quote.
404///
405/// ```rust
406/// # use proc_macro2::{Ident, Span};
407/// # use quote::quote;
408/// #
409/// # const IGNORE: &str = stringify! {
410/// let msg = format!(...);
411/// # };
412/// #
413/// # let ident = Ident::new("var", Span::call_site());
414/// # let msg = format!("try to interpolate: {}", ident);
415/// quote! {
416///     #[doc = #msg]
417///     ///
418///     /// ...
419/// }
420/// # ;
421/// ```
422///
423/// <p><br></p>
424///
425/// ### Indexing into a tuple struct
426///
427/// When interpolating indices of a tuple or tuple struct, we need them not to
428/// appears suffixed as integer literals by interpolating them as [`syn::Index`]
429/// instead.
430///
431/// [`syn::Index`]: https://docs.rs/syn/1.0/syn/struct.Index.html
432///
433/// ```compile_fail
434/// let i = 0usize..self.fields.len();
435///
436/// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
437/// // which is not valid syntax
438/// quote! {
439///     0 #( + self.#i.heap_size() )*
440/// }
441/// ```
442///
443/// ```
444/// # use proc_macro2::{Ident, TokenStream};
445/// # use quote::quote;
446/// #
447/// # mod syn {
448/// #     use proc_macro2::{Literal, TokenStream};
449/// #     use quote::{ToTokens, TokenStreamExt};
450/// #
451/// #     pub struct Index(usize);
452/// #
453/// #     impl From<usize> for Index {
454/// #         fn from(i: usize) -> Self {
455/// #             Index(i)
456/// #         }
457/// #     }
458/// #
459/// #     impl ToTokens for Index {
460/// #         fn to_tokens(&self, tokens: &mut TokenStream) {
461/// #             tokens.append(Literal::usize_unsuffixed(self.0));
462/// #         }
463/// #     }
464/// # }
465/// #
466/// # struct Struct {
467/// #     fields: Vec<Ident>,
468/// # }
469/// #
470/// # impl Struct {
471/// #     fn example(&self) -> TokenStream {
472/// let i = (0..self.fields.len()).map(syn::Index::from);
473///
474/// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
475/// quote! {
476///     0 #( + self.#i.heap_size() )*
477/// }
478/// #     }
479/// # }
480/// ```
481#[cfg(doc)]
482#[macro_export]
483macro_rules! quote {
484    ($($tt:tt)*) => {
485        ...
486    };
487}
488
489#[cfg(not(doc))]
490#[macro_export]
491macro_rules! quote {
492    () => {
493        $crate::__private::TokenStream::new()
494    };
495
496    // Special case rule for a single tt, for performance.
497    ($tt:tt) => {{
498        let mut _s = $crate::__private::TokenStream::new();
499        $crate::quote_token!{$tt _s}
500        _s
501    }};
502
503    // Special case rules for two tts, for performance.
504    (# $var:ident) => {{
505        let mut _s = $crate::__private::TokenStream::new();
506        $crate::ToTokens::to_tokens(&$var, &mut _s);
507        _s
508    }};
509    ($tt1:tt $tt2:tt) => {{
510        let mut _s = $crate::__private::TokenStream::new();
511        $crate::quote_token!{$tt1 _s}
512        $crate::quote_token!{$tt2 _s}
513        _s
514    }};
515
516    // Rule for any other number of tokens.
517    ($($tt:tt)*) => {{
518        let mut _s = $crate::__private::TokenStream::new();
519        $crate::quote_each_token!{_s $($tt)*}
520        _s
521    }};
522}
523
524/// Same as `quote!`, but applies a given span to all tokens originating within
525/// the macro invocation.
526///
527/// <br>
528///
529/// # Syntax
530///
531/// A span expression of type [`Span`], followed by `=>`, followed by the tokens
532/// to quote. The span expression should be brief &mdash; use a variable for
533/// anything more than a few characters. There should be no space before the
534/// `=>` token.
535///
536/// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
537///
538/// ```
539/// # use proc_macro2::Span;
540/// # use quote::quote_spanned;
541/// #
542/// # const IGNORE_TOKENS: &'static str = stringify! {
543/// let span = /* ... */;
544/// # };
545/// # let span = Span::call_site();
546/// # let init = 0;
547///
548/// // On one line, use parentheses.
549/// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
550///
551/// // On multiple lines, place the span at the top and use braces.
552/// let tokens = quote_spanned! {span=>
553///     Box::into_raw(Box::new(#init))
554/// };
555/// ```
556///
557/// The lack of space before the `=>` should look jarring to Rust programmers
558/// and this is intentional. The formatting is designed to be visibly
559/// off-balance and draw the eye a particular way, due to the span expression
560/// being evaluated in the context of the procedural macro and the remaining
561/// tokens being evaluated in the generated code.
562///
563/// <br>
564///
565/// # Hygiene
566///
567/// Any interpolated tokens preserve the `Span` information provided by their
568/// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
569/// invocation are spanned with the given span argument.
570///
571/// <br>
572///
573/// # Example
574///
575/// The following procedural macro code uses `quote_spanned!` to assert that a
576/// particular Rust type implements the [`Sync`] trait so that references can be
577/// safely shared between threads.
578///
579/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
580///
581/// ```
582/// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
583/// # use proc_macro2::{Span, TokenStream};
584/// #
585/// # struct Type;
586/// #
587/// # impl Type {
588/// #     fn span(&self) -> Span {
589/// #         Span::call_site()
590/// #     }
591/// # }
592/// #
593/// # impl ToTokens for Type {
594/// #     fn to_tokens(&self, _tokens: &mut TokenStream) {}
595/// # }
596/// #
597/// # let ty = Type;
598/// # let call_site = Span::call_site();
599/// #
600/// let ty_span = ty.span();
601/// let assert_sync = quote_spanned! {ty_span=>
602///     struct _AssertSync where #ty: Sync;
603/// };
604/// ```
605///
606/// If the assertion fails, the user will see an error like the following. The
607/// input span of their type is highlighted in the error.
608///
609/// ```text
610/// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
611///   --> src/main.rs:10:21
612///    |
613/// 10 |     static ref PTR: *const () = &();
614///    |                     ^^^^^^^^^ `*const ()` cannot be shared between threads safely
615/// ```
616///
617/// In this example it is important for the where-clause to be spanned with the
618/// line/column information of the user's input type so that error messages are
619/// placed appropriately by the compiler.
620#[cfg(doc)]
621#[macro_export]
622macro_rules! quote_spanned {
623    ($span:expr=> $($tt:tt)*) => {
624        ...
625    };
626}
627
628#[cfg(not(doc))]
629#[macro_export]
630macro_rules! quote_spanned {
631    ($span:expr=>) => {{
632        let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
633        $crate::__private::TokenStream::new()
634    }};
635
636    // Special case rule for a single tt, for performance.
637    ($span:expr=> $tt:tt) => {{
638        let mut _s = $crate::__private::TokenStream::new();
639        let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
640        $crate::quote_token_spanned!{$tt _s _span}
641        _s
642    }};
643
644    // Special case rules for two tts, for performance.
645    ($span:expr=> # $var:ident) => {{
646        let mut _s = $crate::__private::TokenStream::new();
647        let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
648        $crate::ToTokens::to_tokens(&$var, &mut _s);
649        _s
650    }};
651    ($span:expr=> $tt1:tt $tt2:tt) => {{
652        let mut _s = $crate::__private::TokenStream::new();
653        let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
654        $crate::quote_token_spanned!{$tt1 _s _span}
655        $crate::quote_token_spanned!{$tt2 _s _span}
656        _s
657    }};
658
659    // Rule for any other number of tokens.
660    ($span:expr=> $($tt:tt)*) => {{
661        let mut _s = $crate::__private::TokenStream::new();
662        let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
663        $crate::quote_each_token_spanned!{_s _span $($tt)*}
664        _s
665    }};
666}
667
668// Extract the names of all #metavariables and pass them to the $call macro.
669//
670// in:   pounded_var_names!(then!(...) a #b c #( #d )* #e)
671// out:  then!(... b);
672//       then!(... d);
673//       then!(... e);
674#[macro_export]
675#[doc(hidden)]
676macro_rules! pounded_var_names {
677    ($call:ident! $extra:tt $($tts:tt)*) => {
678        $crate::pounded_var_names_with_context!{$call! $extra
679            (@ $($tts)*)
680            ($($tts)* @)
681        }
682    };
683}
684
685#[macro_export]
686#[doc(hidden)]
687macro_rules! pounded_var_names_with_context {
688    ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
689        $(
690            $crate::pounded_var_with_context!{$call! $extra $b1 $curr}
691        )*
692    };
693}
694
695#[macro_export]
696#[doc(hidden)]
697macro_rules! pounded_var_with_context {
698    ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
699        $crate::pounded_var_names!{$call! $extra $($inner)*}
700    };
701
702    ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
703        $crate::pounded_var_names!{$call! $extra $($inner)*}
704    };
705
706    ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
707        $crate::pounded_var_names!{$call! $extra $($inner)*}
708    };
709
710    ($call:ident!($($extra:tt)*) # $var:ident) => {
711        $crate::$call!($($extra)* $var);
712    };
713
714    ($call:ident! $extra:tt $b1:tt $curr:tt) => {};
715}
716
717#[macro_export]
718#[doc(hidden)]
719macro_rules! quote_bind_into_iter {
720    ($has_iter:ident $var:ident) => {
721        // `mut` may be unused if $var occurs multiple times in the list.
722        #[allow(unused_mut)]
723        let (mut $var, i) = $var.quote_into_iter();
724        let $has_iter = $has_iter | i;
725    };
726}
727
728#[macro_export]
729#[doc(hidden)]
730macro_rules! quote_bind_next_or_break {
731    ($var:ident) => {
732        let $var = match $var.next() {
733            Some(_x) => $crate::__private::RepInterp(_x),
734            None => break,
735        };
736    };
737}
738
739// The obvious way to write this macro is as a tt muncher. This implementation
740// does something more complex for two reasons.
741//
742//   - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which
743//     this implementation avoids because it isn't tail recursive.
744//
745//   - Compile times for a tt muncher are quadratic relative to the length of
746//     the input. This implementation is linear, so it will be faster
747//     (potentially much faster) for big inputs. However, the constant factors
748//     of this implementation are higher than that of a tt muncher, so it is
749//     somewhat slower than a tt muncher if there are many invocations with
750//     short inputs.
751//
752// An invocation like this:
753//
754//     quote_each_token!(_s a b c d e f g h i j);
755//
756// expands to this:
757//
758//     quote_tokens_with_context!(_s
759//         (@  @  @  @   @   @   a   b   c   d   e   f   g  h  i  j)
760//         (@  @  @  @   @   a   b   c   d   e   f   g   h  i  j  @)
761//         (@  @  @  @   a   b   c   d   e   f   g   h   i  j  @  @)
762//         (@  @  @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @  @  @)
763//         (@  @  a  b   c   d   e   f   g   h   i   j   @  @  @  @)
764//         (@  a  b  c   d   e   f   g   h   i   j   @   @  @  @  @)
765//         (a  b  c  d   e   f   g   h   i   j   @   @   @  @  @  @)
766//     );
767//
768// which gets transposed and expanded to this:
769//
770//     quote_token_with_context!(_s @ @ @  @  @ @ a);
771//     quote_token_with_context!(_s @ @ @  @  @ a b);
772//     quote_token_with_context!(_s @ @ @  @  a b c);
773//     quote_token_with_context!(_s @ @ @ (a) b c d);
774//     quote_token_with_context!(_s @ @ a (b) c d e);
775//     quote_token_with_context!(_s @ a b (c) d e f);
776//     quote_token_with_context!(_s a b c (d) e f g);
777//     quote_token_with_context!(_s b c d (e) f g h);
778//     quote_token_with_context!(_s c d e (f) g h i);
779//     quote_token_with_context!(_s d e f (g) h i j);
780//     quote_token_with_context!(_s e f g (h) i j @);
781//     quote_token_with_context!(_s f g h (i) j @ @);
782//     quote_token_with_context!(_s g h i (j) @ @ @);
783//     quote_token_with_context!(_s h i j  @  @ @ @);
784//     quote_token_with_context!(_s i j @  @  @ @ @);
785//     quote_token_with_context!(_s j @ @  @  @ @ @);
786//
787// Without having used muncher-style recursion, we get one invocation of
788// quote_token_with_context for each original tt, with three tts of context on
789// either side. This is enough for the longest possible interpolation form (a
790// repetition with separator, as in `# (#var) , *`) to be fully represented with
791// the first or last tt in the middle.
792//
793// The middle tt (surrounded by parentheses) is the tt being processed.
794//
795//   - When it is a `#`, quote_token_with_context can do an interpolation. The
796//     interpolation kind will depend on the three subsequent tts.
797//
798//   - When it is within a later part of an interpolation, it can be ignored
799//     because the interpolation has already been done.
800//
801//   - When it is not part of an interpolation it can be pushed as a single
802//     token into the output.
803//
804//   - When the middle token is an unparenthesized `@`, that call is one of the
805//     first 3 or last 3 calls of quote_token_with_context and does not
806//     correspond to one of the original input tokens, so turns into nothing.
807#[macro_export]
808#[doc(hidden)]
809macro_rules! quote_each_token {
810    ($tokens:ident $($tts:tt)*) => {
811        $crate::quote_tokens_with_context!{$tokens
812            (@ @ @ @ @ @ $($tts)*)
813            (@ @ @ @ @ $($tts)* @)
814            (@ @ @ @ $($tts)* @ @)
815            (@ @ @ $(($tts))* @ @ @)
816            (@ @ $($tts)* @ @ @ @)
817            (@ $($tts)* @ @ @ @ @)
818            ($($tts)* @ @ @ @ @ @)
819        }
820    };
821}
822
823// See the explanation on quote_each_token.
824#[macro_export]
825#[doc(hidden)]
826macro_rules! quote_each_token_spanned {
827    ($tokens:ident $span:ident $($tts:tt)*) => {
828        $crate::quote_tokens_with_context_spanned!{$tokens $span
829            (@ @ @ @ @ @ $($tts)*)
830            (@ @ @ @ @ $($tts)* @)
831            (@ @ @ @ $($tts)* @ @)
832            (@ @ @ $(($tts))* @ @ @)
833            (@ @ $($tts)* @ @ @ @)
834            (@ $($tts)* @ @ @ @ @)
835            ($($tts)* @ @ @ @ @ @)
836        }
837    };
838}
839
840// See the explanation on quote_each_token.
841#[macro_export]
842#[doc(hidden)]
843macro_rules! quote_tokens_with_context {
844    ($tokens:ident
845        ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
846        ($($curr:tt)*)
847        ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
848    ) => {
849        $(
850            $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3}
851        )*
852    };
853}
854
855// See the explanation on quote_each_token.
856#[macro_export]
857#[doc(hidden)]
858macro_rules! quote_tokens_with_context_spanned {
859    ($tokens:ident $span:ident
860        ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
861        ($($curr:tt)*)
862        ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
863    ) => {
864        $(
865            $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3}
866        )*
867    };
868}
869
870// See the explanation on quote_each_token.
871#[macro_export]
872#[doc(hidden)]
873macro_rules! quote_token_with_context {
874    // Unparenthesized `@` indicates this call does not correspond to one of the
875    // original input tokens. Ignore it.
876    ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
877
878    // A repetition with no separator.
879    ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
880        use $crate::__private::ext::*;
881        let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
882        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
883        let _: $crate::__private::HasIterator = has_iter;
884        // This is `while true` instead of `loop` because if there are no
885        // iterators used inside of this repetition then the body would not
886        // contain any `break`, so the compiler would emit unreachable code
887        // warnings on anything below the loop. We use has_iter to detect and
888        // fail to compile when there are no iterators, so here we just work
889        // around the unneeded extra warning.
890        while true {
891            $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
892            $crate::quote_each_token!{$tokens $($inner)*}
893        }
894    }};
895    // ... and one step later.
896    ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
897    // ... and one step later.
898    ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
899
900    // A repetition with separator.
901    ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
902        use $crate::__private::ext::*;
903        let mut _i = 0usize;
904        let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
905        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
906        let _: $crate::__private::HasIterator = has_iter;
907        while true {
908            $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
909            if _i > 0 {
910                $crate::quote_token!{$sep $tokens}
911            }
912            _i += 1;
913            $crate::quote_each_token!{$tokens $($inner)*}
914        }
915    }};
916    // ... and one step later.
917    ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
918    // ... and one step later.
919    ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
920    // (A special case for `#(var)**`, where the first `*` is treated as the
921    // repetition symbol and the second `*` is treated as an ordinary token.)
922    ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
923        // https://github.com/dtolnay/quote/issues/130
924        $crate::quote_token!{* $tokens}
925    };
926    // ... and one step later.
927    ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
928
929    // A non-repetition interpolation.
930    ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
931        $crate::ToTokens::to_tokens(&$var, &mut $tokens);
932    };
933    // ... and one step later.
934    ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
935
936    // An ordinary token, not part of any interpolation.
937    ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
938        $crate::quote_token!{$curr $tokens}
939    };
940}
941
942// See the explanation on quote_each_token, and on the individual rules of
943// quote_token_with_context.
944#[macro_export]
945#[doc(hidden)]
946macro_rules! quote_token_with_context_spanned {
947    ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
948
949    ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
950        use $crate::__private::ext::*;
951        let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
952        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
953        let _: $crate::__private::HasIterator = has_iter;
954        while true {
955            $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
956            $crate::quote_each_token_spanned!{$tokens $span $($inner)*}
957        }
958    }};
959    ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
960    ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
961
962    ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
963        use $crate::__private::ext::*;
964        let mut _i = 0usize;
965        let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
966        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
967        let _: $crate::__private::HasIterator = has_iter;
968        while true {
969            $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
970            if _i > 0 {
971                $crate::quote_token_spanned!{$sep $tokens $span}
972            }
973            _i += 1;
974            $crate::quote_each_token_spanned!{$tokens $span $($inner)*}
975        }
976    }};
977    ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
978    ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
979    ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
980        // https://github.com/dtolnay/quote/issues/130
981        $crate::quote_token_spanned!{* $tokens $span}
982    };
983    ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
984
985    ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
986        $crate::ToTokens::to_tokens(&$var, &mut $tokens);
987    };
988    ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
989
990    ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
991        $crate::quote_token_spanned!{$curr $tokens $span}
992    };
993}
994
995// These rules are ordered by approximate token frequency, at least for the
996// first 10 or so, to improve compile times. Having `ident` first is by far the
997// most important because it's typically 2-3x more common than the next most
998// common token.
999//
1000// Separately, we put the token being matched in the very front so that failing
1001// rules may fail to match as quickly as possible.
1002#[macro_export]
1003#[doc(hidden)]
1004macro_rules! quote_token {
1005    ($ident:ident $tokens:ident) => {
1006        $crate::__private::push_ident(&mut $tokens, stringify!($ident));
1007    };
1008
1009    (:: $tokens:ident) => {
1010        $crate::__private::push_colon2(&mut $tokens);
1011    };
1012
1013    (( $($inner:tt)* ) $tokens:ident) => {
1014        $crate::__private::push_group(
1015            &mut $tokens,
1016            $crate::__private::Delimiter::Parenthesis,
1017            $crate::quote!($($inner)*),
1018        );
1019    };
1020
1021    ([ $($inner:tt)* ] $tokens:ident) => {
1022        $crate::__private::push_group(
1023            &mut $tokens,
1024            $crate::__private::Delimiter::Bracket,
1025            $crate::quote!($($inner)*),
1026        );
1027    };
1028
1029    ({ $($inner:tt)* } $tokens:ident) => {
1030        $crate::__private::push_group(
1031            &mut $tokens,
1032            $crate::__private::Delimiter::Brace,
1033            $crate::quote!($($inner)*),
1034        );
1035    };
1036
1037    (# $tokens:ident) => {
1038        $crate::__private::push_pound(&mut $tokens);
1039    };
1040
1041    (, $tokens:ident) => {
1042        $crate::__private::push_comma(&mut $tokens);
1043    };
1044
1045    (. $tokens:ident) => {
1046        $crate::__private::push_dot(&mut $tokens);
1047    };
1048
1049    (; $tokens:ident) => {
1050        $crate::__private::push_semi(&mut $tokens);
1051    };
1052
1053    (: $tokens:ident) => {
1054        $crate::__private::push_colon(&mut $tokens);
1055    };
1056
1057    (+ $tokens:ident) => {
1058        $crate::__private::push_add(&mut $tokens);
1059    };
1060
1061    (+= $tokens:ident) => {
1062        $crate::__private::push_add_eq(&mut $tokens);
1063    };
1064
1065    (& $tokens:ident) => {
1066        $crate::__private::push_and(&mut $tokens);
1067    };
1068
1069    (&& $tokens:ident) => {
1070        $crate::__private::push_and_and(&mut $tokens);
1071    };
1072
1073    (&= $tokens:ident) => {
1074        $crate::__private::push_and_eq(&mut $tokens);
1075    };
1076
1077    (@ $tokens:ident) => {
1078        $crate::__private::push_at(&mut $tokens);
1079    };
1080
1081    (! $tokens:ident) => {
1082        $crate::__private::push_bang(&mut $tokens);
1083    };
1084
1085    (^ $tokens:ident) => {
1086        $crate::__private::push_caret(&mut $tokens);
1087    };
1088
1089    (^= $tokens:ident) => {
1090        $crate::__private::push_caret_eq(&mut $tokens);
1091    };
1092
1093    (/ $tokens:ident) => {
1094        $crate::__private::push_div(&mut $tokens);
1095    };
1096
1097    (/= $tokens:ident) => {
1098        $crate::__private::push_div_eq(&mut $tokens);
1099    };
1100
1101    (.. $tokens:ident) => {
1102        $crate::__private::push_dot2(&mut $tokens);
1103    };
1104
1105    (... $tokens:ident) => {
1106        $crate::__private::push_dot3(&mut $tokens);
1107    };
1108
1109    (..= $tokens:ident) => {
1110        $crate::__private::push_dot_dot_eq(&mut $tokens);
1111    };
1112
1113    (= $tokens:ident) => {
1114        $crate::__private::push_eq(&mut $tokens);
1115    };
1116
1117    (== $tokens:ident) => {
1118        $crate::__private::push_eq_eq(&mut $tokens);
1119    };
1120
1121    (>= $tokens:ident) => {
1122        $crate::__private::push_ge(&mut $tokens);
1123    };
1124
1125    (> $tokens:ident) => {
1126        $crate::__private::push_gt(&mut $tokens);
1127    };
1128
1129    (<= $tokens:ident) => {
1130        $crate::__private::push_le(&mut $tokens);
1131    };
1132
1133    (< $tokens:ident) => {
1134        $crate::__private::push_lt(&mut $tokens);
1135    };
1136
1137    (*= $tokens:ident) => {
1138        $crate::__private::push_mul_eq(&mut $tokens);
1139    };
1140
1141    (!= $tokens:ident) => {
1142        $crate::__private::push_ne(&mut $tokens);
1143    };
1144
1145    (| $tokens:ident) => {
1146        $crate::__private::push_or(&mut $tokens);
1147    };
1148
1149    (|= $tokens:ident) => {
1150        $crate::__private::push_or_eq(&mut $tokens);
1151    };
1152
1153    (|| $tokens:ident) => {
1154        $crate::__private::push_or_or(&mut $tokens);
1155    };
1156
1157    (? $tokens:ident) => {
1158        $crate::__private::push_question(&mut $tokens);
1159    };
1160
1161    (-> $tokens:ident) => {
1162        $crate::__private::push_rarrow(&mut $tokens);
1163    };
1164
1165    (<- $tokens:ident) => {
1166        $crate::__private::push_larrow(&mut $tokens);
1167    };
1168
1169    (% $tokens:ident) => {
1170        $crate::__private::push_rem(&mut $tokens);
1171    };
1172
1173    (%= $tokens:ident) => {
1174        $crate::__private::push_rem_eq(&mut $tokens);
1175    };
1176
1177    (=> $tokens:ident) => {
1178        $crate::__private::push_fat_arrow(&mut $tokens);
1179    };
1180
1181    (<< $tokens:ident) => {
1182        $crate::__private::push_shl(&mut $tokens);
1183    };
1184
1185    (<<= $tokens:ident) => {
1186        $crate::__private::push_shl_eq(&mut $tokens);
1187    };
1188
1189    (>> $tokens:ident) => {
1190        $crate::__private::push_shr(&mut $tokens);
1191    };
1192
1193    (>>= $tokens:ident) => {
1194        $crate::__private::push_shr_eq(&mut $tokens);
1195    };
1196
1197    (* $tokens:ident) => {
1198        $crate::__private::push_star(&mut $tokens);
1199    };
1200
1201    (- $tokens:ident) => {
1202        $crate::__private::push_sub(&mut $tokens);
1203    };
1204
1205    (-= $tokens:ident) => {
1206        $crate::__private::push_sub_eq(&mut $tokens);
1207    };
1208
1209    ($lifetime:lifetime $tokens:ident) => {
1210        $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));
1211    };
1212
1213    (_ $tokens:ident) => {
1214        $crate::__private::push_underscore(&mut $tokens);
1215    };
1216
1217    ($other:tt $tokens:ident) => {
1218        $crate::__private::parse(&mut $tokens, stringify!($other));
1219    };
1220}
1221
1222// See the comment above `quote_token!` about the rule ordering.
1223#[macro_export]
1224#[doc(hidden)]
1225macro_rules! quote_token_spanned {
1226    ($ident:ident $tokens:ident $span:ident) => {
1227        $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
1228    };
1229
1230    (:: $tokens:ident $span:ident) => {
1231        $crate::__private::push_colon2_spanned(&mut $tokens, $span);
1232    };
1233
1234    (( $($inner:tt)* ) $tokens:ident $span:ident) => {
1235        $crate::__private::push_group_spanned(
1236            &mut $tokens,
1237            $span,
1238            $crate::__private::Delimiter::Parenthesis,
1239            $crate::quote_spanned!($span=> $($inner)*),
1240        );
1241    };
1242
1243    ([ $($inner:tt)* ] $tokens:ident $span:ident) => {
1244        $crate::__private::push_group_spanned(
1245            &mut $tokens,
1246            $span,
1247            $crate::__private::Delimiter::Bracket,
1248            $crate::quote_spanned!($span=> $($inner)*),
1249        );
1250    };
1251
1252    ({ $($inner:tt)* } $tokens:ident $span:ident) => {
1253        $crate::__private::push_group_spanned(
1254            &mut $tokens,
1255            $span,
1256            $crate::__private::Delimiter::Brace,
1257            $crate::quote_spanned!($span=> $($inner)*),
1258        );
1259    };
1260
1261    (# $tokens:ident $span:ident) => {
1262        $crate::__private::push_pound_spanned(&mut $tokens, $span);
1263    };
1264
1265    (, $tokens:ident $span:ident) => {
1266        $crate::__private::push_comma_spanned(&mut $tokens, $span);
1267    };
1268
1269    (. $tokens:ident $span:ident) => {
1270        $crate::__private::push_dot_spanned(&mut $tokens, $span);
1271    };
1272
1273    (; $tokens:ident $span:ident) => {
1274        $crate::__private::push_semi_spanned(&mut $tokens, $span);
1275    };
1276
1277    (: $tokens:ident $span:ident) => {
1278        $crate::__private::push_colon_spanned(&mut $tokens, $span);
1279    };
1280
1281    (+ $tokens:ident $span:ident) => {
1282        $crate::__private::push_add_spanned(&mut $tokens, $span);
1283    };
1284
1285    (+= $tokens:ident $span:ident) => {
1286        $crate::__private::push_add_eq_spanned(&mut $tokens, $span);
1287    };
1288
1289    (& $tokens:ident $span:ident) => {
1290        $crate::__private::push_and_spanned(&mut $tokens, $span);
1291    };
1292
1293    (&& $tokens:ident $span:ident) => {
1294        $crate::__private::push_and_and_spanned(&mut $tokens, $span);
1295    };
1296
1297    (&= $tokens:ident $span:ident) => {
1298        $crate::__private::push_and_eq_spanned(&mut $tokens, $span);
1299    };
1300
1301    (@ $tokens:ident $span:ident) => {
1302        $crate::__private::push_at_spanned(&mut $tokens, $span);
1303    };
1304
1305    (! $tokens:ident $span:ident) => {
1306        $crate::__private::push_bang_spanned(&mut $tokens, $span);
1307    };
1308
1309    (^ $tokens:ident $span:ident) => {
1310        $crate::__private::push_caret_spanned(&mut $tokens, $span);
1311    };
1312
1313    (^= $tokens:ident $span:ident) => {
1314        $crate::__private::push_caret_eq_spanned(&mut $tokens, $span);
1315    };
1316
1317    (/ $tokens:ident $span:ident) => {
1318        $crate::__private::push_div_spanned(&mut $tokens, $span);
1319    };
1320
1321    (/= $tokens:ident $span:ident) => {
1322        $crate::__private::push_div_eq_spanned(&mut $tokens, $span);
1323    };
1324
1325    (.. $tokens:ident $span:ident) => {
1326        $crate::__private::push_dot2_spanned(&mut $tokens, $span);
1327    };
1328
1329    (... $tokens:ident $span:ident) => {
1330        $crate::__private::push_dot3_spanned(&mut $tokens, $span);
1331    };
1332
1333    (..= $tokens:ident $span:ident) => {
1334        $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);
1335    };
1336
1337    (= $tokens:ident $span:ident) => {
1338        $crate::__private::push_eq_spanned(&mut $tokens, $span);
1339    };
1340
1341    (== $tokens:ident $span:ident) => {
1342        $crate::__private::push_eq_eq_spanned(&mut $tokens, $span);
1343    };
1344
1345    (>= $tokens:ident $span:ident) => {
1346        $crate::__private::push_ge_spanned(&mut $tokens, $span);
1347    };
1348
1349    (> $tokens:ident $span:ident) => {
1350        $crate::__private::push_gt_spanned(&mut $tokens, $span);
1351    };
1352
1353    (<= $tokens:ident $span:ident) => {
1354        $crate::__private::push_le_spanned(&mut $tokens, $span);
1355    };
1356
1357    (< $tokens:ident $span:ident) => {
1358        $crate::__private::push_lt_spanned(&mut $tokens, $span);
1359    };
1360
1361    (*= $tokens:ident $span:ident) => {
1362        $crate::__private::push_mul_eq_spanned(&mut $tokens, $span);
1363    };
1364
1365    (!= $tokens:ident $span:ident) => {
1366        $crate::__private::push_ne_spanned(&mut $tokens, $span);
1367    };
1368
1369    (| $tokens:ident $span:ident) => {
1370        $crate::__private::push_or_spanned(&mut $tokens, $span);
1371    };
1372
1373    (|= $tokens:ident $span:ident) => {
1374        $crate::__private::push_or_eq_spanned(&mut $tokens, $span);
1375    };
1376
1377    (|| $tokens:ident $span:ident) => {
1378        $crate::__private::push_or_or_spanned(&mut $tokens, $span);
1379    };
1380
1381    (? $tokens:ident $span:ident) => {
1382        $crate::__private::push_question_spanned(&mut $tokens, $span);
1383    };
1384
1385    (-> $tokens:ident $span:ident) => {
1386        $crate::__private::push_rarrow_spanned(&mut $tokens, $span);
1387    };
1388
1389    (<- $tokens:ident $span:ident) => {
1390        $crate::__private::push_larrow_spanned(&mut $tokens, $span);
1391    };
1392
1393    (% $tokens:ident $span:ident) => {
1394        $crate::__private::push_rem_spanned(&mut $tokens, $span);
1395    };
1396
1397    (%= $tokens:ident $span:ident) => {
1398        $crate::__private::push_rem_eq_spanned(&mut $tokens, $span);
1399    };
1400
1401    (=> $tokens:ident $span:ident) => {
1402        $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);
1403    };
1404
1405    (<< $tokens:ident $span:ident) => {
1406        $crate::__private::push_shl_spanned(&mut $tokens, $span);
1407    };
1408
1409    (<<= $tokens:ident $span:ident) => {
1410        $crate::__private::push_shl_eq_spanned(&mut $tokens, $span);
1411    };
1412
1413    (>> $tokens:ident $span:ident) => {
1414        $crate::__private::push_shr_spanned(&mut $tokens, $span);
1415    };
1416
1417    (>>= $tokens:ident $span:ident) => {
1418        $crate::__private::push_shr_eq_spanned(&mut $tokens, $span);
1419    };
1420
1421    (* $tokens:ident $span:ident) => {
1422        $crate::__private::push_star_spanned(&mut $tokens, $span);
1423    };
1424
1425    (- $tokens:ident $span:ident) => {
1426        $crate::__private::push_sub_spanned(&mut $tokens, $span);
1427    };
1428
1429    (-= $tokens:ident $span:ident) => {
1430        $crate::__private::push_sub_eq_spanned(&mut $tokens, $span);
1431    };
1432
1433    ($lifetime:lifetime $tokens:ident $span:ident) => {
1434        $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));
1435    };
1436
1437    (_ $tokens:ident $span:ident) => {
1438        $crate::__private::push_underscore_spanned(&mut $tokens, $span);
1439    };
1440
1441    ($other:tt $tokens:ident $span:ident) => {
1442        $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));
1443    };
1444}