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#![no_std]
92#![doc(html_root_url = "https://docs.rs/quote/1.0.43")]
93#![allow(
94    clippy::doc_markdown,
95    clippy::elidable_lifetime_names,
96    clippy::items_after_statements,
97    clippy::missing_errors_doc,
98    clippy::missing_panics_doc,
99    clippy::module_name_repetitions,
100    clippy::needless_lifetimes,
101    // false positive https://github.com/rust-lang/rust-clippy/issues/6983
102    clippy::wrong_self_convention,
103)]
104
105extern crate alloc;
106extern crate std;
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        /// ```edition2018
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::HasIterator::<false>;
894        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
895        <_ as $crate::__private::CheckHasIterator<true>>::check(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 _first = true;
916        let has_iter = $crate::__private::HasIterator::<false>;
917        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
918        <_ as $crate::__private::CheckHasIterator<true>>::check(has_iter);
919        while true {
920            $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
921            if !_first {
922                $crate::quote_token!{$sep $tokens}
923            }
924            _first = false;
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::HasIterator::<false>;
964        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
965        <_ as $crate::__private::CheckHasIterator<true>>::check(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 _first = true;
977        let has_iter = $crate::__private::HasIterator::<false>;
978        $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
979        <_ as $crate::__private::CheckHasIterator<true>>::check(has_iter);
980        while true {
981            $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
982            if !_first {
983                $crate::quote_token_spanned!{$sep $tokens $span}
984            }
985            _first = false;
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(
1019            &mut $tokens,
1020            $crate::__private::stringify!($ident),
1021        );
1022    };
1023
1024    (:: $tokens:ident) => {
1025        $crate::__private::push_colon2(&mut $tokens);
1026    };
1027
1028    (( $($inner:tt)* ) $tokens:ident) => {
1029        $crate::__private::push_group(
1030            &mut $tokens,
1031            $crate::__private::Delimiter::Parenthesis,
1032            $crate::quote!($($inner)*),
1033        );
1034    };
1035
1036    ([ $($inner:tt)* ] $tokens:ident) => {
1037        $crate::__private::push_group(
1038            &mut $tokens,
1039            $crate::__private::Delimiter::Bracket,
1040            $crate::quote!($($inner)*),
1041        );
1042    };
1043
1044    ({ $($inner:tt)* } $tokens:ident) => {
1045        $crate::__private::push_group(
1046            &mut $tokens,
1047            $crate::__private::Delimiter::Brace,
1048            $crate::quote!($($inner)*),
1049        );
1050    };
1051
1052    (# $tokens:ident) => {
1053        $crate::__private::push_pound(&mut $tokens);
1054    };
1055
1056    (, $tokens:ident) => {
1057        $crate::__private::push_comma(&mut $tokens);
1058    };
1059
1060    (. $tokens:ident) => {
1061        $crate::__private::push_dot(&mut $tokens);
1062    };
1063
1064    (; $tokens:ident) => {
1065        $crate::__private::push_semi(&mut $tokens);
1066    };
1067
1068    (: $tokens:ident) => {
1069        $crate::__private::push_colon(&mut $tokens);
1070    };
1071
1072    (+ $tokens:ident) => {
1073        $crate::__private::push_add(&mut $tokens);
1074    };
1075
1076    (+= $tokens:ident) => {
1077        $crate::__private::push_add_eq(&mut $tokens);
1078    };
1079
1080    (& $tokens:ident) => {
1081        $crate::__private::push_and(&mut $tokens);
1082    };
1083
1084    (&& $tokens:ident) => {
1085        $crate::__private::push_and_and(&mut $tokens);
1086    };
1087
1088    (&= $tokens:ident) => {
1089        $crate::__private::push_and_eq(&mut $tokens);
1090    };
1091
1092    (@ $tokens:ident) => {
1093        $crate::__private::push_at(&mut $tokens);
1094    };
1095
1096    (! $tokens:ident) => {
1097        $crate::__private::push_bang(&mut $tokens);
1098    };
1099
1100    (^ $tokens:ident) => {
1101        $crate::__private::push_caret(&mut $tokens);
1102    };
1103
1104    (^= $tokens:ident) => {
1105        $crate::__private::push_caret_eq(&mut $tokens);
1106    };
1107
1108    (/ $tokens:ident) => {
1109        $crate::__private::push_div(&mut $tokens);
1110    };
1111
1112    (/= $tokens:ident) => {
1113        $crate::__private::push_div_eq(&mut $tokens);
1114    };
1115
1116    (.. $tokens:ident) => {
1117        $crate::__private::push_dot2(&mut $tokens);
1118    };
1119
1120    (... $tokens:ident) => {
1121        $crate::__private::push_dot3(&mut $tokens);
1122    };
1123
1124    (..= $tokens:ident) => {
1125        $crate::__private::push_dot_dot_eq(&mut $tokens);
1126    };
1127
1128    (= $tokens:ident) => {
1129        $crate::__private::push_eq(&mut $tokens);
1130    };
1131
1132    (== $tokens:ident) => {
1133        $crate::__private::push_eq_eq(&mut $tokens);
1134    };
1135
1136    (>= $tokens:ident) => {
1137        $crate::__private::push_ge(&mut $tokens);
1138    };
1139
1140    (> $tokens:ident) => {
1141        $crate::__private::push_gt(&mut $tokens);
1142    };
1143
1144    (<= $tokens:ident) => {
1145        $crate::__private::push_le(&mut $tokens);
1146    };
1147
1148    (< $tokens:ident) => {
1149        $crate::__private::push_lt(&mut $tokens);
1150    };
1151
1152    (*= $tokens:ident) => {
1153        $crate::__private::push_mul_eq(&mut $tokens);
1154    };
1155
1156    (!= $tokens:ident) => {
1157        $crate::__private::push_ne(&mut $tokens);
1158    };
1159
1160    (| $tokens:ident) => {
1161        $crate::__private::push_or(&mut $tokens);
1162    };
1163
1164    (|= $tokens:ident) => {
1165        $crate::__private::push_or_eq(&mut $tokens);
1166    };
1167
1168    (|| $tokens:ident) => {
1169        $crate::__private::push_or_or(&mut $tokens);
1170    };
1171
1172    (? $tokens:ident) => {
1173        $crate::__private::push_question(&mut $tokens);
1174    };
1175
1176    (-> $tokens:ident) => {
1177        $crate::__private::push_rarrow(&mut $tokens);
1178    };
1179
1180    (<- $tokens:ident) => {
1181        $crate::__private::push_larrow(&mut $tokens);
1182    };
1183
1184    (% $tokens:ident) => {
1185        $crate::__private::push_rem(&mut $tokens);
1186    };
1187
1188    (%= $tokens:ident) => {
1189        $crate::__private::push_rem_eq(&mut $tokens);
1190    };
1191
1192    (=> $tokens:ident) => {
1193        $crate::__private::push_fat_arrow(&mut $tokens);
1194    };
1195
1196    (<< $tokens:ident) => {
1197        $crate::__private::push_shl(&mut $tokens);
1198    };
1199
1200    (<<= $tokens:ident) => {
1201        $crate::__private::push_shl_eq(&mut $tokens);
1202    };
1203
1204    (>> $tokens:ident) => {
1205        $crate::__private::push_shr(&mut $tokens);
1206    };
1207
1208    (>>= $tokens:ident) => {
1209        $crate::__private::push_shr_eq(&mut $tokens);
1210    };
1211
1212    (* $tokens:ident) => {
1213        $crate::__private::push_star(&mut $tokens);
1214    };
1215
1216    (- $tokens:ident) => {
1217        $crate::__private::push_sub(&mut $tokens);
1218    };
1219
1220    (-= $tokens:ident) => {
1221        $crate::__private::push_sub_eq(&mut $tokens);
1222    };
1223
1224    ($lifetime:lifetime $tokens:ident) => {
1225        $crate::__private::push_lifetime(
1226            &mut $tokens,
1227            $crate::__private::stringify!($lifetime),
1228        );
1229    };
1230
1231    (_ $tokens:ident) => {
1232        $crate::__private::push_underscore(&mut $tokens);
1233    };
1234
1235    ($other:tt $tokens:ident) => {
1236        $crate::__private::parse(
1237            &mut $tokens,
1238            $crate::__private::stringify!($other),
1239        );
1240    };
1241}
1242
1243// See the comment above `quote_token!` about the rule ordering.
1244#[macro_export]
1245#[doc(hidden)]
1246macro_rules! quote_token_spanned {
1247    ($ident:ident $tokens:ident $span:ident) => {
1248        $crate::__private::push_ident_spanned(
1249            &mut $tokens,
1250            $span,
1251            $crate::__private::stringify!($ident),
1252        );
1253    };
1254
1255    (:: $tokens:ident $span:ident) => {
1256        $crate::__private::push_colon2_spanned(&mut $tokens, $span);
1257    };
1258
1259    (( $($inner:tt)* ) $tokens:ident $span:ident) => {
1260        $crate::__private::push_group_spanned(
1261            &mut $tokens,
1262            $span,
1263            $crate::__private::Delimiter::Parenthesis,
1264            $crate::quote_spanned!($span=> $($inner)*),
1265        );
1266    };
1267
1268    ([ $($inner:tt)* ] $tokens:ident $span:ident) => {
1269        $crate::__private::push_group_spanned(
1270            &mut $tokens,
1271            $span,
1272            $crate::__private::Delimiter::Bracket,
1273            $crate::quote_spanned!($span=> $($inner)*),
1274        );
1275    };
1276
1277    ({ $($inner:tt)* } $tokens:ident $span:ident) => {
1278        $crate::__private::push_group_spanned(
1279            &mut $tokens,
1280            $span,
1281            $crate::__private::Delimiter::Brace,
1282            $crate::quote_spanned!($span=> $($inner)*),
1283        );
1284    };
1285
1286    (# $tokens:ident $span:ident) => {
1287        $crate::__private::push_pound_spanned(&mut $tokens, $span);
1288    };
1289
1290    (, $tokens:ident $span:ident) => {
1291        $crate::__private::push_comma_spanned(&mut $tokens, $span);
1292    };
1293
1294    (. $tokens:ident $span:ident) => {
1295        $crate::__private::push_dot_spanned(&mut $tokens, $span);
1296    };
1297
1298    (; $tokens:ident $span:ident) => {
1299        $crate::__private::push_semi_spanned(&mut $tokens, $span);
1300    };
1301
1302    (: $tokens:ident $span:ident) => {
1303        $crate::__private::push_colon_spanned(&mut $tokens, $span);
1304    };
1305
1306    (+ $tokens:ident $span:ident) => {
1307        $crate::__private::push_add_spanned(&mut $tokens, $span);
1308    };
1309
1310    (+= $tokens:ident $span:ident) => {
1311        $crate::__private::push_add_eq_spanned(&mut $tokens, $span);
1312    };
1313
1314    (& $tokens:ident $span:ident) => {
1315        $crate::__private::push_and_spanned(&mut $tokens, $span);
1316    };
1317
1318    (&& $tokens:ident $span:ident) => {
1319        $crate::__private::push_and_and_spanned(&mut $tokens, $span);
1320    };
1321
1322    (&= $tokens:ident $span:ident) => {
1323        $crate::__private::push_and_eq_spanned(&mut $tokens, $span);
1324    };
1325
1326    (@ $tokens:ident $span:ident) => {
1327        $crate::__private::push_at_spanned(&mut $tokens, $span);
1328    };
1329
1330    (! $tokens:ident $span:ident) => {
1331        $crate::__private::push_bang_spanned(&mut $tokens, $span);
1332    };
1333
1334    (^ $tokens:ident $span:ident) => {
1335        $crate::__private::push_caret_spanned(&mut $tokens, $span);
1336    };
1337
1338    (^= $tokens:ident $span:ident) => {
1339        $crate::__private::push_caret_eq_spanned(&mut $tokens, $span);
1340    };
1341
1342    (/ $tokens:ident $span:ident) => {
1343        $crate::__private::push_div_spanned(&mut $tokens, $span);
1344    };
1345
1346    (/= $tokens:ident $span:ident) => {
1347        $crate::__private::push_div_eq_spanned(&mut $tokens, $span);
1348    };
1349
1350    (.. $tokens:ident $span:ident) => {
1351        $crate::__private::push_dot2_spanned(&mut $tokens, $span);
1352    };
1353
1354    (... $tokens:ident $span:ident) => {
1355        $crate::__private::push_dot3_spanned(&mut $tokens, $span);
1356    };
1357
1358    (..= $tokens:ident $span:ident) => {
1359        $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);
1360    };
1361
1362    (= $tokens:ident $span:ident) => {
1363        $crate::__private::push_eq_spanned(&mut $tokens, $span);
1364    };
1365
1366    (== $tokens:ident $span:ident) => {
1367        $crate::__private::push_eq_eq_spanned(&mut $tokens, $span);
1368    };
1369
1370    (>= $tokens:ident $span:ident) => {
1371        $crate::__private::push_ge_spanned(&mut $tokens, $span);
1372    };
1373
1374    (> $tokens:ident $span:ident) => {
1375        $crate::__private::push_gt_spanned(&mut $tokens, $span);
1376    };
1377
1378    (<= $tokens:ident $span:ident) => {
1379        $crate::__private::push_le_spanned(&mut $tokens, $span);
1380    };
1381
1382    (< $tokens:ident $span:ident) => {
1383        $crate::__private::push_lt_spanned(&mut $tokens, $span);
1384    };
1385
1386    (*= $tokens:ident $span:ident) => {
1387        $crate::__private::push_mul_eq_spanned(&mut $tokens, $span);
1388    };
1389
1390    (!= $tokens:ident $span:ident) => {
1391        $crate::__private::push_ne_spanned(&mut $tokens, $span);
1392    };
1393
1394    (| $tokens:ident $span:ident) => {
1395        $crate::__private::push_or_spanned(&mut $tokens, $span);
1396    };
1397
1398    (|= $tokens:ident $span:ident) => {
1399        $crate::__private::push_or_eq_spanned(&mut $tokens, $span);
1400    };
1401
1402    (|| $tokens:ident $span:ident) => {
1403        $crate::__private::push_or_or_spanned(&mut $tokens, $span);
1404    };
1405
1406    (? $tokens:ident $span:ident) => {
1407        $crate::__private::push_question_spanned(&mut $tokens, $span);
1408    };
1409
1410    (-> $tokens:ident $span:ident) => {
1411        $crate::__private::push_rarrow_spanned(&mut $tokens, $span);
1412    };
1413
1414    (<- $tokens:ident $span:ident) => {
1415        $crate::__private::push_larrow_spanned(&mut $tokens, $span);
1416    };
1417
1418    (% $tokens:ident $span:ident) => {
1419        $crate::__private::push_rem_spanned(&mut $tokens, $span);
1420    };
1421
1422    (%= $tokens:ident $span:ident) => {
1423        $crate::__private::push_rem_eq_spanned(&mut $tokens, $span);
1424    };
1425
1426    (=> $tokens:ident $span:ident) => {
1427        $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);
1428    };
1429
1430    (<< $tokens:ident $span:ident) => {
1431        $crate::__private::push_shl_spanned(&mut $tokens, $span);
1432    };
1433
1434    (<<= $tokens:ident $span:ident) => {
1435        $crate::__private::push_shl_eq_spanned(&mut $tokens, $span);
1436    };
1437
1438    (>> $tokens:ident $span:ident) => {
1439        $crate::__private::push_shr_spanned(&mut $tokens, $span);
1440    };
1441
1442    (>>= $tokens:ident $span:ident) => {
1443        $crate::__private::push_shr_eq_spanned(&mut $tokens, $span);
1444    };
1445
1446    (* $tokens:ident $span:ident) => {
1447        $crate::__private::push_star_spanned(&mut $tokens, $span);
1448    };
1449
1450    (- $tokens:ident $span:ident) => {
1451        $crate::__private::push_sub_spanned(&mut $tokens, $span);
1452    };
1453
1454    (-= $tokens:ident $span:ident) => {
1455        $crate::__private::push_sub_eq_spanned(&mut $tokens, $span);
1456    };
1457
1458    ($lifetime:lifetime $tokens:ident $span:ident) => {
1459        $crate::__private::push_lifetime_spanned(
1460            &mut $tokens,
1461            $span,
1462            $crate::__private::stringify!($lifetime),
1463        );
1464    };
1465
1466    (_ $tokens:ident $span:ident) => {
1467        $crate::__private::push_underscore_spanned(&mut $tokens, $span);
1468    };
1469
1470    ($other:tt $tokens:ident $span:ident) => {
1471        $crate::__private::parse_spanned(
1472            &mut $tokens,
1473            $span,
1474            $crate::__private::stringify!($other),
1475        );
1476    };
1477}