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