quote/
lib.rs

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