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