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