• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote)
2 //!
3 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6 //!
7 //! <br>
8 //!
9 //! This crate provides the [`quote!`] macro for turning Rust syntax tree data
10 //! structures into tokens of source code.
11 //!
12 //! [`quote!`]: macro.quote.html
13 //!
14 //! Procedural macros in Rust receive a stream of tokens as input, execute
15 //! arbitrary Rust code to determine how to manipulate those tokens, and produce
16 //! a stream of tokens to hand back to the compiler to compile into the caller's
17 //! crate. Quasi-quoting is a solution to one piece of that &mdash; producing
18 //! tokens to return to the compiler.
19 //!
20 //! The idea of quasi-quoting is that we write *code* that we treat as *data*.
21 //! Within the `quote!` macro, we can write what looks like code to our text
22 //! editor or IDE. We get all the benefits of the editor's brace matching,
23 //! syntax highlighting, indentation, and maybe autocompletion. But rather than
24 //! compiling that as code into the current crate, we can treat it as data, pass
25 //! it around, mutate it, and eventually hand it back to the compiler as tokens
26 //! to compile into the macro caller's crate.
27 //!
28 //! This crate is motivated by the procedural macro use case, but is a
29 //! general-purpose Rust quasi-quoting library and is not specific to procedural
30 //! macros.
31 //!
32 //! ```toml
33 //! [dependencies]
34 //! quote = "1.0"
35 //! ```
36 //!
37 //! <br>
38 //!
39 //! # Example
40 //!
41 //! The following quasi-quoted block of code is something you might find in [a]
42 //! procedural macro having to do with data structure serialization. The `#var`
43 //! syntax performs interpolation of runtime variables into the quoted tokens.
44 //! Check out the documentation of the [`quote!`] macro for more detail about
45 //! the syntax. See also the [`quote_spanned!`] macro which is important for
46 //! implementing hygienic procedural macros.
47 //!
48 //! [a]: https://serde.rs/
49 //! [`quote_spanned!`]: macro.quote_spanned.html
50 //!
51 //! ```
52 //! # use quote::quote;
53 //! #
54 //! # let generics = "";
55 //! # let where_clause = "";
56 //! # let field_ty = "";
57 //! # let item_ty = "";
58 //! # let path = "";
59 //! # let value = "";
60 //! #
61 //! let tokens = quote! {
62 //!     struct SerializeWith #generics #where_clause {
63 //!         value: &'a #field_ty,
64 //!         phantom: core::marker::PhantomData<#item_ty>,
65 //!     }
66 //!
67 //!     impl #generics serde::Serialize for SerializeWith #generics #where_clause {
68 //!         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69 //!         where
70 //!             S: serde::Serializer,
71 //!         {
72 //!             #path(self.value, serializer)
73 //!         }
74 //!     }
75 //!
76 //!     SerializeWith {
77 //!         value: #value,
78 //!         phantom: core::marker::PhantomData::<#item_ty>,
79 //!     }
80 //! };
81 //! ```
82 //!
83 //! <br>
84 //!
85 //! # Non-macro code generators
86 //!
87 //! When using `quote` in a build.rs or main.rs and writing the output out to a
88 //! file, consider having the code generator pass the tokens through
89 //! [prettyplease] before writing. This way if an error occurs in the generated
90 //! code it is convenient for a human to read and debug.
91 //!
92 //! [prettyplease]: https://github.com/dtolnay/prettyplease
93 
94 // Quote types in rustdoc of other crates get linked to here.
95 #![doc(html_root_url = "https://docs.rs/quote/1.0.35")]
96 #![allow(
97     clippy::doc_markdown,
98     clippy::missing_errors_doc,
99     clippy::missing_panics_doc,
100     clippy::module_name_repetitions,
101     // false positive https://github.com/rust-lang/rust-clippy/issues/6983
102     clippy::wrong_self_convention,
103 )]
104 
105 extern crate alloc;
106 
107 #[cfg(feature = "proc-macro")]
108 extern crate proc_macro;
109 
110 mod ext;
111 mod format;
112 mod ident_fragment;
113 mod to_tokens;
114 
115 // Not public API.
116 #[doc(hidden)]
117 #[path = "runtime.rs"]
118 pub mod __private;
119 
120 pub use crate::ext::TokenStreamExt;
121 pub use crate::ident_fragment::IdentFragment;
122 pub use crate::to_tokens::ToTokens;
123 
124 // Not public API.
125 #[doc(hidden)]
126 pub mod spanned;
127 
128 /// The whole point.
129 ///
130 /// Performs variable interpolation against the input and produces it as
131 /// [`proc_macro2::TokenStream`].
132 ///
133 /// Note: for returning tokens to the compiler in a procedural macro, use
134 /// `.into()` on the result to convert to [`proc_macro::TokenStream`].
135 ///
136 /// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
137 ///
138 /// <br>
139 ///
140 /// # Interpolation
141 ///
142 /// Variable interpolation is done with `#var` (similar to `$var` in
143 /// `macro_rules!` macros). This grabs the `var` variable that is currently in
144 /// scope and inserts it in that location in the output tokens. Any type
145 /// implementing the [`ToTokens`] trait can be interpolated. This includes most
146 /// Rust primitive types as well as most of the syntax tree types from the [Syn]
147 /// crate.
148 ///
149 /// [`ToTokens`]: trait.ToTokens.html
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()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
172 ///
173 /// A different span can be provided through the [`quote_spanned!`] macro.
174 ///
175 /// [`quote_spanned!`]: macro.quote_spanned.html
176 ///
177 /// <br>
178 ///
179 /// # Return type
180 ///
181 /// The macro evaluates to an expression of type `proc_macro2::TokenStream`.
182 /// Meanwhile Rust procedural macros are expected to return the type
183 /// `proc_macro::TokenStream`.
184 ///
185 /// The difference between the two types is that `proc_macro` types are entirely
186 /// specific to procedural macros and cannot ever exist in code outside of a
187 /// procedural macro, while `proc_macro2` types may exist anywhere including
188 /// tests and non-macro code like main.rs and build.rs. This is why even the
189 /// procedural macro ecosystem is largely built around `proc_macro2`, because
190 /// that ensures the libraries are unit testable and accessible in non-macro
191 /// contexts.
192 ///
193 /// There is a [`From`]-conversion in both directions so returning the output of
194 /// `quote!` from a procedural macro usually looks like `tokens.into()` or
195 /// `proc_macro::TokenStream::from(tokens)`.
196 ///
197 /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
198 ///
199 /// <br>
200 ///
201 /// # Examples
202 ///
203 /// ### Procedural macro
204 ///
205 /// The structure of a basic procedural macro is as follows. Refer to the [Syn]
206 /// crate for further useful guidance on using `quote!` as part of a procedural
207 /// macro.
208 ///
209 /// [Syn]: https://github.com/dtolnay/syn
210 ///
211 /// ```
212 /// # #[cfg(any())]
213 /// extern crate proc_macro;
214 /// # extern crate proc_macro2;
215 ///
216 /// # #[cfg(any())]
217 /// use proc_macro::TokenStream;
218 /// # use proc_macro2::TokenStream;
219 /// use quote::quote;
220 ///
221 /// # const IGNORE_TOKENS: &'static str = stringify! {
222 /// #[proc_macro_derive(HeapSize)]
223 /// # };
224 /// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
225 ///     // Parse the input and figure out what implementation to generate...
226 ///     # const IGNORE_TOKENS: &'static str = stringify! {
227 ///     let name = /* ... */;
228 ///     let expr = /* ... */;
229 ///     # };
230 ///     #
231 ///     # let name = 0;
232 ///     # let expr = 0;
233 ///
234 ///     let expanded = quote! {
235 ///         // The generated impl.
236 ///         impl heapsize::HeapSize for #name {
237 ///             fn heap_size_of_children(&self) -> usize {
238 ///                 #expr
239 ///             }
240 ///         }
241 ///     };
242 ///
243 ///     // Hand the output tokens back to the compiler.
244 ///     TokenStream::from(expanded)
245 /// }
246 /// ```
247 ///
248 /// <p><br></p>
249 ///
250 /// ### Combining quoted fragments
251 ///
252 /// Usually you don't end up constructing an entire final `TokenStream` in one
253 /// piece. Different parts may come from different helper functions. The tokens
254 /// produced by `quote!` themselves implement `ToTokens` and so can be
255 /// interpolated into later `quote!` invocations to build up a final result.
256 ///
257 /// ```
258 /// # use quote::quote;
259 /// #
260 /// let type_definition = quote! {...};
261 /// let methods = quote! {...};
262 ///
263 /// let tokens = quote! {
264 ///     #type_definition
265 ///     #methods
266 /// };
267 /// ```
268 ///
269 /// <p><br></p>
270 ///
271 /// ### Constructing identifiers
272 ///
273 /// Suppose we have an identifier `ident` which came from somewhere in a macro
274 /// input and we need to modify it in some way for the macro output. Let's
275 /// consider prepending the identifier with an underscore.
276 ///
277 /// Simply interpolating the identifier next to an underscore will not have the
278 /// behavior of concatenating them. The underscore and the identifier will
279 /// continue to be two separate tokens as if you had written `_ x`.
280 ///
281 /// ```
282 /// # use proc_macro2::{self as syn, Span};
283 /// # use quote::quote;
284 /// #
285 /// # let ident = syn::Ident::new("i", Span::call_site());
286 /// #
287 /// // incorrect
288 /// quote! {
289 ///     let mut _#ident = 0;
290 /// }
291 /// # ;
292 /// ```
293 ///
294 /// The solution is to build a new identifier token with the correct value. As
295 /// this is such a common case, the [`format_ident!`] macro provides a
296 /// convenient utility for doing so correctly.
297 ///
298 /// ```
299 /// # use proc_macro2::{Ident, Span};
300 /// # use quote::{format_ident, quote};
301 /// #
302 /// # let ident = Ident::new("i", Span::call_site());
303 /// #
304 /// let varname = format_ident!("_{}", ident);
305 /// quote! {
306 ///     let mut #varname = 0;
307 /// }
308 /// # ;
309 /// ```
310 ///
311 /// Alternatively, the APIs provided by Syn and proc-macro2 can be used to
312 /// directly build the identifier. This is roughly equivalent to the above, but
313 /// will not handle `ident` being a raw identifier.
314 ///
315 /// ```
316 /// # use proc_macro2::{self as syn, Span};
317 /// # use quote::quote;
318 /// #
319 /// # let ident = syn::Ident::new("i", Span::call_site());
320 /// #
321 /// let concatenated = format!("_{}", ident);
322 /// let varname = syn::Ident::new(&concatenated, ident.span());
323 /// quote! {
324 ///     let mut #varname = 0;
325 /// }
326 /// # ;
327 /// ```
328 ///
329 /// <p><br></p>
330 ///
331 /// ### Making method calls
332 ///
333 /// Let's say our macro requires some type specified in the macro input to have
334 /// a constructor called `new`. We have the type in a variable called
335 /// `field_type` of type `syn::Type` and want to invoke the constructor.
336 ///
337 /// ```
338 /// # use quote::quote;
339 /// #
340 /// # let field_type = quote!(...);
341 /// #
342 /// // incorrect
343 /// quote! {
344 ///     let value = #field_type::new();
345 /// }
346 /// # ;
347 /// ```
348 ///
349 /// This works only sometimes. If `field_type` is `String`, the expanded code
350 /// contains `String::new()` which is fine. But if `field_type` is something
351 /// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid
352 /// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`
353 /// but for macros often the following is more convenient.
354 ///
355 /// ```
356 /// # use quote::quote;
357 /// #
358 /// # let field_type = quote!(...);
359 /// #
360 /// quote! {
361 ///     let value = <#field_type>::new();
362 /// }
363 /// # ;
364 /// ```
365 ///
366 /// This expands to `<Vec<i32>>::new()` which behaves correctly.
367 ///
368 /// A similar pattern is appropriate for trait methods.
369 ///
370 /// ```
371 /// # use quote::quote;
372 /// #
373 /// # let field_type = quote!(...);
374 /// #
375 /// quote! {
376 ///     let value = <#field_type as core::default::Default>::default();
377 /// }
378 /// # ;
379 /// ```
380 ///
381 /// <p><br></p>
382 ///
383 /// ### Interpolating text inside of doc comments
384 ///
385 /// Neither doc comments nor string literals get interpolation behavior in
386 /// quote:
387 ///
388 /// ```compile_fail
389 /// quote! {
390 ///     /// try to interpolate: #ident
391 ///     ///
392 ///     /// ...
393 /// }
394 /// ```
395 ///
396 /// ```compile_fail
397 /// quote! {
398 ///     #[doc = "try to interpolate: #ident"]
399 /// }
400 /// ```
401 ///
402 /// Instead the best way to build doc comments that involve variables is by
403 /// formatting the doc string literal outside of quote.
404 ///
405 /// ```rust
406 /// # use proc_macro2::{Ident, Span};
407 /// # use quote::quote;
408 /// #
409 /// # const IGNORE: &str = stringify! {
410 /// let msg = format!(...);
411 /// # };
412 /// #
413 /// # let ident = Ident::new("var", Span::call_site());
414 /// # let msg = format!("try to interpolate: {}", ident);
415 /// quote! {
416 ///     #[doc = #msg]
417 ///     ///
418 ///     /// ...
419 /// }
420 /// # ;
421 /// ```
422 ///
423 /// <p><br></p>
424 ///
425 /// ### Indexing into a tuple struct
426 ///
427 /// When interpolating indices of a tuple or tuple struct, we need them not to
428 /// appears suffixed as integer literals by interpolating them as [`syn::Index`]
429 /// instead.
430 ///
431 /// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html
432 ///
433 /// ```compile_fail
434 /// let i = 0usize..self.fields.len();
435 ///
436 /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
437 /// // which is not valid syntax
438 /// quote! {
439 ///     0 #( + self.#i.heap_size() )*
440 /// }
441 /// ```
442 ///
443 /// ```
444 /// # use proc_macro2::{Ident, TokenStream};
445 /// # use quote::quote;
446 /// #
447 /// # mod syn {
448 /// #     use proc_macro2::{Literal, TokenStream};
449 /// #     use quote::{ToTokens, TokenStreamExt};
450 /// #
451 /// #     pub struct Index(usize);
452 /// #
453 /// #     impl From<usize> for Index {
454 /// #         fn from(i: usize) -> Self {
455 /// #             Index(i)
456 /// #         }
457 /// #     }
458 /// #
459 /// #     impl ToTokens for Index {
460 /// #         fn to_tokens(&self, tokens: &mut TokenStream) {
461 /// #             tokens.append(Literal::usize_unsuffixed(self.0));
462 /// #         }
463 /// #     }
464 /// # }
465 /// #
466 /// # struct Struct {
467 /// #     fields: Vec<Ident>,
468 /// # }
469 /// #
470 /// # impl Struct {
471 /// #     fn example(&self) -> TokenStream {
472 /// let i = (0..self.fields.len()).map(syn::Index::from);
473 ///
474 /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
475 /// quote! {
476 ///     0 #( + self.#i.heap_size() )*
477 /// }
478 /// #     }
479 /// # }
480 /// ```
481 #[cfg(doc)]
482 #[macro_export]
483 macro_rules! quote {
484     ($($tt:tt)*) => {
485         ...
486     };
487 }
488 
489 #[cfg(not(doc))]
490 #[macro_export]
491 macro_rules! quote {
492     () => {
493         $crate::__private::TokenStream::new()
494     };
495 
496     // Special case rule for a single tt, for performance.
497     ($tt:tt) => {{
498         let mut _s = $crate::__private::TokenStream::new();
499         $crate::quote_token!{$tt _s}
500         _s
501     }};
502 
503     // Special case rules for two tts, for performance.
504     (# $var:ident) => {{
505         let mut _s = $crate::__private::TokenStream::new();
506         $crate::ToTokens::to_tokens(&$var, &mut _s);
507         _s
508     }};
509     ($tt1:tt $tt2:tt) => {{
510         let mut _s = $crate::__private::TokenStream::new();
511         $crate::quote_token!{$tt1 _s}
512         $crate::quote_token!{$tt2 _s}
513         _s
514     }};
515 
516     // Rule for any other number of tokens.
517     ($($tt:tt)*) => {{
518         let mut _s = $crate::__private::TokenStream::new();
519         $crate::quote_each_token!{_s $($tt)*}
520         _s
521     }};
522 }
523 
524 /// Same as `quote!`, but applies a given span to all tokens originating within
525 /// the macro invocation.
526 ///
527 /// <br>
528 ///
529 /// # Syntax
530 ///
531 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens
532 /// to quote. The span expression should be brief &mdash; use a variable for
533 /// anything more than a few characters. There should be no space before the
534 /// `=>` token.
535 ///
536 /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
537 ///
538 /// ```
539 /// # use proc_macro2::Span;
540 /// # use quote::quote_spanned;
541 /// #
542 /// # const IGNORE_TOKENS: &'static str = stringify! {
543 /// let span = /* ... */;
544 /// # };
545 /// # let span = Span::call_site();
546 /// # let init = 0;
547 ///
548 /// // On one line, use parentheses.
549 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
550 ///
551 /// // On multiple lines, place the span at the top and use braces.
552 /// let tokens = quote_spanned! {span=>
553 ///     Box::into_raw(Box::new(#init))
554 /// };
555 /// ```
556 ///
557 /// The lack of space before the `=>` should look jarring to Rust programmers
558 /// and this is intentional. The formatting is designed to be visibly
559 /// off-balance and draw the eye a particular way, due to the span expression
560 /// being evaluated in the context of the procedural macro and the remaining
561 /// tokens being evaluated in the generated code.
562 ///
563 /// <br>
564 ///
565 /// # Hygiene
566 ///
567 /// Any interpolated tokens preserve the `Span` information provided by their
568 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
569 /// invocation are spanned with the given span argument.
570 ///
571 /// <br>
572 ///
573 /// # Example
574 ///
575 /// The following procedural macro code uses `quote_spanned!` to assert that a
576 /// particular Rust type implements the [`Sync`] trait so that references can be
577 /// safely shared between threads.
578 ///
579 /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
580 ///
581 /// ```
582 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
583 /// # use proc_macro2::{Span, TokenStream};
584 /// #
585 /// # struct Type;
586 /// #
587 /// # impl Type {
588 /// #     fn span(&self) -> Span {
589 /// #         Span::call_site()
590 /// #     }
591 /// # }
592 /// #
593 /// # impl ToTokens for Type {
594 /// #     fn to_tokens(&self, _tokens: &mut TokenStream) {}
595 /// # }
596 /// #
597 /// # let ty = Type;
598 /// # let call_site = Span::call_site();
599 /// #
600 /// let ty_span = ty.span();
601 /// let assert_sync = quote_spanned! {ty_span=>
602 ///     struct _AssertSync where #ty: Sync;
603 /// };
604 /// ```
605 ///
606 /// If the assertion fails, the user will see an error like the following. The
607 /// input span of their type is highlighted in the error.
608 ///
609 /// ```text
610 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
611 ///   --> src/main.rs:10:21
612 ///    |
613 /// 10 |     static ref PTR: *const () = &();
614 ///    |                     ^^^^^^^^^ `*const ()` cannot be shared between threads safely
615 /// ```
616 ///
617 /// In this example it is important for the where-clause to be spanned with the
618 /// line/column information of the user's input type so that error messages are
619 /// placed appropriately by the compiler.
620 #[cfg(doc)]
621 #[macro_export]
622 macro_rules! quote_spanned {
623     ($span:expr=> $($tt:tt)*) => {
624         ...
625     };
626 }
627 
628 #[cfg(not(doc))]
629 #[macro_export]
630 macro_rules! quote_spanned {
631     ($span:expr=>) => {{
632         let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
633         $crate::__private::TokenStream::new()
634     }};
635 
636     // Special case rule for a single tt, for performance.
637     ($span:expr=> $tt:tt) => {{
638         let mut _s = $crate::__private::TokenStream::new();
639         let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
640         $crate::quote_token_spanned!{$tt _s _span}
641         _s
642     }};
643 
644     // Special case rules for two tts, for performance.
645     ($span:expr=> # $var:ident) => {{
646         let mut _s = $crate::__private::TokenStream::new();
647         let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
648         $crate::ToTokens::to_tokens(&$var, &mut _s);
649         _s
650     }};
651     ($span:expr=> $tt1:tt $tt2:tt) => {{
652         let mut _s = $crate::__private::TokenStream::new();
653         let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
654         $crate::quote_token_spanned!{$tt1 _s _span}
655         $crate::quote_token_spanned!{$tt2 _s _span}
656         _s
657     }};
658 
659     // Rule for any other number of tokens.
660     ($span:expr=> $($tt: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_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)]
676 macro_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)]
687 macro_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)]
697 macro_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)]
719 macro_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)]
730 macro_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)]
809 macro_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)]
826 macro_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)]
843 macro_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)]
858 macro_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)]
873 macro_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::ThereIsNoIteratorInRepetition;
882         $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
883         let _: $crate::__private::HasIterator = 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 _i = 0usize;
904         let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
905         $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
906         let _: $crate::__private::HasIterator = has_iter;
907         while true {
908             $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
909             if _i > 0 {
910                 $crate::quote_token!{$sep $tokens}
911             }
912             _i += 1;
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)]
946 macro_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::ThereIsNoIteratorInRepetition;
952         $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
953         let _: $crate::__private::HasIterator = 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 _i = 0usize;
965         let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
966         $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
967         let _: $crate::__private::HasIterator = has_iter;
968         while true {
969             $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
970             if _i > 0 {
971                 $crate::quote_token_spanned!{$sep $tokens $span}
972             }
973             _i += 1;
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)]
1004 macro_rules! quote_token {
1005     ($ident:ident $tokens:ident) => {
1006         $crate::__private::push_ident(&mut $tokens, stringify!($ident));
1007     };
1008 
1009     (:: $tokens:ident) => {
1010         $crate::__private::push_colon2(&mut $tokens);
1011     };
1012 
1013     (( $($inner:tt)* ) $tokens:ident) => {
1014         $crate::__private::push_group(
1015             &mut $tokens,
1016             $crate::__private::Delimiter::Parenthesis,
1017             $crate::quote!($($inner)*),
1018         );
1019     };
1020 
1021     ([ $($inner:tt)* ] $tokens:ident) => {
1022         $crate::__private::push_group(
1023             &mut $tokens,
1024             $crate::__private::Delimiter::Bracket,
1025             $crate::quote!($($inner)*),
1026         );
1027     };
1028 
1029     ({ $($inner:tt)* } $tokens:ident) => {
1030         $crate::__private::push_group(
1031             &mut $tokens,
1032             $crate::__private::Delimiter::Brace,
1033             $crate::quote!($($inner)*),
1034         );
1035     };
1036 
1037     (# $tokens:ident) => {
1038         $crate::__private::push_pound(&mut $tokens);
1039     };
1040 
1041     (, $tokens:ident) => {
1042         $crate::__private::push_comma(&mut $tokens);
1043     };
1044 
1045     (. $tokens:ident) => {
1046         $crate::__private::push_dot(&mut $tokens);
1047     };
1048 
1049     (; $tokens:ident) => {
1050         $crate::__private::push_semi(&mut $tokens);
1051     };
1052 
1053     (: $tokens:ident) => {
1054         $crate::__private::push_colon(&mut $tokens);
1055     };
1056 
1057     (+ $tokens:ident) => {
1058         $crate::__private::push_add(&mut $tokens);
1059     };
1060 
1061     (+= $tokens:ident) => {
1062         $crate::__private::push_add_eq(&mut $tokens);
1063     };
1064 
1065     (& $tokens:ident) => {
1066         $crate::__private::push_and(&mut $tokens);
1067     };
1068 
1069     (&& $tokens:ident) => {
1070         $crate::__private::push_and_and(&mut $tokens);
1071     };
1072 
1073     (&= $tokens:ident) => {
1074         $crate::__private::push_and_eq(&mut $tokens);
1075     };
1076 
1077     (@ $tokens:ident) => {
1078         $crate::__private::push_at(&mut $tokens);
1079     };
1080 
1081     (! $tokens:ident) => {
1082         $crate::__private::push_bang(&mut $tokens);
1083     };
1084 
1085     (^ $tokens:ident) => {
1086         $crate::__private::push_caret(&mut $tokens);
1087     };
1088 
1089     (^= $tokens:ident) => {
1090         $crate::__private::push_caret_eq(&mut $tokens);
1091     };
1092 
1093     (/ $tokens:ident) => {
1094         $crate::__private::push_div(&mut $tokens);
1095     };
1096 
1097     (/= $tokens:ident) => {
1098         $crate::__private::push_div_eq(&mut $tokens);
1099     };
1100 
1101     (.. $tokens:ident) => {
1102         $crate::__private::push_dot2(&mut $tokens);
1103     };
1104 
1105     (... $tokens:ident) => {
1106         $crate::__private::push_dot3(&mut $tokens);
1107     };
1108 
1109     (..= $tokens:ident) => {
1110         $crate::__private::push_dot_dot_eq(&mut $tokens);
1111     };
1112 
1113     (= $tokens:ident) => {
1114         $crate::__private::push_eq(&mut $tokens);
1115     };
1116 
1117     (== $tokens:ident) => {
1118         $crate::__private::push_eq_eq(&mut $tokens);
1119     };
1120 
1121     (>= $tokens:ident) => {
1122         $crate::__private::push_ge(&mut $tokens);
1123     };
1124 
1125     (> $tokens:ident) => {
1126         $crate::__private::push_gt(&mut $tokens);
1127     };
1128 
1129     (<= $tokens:ident) => {
1130         $crate::__private::push_le(&mut $tokens);
1131     };
1132 
1133     (< $tokens:ident) => {
1134         $crate::__private::push_lt(&mut $tokens);
1135     };
1136 
1137     (*= $tokens:ident) => {
1138         $crate::__private::push_mul_eq(&mut $tokens);
1139     };
1140 
1141     (!= $tokens:ident) => {
1142         $crate::__private::push_ne(&mut $tokens);
1143     };
1144 
1145     (| $tokens:ident) => {
1146         $crate::__private::push_or(&mut $tokens);
1147     };
1148 
1149     (|= $tokens:ident) => {
1150         $crate::__private::push_or_eq(&mut $tokens);
1151     };
1152 
1153     (|| $tokens:ident) => {
1154         $crate::__private::push_or_or(&mut $tokens);
1155     };
1156 
1157     (? $tokens:ident) => {
1158         $crate::__private::push_question(&mut $tokens);
1159     };
1160 
1161     (-> $tokens:ident) => {
1162         $crate::__private::push_rarrow(&mut $tokens);
1163     };
1164 
1165     (<- $tokens:ident) => {
1166         $crate::__private::push_larrow(&mut $tokens);
1167     };
1168 
1169     (% $tokens:ident) => {
1170         $crate::__private::push_rem(&mut $tokens);
1171     };
1172 
1173     (%= $tokens:ident) => {
1174         $crate::__private::push_rem_eq(&mut $tokens);
1175     };
1176 
1177     (=> $tokens:ident) => {
1178         $crate::__private::push_fat_arrow(&mut $tokens);
1179     };
1180 
1181     (<< $tokens:ident) => {
1182         $crate::__private::push_shl(&mut $tokens);
1183     };
1184 
1185     (<<= $tokens:ident) => {
1186         $crate::__private::push_shl_eq(&mut $tokens);
1187     };
1188 
1189     (>> $tokens:ident) => {
1190         $crate::__private::push_shr(&mut $tokens);
1191     };
1192 
1193     (>>= $tokens:ident) => {
1194         $crate::__private::push_shr_eq(&mut $tokens);
1195     };
1196 
1197     (* $tokens:ident) => {
1198         $crate::__private::push_star(&mut $tokens);
1199     };
1200 
1201     (- $tokens:ident) => {
1202         $crate::__private::push_sub(&mut $tokens);
1203     };
1204 
1205     (-= $tokens:ident) => {
1206         $crate::__private::push_sub_eq(&mut $tokens);
1207     };
1208 
1209     ($lifetime:lifetime $tokens:ident) => {
1210         $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));
1211     };
1212 
1213     (_ $tokens:ident) => {
1214         $crate::__private::push_underscore(&mut $tokens);
1215     };
1216 
1217     ($other:tt $tokens:ident) => {
1218         $crate::__private::parse(&mut $tokens, stringify!($other));
1219     };
1220 }
1221 
1222 // See the comment above `quote_token!` about the rule ordering.
1223 #[macro_export]
1224 #[doc(hidden)]
1225 macro_rules! quote_token_spanned {
1226     ($ident:ident $tokens:ident $span:ident) => {
1227         $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
1228     };
1229 
1230     (:: $tokens:ident $span:ident) => {
1231         $crate::__private::push_colon2_spanned(&mut $tokens, $span);
1232     };
1233 
1234     (( $($inner:tt)* ) $tokens:ident $span:ident) => {
1235         $crate::__private::push_group_spanned(
1236             &mut $tokens,
1237             $span,
1238             $crate::__private::Delimiter::Parenthesis,
1239             $crate::quote_spanned!($span=> $($inner)*),
1240         );
1241     };
1242 
1243     ([ $($inner:tt)* ] $tokens:ident $span:ident) => {
1244         $crate::__private::push_group_spanned(
1245             &mut $tokens,
1246             $span,
1247             $crate::__private::Delimiter::Bracket,
1248             $crate::quote_spanned!($span=> $($inner)*),
1249         );
1250     };
1251 
1252     ({ $($inner:tt)* } $tokens:ident $span:ident) => {
1253         $crate::__private::push_group_spanned(
1254             &mut $tokens,
1255             $span,
1256             $crate::__private::Delimiter::Brace,
1257             $crate::quote_spanned!($span=> $($inner)*),
1258         );
1259     };
1260 
1261     (# $tokens:ident $span:ident) => {
1262         $crate::__private::push_pound_spanned(&mut $tokens, $span);
1263     };
1264 
1265     (, $tokens:ident $span:ident) => {
1266         $crate::__private::push_comma_spanned(&mut $tokens, $span);
1267     };
1268 
1269     (. $tokens:ident $span:ident) => {
1270         $crate::__private::push_dot_spanned(&mut $tokens, $span);
1271     };
1272 
1273     (; $tokens:ident $span:ident) => {
1274         $crate::__private::push_semi_spanned(&mut $tokens, $span);
1275     };
1276 
1277     (: $tokens:ident $span:ident) => {
1278         $crate::__private::push_colon_spanned(&mut $tokens, $span);
1279     };
1280 
1281     (+ $tokens:ident $span:ident) => {
1282         $crate::__private::push_add_spanned(&mut $tokens, $span);
1283     };
1284 
1285     (+= $tokens:ident $span:ident) => {
1286         $crate::__private::push_add_eq_spanned(&mut $tokens, $span);
1287     };
1288 
1289     (& $tokens:ident $span:ident) => {
1290         $crate::__private::push_and_spanned(&mut $tokens, $span);
1291     };
1292 
1293     (&& $tokens:ident $span:ident) => {
1294         $crate::__private::push_and_and_spanned(&mut $tokens, $span);
1295     };
1296 
1297     (&= $tokens:ident $span:ident) => {
1298         $crate::__private::push_and_eq_spanned(&mut $tokens, $span);
1299     };
1300 
1301     (@ $tokens:ident $span:ident) => {
1302         $crate::__private::push_at_spanned(&mut $tokens, $span);
1303     };
1304 
1305     (! $tokens:ident $span:ident) => {
1306         $crate::__private::push_bang_spanned(&mut $tokens, $span);
1307     };
1308 
1309     (^ $tokens:ident $span:ident) => {
1310         $crate::__private::push_caret_spanned(&mut $tokens, $span);
1311     };
1312 
1313     (^= $tokens:ident $span:ident) => {
1314         $crate::__private::push_caret_eq_spanned(&mut $tokens, $span);
1315     };
1316 
1317     (/ $tokens:ident $span:ident) => {
1318         $crate::__private::push_div_spanned(&mut $tokens, $span);
1319     };
1320 
1321     (/= $tokens:ident $span:ident) => {
1322         $crate::__private::push_div_eq_spanned(&mut $tokens, $span);
1323     };
1324 
1325     (.. $tokens:ident $span:ident) => {
1326         $crate::__private::push_dot2_spanned(&mut $tokens, $span);
1327     };
1328 
1329     (... $tokens:ident $span:ident) => {
1330         $crate::__private::push_dot3_spanned(&mut $tokens, $span);
1331     };
1332 
1333     (..= $tokens:ident $span:ident) => {
1334         $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);
1335     };
1336 
1337     (= $tokens:ident $span:ident) => {
1338         $crate::__private::push_eq_spanned(&mut $tokens, $span);
1339     };
1340 
1341     (== $tokens:ident $span:ident) => {
1342         $crate::__private::push_eq_eq_spanned(&mut $tokens, $span);
1343     };
1344 
1345     (>= $tokens:ident $span:ident) => {
1346         $crate::__private::push_ge_spanned(&mut $tokens, $span);
1347     };
1348 
1349     (> $tokens:ident $span:ident) => {
1350         $crate::__private::push_gt_spanned(&mut $tokens, $span);
1351     };
1352 
1353     (<= $tokens:ident $span:ident) => {
1354         $crate::__private::push_le_spanned(&mut $tokens, $span);
1355     };
1356 
1357     (< $tokens:ident $span:ident) => {
1358         $crate::__private::push_lt_spanned(&mut $tokens, $span);
1359     };
1360 
1361     (*= $tokens:ident $span:ident) => {
1362         $crate::__private::push_mul_eq_spanned(&mut $tokens, $span);
1363     };
1364 
1365     (!= $tokens:ident $span:ident) => {
1366         $crate::__private::push_ne_spanned(&mut $tokens, $span);
1367     };
1368 
1369     (| $tokens:ident $span:ident) => {
1370         $crate::__private::push_or_spanned(&mut $tokens, $span);
1371     };
1372 
1373     (|= $tokens:ident $span:ident) => {
1374         $crate::__private::push_or_eq_spanned(&mut $tokens, $span);
1375     };
1376 
1377     (|| $tokens:ident $span:ident) => {
1378         $crate::__private::push_or_or_spanned(&mut $tokens, $span);
1379     };
1380 
1381     (? $tokens:ident $span:ident) => {
1382         $crate::__private::push_question_spanned(&mut $tokens, $span);
1383     };
1384 
1385     (-> $tokens:ident $span:ident) => {
1386         $crate::__private::push_rarrow_spanned(&mut $tokens, $span);
1387     };
1388 
1389     (<- $tokens:ident $span:ident) => {
1390         $crate::__private::push_larrow_spanned(&mut $tokens, $span);
1391     };
1392 
1393     (% $tokens:ident $span:ident) => {
1394         $crate::__private::push_rem_spanned(&mut $tokens, $span);
1395     };
1396 
1397     (%= $tokens:ident $span:ident) => {
1398         $crate::__private::push_rem_eq_spanned(&mut $tokens, $span);
1399     };
1400 
1401     (=> $tokens:ident $span:ident) => {
1402         $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);
1403     };
1404 
1405     (<< $tokens:ident $span:ident) => {
1406         $crate::__private::push_shl_spanned(&mut $tokens, $span);
1407     };
1408 
1409     (<<= $tokens:ident $span:ident) => {
1410         $crate::__private::push_shl_eq_spanned(&mut $tokens, $span);
1411     };
1412 
1413     (>> $tokens:ident $span:ident) => {
1414         $crate::__private::push_shr_spanned(&mut $tokens, $span);
1415     };
1416 
1417     (>>= $tokens:ident $span:ident) => {
1418         $crate::__private::push_shr_eq_spanned(&mut $tokens, $span);
1419     };
1420 
1421     (* $tokens:ident $span:ident) => {
1422         $crate::__private::push_star_spanned(&mut $tokens, $span);
1423     };
1424 
1425     (- $tokens:ident $span:ident) => {
1426         $crate::__private::push_sub_spanned(&mut $tokens, $span);
1427     };
1428 
1429     (-= $tokens:ident $span:ident) => {
1430         $crate::__private::push_sub_eq_spanned(&mut $tokens, $span);
1431     };
1432 
1433     ($lifetime:lifetime $tokens:ident $span:ident) => {
1434         $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));
1435     };
1436 
1437     (_ $tokens:ident $span:ident) => {
1438         $crate::__private::push_underscore_spanned(&mut $tokens, $span);
1439     };
1440 
1441     ($other:tt $tokens:ident $span:ident) => {
1442         $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));
1443     };
1444 }
1445