• 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&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
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.15")]
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 /// Macro calls in a doc attribute are not valid syntax:
393 ///
394 /// ```compile_fail
395 /// quote! {
396 ///     #[doc = concat!("try to interpolate: ", stringify!(#ident))]
397 /// }
398 /// ```
399 ///
400 /// Instead the best way to build doc comments that involve variables is by
401 /// formatting the doc string literal outside of quote.
402 ///
403 /// ```rust
404 /// # use proc_macro2::{Ident, Span};
405 /// # use quote::quote;
406 /// #
407 /// # const IGNORE: &str = stringify! {
408 /// let msg = format!(...);
409 /// # };
410 /// #
411 /// # let ident = Ident::new("var", Span::call_site());
412 /// # let msg = format!("try to interpolate: {}", ident);
413 /// quote! {
414 ///     #[doc = #msg]
415 ///     ///
416 ///     /// ...
417 /// }
418 /// # ;
419 /// ```
420 ///
421 /// <p><br></p>
422 ///
423 /// ### Indexing into a tuple struct
424 ///
425 /// When interpolating indices of a tuple or tuple struct, we need them not to
426 /// appears suffixed as integer literals by interpolating them as [`syn::Index`]
427 /// instead.
428 ///
429 /// [`syn::Index`]: https://docs.rs/syn/1.0/syn/struct.Index.html
430 ///
431 /// ```compile_fail
432 /// let i = 0usize..self.fields.len();
433 ///
434 /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
435 /// // which is not valid syntax
436 /// quote! {
437 ///     0 #( + self.#i.heap_size() )*
438 /// }
439 /// ```
440 ///
441 /// ```
442 /// # use proc_macro2::{Ident, TokenStream};
443 /// # use quote::quote;
444 /// #
445 /// # mod syn {
446 /// #     use proc_macro2::{Literal, TokenStream};
447 /// #     use quote::{ToTokens, TokenStreamExt};
448 /// #
449 /// #     pub struct Index(usize);
450 /// #
451 /// #     impl From<usize> for Index {
452 /// #         fn from(i: usize) -> Self {
453 /// #             Index(i)
454 /// #         }
455 /// #     }
456 /// #
457 /// #     impl ToTokens for Index {
458 /// #         fn to_tokens(&self, tokens: &mut TokenStream) {
459 /// #             tokens.append(Literal::usize_unsuffixed(self.0));
460 /// #         }
461 /// #     }
462 /// # }
463 /// #
464 /// # struct Struct {
465 /// #     fields: Vec<Ident>,
466 /// # }
467 /// #
468 /// # impl Struct {
469 /// #     fn example(&self) -> TokenStream {
470 /// let i = (0..self.fields.len()).map(syn::Index::from);
471 ///
472 /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
473 /// quote! {
474 ///     0 #( + self.#i.heap_size() )*
475 /// }
476 /// #     }
477 /// # }
478 /// ```
479 #[macro_export]
480 macro_rules! quote {
481     () => {
482         $crate::__private::TokenStream::new()
483     };
484     ($($tt:tt)*) => {{
485         let mut _s = $crate::__private::TokenStream::new();
486         $crate::quote_each_token!(_s $($tt)*);
487         _s
488     }};
489 }
490 
491 /// Same as `quote!`, but applies a given span to all tokens originating within
492 /// the macro invocation.
493 ///
494 /// <br>
495 ///
496 /// # Syntax
497 ///
498 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens
499 /// to quote. The span expression should be brief &mdash; use a variable for
500 /// anything more than a few characters. There should be no space before the
501 /// `=>` token.
502 ///
503 /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
504 ///
505 /// ```
506 /// # use proc_macro2::Span;
507 /// # use quote::quote_spanned;
508 /// #
509 /// # const IGNORE_TOKENS: &'static str = stringify! {
510 /// let span = /* ... */;
511 /// # };
512 /// # let span = Span::call_site();
513 /// # let init = 0;
514 ///
515 /// // On one line, use parentheses.
516 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
517 ///
518 /// // On multiple lines, place the span at the top and use braces.
519 /// let tokens = quote_spanned! {span=>
520 ///     Box::into_raw(Box::new(#init))
521 /// };
522 /// ```
523 ///
524 /// The lack of space before the `=>` should look jarring to Rust programmers
525 /// and this is intentional. The formatting is designed to be visibly
526 /// off-balance and draw the eye a particular way, due to the span expression
527 /// being evaluated in the context of the procedural macro and the remaining
528 /// tokens being evaluated in the generated code.
529 ///
530 /// <br>
531 ///
532 /// # Hygiene
533 ///
534 /// Any interpolated tokens preserve the `Span` information provided by their
535 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
536 /// invocation are spanned with the given span argument.
537 ///
538 /// <br>
539 ///
540 /// # Example
541 ///
542 /// The following procedural macro code uses `quote_spanned!` to assert that a
543 /// particular Rust type implements the [`Sync`] trait so that references can be
544 /// safely shared between threads.
545 ///
546 /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
547 ///
548 /// ```
549 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
550 /// # use proc_macro2::{Span, TokenStream};
551 /// #
552 /// # struct Type;
553 /// #
554 /// # impl Type {
555 /// #     fn span(&self) -> Span {
556 /// #         Span::call_site()
557 /// #     }
558 /// # }
559 /// #
560 /// # impl ToTokens for Type {
561 /// #     fn to_tokens(&self, _tokens: &mut TokenStream) {}
562 /// # }
563 /// #
564 /// # let ty = Type;
565 /// # let call_site = Span::call_site();
566 /// #
567 /// let ty_span = ty.span();
568 /// let assert_sync = quote_spanned! {ty_span=>
569 ///     struct _AssertSync where #ty: Sync;
570 /// };
571 /// ```
572 ///
573 /// If the assertion fails, the user will see an error like the following. The
574 /// input span of their type is highlighted in the error.
575 ///
576 /// ```text
577 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
578 ///   --> src/main.rs:10:21
579 ///    |
580 /// 10 |     static ref PTR: *const () = &();
581 ///    |                     ^^^^^^^^^ `*const ()` cannot be shared between threads safely
582 /// ```
583 ///
584 /// In this example it is important for the where-clause to be spanned with the
585 /// line/column information of the user's input type so that error messages are
586 /// placed appropriately by the compiler.
587 #[macro_export]
588 macro_rules! quote_spanned {
589     ($span:expr=>) => {{
590         let _: $crate::__private::Span = $span;
591         $crate::__private::TokenStream::new()
592     }};
593     ($span:expr=> $($tt:tt)*) => {{
594         let mut _s = $crate::__private::TokenStream::new();
595         let _span: $crate::__private::Span = $span;
596         $crate::quote_each_token_spanned!(_s _span $($tt)*);
597         _s
598     }};
599 }
600 
601 // Extract the names of all #metavariables and pass them to the $call macro.
602 //
603 // in:   pounded_var_names!(then!(...) a #b c #( #d )* #e)
604 // out:  then!(... b);
605 //       then!(... d);
606 //       then!(... e);
607 #[macro_export]
608 #[doc(hidden)]
609 macro_rules! pounded_var_names {
610     ($call:ident! $extra:tt $($tts:tt)*) => {
611         $crate::pounded_var_names_with_context!($call! $extra
612             (@ $($tts)*)
613             ($($tts)* @)
614         )
615     };
616 }
617 
618 #[macro_export]
619 #[doc(hidden)]
620 macro_rules! pounded_var_names_with_context {
621     ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
622         $(
623             $crate::pounded_var_with_context!($call! $extra $b1 $curr);
624         )*
625     };
626 }
627 
628 #[macro_export]
629 #[doc(hidden)]
630 macro_rules! pounded_var_with_context {
631     ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
632         $crate::pounded_var_names!($call! $extra $($inner)*);
633     };
634 
635     ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
636         $crate::pounded_var_names!($call! $extra $($inner)*);
637     };
638 
639     ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
640         $crate::pounded_var_names!($call! $extra $($inner)*);
641     };
642 
643     ($call:ident!($($extra:tt)*) # $var:ident) => {
644         $crate::$call!($($extra)* $var);
645     };
646 
647     ($call:ident! $extra:tt $b1:tt $curr:tt) => {};
648 }
649 
650 #[macro_export]
651 #[doc(hidden)]
652 macro_rules! quote_bind_into_iter {
653     ($has_iter:ident $var:ident) => {
654         // `mut` may be unused if $var occurs multiple times in the list.
655         #[allow(unused_mut)]
656         let (mut $var, i) = $var.quote_into_iter();
657         let $has_iter = $has_iter | i;
658     };
659 }
660 
661 #[macro_export]
662 #[doc(hidden)]
663 macro_rules! quote_bind_next_or_break {
664     ($var:ident) => {
665         let $var = match $var.next() {
666             Some(_x) => $crate::__private::RepInterp(_x),
667             None => break,
668         };
669     };
670 }
671 
672 #[macro_export]
673 #[doc(hidden)]
674 macro_rules! quote_each_token {
675     ($tokens:ident $($tts:tt)*) => {
676         $crate::quote_tokens_with_context!($tokens
677             (@ @ @ @ @ @ $($tts)*)
678             (@ @ @ @ @ $($tts)* @)
679             (@ @ @ @ $($tts)* @ @)
680             (@ @ @ $(($tts))* @ @ @)
681             (@ @ $($tts)* @ @ @ @)
682             (@ $($tts)* @ @ @ @ @)
683             ($($tts)* @ @ @ @ @ @)
684         );
685     };
686 }
687 
688 #[macro_export]
689 #[doc(hidden)]
690 macro_rules! quote_each_token_spanned {
691     ($tokens:ident $span:ident $($tts:tt)*) => {
692         $crate::quote_tokens_with_context_spanned!($tokens $span
693             (@ @ @ @ @ @ $($tts)*)
694             (@ @ @ @ @ $($tts)* @)
695             (@ @ @ @ $($tts)* @ @)
696             (@ @ @ $(($tts))* @ @ @)
697             (@ @ $($tts)* @ @ @ @)
698             (@ $($tts)* @ @ @ @ @)
699             ($($tts)* @ @ @ @ @ @)
700         );
701     };
702 }
703 
704 #[macro_export]
705 #[doc(hidden)]
706 macro_rules! quote_tokens_with_context {
707     ($tokens:ident
708         ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
709         ($($curr:tt)*)
710         ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
711     ) => {
712         $(
713             $crate::quote_token_with_context!($tokens $b3 $b2 $b1 $curr $a1 $a2 $a3);
714         )*
715     };
716 }
717 
718 #[macro_export]
719 #[doc(hidden)]
720 macro_rules! quote_tokens_with_context_spanned {
721     ($tokens:ident $span:ident
722         ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
723         ($($curr:tt)*)
724         ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
725     ) => {
726         $(
727             $crate::quote_token_with_context_spanned!($tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3);
728         )*
729     };
730 }
731 
732 #[macro_export]
733 #[doc(hidden)]
734 macro_rules! quote_token_with_context {
735     ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
736 
737     ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
738         use $crate::__private::ext::*;
739         let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
740         $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
741         let _: $crate::__private::HasIterator = has_iter;
742         // This is `while true` instead of `loop` because if there are no
743         // iterators used inside of this repetition then the body would not
744         // contain any `break`, so the compiler would emit unreachable code
745         // warnings on anything below the loop. We use has_iter to detect and
746         // fail to compile when there are no iterators, so here we just work
747         // around the unneeded extra warning.
748         //
749         // FIXME: temporariliy working around Clippy regression.
750         // https://github.com/rust-lang/rust-clippy/issues/7768
751         loop {
752             $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
753             $crate::quote_each_token!($tokens $($inner)*);
754             if false {
755                 break;
756             }
757         }
758     }};
759     ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
760     ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
761 
762     ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
763         use $crate::__private::ext::*;
764         let mut _i = 0usize;
765         let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
766         $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
767         let _: $crate::__private::HasIterator = has_iter;
768         loop {
769             $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
770             if _i > 0 {
771                 $crate::quote_token!($tokens $sep);
772             }
773             _i += 1;
774             $crate::quote_each_token!($tokens $($inner)*);
775             if false {
776                 break;
777             }
778         }
779     }};
780     ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
781     ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
782     ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
783         // https://github.com/dtolnay/quote/issues/130
784         $crate::quote_token!($tokens *);
785     };
786     ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
787 
788     ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
789         $crate::ToTokens::to_tokens(&$var, &mut $tokens);
790     };
791     ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
792     ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
793         $crate::quote_token!($tokens $curr);
794     };
795 }
796 
797 #[macro_export]
798 #[doc(hidden)]
799 macro_rules! quote_token_with_context_spanned {
800     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
801 
802     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
803         use $crate::__private::ext::*;
804         let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
805         $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
806         let _: $crate::__private::HasIterator = has_iter;
807         // This is `while true` instead of `loop` because if there are no
808         // iterators used inside of this repetition then the body would not
809         // contain any `break`, so the compiler would emit unreachable code
810         // warnings on anything below the loop. We use has_iter to detect and
811         // fail to compile when there are no iterators, so here we just work
812         // around the unneeded extra warning.
813         //
814         // FIXME: temporariliy working around Clippy regression.
815         // https://github.com/rust-lang/rust-clippy/issues/7768
816         loop {
817             $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
818             $crate::quote_each_token_spanned!($tokens $span $($inner)*);
819             if false {
820                 break;
821             }
822         }
823     }};
824     ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
825     ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
826 
827     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
828         use $crate::__private::ext::*;
829         let mut _i = 0usize;
830         let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
831         $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
832         let _: $crate::__private::HasIterator = has_iter;
833         loop {
834             $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
835             if _i > 0 {
836                 $crate::quote_token_spanned!($tokens $span $sep);
837             }
838             _i += 1;
839             $crate::quote_each_token_spanned!($tokens $span $($inner)*);
840             if false {
841                 break;
842             }
843         }
844     }};
845     ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
846     ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
847     ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
848         // https://github.com/dtolnay/quote/issues/130
849         $crate::quote_token_spanned!($tokens $span *);
850     };
851     ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
852 
853     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
854         $crate::ToTokens::to_tokens(&$var, &mut $tokens);
855     };
856     ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
857     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
858         $crate::quote_token_spanned!($tokens $span $curr);
859     };
860 }
861 
862 #[macro_export]
863 #[doc(hidden)]
864 macro_rules! quote_token {
865     ($tokens:ident ( $($inner:tt)* )) => {
866         $crate::__private::push_group(
867             &mut $tokens,
868             $crate::__private::Delimiter::Parenthesis,
869             $crate::quote!($($inner)*),
870         );
871     };
872 
873     ($tokens:ident [ $($inner:tt)* ]) => {
874         $crate::__private::push_group(
875             &mut $tokens,
876             $crate::__private::Delimiter::Bracket,
877             $crate::quote!($($inner)*),
878         );
879     };
880 
881     ($tokens:ident { $($inner:tt)* }) => {
882         $crate::__private::push_group(
883             &mut $tokens,
884             $crate::__private::Delimiter::Brace,
885             $crate::quote!($($inner)*),
886         );
887     };
888 
889     ($tokens:ident +) => {
890         $crate::__private::push_add(&mut $tokens);
891     };
892 
893     ($tokens:ident +=) => {
894         $crate::__private::push_add_eq(&mut $tokens);
895     };
896 
897     ($tokens:ident &) => {
898         $crate::__private::push_and(&mut $tokens);
899     };
900 
901     ($tokens:ident &&) => {
902         $crate::__private::push_and_and(&mut $tokens);
903     };
904 
905     ($tokens:ident &=) => {
906         $crate::__private::push_and_eq(&mut $tokens);
907     };
908 
909     ($tokens:ident @) => {
910         $crate::__private::push_at(&mut $tokens);
911     };
912 
913     ($tokens:ident !) => {
914         $crate::__private::push_bang(&mut $tokens);
915     };
916 
917     ($tokens:ident ^) => {
918         $crate::__private::push_caret(&mut $tokens);
919     };
920 
921     ($tokens:ident ^=) => {
922         $crate::__private::push_caret_eq(&mut $tokens);
923     };
924 
925     ($tokens:ident :) => {
926         $crate::__private::push_colon(&mut $tokens);
927     };
928 
929     ($tokens:ident ::) => {
930         $crate::__private::push_colon2(&mut $tokens);
931     };
932 
933     ($tokens:ident ,) => {
934         $crate::__private::push_comma(&mut $tokens);
935     };
936 
937     ($tokens:ident /) => {
938         $crate::__private::push_div(&mut $tokens);
939     };
940 
941     ($tokens:ident /=) => {
942         $crate::__private::push_div_eq(&mut $tokens);
943     };
944 
945     ($tokens:ident .) => {
946         $crate::__private::push_dot(&mut $tokens);
947     };
948 
949     ($tokens:ident ..) => {
950         $crate::__private::push_dot2(&mut $tokens);
951     };
952 
953     ($tokens:ident ...) => {
954         $crate::__private::push_dot3(&mut $tokens);
955     };
956 
957     ($tokens:ident ..=) => {
958         $crate::__private::push_dot_dot_eq(&mut $tokens);
959     };
960 
961     ($tokens:ident =) => {
962         $crate::__private::push_eq(&mut $tokens);
963     };
964 
965     ($tokens:ident ==) => {
966         $crate::__private::push_eq_eq(&mut $tokens);
967     };
968 
969     ($tokens:ident >=) => {
970         $crate::__private::push_ge(&mut $tokens);
971     };
972 
973     ($tokens:ident >) => {
974         $crate::__private::push_gt(&mut $tokens);
975     };
976 
977     ($tokens:ident <=) => {
978         $crate::__private::push_le(&mut $tokens);
979     };
980 
981     ($tokens:ident <) => {
982         $crate::__private::push_lt(&mut $tokens);
983     };
984 
985     ($tokens:ident *=) => {
986         $crate::__private::push_mul_eq(&mut $tokens);
987     };
988 
989     ($tokens:ident !=) => {
990         $crate::__private::push_ne(&mut $tokens);
991     };
992 
993     ($tokens:ident |) => {
994         $crate::__private::push_or(&mut $tokens);
995     };
996 
997     ($tokens:ident |=) => {
998         $crate::__private::push_or_eq(&mut $tokens);
999     };
1000 
1001     ($tokens:ident ||) => {
1002         $crate::__private::push_or_or(&mut $tokens);
1003     };
1004 
1005     ($tokens:ident #) => {
1006         $crate::__private::push_pound(&mut $tokens);
1007     };
1008 
1009     ($tokens:ident ?) => {
1010         $crate::__private::push_question(&mut $tokens);
1011     };
1012 
1013     ($tokens:ident ->) => {
1014         $crate::__private::push_rarrow(&mut $tokens);
1015     };
1016 
1017     ($tokens:ident <-) => {
1018         $crate::__private::push_larrow(&mut $tokens);
1019     };
1020 
1021     ($tokens:ident %) => {
1022         $crate::__private::push_rem(&mut $tokens);
1023     };
1024 
1025     ($tokens:ident %=) => {
1026         $crate::__private::push_rem_eq(&mut $tokens);
1027     };
1028 
1029     ($tokens:ident =>) => {
1030         $crate::__private::push_fat_arrow(&mut $tokens);
1031     };
1032 
1033     ($tokens:ident ;) => {
1034         $crate::__private::push_semi(&mut $tokens);
1035     };
1036 
1037     ($tokens:ident <<) => {
1038         $crate::__private::push_shl(&mut $tokens);
1039     };
1040 
1041     ($tokens:ident <<=) => {
1042         $crate::__private::push_shl_eq(&mut $tokens);
1043     };
1044 
1045     ($tokens:ident >>) => {
1046         $crate::__private::push_shr(&mut $tokens);
1047     };
1048 
1049     ($tokens:ident >>=) => {
1050         $crate::__private::push_shr_eq(&mut $tokens);
1051     };
1052 
1053     ($tokens:ident *) => {
1054         $crate::__private::push_star(&mut $tokens);
1055     };
1056 
1057     ($tokens:ident -) => {
1058         $crate::__private::push_sub(&mut $tokens);
1059     };
1060 
1061     ($tokens:ident -=) => {
1062         $crate::__private::push_sub_eq(&mut $tokens);
1063     };
1064 
1065     ($tokens:ident $ident:ident) => {
1066         $crate::__private::push_ident(&mut $tokens, stringify!($ident));
1067     };
1068 
1069     ($tokens:ident $lifetime:lifetime) => {
1070         $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));
1071     };
1072 
1073     ($tokens:ident _) => {
1074         $crate::__private::push_underscore(&mut $tokens);
1075     };
1076 
1077     ($tokens:ident $other:tt) => {
1078         $crate::__private::parse(&mut $tokens, stringify!($other));
1079     };
1080 }
1081 
1082 #[macro_export]
1083 #[doc(hidden)]
1084 macro_rules! quote_token_spanned {
1085     ($tokens:ident $span:ident ( $($inner:tt)* )) => {
1086         $crate::__private::push_group_spanned(
1087             &mut $tokens,
1088             $span,
1089             $crate::__private::Delimiter::Parenthesis,
1090             $crate::quote_spanned!($span=> $($inner)*),
1091         );
1092     };
1093 
1094     ($tokens:ident $span:ident [ $($inner:tt)* ]) => {
1095         $crate::__private::push_group_spanned(
1096             &mut $tokens,
1097             $span,
1098             $crate::__private::Delimiter::Bracket,
1099             $crate::quote_spanned!($span=> $($inner)*),
1100         );
1101     };
1102 
1103     ($tokens:ident $span:ident { $($inner:tt)* }) => {
1104         $crate::__private::push_group_spanned(
1105             &mut $tokens,
1106             $span,
1107             $crate::__private::Delimiter::Brace,
1108             $crate::quote_spanned!($span=> $($inner)*),
1109         );
1110     };
1111 
1112     ($tokens:ident $span:ident +) => {
1113         $crate::__private::push_add_spanned(&mut $tokens, $span);
1114     };
1115 
1116     ($tokens:ident $span:ident +=) => {
1117         $crate::__private::push_add_eq_spanned(&mut $tokens, $span);
1118     };
1119 
1120     ($tokens:ident $span:ident &) => {
1121         $crate::__private::push_and_spanned(&mut $tokens, $span);
1122     };
1123 
1124     ($tokens:ident $span:ident &&) => {
1125         $crate::__private::push_and_and_spanned(&mut $tokens, $span);
1126     };
1127 
1128     ($tokens:ident $span:ident &=) => {
1129         $crate::__private::push_and_eq_spanned(&mut $tokens, $span);
1130     };
1131 
1132     ($tokens:ident $span:ident @) => {
1133         $crate::__private::push_at_spanned(&mut $tokens, $span);
1134     };
1135 
1136     ($tokens:ident $span:ident !) => {
1137         $crate::__private::push_bang_spanned(&mut $tokens, $span);
1138     };
1139 
1140     ($tokens:ident $span:ident ^) => {
1141         $crate::__private::push_caret_spanned(&mut $tokens, $span);
1142     };
1143 
1144     ($tokens:ident $span:ident ^=) => {
1145         $crate::__private::push_caret_eq_spanned(&mut $tokens, $span);
1146     };
1147 
1148     ($tokens:ident $span:ident :) => {
1149         $crate::__private::push_colon_spanned(&mut $tokens, $span);
1150     };
1151 
1152     ($tokens:ident $span:ident ::) => {
1153         $crate::__private::push_colon2_spanned(&mut $tokens, $span);
1154     };
1155 
1156     ($tokens:ident $span:ident ,) => {
1157         $crate::__private::push_comma_spanned(&mut $tokens, $span);
1158     };
1159 
1160     ($tokens:ident $span:ident /) => {
1161         $crate::__private::push_div_spanned(&mut $tokens, $span);
1162     };
1163 
1164     ($tokens:ident $span:ident /=) => {
1165         $crate::__private::push_div_eq_spanned(&mut $tokens, $span);
1166     };
1167 
1168     ($tokens:ident $span:ident .) => {
1169         $crate::__private::push_dot_spanned(&mut $tokens, $span);
1170     };
1171 
1172     ($tokens:ident $span:ident ..) => {
1173         $crate::__private::push_dot2_spanned(&mut $tokens, $span);
1174     };
1175 
1176     ($tokens:ident $span:ident ...) => {
1177         $crate::__private::push_dot3_spanned(&mut $tokens, $span);
1178     };
1179 
1180     ($tokens:ident $span:ident ..=) => {
1181         $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);
1182     };
1183 
1184     ($tokens:ident $span:ident =) => {
1185         $crate::__private::push_eq_spanned(&mut $tokens, $span);
1186     };
1187 
1188     ($tokens:ident $span:ident ==) => {
1189         $crate::__private::push_eq_eq_spanned(&mut $tokens, $span);
1190     };
1191 
1192     ($tokens:ident $span:ident >=) => {
1193         $crate::__private::push_ge_spanned(&mut $tokens, $span);
1194     };
1195 
1196     ($tokens:ident $span:ident >) => {
1197         $crate::__private::push_gt_spanned(&mut $tokens, $span);
1198     };
1199 
1200     ($tokens:ident $span:ident <=) => {
1201         $crate::__private::push_le_spanned(&mut $tokens, $span);
1202     };
1203 
1204     ($tokens:ident $span:ident <) => {
1205         $crate::__private::push_lt_spanned(&mut $tokens, $span);
1206     };
1207 
1208     ($tokens:ident $span:ident *=) => {
1209         $crate::__private::push_mul_eq_spanned(&mut $tokens, $span);
1210     };
1211 
1212     ($tokens:ident $span:ident !=) => {
1213         $crate::__private::push_ne_spanned(&mut $tokens, $span);
1214     };
1215 
1216     ($tokens:ident $span:ident |) => {
1217         $crate::__private::push_or_spanned(&mut $tokens, $span);
1218     };
1219 
1220     ($tokens:ident $span:ident |=) => {
1221         $crate::__private::push_or_eq_spanned(&mut $tokens, $span);
1222     };
1223 
1224     ($tokens:ident $span:ident ||) => {
1225         $crate::__private::push_or_or_spanned(&mut $tokens, $span);
1226     };
1227 
1228     ($tokens:ident $span:ident #) => {
1229         $crate::__private::push_pound_spanned(&mut $tokens, $span);
1230     };
1231 
1232     ($tokens:ident $span:ident ?) => {
1233         $crate::__private::push_question_spanned(&mut $tokens, $span);
1234     };
1235 
1236     ($tokens:ident $span:ident ->) => {
1237         $crate::__private::push_rarrow_spanned(&mut $tokens, $span);
1238     };
1239 
1240     ($tokens:ident $span:ident <-) => {
1241         $crate::__private::push_larrow_spanned(&mut $tokens, $span);
1242     };
1243 
1244     ($tokens:ident $span:ident %) => {
1245         $crate::__private::push_rem_spanned(&mut $tokens, $span);
1246     };
1247 
1248     ($tokens:ident $span:ident %=) => {
1249         $crate::__private::push_rem_eq_spanned(&mut $tokens, $span);
1250     };
1251 
1252     ($tokens:ident $span:ident =>) => {
1253         $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);
1254     };
1255 
1256     ($tokens:ident $span:ident ;) => {
1257         $crate::__private::push_semi_spanned(&mut $tokens, $span);
1258     };
1259 
1260     ($tokens:ident $span:ident <<) => {
1261         $crate::__private::push_shl_spanned(&mut $tokens, $span);
1262     };
1263 
1264     ($tokens:ident $span:ident <<=) => {
1265         $crate::__private::push_shl_eq_spanned(&mut $tokens, $span);
1266     };
1267 
1268     ($tokens:ident $span:ident >>) => {
1269         $crate::__private::push_shr_spanned(&mut $tokens, $span);
1270     };
1271 
1272     ($tokens:ident $span:ident >>=) => {
1273         $crate::__private::push_shr_eq_spanned(&mut $tokens, $span);
1274     };
1275 
1276     ($tokens:ident $span:ident *) => {
1277         $crate::__private::push_star_spanned(&mut $tokens, $span);
1278     };
1279 
1280     ($tokens:ident $span:ident -) => {
1281         $crate::__private::push_sub_spanned(&mut $tokens, $span);
1282     };
1283 
1284     ($tokens:ident $span:ident -=) => {
1285         $crate::__private::push_sub_eq_spanned(&mut $tokens, $span);
1286     };
1287 
1288     ($tokens:ident $span:ident $ident:ident) => {
1289         $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
1290     };
1291 
1292     ($tokens:ident $span:ident $lifetime:lifetime) => {
1293         $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));
1294     };
1295 
1296     ($tokens:ident $span:ident _) => {
1297         $crate::__private::push_underscore_spanned(&mut $tokens, $span);
1298     };
1299 
1300     ($tokens:ident $span:ident $other:tt) => {
1301         $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));
1302     };
1303 }
1304