Skip to main content

quote/
lib.rs

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