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 — 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 — 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