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