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