1 //! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote)
3 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
9 //! This crate provides the [`quote!`] macro for turning Rust syntax tree data
10 //! structures into tokens of source code.
12 //! [`quote!`]: macro.quote.html
14 //! Procedural macros in Rust receive a stream of tokens as input, execute
15 //! arbitrary Rust code to determine how to manipulate those tokens, and produce
16 //! a stream of tokens to hand back to the compiler to compile into the caller's
17 //! crate. Quasi-quoting is a solution to one piece of that — producing
18 //! tokens to return to the compiler.
20 //! The idea of quasi-quoting is that we write *code* that we treat as *data*.
21 //! Within the `quote!` macro, we can write what looks like code to our text
22 //! editor or IDE. We get all the benefits of the editor's brace matching,
23 //! syntax highlighting, indentation, and maybe autocompletion. But rather than
24 //! compiling that as code into the current crate, we can treat it as data, pass
25 //! it around, mutate it, and eventually hand it back to the compiler as tokens
26 //! to compile into the macro caller's crate.
28 //! This crate is motivated by the procedural macro use case, but is a
29 //! general-purpose Rust quasi-quoting library and is not specific to procedural
41 //! The following quasi-quoted block of code is something you might find in [a]
42 //! procedural macro having to do with data structure serialization. The `#var`
43 //! syntax performs interpolation of runtime variables into the quoted tokens.
44 //! Check out the documentation of the [`quote!`] macro for more detail about
45 //! the syntax. See also the [`quote_spanned!`] macro which is important for
46 //! implementing hygienic procedural macros.
48 //! [a]: https://serde.rs/
49 //! [`quote_spanned!`]: macro.quote_spanned.html
52 //! # use quote::quote;
54 //! # let generics = "";
55 //! # let where_clause = "";
56 //! # let field_ty = "";
57 //! # let item_ty = "";
61 //! let tokens = quote! {
62 //! struct SerializeWith #generics #where_clause {
63 //! value: &'a #field_ty,
64 //! phantom: core::marker::PhantomData<#item_ty>,
67 //! impl #generics serde::Serialize for SerializeWith #generics #where_clause {
68 //! fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 //! S: serde::Serializer,
72 //! #path(self.value, serializer)
78 //! phantom: core::marker::PhantomData::<#item_ty>,
83 // Quote types in rustdoc of other crates get linked to here.
84 #![doc(html_root_url = "https://docs.rs/quote/1.0.9")]
87 clippy
::missing_errors_doc
,
88 clippy
::missing_panics_doc
,
89 clippy
::module_name_repetitions
93 not(all(target_arch
= "wasm32", target_os
= "unknown")),
94 feature
= "proc-macro"
96 extern crate proc_macro
;
105 #[path = "runtime.rs"]
108 pub use crate::ext
::TokenStreamExt
;
109 pub use crate::ident_fragment
::IdentFragment
;
110 pub use crate::to_tokens
::ToTokens
;
118 /// Performs variable interpolation against the input and produces it as
119 /// [`proc_macro2::TokenStream`].
121 /// Note: for returning tokens to the compiler in a procedural macro, use
122 /// `.into()` on the result to convert to [`proc_macro::TokenStream`].
124 /// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
130 /// Variable interpolation is done with `#var` (similar to `$var` in
131 /// `macro_rules!` macros). This grabs the `var` variable that is currently in
132 /// scope and inserts it in that location in the output tokens. Any type
133 /// implementing the [`ToTokens`] trait can be interpolated. This includes most
134 /// Rust primitive types as well as most of the syntax tree types from the [Syn]
137 /// [`ToTokens`]: trait.ToTokens.html
138 /// [Syn]: https://github.com/dtolnay/syn
140 /// Repetition is done using `#(...)*` or `#(...),*` again similar to
141 /// `macro_rules!`. This iterates through the elements of any variable
142 /// interpolated within the repetition and inserts a copy of the repetition body
143 /// for each one. The variables in an interpolation may be a `Vec`, slice,
144 /// `BTreeSet`, or any `Iterator`.
146 /// - `#(#var)*` — no separators
147 /// - `#(#var),*` — the character before the asterisk is used as a separator
148 /// - `#( struct #var; )*` — the repetition can contain other tokens
149 /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
155 /// Any interpolated tokens preserve the `Span` information provided by their
156 /// `ToTokens` implementation. Tokens that originate within the `quote!`
157 /// invocation are spanned with [`Span::call_site()`].
159 /// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
161 /// A different span can be provided through the [`quote_spanned!`] macro.
163 /// [`quote_spanned!`]: macro.quote_spanned.html
169 /// The macro evaluates to an expression of type `proc_macro2::TokenStream`.
170 /// Meanwhile Rust procedural macros are expected to return the type
171 /// `proc_macro::TokenStream`.
173 /// The difference between the two types is that `proc_macro` types are entirely
174 /// specific to procedural macros and cannot ever exist in code outside of a
175 /// procedural macro, while `proc_macro2` types may exist anywhere including
176 /// tests and non-macro code like main.rs and build.rs. This is why even the
177 /// procedural macro ecosystem is largely built around `proc_macro2`, because
178 /// that ensures the libraries are unit testable and accessible in non-macro
181 /// There is a [`From`]-conversion in both directions so returning the output of
182 /// `quote!` from a procedural macro usually looks like `tokens.into()` or
183 /// `proc_macro::TokenStream::from(tokens)`.
185 /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
191 /// ### Procedural macro
193 /// The structure of a basic procedural macro is as follows. Refer to the [Syn]
194 /// crate for further useful guidance on using `quote!` as part of a procedural
197 /// [Syn]: https://github.com/dtolnay/syn
201 /// extern crate proc_macro;
202 /// # extern crate proc_macro2;
205 /// use proc_macro::TokenStream;
206 /// # use proc_macro2::TokenStream;
207 /// use quote::quote;
209 /// # const IGNORE_TOKENS: &'static str = stringify! {
210 /// #[proc_macro_derive(HeapSize)]
212 /// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
213 /// // Parse the input and figure out what implementation to generate...
214 /// # const IGNORE_TOKENS: &'static str = stringify! {
215 /// let name = /* ... */;
216 /// let expr = /* ... */;
222 /// let expanded = quote! {
223 /// // The generated impl.
224 /// impl heapsize::HeapSize for #name {
225 /// fn heap_size_of_children(&self) -> usize {
231 /// // Hand the output tokens back to the compiler.
232 /// TokenStream::from(expanded)
238 /// ### Combining quoted fragments
240 /// Usually you don't end up constructing an entire final `TokenStream` in one
241 /// piece. Different parts may come from different helper functions. The tokens
242 /// produced by `quote!` themselves implement `ToTokens` and so can be
243 /// interpolated into later `quote!` invocations to build up a final result.
246 /// # use quote::quote;
248 /// let type_definition = quote! {...};
249 /// let methods = quote! {...};
251 /// let tokens = quote! {
259 /// ### Constructing identifiers
261 /// Suppose we have an identifier `ident` which came from somewhere in a macro
262 /// input and we need to modify it in some way for the macro output. Let's
263 /// consider prepending the identifier with an underscore.
265 /// Simply interpolating the identifier next to an underscore will not have the
266 /// behavior of concatenating them. The underscore and the identifier will
267 /// continue to be two separate tokens as if you had written `_ x`.
270 /// # use proc_macro2::{self as syn, Span};
271 /// # use quote::quote;
273 /// # let ident = syn::Ident::new("i", Span::call_site());
277 /// let mut _#ident = 0;
282 /// The solution is to build a new identifier token with the correct value. As
283 /// this is such a common case, the [`format_ident!`] macro provides a
284 /// convenient utility for doing so correctly.
287 /// # use proc_macro2::{Ident, Span};
288 /// # use quote::{format_ident, quote};
290 /// # let ident = Ident::new("i", Span::call_site());
292 /// let varname = format_ident!("_{}", ident);
294 /// let mut #varname = 0;
299 /// Alternatively, the APIs provided by Syn and proc-macro2 can be used to
300 /// directly build the identifier. This is roughly equivalent to the above, but
301 /// will not handle `ident` being a raw identifier.
304 /// # use proc_macro2::{self as syn, Span};
305 /// # use quote::quote;
307 /// # let ident = syn::Ident::new("i", Span::call_site());
309 /// let concatenated = format!("_{}", ident);
310 /// let varname = syn::Ident::new(&concatenated, ident.span());
312 /// let mut #varname = 0;
319 /// ### Making method calls
321 /// Let's say our macro requires some type specified in the macro input to have
322 /// a constructor called `new`. We have the type in a variable called
323 /// `field_type` of type `syn::Type` and want to invoke the constructor.
326 /// # use quote::quote;
328 /// # let field_type = quote!(...);
332 /// let value = #field_type::new();
337 /// This works only sometimes. If `field_type` is `String`, the expanded code
338 /// contains `String::new()` which is fine. But if `field_type` is something
339 /// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid
340 /// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`
341 /// but for macros often the following is more convenient.
344 /// # use quote::quote;
346 /// # let field_type = quote!(...);
349 /// let value = <#field_type>::new();
354 /// This expands to `<Vec<i32>>::new()` which behaves correctly.
356 /// A similar pattern is appropriate for trait methods.
359 /// # use quote::quote;
361 /// # let field_type = quote!(...);
364 /// let value = <#field_type as core::default::Default>::default();
371 /// ### Interpolating text inside of doc comments
373 /// Neither doc comments nor string literals get interpolation behavior in
378 /// /// try to interpolate: #ident
386 /// #[doc = "try to interpolate: #ident"]
390 /// Macro calls in a doc attribute are not valid syntax:
394 /// #[doc = concat!("try to interpolate: ", stringify!(#ident))]
398 /// Instead the best way to build doc comments that involve variables is by
399 /// formatting the doc string literal outside of quote.
402 /// # use proc_macro2::{Ident, Span};
403 /// # use quote::quote;
405 /// # const IGNORE: &str = stringify! {
406 /// let msg = format!(...);
409 /// # let ident = Ident::new("var", Span::call_site());
410 /// # let msg = format!("try to interpolate: {}", ident);
421 /// ### Indexing into a tuple struct
423 /// When interpolating indices of a tuple or tuple struct, we need them not to
424 /// appears suffixed as integer literals by interpolating them as [`syn::Index`]
427 /// [`syn::Index`]: https://docs.rs/syn/1.0/syn/struct.Index.html
430 /// let i = 0usize..self.fields.len();
432 /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
433 /// // which is not valid syntax
435 /// 0 #( + self.#i.heap_size() )*
440 /// # use proc_macro2::{Ident, TokenStream};
441 /// # use quote::quote;
444 /// # use proc_macro2::{Literal, TokenStream};
445 /// # use quote::{ToTokens, TokenStreamExt};
447 /// # pub struct Index(usize);
449 /// # impl From<usize> for Index {
450 /// # fn from(i: usize) -> Self {
455 /// # impl ToTokens for Index {
456 /// # fn to_tokens(&self, tokens: &mut TokenStream) {
457 /// # tokens.append(Literal::usize_unsuffixed(self.0));
462 /// # struct Struct {
463 /// # fields: Vec<Ident>,
467 /// # fn example(&self) -> TokenStream {
468 /// let i = (0..self.fields.len()).map(syn::Index::from);
470 /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
472 /// 0 #( + self.#i.heap_size() )*
480 $
crate::__private
::TokenStream
::new()
483 let mut _s
= $
crate::__private
::TokenStream
::new();
484 $
crate::quote_each_token
!(_s $
($tt
)*);
489 /// Same as `quote!`, but applies a given span to all tokens originating within
490 /// the macro invocation.
496 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens
497 /// to quote. The span expression should be brief — use a variable for
498 /// anything more than a few characters. There should be no space before the
501 /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
504 /// # use proc_macro2::Span;
505 /// # use quote::quote_spanned;
507 /// # const IGNORE_TOKENS: &'static str = stringify! {
508 /// let span = /* ... */;
510 /// # let span = Span::call_site();
513 /// // On one line, use parentheses.
514 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
516 /// // On multiple lines, place the span at the top and use braces.
517 /// let tokens = quote_spanned! {span=>
518 /// Box::into_raw(Box::new(#init))
522 /// The lack of space before the `=>` should look jarring to Rust programmers
523 /// and this is intentional. The formatting is designed to be visibly
524 /// off-balance and draw the eye a particular way, due to the span expression
525 /// being evaluated in the context of the procedural macro and the remaining
526 /// tokens being evaluated in the generated code.
532 /// Any interpolated tokens preserve the `Span` information provided by their
533 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
534 /// invocation are spanned with the given span argument.
540 /// The following procedural macro code uses `quote_spanned!` to assert that a
541 /// particular Rust type implements the [`Sync`] trait so that references can be
542 /// safely shared between threads.
544 /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
547 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
548 /// # use proc_macro2::{Span, TokenStream};
553 /// # fn span(&self) -> Span {
554 /// # Span::call_site()
558 /// # impl ToTokens for Type {
559 /// # fn to_tokens(&self, _tokens: &mut TokenStream) {}
563 /// # let call_site = Span::call_site();
565 /// let ty_span = ty.span();
566 /// let assert_sync = quote_spanned! {ty_span=>
567 /// struct _AssertSync where #ty: Sync;
571 /// If the assertion fails, the user will see an error like the following. The
572 /// input span of their type is highlighted in the error.
575 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
576 /// --> src/main.rs:10:21
578 /// 10 | static ref PTR: *const () = &();
579 /// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely
582 /// In this example it is important for the where-clause to be spanned with the
583 /// line/column information of the user's input type so that error messages are
584 /// placed appropriately by the compiler.
586 macro_rules
! quote_spanned
{
588 let _
: $
crate::__private
::Span
= $span
;
589 $
crate::__private
::TokenStream
::new()
591 ($span
:expr
=> $
($tt
:tt
)*) => {{
592 let mut _s
= $
crate::__private
::TokenStream
::new();
593 let _span
: $
crate::__private
::Span
= $span
;
594 $
crate::quote_each_token_spanned
!(_s _span $
($tt
)*);
599 // Extract the names of all #metavariables and pass them to the $call macro.
601 // in: pounded_var_names!(then!(...) a #b c #( #d )* #e)
602 // out: then!(... b);
607 macro_rules
! pounded_var_names
{
608 ($call
:ident
! $extra
:tt $
($tts
:tt
)*) => {
609 $
crate::pounded_var_names_with_context
!($call
! $extra
618 macro_rules
! pounded_var_names_with_context
{
619 ($call
:ident
! $extra
:tt ($
($b1
:tt
)*) ($
($curr
:tt
)*)) => {
621 $
crate::pounded_var_with_context
!($call
! $extra $b1 $curr
);
628 macro_rules
! pounded_var_with_context
{
629 ($call
:ident
! $extra
:tt $b1
:tt ( $
($inner
:tt
)* )) => {
630 $
crate::pounded_var_names
!($call
! $extra $
($inner
)*);
633 ($call
:ident
! $extra
:tt $b1
:tt
[ $
($inner
:tt
)* ]) => {
634 $
crate::pounded_var_names
!($call
! $extra $
($inner
)*);
637 ($call
:ident
! $extra
:tt $b1
:tt { $($inner:tt)* }
) => {
638 $
crate::pounded_var_names
!($call
! $extra $
($inner
)*);
641 ($call
:ident
!($
($extra
:tt
)*) # $var:ident) => {
642 $
crate::$call
!($
($extra
)* $var
);
645 ($call
:ident
! $extra
:tt $b1
:tt $curr
:tt
) => {}
;
650 macro_rules
! quote_bind_into_iter
{
651 ($has_iter
:ident $var
:ident
) => {
652 // `mut` may be unused if $var occurs multiple times in the list.
654 let (mut $var
, i
) = $var
.quote_into_iter();
655 let $has_iter
= $has_iter
| i
;
661 macro_rules
! quote_bind_next_or_break
{
663 let $var
= match $var
.next() {
664 Some(_x
) => $
crate::__private
::RepInterp(_x
),
672 macro_rules
! quote_each_token
{
673 ($tokens
:ident $
($tts
:tt
)*) => {
674 $
crate::quote_tokens_with_context
!($tokens
675 (@ @ @ @ @ @ $
($tts
)*)
676 (@ @ @ @ @ $
($tts
)* @
)
677 (@ @ @ @ $
($tts
)* @ @
)
678 (@ @ @ $
(($tts
))* @ @ @
)
679 (@ @ $
($tts
)* @ @ @ @
)
680 (@ $
($tts
)* @ @ @ @ @
)
681 ($
($tts
)* @ @ @ @ @ @
)
688 macro_rules
! quote_each_token_spanned
{
689 ($tokens
:ident $span
:ident $
($tts
:tt
)*) => {
690 $
crate::quote_tokens_with_context_spanned
!($tokens $span
691 (@ @ @ @ @ @ $
($tts
)*)
692 (@ @ @ @ @ $
($tts
)* @
)
693 (@ @ @ @ $
($tts
)* @ @
)
694 (@ @ @ $
(($tts
))* @ @ @
)
695 (@ @ $
($tts
)* @ @ @ @
)
696 (@ $
($tts
)* @ @ @ @ @
)
697 ($
($tts
)* @ @ @ @ @ @
)
704 macro_rules
! quote_tokens_with_context
{
706 ($
($b3
:tt
)*) ($
($b2
:tt
)*) ($
($b1
:tt
)*)
708 ($
($a1
:tt
)*) ($
($a2
:tt
)*) ($
($a3
:tt
)*)
711 $
crate::quote_token_with_context
!($tokens $b3 $b2 $b1 $curr $a1 $a2 $a3
);
718 macro_rules
! quote_tokens_with_context_spanned
{
719 ($tokens
:ident $span
:ident
720 ($
($b3
:tt
)*) ($
($b2
:tt
)*) ($
($b1
:tt
)*)
722 ($
($a1
:tt
)*) ($
($a2
:tt
)*) ($
($a3
:tt
)*)
725 $
crate::quote_token_with_context_spanned
!($tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3
);
732 macro_rules
! quote_token_with_context
{
733 ($tokens
:ident $b3
:tt $b2
:tt $b1
:tt @ $a1
:tt $a2
:tt $a3
:tt
) => {}
;
735 ($tokens
:ident $b3
:tt $b2
:tt $b1
:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
736 use $
crate::__private
::ext
::*;
737 let has_iter
= $
crate::__private
::ThereIsNoIteratorInRepetition
;
738 $
crate::pounded_var_names
!(quote_bind_into_iter
!(has_iter
) () $
($inner
)*);
739 let _
: $
crate::__private
::HasIterator
= has_iter
;
740 // This is `while true` instead of `loop` because if there are no
741 // iterators used inside of this repetition then the body would not
742 // contain any `break`, so the compiler would emit unreachable code
743 // warnings on anything below the loop. We use has_iter to detect and
744 // fail to compile when there are no iterators, so here we just work
745 // around the unneeded extra warning.
747 $
crate::pounded_var_names
!(quote_bind_next_or_break
!() () $
($inner
)*);
748 $
crate::quote_each_token
!($tokens $
($inner
)*);
751 ($tokens
:ident $b3
:tt $b2
:tt
# (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
752 ($tokens
:ident $b3
:tt
# ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
754 ($tokens
:ident $b3
:tt $b2
:tt $b1
:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
755 use $
crate::__private
::ext
::*;
757 let has_iter
= $
crate::__private
::ThereIsNoIteratorInRepetition
;
758 $
crate::pounded_var_names
!(quote_bind_into_iter
!(has_iter
) () $
($inner
)*);
759 let _
: $
crate::__private
::HasIterator
= has_iter
;
761 $
crate::pounded_var_names
!(quote_bind_next_or_break
!() () $
($inner
)*);
763 $
crate::quote_token
!($tokens $sep
);
766 $
crate::quote_each_token
!($tokens $
($inner
)*);
769 ($tokens
:ident $b3
:tt $b2
:tt
# (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
770 ($tokens
:ident $b3
:tt
# ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
771 ($tokens
:ident
# ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
772 // https://github.com/dtolnay/quote/issues/130
773 $
crate::quote_token
!($tokens
*);
775 ($tokens
:ident
# ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
777 ($tokens
:ident $b3
:tt $b2
:tt $b1
:tt (#) $var:ident $a2:tt $a3:tt) => {
778 $
crate::ToTokens
::to_tokens(&$var
, &mut $tokens
);
780 ($tokens
:ident $b3
:tt $b2
:tt
# ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
781 ($tokens
:ident $b3
:tt $b2
:tt $b1
:tt ($curr
:tt
) $a1
:tt $a2
:tt $a3
:tt
) => {
782 $
crate::quote_token
!($tokens $curr
);
788 macro_rules
! quote_token_with_context_spanned
{
789 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt $b1
:tt @ $a1
:tt $a2
:tt $a3
:tt
) => {}
;
791 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt $b1
:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
792 use $
crate::__private
::ext
::*;
793 let has_iter
= $
crate::__private
::ThereIsNoIteratorInRepetition
;
794 $
crate::pounded_var_names
!(quote_bind_into_iter
!(has_iter
) () $
($inner
)*);
795 let _
: $
crate::__private
::HasIterator
= has_iter
;
796 // This is `while true` instead of `loop` because if there are no
797 // iterators used inside of this repetition then the body would not
798 // contain any `break`, so the compiler would emit unreachable code
799 // warnings on anything below the loop. We use has_iter to detect and
800 // fail to compile when there are no iterators, so here we just work
801 // around the unneeded extra warning.
803 $
crate::pounded_var_names
!(quote_bind_next_or_break
!() () $
($inner
)*);
804 $
crate::quote_each_token_spanned
!($tokens $span $
($inner
)*);
807 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt
# (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
808 ($tokens
:ident $span
:ident $b3
:tt
# ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
810 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt $b1
:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
811 use $
crate::__private
::ext
::*;
813 let has_iter
= $
crate::__private
::ThereIsNoIteratorInRepetition
;
814 $
crate::pounded_var_names
!(quote_bind_into_iter
!(has_iter
) () $
($inner
)*);
815 let _
: $
crate::__private
::HasIterator
= has_iter
;
817 $
crate::pounded_var_names
!(quote_bind_next_or_break
!() () $
($inner
)*);
819 $
crate::quote_token_spanned
!($tokens $span $sep
);
822 $
crate::quote_each_token_spanned
!($tokens $span $
($inner
)*);
825 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt
# (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
826 ($tokens
:ident $span
:ident $b3
:tt
# ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
827 ($tokens
:ident $span
:ident
# ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
828 // https://github.com/dtolnay/quote/issues/130
829 $
crate::quote_token_spanned
!($tokens $span
*);
831 ($tokens
:ident $span
:ident
# ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
833 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt $b1
:tt (#) $var:ident $a2:tt $a3:tt) => {
834 $
crate::ToTokens
::to_tokens(&$var
, &mut $tokens
);
836 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt
# ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
837 ($tokens
:ident $span
:ident $b3
:tt $b2
:tt $b1
:tt ($curr
:tt
) $a1
:tt $a2
:tt $a3
:tt
) => {
838 $
crate::quote_token_spanned
!($tokens $span $curr
);
844 macro_rules
! quote_token
{
845 ($tokens
:ident ( $
($inner
:tt
)* )) => {
846 $
crate::__private
::push_group(
848 $
crate::__private
::Delimiter
::Parenthesis
,
849 $
crate::quote
!($
($inner
)*),
853 ($tokens
:ident
[ $
($inner
:tt
)* ]) => {
854 $
crate::__private
::push_group(
856 $
crate::__private
::Delimiter
::Bracket
,
857 $
crate::quote
!($
($inner
)*),
861 ($tokens
:ident { $($inner:tt)* }
) => {
862 $
crate::__private
::push_group(
864 $
crate::__private
::Delimiter
::Brace
,
865 $
crate::quote
!($
($inner
)*),
869 ($tokens
:ident
+) => {
870 $
crate::__private
::push_add(&mut $tokens
);
873 ($tokens
:ident
+=) => {
874 $
crate::__private
::push_add_eq(&mut $tokens
);
877 ($tokens
:ident
&) => {
878 $
crate::__private
::push_and(&mut $tokens
);
881 ($tokens
:ident
&&) => {
882 $
crate::__private
::push_and_and(&mut $tokens
);
885 ($tokens
:ident
&=) => {
886 $
crate::__private
::push_and_eq(&mut $tokens
);
889 ($tokens
:ident @
) => {
890 $
crate::__private
::push_at(&mut $tokens
);
893 ($tokens
:ident
!) => {
894 $
crate::__private
::push_bang(&mut $tokens
);
897 ($tokens
:ident ^
) => {
898 $
crate::__private
::push_caret(&mut $tokens
);
901 ($tokens
:ident ^
=) => {
902 $
crate::__private
::push_caret_eq(&mut $tokens
);
905 ($tokens
:ident
:) => {
906 $
crate::__private
::push_colon(&mut $tokens
);
909 ($tokens
:ident
::) => {
910 $
crate::__private
::push_colon2(&mut $tokens
);
913 ($tokens
:ident
,) => {
914 $
crate::__private
::push_comma(&mut $tokens
);
917 ($tokens
:ident
/) => {
918 $
crate::__private
::push_div(&mut $tokens
);
921 ($tokens
:ident
/=) => {
922 $
crate::__private
::push_div_eq(&mut $tokens
);
925 ($tokens
:ident
.) => {
926 $
crate::__private
::push_dot(&mut $tokens
);
929 ($tokens
:ident
..) => {
930 $
crate::__private
::push_dot2(&mut $tokens
);
933 ($tokens
:ident
...) => {
934 $
crate::__private
::push_dot3(&mut $tokens
);
937 ($tokens
:ident
..=) => {
938 $
crate::__private
::push_dot_dot_eq(&mut $tokens
);
941 ($tokens
:ident
=) => {
942 $
crate::__private
::push_eq(&mut $tokens
);
945 ($tokens
:ident
==) => {
946 $
crate::__private
::push_eq_eq(&mut $tokens
);
949 ($tokens
:ident
>=) => {
950 $
crate::__private
::push_ge(&mut $tokens
);
953 ($tokens
:ident
>) => {
954 $
crate::__private
::push_gt(&mut $tokens
);
957 ($tokens
:ident
<=) => {
958 $
crate::__private
::push_le(&mut $tokens
);
961 ($tokens
:ident
<) => {
962 $
crate::__private
::push_lt(&mut $tokens
);
965 ($tokens
:ident
*=) => {
966 $
crate::__private
::push_mul_eq(&mut $tokens
);
969 ($tokens
:ident
!=) => {
970 $
crate::__private
::push_ne(&mut $tokens
);
973 ($tokens
:ident
|) => {
974 $
crate::__private
::push_or(&mut $tokens
);
977 ($tokens
:ident
|=) => {
978 $
crate::__private
::push_or_eq(&mut $tokens
);
981 ($tokens
:ident
||) => {
982 $
crate::__private
::push_or_or(&mut $tokens
);
985 ($tokens
:ident
#) => {
986 $
crate::__private
::push_pound(&mut $tokens
);
989 ($tokens
:ident ?
) => {
990 $
crate::__private
::push_question(&mut $tokens
);
993 ($tokens
:ident
->) => {
994 $
crate::__private
::push_rarrow(&mut $tokens
);
997 ($tokens
:ident
<-) => {
998 $
crate::__private
::push_larrow(&mut $tokens
);
1001 ($tokens
:ident
%) => {
1002 $
crate::__private
::push_rem(&mut $tokens
);
1005 ($tokens
:ident
%=) => {
1006 $
crate::__private
::push_rem_eq(&mut $tokens
);
1009 ($tokens
:ident
=>) => {
1010 $
crate::__private
::push_fat_arrow(&mut $tokens
);
1013 ($tokens
:ident
;) => {
1014 $
crate::__private
::push_semi(&mut $tokens
);
1017 ($tokens
:ident
<<) => {
1018 $
crate::__private
::push_shl(&mut $tokens
);
1021 ($tokens
:ident
<<=) => {
1022 $
crate::__private
::push_shl_eq(&mut $tokens
);
1025 ($tokens
:ident
>>) => {
1026 $
crate::__private
::push_shr(&mut $tokens
);
1029 ($tokens
:ident
>>=) => {
1030 $
crate::__private
::push_shr_eq(&mut $tokens
);
1033 ($tokens
:ident
*) => {
1034 $
crate::__private
::push_star(&mut $tokens
);
1037 ($tokens
:ident
-) => {
1038 $
crate::__private
::push_sub(&mut $tokens
);
1041 ($tokens
:ident
-=) => {
1042 $
crate::__private
::push_sub_eq(&mut $tokens
);
1045 ($tokens
:ident $ident
:ident
) => {
1046 $
crate::__private
::push_ident(&mut $tokens
, stringify
!($ident
));
1049 ($tokens
:ident $other
:tt
) => {
1050 $
crate::__private
::parse(&mut $tokens
, stringify
!($other
));
1056 macro_rules
! quote_token_spanned
{
1057 ($tokens
:ident $span
:ident ( $
($inner
:tt
)* )) => {
1058 $
crate::__private
::push_group_spanned(
1061 $
crate::__private
::Delimiter
::Parenthesis
,
1062 $
crate::quote_spanned
!($span
=> $
($inner
)*),
1066 ($tokens
:ident $span
:ident
[ $
($inner
:tt
)* ]) => {
1067 $
crate::__private
::push_group_spanned(
1070 $
crate::__private
::Delimiter
::Bracket
,
1071 $
crate::quote_spanned
!($span
=> $
($inner
)*),
1075 ($tokens
:ident $span
:ident { $($inner:tt)* }
) => {
1076 $
crate::__private
::push_group_spanned(
1079 $
crate::__private
::Delimiter
::Brace
,
1080 $
crate::quote_spanned
!($span
=> $
($inner
)*),
1084 ($tokens
:ident $span
:ident
+) => {
1085 $
crate::__private
::push_add_spanned(&mut $tokens
, $span
);
1088 ($tokens
:ident $span
:ident
+=) => {
1089 $
crate::__private
::push_add_eq_spanned(&mut $tokens
, $span
);
1092 ($tokens
:ident $span
:ident
&) => {
1093 $
crate::__private
::push_and_spanned(&mut $tokens
, $span
);
1096 ($tokens
:ident $span
:ident
&&) => {
1097 $
crate::__private
::push_and_and_spanned(&mut $tokens
, $span
);
1100 ($tokens
:ident $span
:ident
&=) => {
1101 $
crate::__private
::push_and_eq_spanned(&mut $tokens
, $span
);
1104 ($tokens
:ident $span
:ident @
) => {
1105 $
crate::__private
::push_at_spanned(&mut $tokens
, $span
);
1108 ($tokens
:ident $span
:ident
!) => {
1109 $
crate::__private
::push_bang_spanned(&mut $tokens
, $span
);
1112 ($tokens
:ident $span
:ident ^
) => {
1113 $
crate::__private
::push_caret_spanned(&mut $tokens
, $span
);
1116 ($tokens
:ident $span
:ident ^
=) => {
1117 $
crate::__private
::push_caret_eq_spanned(&mut $tokens
, $span
);
1120 ($tokens
:ident $span
:ident
:) => {
1121 $
crate::__private
::push_colon_spanned(&mut $tokens
, $span
);
1124 ($tokens
:ident $span
:ident
::) => {
1125 $
crate::__private
::push_colon2_spanned(&mut $tokens
, $span
);
1128 ($tokens
:ident $span
:ident
,) => {
1129 $
crate::__private
::push_comma_spanned(&mut $tokens
, $span
);
1132 ($tokens
:ident $span
:ident
/) => {
1133 $
crate::__private
::push_div_spanned(&mut $tokens
, $span
);
1136 ($tokens
:ident $span
:ident
/=) => {
1137 $
crate::__private
::push_div_eq_spanned(&mut $tokens
, $span
);
1140 ($tokens
:ident $span
:ident
.) => {
1141 $
crate::__private
::push_dot_spanned(&mut $tokens
, $span
);
1144 ($tokens
:ident $span
:ident
..) => {
1145 $
crate::__private
::push_dot2_spanned(&mut $tokens
, $span
);
1148 ($tokens
:ident $span
:ident
...) => {
1149 $
crate::__private
::push_dot3_spanned(&mut $tokens
, $span
);
1152 ($tokens
:ident $span
:ident
..=) => {
1153 $
crate::__private
::push_dot_dot_eq_spanned(&mut $tokens
, $span
);
1156 ($tokens
:ident $span
:ident
=) => {
1157 $
crate::__private
::push_eq_spanned(&mut $tokens
, $span
);
1160 ($tokens
:ident $span
:ident
==) => {
1161 $
crate::__private
::push_eq_eq_spanned(&mut $tokens
, $span
);
1164 ($tokens
:ident $span
:ident
>=) => {
1165 $
crate::__private
::push_ge_spanned(&mut $tokens
, $span
);
1168 ($tokens
:ident $span
:ident
>) => {
1169 $
crate::__private
::push_gt_spanned(&mut $tokens
, $span
);
1172 ($tokens
:ident $span
:ident
<=) => {
1173 $
crate::__private
::push_le_spanned(&mut $tokens
, $span
);
1176 ($tokens
:ident $span
:ident
<) => {
1177 $
crate::__private
::push_lt_spanned(&mut $tokens
, $span
);
1180 ($tokens
:ident $span
:ident
*=) => {
1181 $
crate::__private
::push_mul_eq_spanned(&mut $tokens
, $span
);
1184 ($tokens
:ident $span
:ident
!=) => {
1185 $
crate::__private
::push_ne_spanned(&mut $tokens
, $span
);
1188 ($tokens
:ident $span
:ident
|) => {
1189 $
crate::__private
::push_or_spanned(&mut $tokens
, $span
);
1192 ($tokens
:ident $span
:ident
|=) => {
1193 $
crate::__private
::push_or_eq_spanned(&mut $tokens
, $span
);
1196 ($tokens
:ident $span
:ident
||) => {
1197 $
crate::__private
::push_or_or_spanned(&mut $tokens
, $span
);
1200 ($tokens
:ident $span
:ident
#) => {
1201 $
crate::__private
::push_pound_spanned(&mut $tokens
, $span
);
1204 ($tokens
:ident $span
:ident ?
) => {
1205 $
crate::__private
::push_question_spanned(&mut $tokens
, $span
);
1208 ($tokens
:ident $span
:ident
->) => {
1209 $
crate::__private
::push_rarrow_spanned(&mut $tokens
, $span
);
1212 ($tokens
:ident $span
:ident
<-) => {
1213 $
crate::__private
::push_larrow_spanned(&mut $tokens
, $span
);
1216 ($tokens
:ident $span
:ident
%) => {
1217 $
crate::__private
::push_rem_spanned(&mut $tokens
, $span
);
1220 ($tokens
:ident $span
:ident
%=) => {
1221 $
crate::__private
::push_rem_eq_spanned(&mut $tokens
, $span
);
1224 ($tokens
:ident $span
:ident
=>) => {
1225 $
crate::__private
::push_fat_arrow_spanned(&mut $tokens
, $span
);
1228 ($tokens
:ident $span
:ident
;) => {
1229 $
crate::__private
::push_semi_spanned(&mut $tokens
, $span
);
1232 ($tokens
:ident $span
:ident
<<) => {
1233 $
crate::__private
::push_shl_spanned(&mut $tokens
, $span
);
1236 ($tokens
:ident $span
:ident
<<=) => {
1237 $
crate::__private
::push_shl_eq_spanned(&mut $tokens
, $span
);
1240 ($tokens
:ident $span
:ident
>>) => {
1241 $
crate::__private
::push_shr_spanned(&mut $tokens
, $span
);
1244 ($tokens
:ident $span
:ident
>>=) => {
1245 $
crate::__private
::push_shr_eq_spanned(&mut $tokens
, $span
);
1248 ($tokens
:ident $span
:ident
*) => {
1249 $
crate::__private
::push_star_spanned(&mut $tokens
, $span
);
1252 ($tokens
:ident $span
:ident
-) => {
1253 $
crate::__private
::push_sub_spanned(&mut $tokens
, $span
);
1256 ($tokens
:ident $span
:ident
-=) => {
1257 $
crate::__private
::push_sub_eq_spanned(&mut $tokens
, $span
);
1260 ($tokens
:ident $span
:ident $ident
:ident
) => {
1261 $
crate::__private
::push_ident_spanned(&mut $tokens
, $span
, stringify
!($ident
));
1264 ($tokens
:ident $span
:ident $other
:tt
) => {
1265 $
crate::__private
::parse_spanned(&mut $tokens
, $span
, stringify
!($other
));