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