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