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