// SPDX-License-Identifier: Apache-2.0 OR MIT12//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote)3//!4//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github5//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust6//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs7//!8//! <br>9//!10//! This crate provides the [`quote!`] macro for turning Rust syntax tree data11//! structures into tokens of source code.12//!13//! Procedural macros in Rust receive a stream of tokens as input, execute14//! arbitrary Rust code to determine how to manipulate those tokens, and produce15//! a stream of tokens to hand back to the compiler to compile into the caller's16//! crate. Quasi-quoting is a solution to one piece of that — producing17//! tokens to return to the compiler.18//!19//! The idea of quasi-quoting is that we write *code* that we treat as *data*.20//! Within the `quote!` macro, we can write what looks like code to our text21//! editor or IDE. We get all the benefits of the editor's brace matching,22//! syntax highlighting, indentation, and maybe autocompletion. But rather than23//! compiling that as code into the current crate, we can treat it as data, pass24//! it around, mutate it, and eventually hand it back to the compiler as tokens25//! to compile into the macro caller's crate.26//!27//! This crate is motivated by the procedural macro use case, but is a28//! general-purpose Rust quasi-quoting library and is not specific to procedural29//! macros.30//!31//! ```toml32//! [dependencies]33//! quote = "1.0"34//! ```35//!36//! <br>37//!38//! # Example39//!40//! The following quasi-quoted block of code is something you might find in [a]41//! procedural macro having to do with data structure serialization. The `#var`42//! syntax performs interpolation of runtime variables into the quoted tokens.43//! Check out the documentation of the [`quote!`] macro for more detail about44//! the syntax. See also the [`quote_spanned!`] macro which is important for45//! implementing hygienic procedural macros.46//!47//! [a]: https://serde.rs/48//!49//! ```50//! # use quote::quote;51//! #52//! # let generics = "";53//! # let where_clause = "";54//! # let field_ty = "";55//! # let item_ty = "";56//! # let path = "";57//! # let value = "";58//! #59//! let tokens = quote! {60//! struct SerializeWith #generics #where_clause {61//! value: &'a #field_ty,62//! phantom: core::marker::PhantomData<#item_ty>,63//! }64//!65//! impl #generics serde::Serialize for SerializeWith #generics #where_clause {66//! fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>67//! where68//! S: serde::Serializer,69//! {70//! #path(self.value, serializer)71//! }72//! }73//!74//! SerializeWith {75//! value: #value,76//! phantom: core::marker::PhantomData::<#item_ty>,77//! }78//! };79//! ```80//!81//! <br>82//!83//! # Non-macro code generators84//!85//! When using `quote` in a build.rs or main.rs and writing the output out to a86//! file, consider having the code generator pass the tokens through87//! [prettyplease] before writing. This way if an error occurs in the generated88//! code it is convenient for a human to read and debug.89//!90//! [prettyplease]: https://github.com/dtolnay/prettyplease9192// Quote types in rustdoc of other crates get linked to here.93#![doc(html_root_url = "https://docs.rs/quote/1.0.40")]94#![allow(95clippy::doc_markdown,96clippy::elidable_lifetime_names,97clippy::missing_errors_doc,98clippy::missing_panics_doc,99clippy::module_name_repetitions,100clippy::needless_lifetimes,101// false positive https://github.com/rust-lang/rust-clippy/issues/6983102clippy::wrong_self_convention,103)]104105extern crate alloc;106107#[cfg(feature = "proc-macro")]108extern crate proc_macro;109110mod ext;111mod format;112mod ident_fragment;113mod to_tokens;114115// Not public API.116#[doc(hidden)]117#[path = "runtime.rs"]118pub mod __private;119120pub use crate::ext::TokenStreamExt;121pub use crate::ident_fragment::IdentFragment;122pub use crate::to_tokens::ToTokens;123124// Not public API.125#[doc(hidden)]126pub mod spanned;127128macro_rules! __quote {129($quote:item) => {130/// The whole point.131///132/// Performs variable interpolation against the input and produces it as133/// [`proc_macro2::TokenStream`].134///135/// Note: for returning tokens to the compiler in a procedural macro, use136/// `.into()` on the result to convert to [`proc_macro::TokenStream`].137///138/// <br>139///140/// # Interpolation141///142/// Variable interpolation is done with `#var` (similar to `$var` in143/// `macro_rules!` macros). This grabs the `var` variable that is currently in144/// scope and inserts it in that location in the output tokens. Any type145/// implementing the [`ToTokens`] trait can be interpolated. This includes most146/// Rust primitive types as well as most of the syntax tree types from the [Syn]147/// crate.148///149/// [Syn]: https://github.com/dtolnay/syn150///151/// Repetition is done using `#(...)*` or `#(...),*` again similar to152/// `macro_rules!`. This iterates through the elements of any variable153/// interpolated within the repetition and inserts a copy of the repetition body154/// for each one. The variables in an interpolation may be a `Vec`, slice,155/// `BTreeSet`, or any `Iterator`.156///157/// - `#(#var)*` — no separators158/// - `#(#var),*` — the character before the asterisk is used as a separator159/// - `#( struct #var; )*` — the repetition can contain other tokens160/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations161///162/// <br>163///164/// # Hygiene165///166/// Any interpolated tokens preserve the `Span` information provided by their167/// `ToTokens` implementation. Tokens that originate within the `quote!`168/// invocation are spanned with [`Span::call_site()`].169///170/// [`Span::call_site()`]: proc_macro2::Span::call_site171///172/// A different span can be provided through the [`quote_spanned!`] macro.173///174/// <br>175///176/// # Return type177///178/// The macro evaluates to an expression of type `proc_macro2::TokenStream`.179/// Meanwhile Rust procedural macros are expected to return the type180/// `proc_macro::TokenStream`.181///182/// The difference between the two types is that `proc_macro` types are entirely183/// specific to procedural macros and cannot ever exist in code outside of a184/// procedural macro, while `proc_macro2` types may exist anywhere including185/// tests and non-macro code like main.rs and build.rs. This is why even the186/// procedural macro ecosystem is largely built around `proc_macro2`, because187/// that ensures the libraries are unit testable and accessible in non-macro188/// contexts.189///190/// There is a [`From`]-conversion in both directions so returning the output of191/// `quote!` from a procedural macro usually looks like `tokens.into()` or192/// `proc_macro::TokenStream::from(tokens)`.193///194/// <br>195///196/// # Examples197///198/// ### Procedural macro199///200/// The structure of a basic procedural macro is as follows. Refer to the [Syn]201/// crate for further useful guidance on using `quote!` as part of a procedural202/// macro.203///204/// [Syn]: https://github.com/dtolnay/syn205///206/// ```207/// # #[cfg(any())]208/// extern crate proc_macro;209/// # extern crate proc_macro2;210///211/// # #[cfg(any())]212/// use proc_macro::TokenStream;213/// # use proc_macro2::TokenStream;214/// use quote::quote;215///216/// # const IGNORE_TOKENS: &'static str = stringify! {217/// #[proc_macro_derive(HeapSize)]218/// # };219/// pub fn derive_heap_size(input: TokenStream) -> TokenStream {220/// // Parse the input and figure out what implementation to generate...221/// # const IGNORE_TOKENS: &'static str = stringify! {222/// let name = /* ... */;223/// let expr = /* ... */;224/// # };225/// #226/// # let name = 0;227/// # let expr = 0;228///229/// let expanded = quote! {230/// // The generated impl.231/// impl heapsize::HeapSize for #name {232/// fn heap_size_of_children(&self) -> usize {233/// #expr234/// }235/// }236/// };237///238/// // Hand the output tokens back to the compiler.239/// TokenStream::from(expanded)240/// }241/// ```242///243/// <p><br></p>244///245/// ### Combining quoted fragments246///247/// Usually you don't end up constructing an entire final `TokenStream` in one248/// piece. Different parts may come from different helper functions. The tokens249/// produced by `quote!` themselves implement `ToTokens` and so can be250/// interpolated into later `quote!` invocations to build up a final result.251///252/// ```253/// # use quote::quote;254/// #255/// let type_definition = quote! {...};256/// let methods = quote! {...};257///258/// let tokens = quote! {259/// #type_definition260/// #methods261/// };262/// ```263///264/// <p><br></p>265///266/// ### Constructing identifiers267///268/// Suppose we have an identifier `ident` which came from somewhere in a macro269/// input and we need to modify it in some way for the macro output. Let's270/// consider prepending the identifier with an underscore.271///272/// Simply interpolating the identifier next to an underscore will not have the273/// behavior of concatenating them. The underscore and the identifier will274/// continue to be two separate tokens as if you had written `_ x`.275///276/// ```277/// # use proc_macro2::{self as syn, Span};278/// # use quote::quote;279/// #280/// # let ident = syn::Ident::new("i", Span::call_site());281/// #282/// // incorrect283/// quote! {284/// let mut _#ident = 0;285/// }286/// # ;287/// ```288///289/// The solution is to build a new identifier token with the correct value. As290/// this is such a common case, the [`format_ident!`] macro provides a291/// convenient utility for doing so correctly.292///293/// ```294/// # use proc_macro2::{Ident, Span};295/// # use quote::{format_ident, quote};296/// #297/// # let ident = Ident::new("i", Span::call_site());298/// #299/// let varname = format_ident!("_{}", ident);300/// quote! {301/// let mut #varname = 0;302/// }303/// # ;304/// ```305///306/// Alternatively, the APIs provided by Syn and proc-macro2 can be used to307/// directly build the identifier. This is roughly equivalent to the above, but308/// will not handle `ident` being a raw identifier.309///310/// ```311/// # use proc_macro2::{self as syn, Span};312/// # use quote::quote;313/// #314/// # let ident = syn::Ident::new("i", Span::call_site());315/// #316/// let concatenated = format!("_{}", ident);317/// let varname = syn::Ident::new(&concatenated, ident.span());318/// quote! {319/// let mut #varname = 0;320/// }321/// # ;322/// ```323///324/// <p><br></p>325///326/// ### Making method calls327///328/// Let's say our macro requires some type specified in the macro input to have329/// a constructor called `new`. We have the type in a variable called330/// `field_type` of type `syn::Type` and want to invoke the constructor.331///332/// ```333/// # use quote::quote;334/// #335/// # let field_type = quote!(...);336/// #337/// // incorrect338/// quote! {339/// let value = #field_type::new();340/// }341/// # ;342/// ```343///344/// This works only sometimes. If `field_type` is `String`, the expanded code345/// contains `String::new()` which is fine. But if `field_type` is something346/// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid347/// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`348/// but for macros often the following is more convenient.349///350/// ```351/// # use quote::quote;352/// #353/// # let field_type = quote!(...);354/// #355/// quote! {356/// let value = <#field_type>::new();357/// }358/// # ;359/// ```360///361/// This expands to `<Vec<i32>>::new()` which behaves correctly.362///363/// A similar pattern is appropriate for trait methods.364///365/// ```366/// # use quote::quote;367/// #368/// # let field_type = quote!(...);369/// #370/// quote! {371/// let value = <#field_type as core::default::Default>::default();372/// }373/// # ;374/// ```375///376/// <p><br></p>377///378/// ### Interpolating text inside of doc comments379///380/// Neither doc comments nor string literals get interpolation behavior in381/// quote:382///383/// ```compile_fail384/// quote! {385/// /// try to interpolate: #ident386/// ///387/// /// ...388/// }389/// ```390///391/// ```compile_fail392/// quote! {393/// #[doc = "try to interpolate: #ident"]394/// }395/// ```396///397/// Instead the best way to build doc comments that involve variables is by398/// formatting the doc string literal outside of quote.399///400/// ```rust401/// # use proc_macro2::{Ident, Span};402/// # use quote::quote;403/// #404/// # const IGNORE: &str = stringify! {405/// let msg = format!(...);406/// # };407/// #408/// # let ident = Ident::new("var", Span::call_site());409/// # let msg = format!("try to interpolate: {}", ident);410/// quote! {411/// #[doc = #msg]412/// ///413/// /// ...414/// }415/// # ;416/// ```417///418/// <p><br></p>419///420/// ### Indexing into a tuple struct421///422/// When interpolating indices of a tuple or tuple struct, we need them not to423/// appears suffixed as integer literals by interpolating them as [`syn::Index`]424/// instead.425///426/// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html427///428/// ```compile_fail429/// let i = 0usize..self.fields.len();430///431/// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...432/// // which is not valid syntax433/// quote! {434/// 0 #( + self.#i.heap_size() )*435/// }436/// ```437///438/// ```439/// # use proc_macro2::{Ident, TokenStream};440/// # use quote::quote;441/// #442/// # mod syn {443/// # use proc_macro2::{Literal, TokenStream};444/// # use quote::{ToTokens, TokenStreamExt};445/// #446/// # pub struct Index(usize);447/// #448/// # impl From<usize> for Index {449/// # fn from(i: usize) -> Self {450/// # Index(i)451/// # }452/// # }453/// #454/// # impl ToTokens for Index {455/// # fn to_tokens(&self, tokens: &mut TokenStream) {456/// # tokens.append(Literal::usize_unsuffixed(self.0));457/// # }458/// # }459/// # }460/// #461/// # struct Struct {462/// # fields: Vec<Ident>,463/// # }464/// #465/// # impl Struct {466/// # fn example(&self) -> TokenStream {467/// let i = (0..self.fields.len()).map(syn::Index::from);468///469/// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...470/// quote! {471/// 0 #( + self.#i.heap_size() )*472/// }473/// # }474/// # }475/// ```476$quote477};478}479480#[cfg(doc)]481__quote![482#[macro_export]483macro_rules! quote {484($($tt:tt)*) => {485...486};487}488];489490#[cfg(not(doc))]491__quote![492#[macro_export]493macro_rules! quote {494() => {495$crate::__private::TokenStream::new()496};497498// Special case rule for a single tt, for performance.499($tt:tt) => {{500let mut _s = $crate::__private::TokenStream::new();501$crate::quote_token!{$tt _s}502_s503}};504505// Special case rules for two tts, for performance.506(# $var:ident) => {{507let mut _s = $crate::__private::TokenStream::new();508$crate::ToTokens::to_tokens(&$var, &mut _s);509_s510}};511($tt1:tt $tt2:tt) => {{512let mut _s = $crate::__private::TokenStream::new();513$crate::quote_token!{$tt1 _s}514$crate::quote_token!{$tt2 _s}515_s516}};517518// Rule for any other number of tokens.519($($tt:tt)*) => {{520let mut _s = $crate::__private::TokenStream::new();521$crate::quote_each_token!{_s $($tt)*}522_s523}};524}525];526527macro_rules! __quote_spanned {528($quote_spanned:item) => {529/// Same as `quote!`, but applies a given span to all tokens originating within530/// the macro invocation.531///532/// <br>533///534/// # Syntax535///536/// A span expression of type [`Span`], followed by `=>`, followed by the tokens537/// to quote. The span expression should be brief — use a variable for538/// anything more than a few characters. There should be no space before the539/// `=>` token.540///541/// [`Span`]: proc_macro2::Span542///543/// ```544/// # use proc_macro2::Span;545/// # use quote::quote_spanned;546/// #547/// # const IGNORE_TOKENS: &'static str = stringify! {548/// let span = /* ... */;549/// # };550/// # let span = Span::call_site();551/// # let init = 0;552///553/// // On one line, use parentheses.554/// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));555///556/// // On multiple lines, place the span at the top and use braces.557/// let tokens = quote_spanned! {span=>558/// Box::into_raw(Box::new(#init))559/// };560/// ```561///562/// The lack of space before the `=>` should look jarring to Rust programmers563/// and this is intentional. The formatting is designed to be visibly564/// off-balance and draw the eye a particular way, due to the span expression565/// being evaluated in the context of the procedural macro and the remaining566/// tokens being evaluated in the generated code.567///568/// <br>569///570/// # Hygiene571///572/// Any interpolated tokens preserve the `Span` information provided by their573/// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`574/// invocation are spanned with the given span argument.575///576/// <br>577///578/// # Example579///580/// The following procedural macro code uses `quote_spanned!` to assert that a581/// particular Rust type implements the [`Sync`] trait so that references can be582/// safely shared between threads.583///584/// ```585/// # use quote::{quote_spanned, TokenStreamExt, ToTokens};586/// # use proc_macro2::{Span, TokenStream};587/// #588/// # struct Type;589/// #590/// # impl Type {591/// # fn span(&self) -> Span {592/// # Span::call_site()593/// # }594/// # }595/// #596/// # impl ToTokens for Type {597/// # fn to_tokens(&self, _tokens: &mut TokenStream) {}598/// # }599/// #600/// # let ty = Type;601/// # let call_site = Span::call_site();602/// #603/// let ty_span = ty.span();604/// let assert_sync = quote_spanned! {ty_span=>605/// struct _AssertSync where #ty: Sync;606/// };607/// ```608///609/// If the assertion fails, the user will see an error like the following. The610/// input span of their type is highlighted in the error.611///612/// ```text613/// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied614/// --> src/main.rs:10:21615/// |616/// 10 | static ref PTR: *const () = &();617/// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely618/// ```619///620/// In this example it is important for the where-clause to be spanned with the621/// line/column information of the user's input type so that error messages are622/// placed appropriately by the compiler.623$quote_spanned624};625}626627#[cfg(doc)]628__quote_spanned![629#[macro_export]630macro_rules! quote_spanned {631($span:expr=> $($tt:tt)*) => {632...633};634}635];636637#[cfg(not(doc))]638__quote_spanned![639#[macro_export]640macro_rules! quote_spanned {641($span:expr=>) => {{642let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();643$crate::__private::TokenStream::new()644}};645646// Special case rule for a single tt, for performance.647($span:expr=> $tt:tt) => {{648let mut _s = $crate::__private::TokenStream::new();649let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();650$crate::quote_token_spanned!{$tt _s _span}651_s652}};653654// Special case rules for two tts, for performance.655($span:expr=> # $var:ident) => {{656let mut _s = $crate::__private::TokenStream::new();657let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();658$crate::ToTokens::to_tokens(&$var, &mut _s);659_s660}};661($span:expr=> $tt1:tt $tt2:tt) => {{662let mut _s = $crate::__private::TokenStream::new();663let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();664$crate::quote_token_spanned!{$tt1 _s _span}665$crate::quote_token_spanned!{$tt2 _s _span}666_s667}};668669// Rule for any other number of tokens.670($span:expr=> $($tt:tt)*) => {{671let mut _s = $crate::__private::TokenStream::new();672let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();673$crate::quote_each_token_spanned!{_s _span $($tt)*}674_s675}};676}677];678679// Extract the names of all #metavariables and pass them to the $call macro.680//681// in: pounded_var_names!(then!(...) a #b c #( #d )* #e)682// out: then!(... b);683// then!(... d);684// then!(... e);685#[macro_export]686#[doc(hidden)]687macro_rules! pounded_var_names {688($call:ident! $extra:tt $($tts:tt)*) => {689$crate::pounded_var_names_with_context!{$call! $extra690(@ $($tts)*)691($($tts)* @)692}693};694}695696#[macro_export]697#[doc(hidden)]698macro_rules! pounded_var_names_with_context {699($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {700$(701$crate::pounded_var_with_context!{$call! $extra $b1 $curr}702)*703};704}705706#[macro_export]707#[doc(hidden)]708macro_rules! pounded_var_with_context {709($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {710$crate::pounded_var_names!{$call! $extra $($inner)*}711};712713($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {714$crate::pounded_var_names!{$call! $extra $($inner)*}715};716717($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {718$crate::pounded_var_names!{$call! $extra $($inner)*}719};720721($call:ident!($($extra:tt)*) # $var:ident) => {722$crate::$call!($($extra)* $var);723};724725($call:ident! $extra:tt $b1:tt $curr:tt) => {};726}727728#[macro_export]729#[doc(hidden)]730macro_rules! quote_bind_into_iter {731($has_iter:ident $var:ident) => {732// `mut` may be unused if $var occurs multiple times in the list.733#[allow(unused_mut)]734let (mut $var, i) = $var.quote_into_iter();735let $has_iter = $has_iter | i;736};737}738739#[macro_export]740#[doc(hidden)]741macro_rules! quote_bind_next_or_break {742($var:ident) => {743let $var = match $var.next() {744Some(_x) => $crate::__private::RepInterp(_x),745None => break,746};747};748}749750// The obvious way to write this macro is as a tt muncher. This implementation751// does something more complex for two reasons.752//753// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which754// this implementation avoids because it isn't tail recursive.755//756// - Compile times for a tt muncher are quadratic relative to the length of757// the input. This implementation is linear, so it will be faster758// (potentially much faster) for big inputs. However, the constant factors759// of this implementation are higher than that of a tt muncher, so it is760// somewhat slower than a tt muncher if there are many invocations with761// short inputs.762//763// An invocation like this:764//765// quote_each_token!(_s a b c d e f g h i j);766//767// expands to this:768//769// quote_tokens_with_context!(_s770// (@ @ @ @ @ @ a b c d e f g h i j)771// (@ @ @ @ @ a b c d e f g h i j @)772// (@ @ @ @ a b c d e f g h i j @ @)773// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @)774// (@ @ a b c d e f g h i j @ @ @ @)775// (@ a b c d e f g h i j @ @ @ @ @)776// (a b c d e f g h i j @ @ @ @ @ @)777// );778//779// which gets transposed and expanded to this:780//781// quote_token_with_context!(_s @ @ @ @ @ @ a);782// quote_token_with_context!(_s @ @ @ @ @ a b);783// quote_token_with_context!(_s @ @ @ @ a b c);784// quote_token_with_context!(_s @ @ @ (a) b c d);785// quote_token_with_context!(_s @ @ a (b) c d e);786// quote_token_with_context!(_s @ a b (c) d e f);787// quote_token_with_context!(_s a b c (d) e f g);788// quote_token_with_context!(_s b c d (e) f g h);789// quote_token_with_context!(_s c d e (f) g h i);790// quote_token_with_context!(_s d e f (g) h i j);791// quote_token_with_context!(_s e f g (h) i j @);792// quote_token_with_context!(_s f g h (i) j @ @);793// quote_token_with_context!(_s g h i (j) @ @ @);794// quote_token_with_context!(_s h i j @ @ @ @);795// quote_token_with_context!(_s i j @ @ @ @ @);796// quote_token_with_context!(_s j @ @ @ @ @ @);797//798// Without having used muncher-style recursion, we get one invocation of799// quote_token_with_context for each original tt, with three tts of context on800// either side. This is enough for the longest possible interpolation form (a801// repetition with separator, as in `# (#var) , *`) to be fully represented with802// the first or last tt in the middle.803//804// The middle tt (surrounded by parentheses) is the tt being processed.805//806// - When it is a `#`, quote_token_with_context can do an interpolation. The807// interpolation kind will depend on the three subsequent tts.808//809// - When it is within a later part of an interpolation, it can be ignored810// because the interpolation has already been done.811//812// - When it is not part of an interpolation it can be pushed as a single813// token into the output.814//815// - When the middle token is an unparenthesized `@`, that call is one of the816// first 3 or last 3 calls of quote_token_with_context and does not817// correspond to one of the original input tokens, so turns into nothing.818#[macro_export]819#[doc(hidden)]820macro_rules! quote_each_token {821($tokens:ident $($tts:tt)*) => {822$crate::quote_tokens_with_context!{$tokens823(@ @ @ @ @ @ $($tts)*)824(@ @ @ @ @ $($tts)* @)825(@ @ @ @ $($tts)* @ @)826(@ @ @ $(($tts))* @ @ @)827(@ @ $($tts)* @ @ @ @)828(@ $($tts)* @ @ @ @ @)829($($tts)* @ @ @ @ @ @)830}831};832}833834// See the explanation on quote_each_token.835#[macro_export]836#[doc(hidden)]837macro_rules! quote_each_token_spanned {838($tokens:ident $span:ident $($tts:tt)*) => {839$crate::quote_tokens_with_context_spanned!{$tokens $span840(@ @ @ @ @ @ $($tts)*)841(@ @ @ @ @ $($tts)* @)842(@ @ @ @ $($tts)* @ @)843(@ @ @ $(($tts))* @ @ @)844(@ @ $($tts)* @ @ @ @)845(@ $($tts)* @ @ @ @ @)846($($tts)* @ @ @ @ @ @)847}848};849}850851// See the explanation on quote_each_token.852#[macro_export]853#[doc(hidden)]854macro_rules! quote_tokens_with_context {855($tokens:ident856($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)857($($curr:tt)*)858($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)859) => {860$(861$crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3}862)*863};864}865866// See the explanation on quote_each_token.867#[macro_export]868#[doc(hidden)]869macro_rules! quote_tokens_with_context_spanned {870($tokens:ident $span:ident871($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)872($($curr:tt)*)873($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)874) => {875$(876$crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3}877)*878};879}880881// See the explanation on quote_each_token.882#[macro_export]883#[doc(hidden)]884macro_rules! quote_token_with_context {885// Unparenthesized `@` indicates this call does not correspond to one of the886// original input tokens. Ignore it.887($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};888889// A repetition with no separator.890($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{891use $crate::__private::ext::*;892let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;893$crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}894let _: $crate::__private::HasIterator = has_iter;895// This is `while true` instead of `loop` because if there are no896// iterators used inside of this repetition then the body would not897// contain any `break`, so the compiler would emit unreachable code898// warnings on anything below the loop. We use has_iter to detect and899// fail to compile when there are no iterators, so here we just work900// around the unneeded extra warning.901while true {902$crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}903$crate::quote_each_token!{$tokens $($inner)*}904}905}};906// ... and one step later.907($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};908// ... and one step later.909($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};910911// A repetition with separator.912($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{913use $crate::__private::ext::*;914let mut _i = 0usize;915let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;916$crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}917let _: $crate::__private::HasIterator = has_iter;918while true {919$crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}920if _i > 0 {921$crate::quote_token!{$sep $tokens}922}923_i += 1;924$crate::quote_each_token!{$tokens $($inner)*}925}926}};927// ... and one step later.928($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};929// ... and one step later.930($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};931// (A special case for `#(var)**`, where the first `*` is treated as the932// repetition symbol and the second `*` is treated as an ordinary token.)933($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {934// https://github.com/dtolnay/quote/issues/130935$crate::quote_token!{* $tokens}936};937// ... and one step later.938($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};939940// A non-repetition interpolation.941($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {942$crate::ToTokens::to_tokens(&$var, &mut $tokens);943};944// ... and one step later.945($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};946947// An ordinary token, not part of any interpolation.948($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {949$crate::quote_token!{$curr $tokens}950};951}952953// See the explanation on quote_each_token, and on the individual rules of954// quote_token_with_context.955#[macro_export]956#[doc(hidden)]957macro_rules! quote_token_with_context_spanned {958($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};959960($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{961use $crate::__private::ext::*;962let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;963$crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}964let _: $crate::__private::HasIterator = has_iter;965while true {966$crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}967$crate::quote_each_token_spanned!{$tokens $span $($inner)*}968}969}};970($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};971($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};972973($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{974use $crate::__private::ext::*;975let mut _i = 0usize;976let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;977$crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}978let _: $crate::__private::HasIterator = has_iter;979while true {980$crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}981if _i > 0 {982$crate::quote_token_spanned!{$sep $tokens $span}983}984_i += 1;985$crate::quote_each_token_spanned!{$tokens $span $($inner)*}986}987}};988($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};989($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};990($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {991// https://github.com/dtolnay/quote/issues/130992$crate::quote_token_spanned!{* $tokens $span}993};994($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};995996($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {997$crate::ToTokens::to_tokens(&$var, &mut $tokens);998};999($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};10001001($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {1002$crate::quote_token_spanned!{$curr $tokens $span}1003};1004}10051006// These rules are ordered by approximate token frequency, at least for the1007// first 10 or so, to improve compile times. Having `ident` first is by far the1008// most important because it's typically 2-3x more common than the next most1009// common token.1010//1011// Separately, we put the token being matched in the very front so that failing1012// rules may fail to match as quickly as possible.1013#[macro_export]1014#[doc(hidden)]1015macro_rules! quote_token {1016($ident:ident $tokens:ident) => {1017$crate::__private::push_ident(&mut $tokens, stringify!($ident));1018};10191020(:: $tokens:ident) => {1021$crate::__private::push_colon2(&mut $tokens);1022};10231024(( $($inner:tt)* ) $tokens:ident) => {1025$crate::__private::push_group(1026&mut $tokens,1027$crate::__private::Delimiter::Parenthesis,1028$crate::quote!($($inner)*),1029);1030};10311032([ $($inner:tt)* ] $tokens:ident) => {1033$crate::__private::push_group(1034&mut $tokens,1035$crate::__private::Delimiter::Bracket,1036$crate::quote!($($inner)*),1037);1038};10391040({ $($inner:tt)* } $tokens:ident) => {1041$crate::__private::push_group(1042&mut $tokens,1043$crate::__private::Delimiter::Brace,1044$crate::quote!($($inner)*),1045);1046};10471048(# $tokens:ident) => {1049$crate::__private::push_pound(&mut $tokens);1050};10511052(, $tokens:ident) => {1053$crate::__private::push_comma(&mut $tokens);1054};10551056(. $tokens:ident) => {1057$crate::__private::push_dot(&mut $tokens);1058};10591060(; $tokens:ident) => {1061$crate::__private::push_semi(&mut $tokens);1062};10631064(: $tokens:ident) => {1065$crate::__private::push_colon(&mut $tokens);1066};10671068(+ $tokens:ident) => {1069$crate::__private::push_add(&mut $tokens);1070};10711072(+= $tokens:ident) => {1073$crate::__private::push_add_eq(&mut $tokens);1074};10751076(& $tokens:ident) => {1077$crate::__private::push_and(&mut $tokens);1078};10791080(&& $tokens:ident) => {1081$crate::__private::push_and_and(&mut $tokens);1082};10831084(&= $tokens:ident) => {1085$crate::__private::push_and_eq(&mut $tokens);1086};10871088(@ $tokens:ident) => {1089$crate::__private::push_at(&mut $tokens);1090};10911092(! $tokens:ident) => {1093$crate::__private::push_bang(&mut $tokens);1094};10951096(^ $tokens:ident) => {1097$crate::__private::push_caret(&mut $tokens);1098};10991100(^= $tokens:ident) => {1101$crate::__private::push_caret_eq(&mut $tokens);1102};11031104(/ $tokens:ident) => {1105$crate::__private::push_div(&mut $tokens);1106};11071108(/= $tokens:ident) => {1109$crate::__private::push_div_eq(&mut $tokens);1110};11111112(.. $tokens:ident) => {1113$crate::__private::push_dot2(&mut $tokens);1114};11151116(... $tokens:ident) => {1117$crate::__private::push_dot3(&mut $tokens);1118};11191120(..= $tokens:ident) => {1121$crate::__private::push_dot_dot_eq(&mut $tokens);1122};11231124(= $tokens:ident) => {1125$crate::__private::push_eq(&mut $tokens);1126};11271128(== $tokens:ident) => {1129$crate::__private::push_eq_eq(&mut $tokens);1130};11311132(>= $tokens:ident) => {1133$crate::__private::push_ge(&mut $tokens);1134};11351136(> $tokens:ident) => {1137$crate::__private::push_gt(&mut $tokens);1138};11391140(<= $tokens:ident) => {1141$crate::__private::push_le(&mut $tokens);1142};11431144(< $tokens:ident) => {1145$crate::__private::push_lt(&mut $tokens);1146};11471148(*= $tokens:ident) => {1149$crate::__private::push_mul_eq(&mut $tokens);1150};11511152(!= $tokens:ident) => {1153$crate::__private::push_ne(&mut $tokens);1154};11551156(| $tokens:ident) => {1157$crate::__private::push_or(&mut $tokens);1158};11591160(|= $tokens:ident) => {1161$crate::__private::push_or_eq(&mut $tokens);1162};11631164(|| $tokens:ident) => {1165$crate::__private::push_or_or(&mut $tokens);1166};11671168(? $tokens:ident) => {1169$crate::__private::push_question(&mut $tokens);1170};11711172(-> $tokens:ident) => {1173$crate::__private::push_rarrow(&mut $tokens);1174};11751176(<- $tokens:ident) => {1177$crate::__private::push_larrow(&mut $tokens);1178};11791180(% $tokens:ident) => {1181$crate::__private::push_rem(&mut $tokens);1182};11831184(%= $tokens:ident) => {1185$crate::__private::push_rem_eq(&mut $tokens);1186};11871188(=> $tokens:ident) => {1189$crate::__private::push_fat_arrow(&mut $tokens);1190};11911192(<< $tokens:ident) => {1193$crate::__private::push_shl(&mut $tokens);1194};11951196(<<= $tokens:ident) => {1197$crate::__private::push_shl_eq(&mut $tokens);1198};11991200(>> $tokens:ident) => {1201$crate::__private::push_shr(&mut $tokens);1202};12031204(>>= $tokens:ident) => {1205$crate::__private::push_shr_eq(&mut $tokens);1206};12071208(* $tokens:ident) => {1209$crate::__private::push_star(&mut $tokens);1210};12111212(- $tokens:ident) => {1213$crate::__private::push_sub(&mut $tokens);1214};12151216(-= $tokens:ident) => {1217$crate::__private::push_sub_eq(&mut $tokens);1218};12191220($lifetime:lifetime $tokens:ident) => {1221$crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));1222};12231224(_ $tokens:ident) => {1225$crate::__private::push_underscore(&mut $tokens);1226};12271228($other:tt $tokens:ident) => {1229$crate::__private::parse(&mut $tokens, stringify!($other));1230};1231}12321233// See the comment above `quote_token!` about the rule ordering.1234#[macro_export]1235#[doc(hidden)]1236macro_rules! quote_token_spanned {1237($ident:ident $tokens:ident $span:ident) => {1238$crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));1239};12401241(:: $tokens:ident $span:ident) => {1242$crate::__private::push_colon2_spanned(&mut $tokens, $span);1243};12441245(( $($inner:tt)* ) $tokens:ident $span:ident) => {1246$crate::__private::push_group_spanned(1247&mut $tokens,1248$span,1249$crate::__private::Delimiter::Parenthesis,1250$crate::quote_spanned!($span=> $($inner)*),1251);1252};12531254([ $($inner:tt)* ] $tokens:ident $span:ident) => {1255$crate::__private::push_group_spanned(1256&mut $tokens,1257$span,1258$crate::__private::Delimiter::Bracket,1259$crate::quote_spanned!($span=> $($inner)*),1260);1261};12621263({ $($inner:tt)* } $tokens:ident $span:ident) => {1264$crate::__private::push_group_spanned(1265&mut $tokens,1266$span,1267$crate::__private::Delimiter::Brace,1268$crate::quote_spanned!($span=> $($inner)*),1269);1270};12711272(# $tokens:ident $span:ident) => {1273$crate::__private::push_pound_spanned(&mut $tokens, $span);1274};12751276(, $tokens:ident $span:ident) => {1277$crate::__private::push_comma_spanned(&mut $tokens, $span);1278};12791280(. $tokens:ident $span:ident) => {1281$crate::__private::push_dot_spanned(&mut $tokens, $span);1282};12831284(; $tokens:ident $span:ident) => {1285$crate::__private::push_semi_spanned(&mut $tokens, $span);1286};12871288(: $tokens:ident $span:ident) => {1289$crate::__private::push_colon_spanned(&mut $tokens, $span);1290};12911292(+ $tokens:ident $span:ident) => {1293$crate::__private::push_add_spanned(&mut $tokens, $span);1294};12951296(+= $tokens:ident $span:ident) => {1297$crate::__private::push_add_eq_spanned(&mut $tokens, $span);1298};12991300(& $tokens:ident $span:ident) => {1301$crate::__private::push_and_spanned(&mut $tokens, $span);1302};13031304(&& $tokens:ident $span:ident) => {1305$crate::__private::push_and_and_spanned(&mut $tokens, $span);1306};13071308(&= $tokens:ident $span:ident) => {1309$crate::__private::push_and_eq_spanned(&mut $tokens, $span);1310};13111312(@ $tokens:ident $span:ident) => {1313$crate::__private::push_at_spanned(&mut $tokens, $span);1314};13151316(! $tokens:ident $span:ident) => {1317$crate::__private::push_bang_spanned(&mut $tokens, $span);1318};13191320(^ $tokens:ident $span:ident) => {1321$crate::__private::push_caret_spanned(&mut $tokens, $span);1322};13231324(^= $tokens:ident $span:ident) => {1325$crate::__private::push_caret_eq_spanned(&mut $tokens, $span);1326};13271328(/ $tokens:ident $span:ident) => {1329$crate::__private::push_div_spanned(&mut $tokens, $span);1330};13311332(/= $tokens:ident $span:ident) => {1333$crate::__private::push_div_eq_spanned(&mut $tokens, $span);1334};13351336(.. $tokens:ident $span:ident) => {1337$crate::__private::push_dot2_spanned(&mut $tokens, $span);1338};13391340(... $tokens:ident $span:ident) => {1341$crate::__private::push_dot3_spanned(&mut $tokens, $span);1342};13431344(..= $tokens:ident $span:ident) => {1345$crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);1346};13471348(= $tokens:ident $span:ident) => {1349$crate::__private::push_eq_spanned(&mut $tokens, $span);1350};13511352(== $tokens:ident $span:ident) => {1353$crate::__private::push_eq_eq_spanned(&mut $tokens, $span);1354};13551356(>= $tokens:ident $span:ident) => {1357$crate::__private::push_ge_spanned(&mut $tokens, $span);1358};13591360(> $tokens:ident $span:ident) => {1361$crate::__private::push_gt_spanned(&mut $tokens, $span);1362};13631364(<= $tokens:ident $span:ident) => {1365$crate::__private::push_le_spanned(&mut $tokens, $span);1366};13671368(< $tokens:ident $span:ident) => {1369$crate::__private::push_lt_spanned(&mut $tokens, $span);1370};13711372(*= $tokens:ident $span:ident) => {1373$crate::__private::push_mul_eq_spanned(&mut $tokens, $span);1374};13751376(!= $tokens:ident $span:ident) => {1377$crate::__private::push_ne_spanned(&mut $tokens, $span);1378};13791380(| $tokens:ident $span:ident) => {1381$crate::__private::push_or_spanned(&mut $tokens, $span);1382};13831384(|= $tokens:ident $span:ident) => {1385$crate::__private::push_or_eq_spanned(&mut $tokens, $span);1386};13871388(|| $tokens:ident $span:ident) => {1389$crate::__private::push_or_or_spanned(&mut $tokens, $span);1390};13911392(? $tokens:ident $span:ident) => {1393$crate::__private::push_question_spanned(&mut $tokens, $span);1394};13951396(-> $tokens:ident $span:ident) => {1397$crate::__private::push_rarrow_spanned(&mut $tokens, $span);1398};13991400(<- $tokens:ident $span:ident) => {1401$crate::__private::push_larrow_spanned(&mut $tokens, $span);1402};14031404(% $tokens:ident $span:ident) => {1405$crate::__private::push_rem_spanned(&mut $tokens, $span);1406};14071408(%= $tokens:ident $span:ident) => {1409$crate::__private::push_rem_eq_spanned(&mut $tokens, $span);1410};14111412(=> $tokens:ident $span:ident) => {1413$crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);1414};14151416(<< $tokens:ident $span:ident) => {1417$crate::__private::push_shl_spanned(&mut $tokens, $span);1418};14191420(<<= $tokens:ident $span:ident) => {1421$crate::__private::push_shl_eq_spanned(&mut $tokens, $span);1422};14231424(>> $tokens:ident $span:ident) => {1425$crate::__private::push_shr_spanned(&mut $tokens, $span);1426};14271428(>>= $tokens:ident $span:ident) => {1429$crate::__private::push_shr_eq_spanned(&mut $tokens, $span);1430};14311432(* $tokens:ident $span:ident) => {1433$crate::__private::push_star_spanned(&mut $tokens, $span);1434};14351436(- $tokens:ident $span:ident) => {1437$crate::__private::push_sub_spanned(&mut $tokens, $span);1438};14391440(-= $tokens:ident $span:ident) => {1441$crate::__private::push_sub_eq_spanned(&mut $tokens, $span);1442};14431444($lifetime:lifetime $tokens:ident $span:ident) => {1445$crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));1446};14471448(_ $tokens:ident $span:ident) => {1449$crate::__private::push_underscore_spanned(&mut $tokens, $span);1450};14511452($other:tt $tokens:ident $span:ident) => {1453$crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));1454};1455}145614571458