Skip to main content

quote/
lib.rs

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