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