1 //! This crate provides the [`quote!`] macro for turning Rust syntax tree data
2 //! structures into tokens of source code.
3 //!
4 //! [`quote!`]: macro.quote.html
5 //!
6 //! Procedural macros in Rust receive a stream of tokens as input, execute
7 //! arbitrary Rust code to determine how to manipulate those tokens, and produce
8 //! a stream of tokens to hand back to the compiler to compile into the caller's
9 //! crate. Quasi-quoting is a solution to one piece of that — producing
10 //! tokens to return to the compiler.
11 //!
12 //! The idea of quasi-quoting is that we write *code* that we treat as *data*.
13 //! Within the `quote!` macro, we can write what looks like code to our text
14 //! editor or IDE. We get all the benefits of the editor's brace matching,
15 //! syntax highlighting, indentation, and maybe autocompletion. But rather than
16 //! compiling that as code into the current crate, we can treat it as data, pass
17 //! it around, mutate it, and eventually hand it back to the compiler as tokens
18 //! to compile into the macro caller's crate.
19 //!
20 //! This crate is motivated by the procedural macro use case, but is a
21 //! general-purpose Rust quasi-quoting library and is not specific to procedural
22 //! macros.
23 //!
24 //! ```toml
25 //! [dependencies]
26 //! quote = "1.0"
27 //! ```
28 //!
29 //! <br>
30 //!
31 //! # Example
32 //!
33 //! The following quasi-quoted block of code is something you might find in [a]
34 //! procedural macro having to do with data structure serialization. The `#var`
35 //! syntax performs interpolation of runtime variables into the quoted tokens.
36 //! Check out the documentation of the [`quote!`] macro for more detail about
37 //! the syntax. See also the [`quote_spanned!`] macro which is important for
38 //! implementing hygienic procedural macros.
39 //!
40 //! [a]: https://serde.rs/
41 //! [`quote_spanned!`]: macro.quote_spanned.html
42 //!
43 //! ```
44 //! # use quote::quote;
45 //! #
46 //! # let generics = "";
47 //! # let where_clause = "";
48 //! # let field_ty = "";
49 //! # let item_ty = "";
50 //! # let path = "";
51 //! # let value = "";
52 //! #
53 //! let tokens = quote! {
54 //!     struct SerializeWith #generics #where_clause {
55 //!         value: &'a #field_ty,
56 //!         phantom: core::marker::PhantomData<#item_ty>,
57 //!     }
58 //!
59 //!     impl #generics serde::Serialize for SerializeWith #generics #where_clause {
60 //!         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
61 //!         where
62 //!             S: serde::Serializer,
63 //!         {
64 //!             #path(self.value, serializer)
65 //!         }
66 //!     }
67 //!
68 //!     SerializeWith {
69 //!         value: #value,
70 //!         phantom: core::marker::PhantomData::<#item_ty>,
71 //!     }
72 //! };
73 //! ```
74 
75 // Quote types in rustdoc of other crates get linked to here.
76 #![doc(html_root_url = "https://docs.rs/quote/1.0.2")]
77 
78 #[cfg(all(
79     not(all(target_arch = "wasm32", target_os = "unknown")),
80     feature = "proc-macro"
81 ))]
82 extern crate proc_macro;
83 
84 mod ext;
85 mod format;
86 mod ident_fragment;
87 mod to_tokens;
88 
89 // Not public API.
90 #[doc(hidden)]
91 #[path = "runtime.rs"]
92 pub mod __rt;
93 
94 pub use crate::ext::TokenStreamExt;
95 pub use crate::ident_fragment::IdentFragment;
96 pub use crate::to_tokens::ToTokens;
97 
98 // Not public API.
99 #[doc(hidden)]
100 pub mod spanned;
101 
102 /// The whole point.
103 ///
104 /// Performs variable interpolation against the input and produces it as
105 /// [`proc_macro2::TokenStream`].
106 ///
107 /// Note: for returning tokens to the compiler in a procedural macro, use
108 /// `.into()` on the result to convert to [`proc_macro::TokenStream`].
109 ///
110 /// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
111 ///
112 /// <br>
113 ///
114 /// # Interpolation
115 ///
116 /// Variable interpolation is done with `#var` (similar to `$var` in
117 /// `macro_rules!` macros). This grabs the `var` variable that is currently in
118 /// scope and inserts it in that location in the output tokens. Any type
119 /// implementing the [`ToTokens`] trait can be interpolated. This includes most
120 /// Rust primitive types as well as most of the syntax tree types from the [Syn]
121 /// crate.
122 ///
123 /// [`ToTokens`]: trait.ToTokens.html
124 /// [Syn]: https://github.com/dtolnay/syn
125 ///
126 /// Repetition is done using `#(...)*` or `#(...),*` again similar to
127 /// `macro_rules!`. This iterates through the elements of any variable
128 /// interpolated within the repetition and inserts a copy of the repetition body
129 /// for each one. The variables in an interpolation may be a `Vec`, slice,
130 /// `BTreeSet`, or any `Iterator`.
131 ///
132 /// - `#(#var)*` — no separators
133 /// - `#(#var),*` — the character before the asterisk is used as a separator
134 /// - `#( struct #var; )*` — the repetition can contain other tokens
135 /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
136 ///
137 /// <br>
138 ///
139 /// # Hygiene
140 ///
141 /// Any interpolated tokens preserve the `Span` information provided by their
142 /// `ToTokens` implementation. Tokens that originate within the `quote!`
143 /// invocation are spanned with [`Span::call_site()`].
144 ///
145 /// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
146 ///
147 /// A different span can be provided through the [`quote_spanned!`] macro.
148 ///
149 /// [`quote_spanned!`]: macro.quote_spanned.html
150 ///
151 /// <br>
152 ///
153 /// # Return type
154 ///
155 /// The macro evaluates to an expression of type `proc_macro2::TokenStream`.
156 /// Meanwhile Rust procedural macros are expected to return the type
157 /// `proc_macro::TokenStream`.
158 ///
159 /// The difference between the two types is that `proc_macro` types are entirely
160 /// specific to procedural macros and cannot ever exist in code outside of a
161 /// procedural macro, while `proc_macro2` types may exist anywhere including
162 /// tests and non-macro code like main.rs and build.rs. This is why even the
163 /// procedural macro ecosystem is largely built around `proc_macro2`, because
164 /// that ensures the libraries are unit testable and accessible in non-macro
165 /// contexts.
166 ///
167 /// There is a [`From`]-conversion in both directions so returning the output of
168 /// `quote!` from a procedural macro usually looks like `tokens.into()` or
169 /// `proc_macro::TokenStream::from(tokens)`.
170 ///
171 /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
172 ///
173 /// <br>
174 ///
175 /// # Examples
176 ///
177 /// ### Procedural macro
178 ///
179 /// The structure of a basic procedural macro is as follows. Refer to the [Syn]
180 /// crate for further useful guidance on using `quote!` as part of a procedural
181 /// macro.
182 ///
183 /// [Syn]: https://github.com/dtolnay/syn
184 ///
185 /// ```
186 /// # #[cfg(any())]
187 /// extern crate proc_macro;
188 /// # extern crate proc_macro2;
189 ///
190 /// # #[cfg(any())]
191 /// use proc_macro::TokenStream;
192 /// # use proc_macro2::TokenStream;
193 /// use quote::quote;
194 ///
195 /// # const IGNORE_TOKENS: &'static str = stringify! {
196 /// #[proc_macro_derive(HeapSize)]
197 /// # };
198 /// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
199 ///     // Parse the input and figure out what implementation to generate...
200 ///     # const IGNORE_TOKENS: &'static str = stringify! {
201 ///     let name = /* ... */;
202 ///     let expr = /* ... */;
203 ///     # };
204 ///     #
205 ///     # let name = 0;
206 ///     # let expr = 0;
207 ///
208 ///     let expanded = quote! {
209 ///         // The generated impl.
210 ///         impl heapsize::HeapSize for #name {
211 ///             fn heap_size_of_children(&self) -> usize {
212 ///                 #expr
213 ///             }
214 ///         }
215 ///     };
216 ///
217 ///     // Hand the output tokens back to the compiler.
218 ///     TokenStream::from(expanded)
219 /// }
220 /// ```
221 ///
222 /// <p><br></p>
223 ///
224 /// ### Combining quoted fragments
225 ///
226 /// Usually you don't end up constructing an entire final `TokenStream` in one
227 /// piece. Different parts may come from different helper functions. The tokens
228 /// produced by `quote!` themselves implement `ToTokens` and so can be
229 /// interpolated into later `quote!` invocations to build up a final result.
230 ///
231 /// ```
232 /// # use quote::quote;
233 /// #
234 /// let type_definition = quote! {...};
235 /// let methods = quote! {...};
236 ///
237 /// let tokens = quote! {
238 ///     #type_definition
239 ///     #methods
240 /// };
241 /// ```
242 ///
243 /// <p><br></p>
244 ///
245 /// ### Constructing identifiers
246 ///
247 /// Suppose we have an identifier `ident` which came from somewhere in a macro
248 /// input and we need to modify it in some way for the macro output. Let's
249 /// consider prepending the identifier with an underscore.
250 ///
251 /// Simply interpolating the identifier next to an underscore will not have the
252 /// behavior of concatenating them. The underscore and the identifier will
253 /// continue to be two separate tokens as if you had written `_ x`.
254 ///
255 /// ```
256 /// # use proc_macro2::{self as syn, Span};
257 /// # use quote::quote;
258 /// #
259 /// # let ident = syn::Ident::new("i", Span::call_site());
260 /// #
261 /// // incorrect
262 /// quote! {
263 ///     let mut _#ident = 0;
264 /// }
265 /// # ;
266 /// ```
267 ///
268 /// The solution is to build a new identifier token with the correct value. As
269 /// this is such a common case, the [`format_ident!`] macro provides a
270 /// convenient utility for doing so correctly.
271 ///
272 /// ```
273 /// # use proc_macro2::{Ident, Span};
274 /// # use quote::{format_ident, quote};
275 /// #
276 /// # let ident = Ident::new("i", Span::call_site());
277 /// #
278 /// let varname = format_ident!("_{}", ident);
279 /// quote! {
280 ///     let mut #varname = 0;
281 /// }
282 /// # ;
283 /// ```
284 ///
285 /// Alternatively, the APIs provided by Syn and proc-macro2 can be used to
286 /// directly build the identifier. This is roughly equivalent to the above, but
287 /// will not handle `ident` being a raw identifier.
288 ///
289 /// ```
290 /// # use proc_macro2::{self as syn, Span};
291 /// # use quote::quote;
292 /// #
293 /// # let ident = syn::Ident::new("i", Span::call_site());
294 /// #
295 /// let concatenated = format!("_{}", ident);
296 /// let varname = syn::Ident::new(&concatenated, ident.span());
297 /// quote! {
298 ///     let mut #varname = 0;
299 /// }
300 /// # ;
301 /// ```
302 ///
303 /// <p><br></p>
304 ///
305 /// ### Making method calls
306 ///
307 /// Let's say our macro requires some type specified in the macro input to have
308 /// a constructor called `new`. We have the type in a variable called
309 /// `field_type` of type `syn::Type` and want to invoke the constructor.
310 ///
311 /// ```
312 /// # use quote::quote;
313 /// #
314 /// # let field_type = quote!(...);
315 /// #
316 /// // incorrect
317 /// quote! {
318 ///     let value = #field_type::new();
319 /// }
320 /// # ;
321 /// ```
322 ///
323 /// This works only sometimes. If `field_type` is `String`, the expanded code
324 /// contains `String::new()` which is fine. But if `field_type` is something
325 /// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid
326 /// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`
327 /// but for macros often the following is more convenient.
328 ///
329 /// ```
330 /// # use quote::quote;
331 /// #
332 /// # let field_type = quote!(...);
333 /// #
334 /// quote! {
335 ///     let value = <#field_type>::new();
336 /// }
337 /// # ;
338 /// ```
339 ///
340 /// This expands to `<Vec<i32>>::new()` which behaves correctly.
341 ///
342 /// A similar pattern is appropriate for trait methods.
343 ///
344 /// ```
345 /// # use quote::quote;
346 /// #
347 /// # let field_type = quote!(...);
348 /// #
349 /// quote! {
350 ///     let value = <#field_type as core::default::Default>::default();
351 /// }
352 /// # ;
353 /// ```
354 ///
355 /// <p><br></p>
356 ///
357 /// ### Interpolating text inside of doc comments
358 ///
359 /// Neither doc comments nor string literals get interpolation behavior in
360 /// quote:
361 ///
362 /// ```compile_fail
363 /// quote! {
364 ///     /// try to interpolate: #ident
365 ///     ///
366 ///     /// ...
367 /// }
368 /// ```
369 ///
370 /// ```compile_fail
371 /// quote! {
372 ///     #[doc = "try to interpolate: #ident"]
373 /// }
374 /// ```
375 ///
376 /// Macro calls in a doc attribute are not valid syntax:
377 ///
378 /// ```compile_fail
379 /// quote! {
380 ///     #[doc = concat!("try to interpolate: ", stringify!(#ident))]
381 /// }
382 /// ```
383 ///
384 /// Instead the best way to build doc comments that involve variables is by
385 /// formatting the doc string literal outside of quote.
386 ///
387 /// ```rust
388 /// # use proc_macro2::{Ident, Span};
389 /// # use quote::quote;
390 /// #
391 /// # const IGNORE: &str = stringify! {
392 /// let msg = format!(...);
393 /// # };
394 /// #
395 /// # let ident = Ident::new("var", Span::call_site());
396 /// # let msg = format!("try to interpolate: {}", ident);
397 /// quote! {
398 ///     #[doc = #msg]
399 ///     ///
400 ///     /// ...
401 /// }
402 /// # ;
403 /// ```
404 ///
405 /// <p><br></p>
406 ///
407 /// ### Indexing into a tuple struct
408 ///
409 /// When interpolating indices of a tuple or tuple struct, we need them not to
410 /// appears suffixed as integer literals by interpolating them as [`syn::Index`]
411 /// instead.
412 ///
413 /// [`syn::Index`]: https://docs.rs/syn/1.0/syn/struct.Index.html
414 ///
415 /// ```compile_fail
416 /// let i = 0usize..self.fields.len();
417 ///
418 /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
419 /// // which is not valid syntax
420 /// quote! {
421 ///     0 #( + self.#i.heap_size() )*
422 /// }
423 /// ```
424 ///
425 /// ```
426 /// # use proc_macro2::{Ident, TokenStream};
427 /// # use quote::quote;
428 /// #
429 /// # mod syn {
430 /// #     use proc_macro2::{Literal, TokenStream};
431 /// #     use quote::{ToTokens, TokenStreamExt};
432 /// #
433 /// #     pub struct Index(usize);
434 /// #
435 /// #     impl From<usize> for Index {
436 /// #         fn from(i: usize) -> Self {
437 /// #             Index(i)
438 /// #         }
439 /// #     }
440 /// #
441 /// #     impl ToTokens for Index {
442 /// #         fn to_tokens(&self, tokens: &mut TokenStream) {
443 /// #             tokens.append(Literal::usize_unsuffixed(self.0));
444 /// #         }
445 /// #     }
446 /// # }
447 /// #
448 /// # struct Struct {
449 /// #     fields: Vec<Ident>,
450 /// # }
451 /// #
452 /// # impl Struct {
453 /// #     fn example(&self) -> TokenStream {
454 /// let i = (0..self.fields.len()).map(syn::Index::from);
455 ///
456 /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
457 /// quote! {
458 ///     0 #( + self.#i.heap_size() )*
459 /// }
460 /// #     }
461 /// # }
462 /// ```
463 #[macro_export]
464 macro_rules! quote {
465     ($($tt:tt)*) => {
466         $crate::quote_spanned!($crate::__rt::Span::call_site()=> $($tt)*)
467     };
468 }
469 
470 /// Same as `quote!`, but applies a given span to all tokens originating within
471 /// the macro invocation.
472 ///
473 /// <br>
474 ///
475 /// # Syntax
476 ///
477 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens
478 /// to quote. The span expression should be brief &mdash; use a variable for
479 /// anything more than a few characters. There should be no space before the
480 /// `=>` token.
481 ///
482 /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
483 ///
484 /// ```
485 /// # use proc_macro2::Span;
486 /// # use quote::quote_spanned;
487 /// #
488 /// # const IGNORE_TOKENS: &'static str = stringify! {
489 /// let span = /* ... */;
490 /// # };
491 /// # let span = Span::call_site();
492 /// # let init = 0;
493 ///
494 /// // On one line, use parentheses.
495 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
496 ///
497 /// // On multiple lines, place the span at the top and use braces.
498 /// let tokens = quote_spanned! {span=>
499 ///     Box::into_raw(Box::new(#init))
500 /// };
501 /// ```
502 ///
503 /// The lack of space before the `=>` should look jarring to Rust programmers
504 /// and this is intentional. The formatting is designed to be visibly
505 /// off-balance and draw the eye a particular way, due to the span expression
506 /// being evaluated in the context of the procedural macro and the remaining
507 /// tokens being evaluated in the generated code.
508 ///
509 /// <br>
510 ///
511 /// # Hygiene
512 ///
513 /// Any interpolated tokens preserve the `Span` information provided by their
514 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
515 /// invocation are spanned with the given span argument.
516 ///
517 /// <br>
518 ///
519 /// # Example
520 ///
521 /// The following procedural macro code uses `quote_spanned!` to assert that a
522 /// particular Rust type implements the [`Sync`] trait so that references can be
523 /// safely shared between threads.
524 ///
525 /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
526 ///
527 /// ```
528 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
529 /// # use proc_macro2::{Span, TokenStream};
530 /// #
531 /// # struct Type;
532 /// #
533 /// # impl Type {
534 /// #     fn span(&self) -> Span {
535 /// #         Span::call_site()
536 /// #     }
537 /// # }
538 /// #
539 /// # impl ToTokens for Type {
540 /// #     fn to_tokens(&self, _tokens: &mut TokenStream) {}
541 /// # }
542 /// #
543 /// # let ty = Type;
544 /// # let call_site = Span::call_site();
545 /// #
546 /// let ty_span = ty.span();
547 /// let assert_sync = quote_spanned! {ty_span=>
548 ///     struct _AssertSync where #ty: Sync;
549 /// };
550 /// ```
551 ///
552 /// If the assertion fails, the user will see an error like the following. The
553 /// input span of their type is hightlighted in the error.
554 ///
555 /// ```text
556 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
557 ///   --> src/main.rs:10:21
558 ///    |
559 /// 10 |     static ref PTR: *const () = &();
560 ///    |                     ^^^^^^^^^ `*const ()` cannot be shared between threads safely
561 /// ```
562 ///
563 /// In this example it is important for the where-clause to be spanned with the
564 /// line/column information of the user's input type so that error messages are
565 /// placed appropriately by the compiler.
566 #[macro_export]
567 macro_rules! quote_spanned {
568     ($span:expr=> $($tt:tt)*) => {{
569         let mut _s = $crate::__rt::TokenStream::new();
570         let _span: $crate::__rt::Span = $span;
571         $crate::quote_each_token!(_s _span $($tt)*);
572         _s
573     }};
574 }
575 
576 // Extract the names of all #metavariables and pass them to the $call macro.
577 //
578 // in:   pounded_var_names!(then!(...) a #b c #( #d )* #e)
579 // out:  then!(... b);
580 //       then!(... d);
581 //       then!(... e);
582 #[macro_export]
583 #[doc(hidden)]
584 macro_rules! pounded_var_names {
585     ($call:ident! $extra:tt $($tts:tt)*) => {
586         $crate::pounded_var_names_with_context!($call! $extra
587             (@ $($tts)*)
588             ($($tts)* @)
589         )
590     };
591 }
592 
593 #[macro_export]
594 #[doc(hidden)]
595 macro_rules! pounded_var_names_with_context {
596     ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
597         $(
598             $crate::pounded_var_with_context!($call! $extra $b1 $curr);
599         )*
600     };
601 }
602 
603 #[macro_export]
604 #[doc(hidden)]
605 macro_rules! pounded_var_with_context {
606     ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
607         $crate::pounded_var_names!($call! $extra $($inner)*);
608     };
609 
610     ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
611         $crate::pounded_var_names!($call! $extra $($inner)*);
612     };
613 
614     ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
615         $crate::pounded_var_names!($call! $extra $($inner)*);
616     };
617 
618     ($call:ident!($($extra:tt)*) # $var:ident) => {
619         $crate::$call!($($extra)* $var);
620     };
621 
622     ($call:ident! $extra:tt $b1:tt $curr:tt) => {};
623 }
624 
625 #[macro_export]
626 #[doc(hidden)]
627 macro_rules! quote_bind_into_iter {
628     ($has_iter:ident $var:ident) => {
629         // `mut` may be unused if $var occurs multiple times in the list.
630         #[allow(unused_mut)]
631         let (mut $var, i) = $var.quote_into_iter();
632         let $has_iter = $has_iter | i;
633     };
634 }
635 
636 #[macro_export]
637 #[doc(hidden)]
638 macro_rules! quote_bind_next_or_break {
639     ($var:ident) => {
640         let $var = match $var.next() {
641             Some(_x) => $crate::__rt::RepInterp(_x),
642             None => break,
643         };
644     };
645 }
646 
647 #[macro_export]
648 #[doc(hidden)]
649 macro_rules! quote_each_token {
650     ($tokens:ident $span:ident $($tts:tt)*) => {
651         $crate::quote_tokens_with_context!($tokens $span
652             (@ @ @ @ @ @ $($tts)*)
653             (@ @ @ @ @ $($tts)* @)
654             (@ @ @ @ $($tts)* @ @)
655             (@ @ @ $(($tts))* @ @ @)
656             (@ @ $($tts)* @ @ @ @)
657             (@ $($tts)* @ @ @ @ @)
658             ($($tts)* @ @ @ @ @ @)
659         );
660     };
661 }
662 
663 #[macro_export]
664 #[doc(hidden)]
665 macro_rules! quote_tokens_with_context {
666     ($tokens:ident $span:ident
667         ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
668         ($($curr:tt)*)
669         ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
670     ) => {
671         $(
672             $crate::quote_token_with_context!($tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3);
673         )*
674     };
675 }
676 
677 #[macro_export]
678 #[doc(hidden)]
679 macro_rules! quote_token_with_context {
680     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
681 
682     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
683         use $crate::__rt::ext::*;
684         let has_iter = $crate::__rt::ThereIsNoIteratorInRepetition;
685         $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
686         let _: $crate::__rt::HasIterator = has_iter;
687         // This is `while true` instead of `loop` because if there are no
688         // iterators used inside of this repetition then the body would not
689         // contain any `break`, so the compiler would emit unreachable code
690         // warnings on anything below the loop. We use has_iter to detect and
691         // fail to compile when there are no iterators, so here we just work
692         // around the unneeded extra warning.
693         while true {
694             $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
695             $crate::quote_each_token!($tokens $span $($inner)*);
696         }
697     }};
698     ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
699     ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
700 
701     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
702         use $crate::__rt::ext::*;
703         let mut _i = 0usize;
704         let has_iter = $crate::__rt::ThereIsNoIteratorInRepetition;
705         $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
706         let _: $crate::__rt::HasIterator = has_iter;
707         while true {
708             $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
709             if _i > 0 {
710                 $crate::quote_token!($tokens $span $sep);
711             }
712             _i += 1;
713             $crate::quote_each_token!($tokens $span $($inner)*);
714         }
715     }};
716     ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
717     ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
718     ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
719         // https://github.com/dtolnay/quote/issues/130
720         $crate::quote_token!($tokens $span *);
721     };
722     ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
723 
724     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
725         $crate::ToTokens::to_tokens(&$var, &mut $tokens);
726     };
727     ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
728     ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
729         $crate::quote_token!($tokens $span $curr);
730     };
731 }
732 
733 #[macro_export]
734 #[doc(hidden)]
735 macro_rules! quote_token {
736     ($tokens:ident $span:ident ( $($inner:tt)* )) => {
737         $tokens.extend({
738             let mut g = $crate::__rt::Group::new(
739                 $crate::__rt::Delimiter::Parenthesis,
740                 $crate::quote_spanned!($span=> $($inner)*),
741             );
742             g.set_span($span);
743             Some($crate::__rt::TokenTree::from(g))
744         });
745     };
746 
747     ($tokens:ident $span:ident [ $($inner:tt)* ]) => {
748         $tokens.extend({
749             let mut g = $crate::__rt::Group::new(
750                 $crate::__rt::Delimiter::Bracket,
751                 $crate::quote_spanned!($span=> $($inner)*),
752             );
753             g.set_span($span);
754             Some($crate::__rt::TokenTree::from(g))
755         });
756     };
757 
758     ($tokens:ident $span:ident { $($inner:tt)* }) => {
759         $tokens.extend({
760             let mut g = $crate::__rt::Group::new(
761                 $crate::__rt::Delimiter::Brace,
762                 $crate::quote_spanned!($span=> $($inner)*),
763             );
764             g.set_span($span);
765             Some($crate::__rt::TokenTree::from(g))
766         });
767     };
768 
769     ($tokens:ident $span:ident +) => {
770         $crate::__rt::push_add(&mut $tokens, $span);
771     };
772 
773     ($tokens:ident $span:ident +=) => {
774         $crate::__rt::push_add_eq(&mut $tokens, $span);
775     };
776 
777     ($tokens:ident $span:ident &) => {
778         $crate::__rt::push_and(&mut $tokens, $span);
779     };
780 
781     ($tokens:ident $span:ident &&) => {
782         $crate::__rt::push_and_and(&mut $tokens, $span);
783     };
784 
785     ($tokens:ident $span:ident &=) => {
786         $crate::__rt::push_and_eq(&mut $tokens, $span);
787     };
788 
789     ($tokens:ident $span:ident @) => {
790         $crate::__rt::push_at(&mut $tokens, $span);
791     };
792 
793     ($tokens:ident $span:ident !) => {
794         $crate::__rt::push_bang(&mut $tokens, $span);
795     };
796 
797     ($tokens:ident $span:ident ^) => {
798         $crate::__rt::push_caret(&mut $tokens, $span);
799     };
800 
801     ($tokens:ident $span:ident ^=) => {
802         $crate::__rt::push_caret_eq(&mut $tokens, $span);
803     };
804 
805     ($tokens:ident $span:ident :) => {
806         $crate::__rt::push_colon(&mut $tokens, $span);
807     };
808 
809     ($tokens:ident $span:ident ::) => {
810         $crate::__rt::push_colon2(&mut $tokens, $span);
811     };
812 
813     ($tokens:ident $span:ident ,) => {
814         $crate::__rt::push_comma(&mut $tokens, $span);
815     };
816 
817     ($tokens:ident $span:ident /) => {
818         $crate::__rt::push_div(&mut $tokens, $span);
819     };
820 
821     ($tokens:ident $span:ident /=) => {
822         $crate::__rt::push_div_eq(&mut $tokens, $span);
823     };
824 
825     ($tokens:ident $span:ident .) => {
826         $crate::__rt::push_dot(&mut $tokens, $span);
827     };
828 
829     ($tokens:ident $span:ident ..) => {
830         $crate::__rt::push_dot2(&mut $tokens, $span);
831     };
832 
833     ($tokens:ident $span:ident ...) => {
834         $crate::__rt::push_dot3(&mut $tokens, $span);
835     };
836 
837     ($tokens:ident $span:ident ..=) => {
838         $crate::__rt::push_dot_dot_eq(&mut $tokens, $span);
839     };
840 
841     ($tokens:ident $span:ident =) => {
842         $crate::__rt::push_eq(&mut $tokens, $span);
843     };
844 
845     ($tokens:ident $span:ident ==) => {
846         $crate::__rt::push_eq_eq(&mut $tokens, $span);
847     };
848 
849     ($tokens:ident $span:ident >=) => {
850         $crate::__rt::push_ge(&mut $tokens, $span);
851     };
852 
853     ($tokens:ident $span:ident >) => {
854         $crate::__rt::push_gt(&mut $tokens, $span);
855     };
856 
857     ($tokens:ident $span:ident <=) => {
858         $crate::__rt::push_le(&mut $tokens, $span);
859     };
860 
861     ($tokens:ident $span:ident <) => {
862         $crate::__rt::push_lt(&mut $tokens, $span);
863     };
864 
865     ($tokens:ident $span:ident *=) => {
866         $crate::__rt::push_mul_eq(&mut $tokens, $span);
867     };
868 
869     ($tokens:ident $span:ident !=) => {
870         $crate::__rt::push_ne(&mut $tokens, $span);
871     };
872 
873     ($tokens:ident $span:ident |) => {
874         $crate::__rt::push_or(&mut $tokens, $span);
875     };
876 
877     ($tokens:ident $span:ident |=) => {
878         $crate::__rt::push_or_eq(&mut $tokens, $span);
879     };
880 
881     ($tokens:ident $span:ident ||) => {
882         $crate::__rt::push_or_or(&mut $tokens, $span);
883     };
884 
885     ($tokens:ident $span:ident #) => {
886         $crate::__rt::push_pound(&mut $tokens, $span);
887     };
888 
889     ($tokens:ident $span:ident ?) => {
890         $crate::__rt::push_question(&mut $tokens, $span);
891     };
892 
893     ($tokens:ident $span:ident ->) => {
894         $crate::__rt::push_rarrow(&mut $tokens, $span);
895     };
896 
897     ($tokens:ident $span:ident <-) => {
898         $crate::__rt::push_larrow(&mut $tokens, $span);
899     };
900 
901     ($tokens:ident $span:ident %) => {
902         $crate::__rt::push_rem(&mut $tokens, $span);
903     };
904 
905     ($tokens:ident $span:ident %=) => {
906         $crate::__rt::push_rem_eq(&mut $tokens, $span);
907     };
908 
909     ($tokens:ident $span:ident =>) => {
910         $crate::__rt::push_fat_arrow(&mut $tokens, $span);
911     };
912 
913     ($tokens:ident $span:ident ;) => {
914         $crate::__rt::push_semi(&mut $tokens, $span);
915     };
916 
917     ($tokens:ident $span:ident <<) => {
918         $crate::__rt::push_shl(&mut $tokens, $span);
919     };
920 
921     ($tokens:ident $span:ident <<=) => {
922         $crate::__rt::push_shl_eq(&mut $tokens, $span);
923     };
924 
925     ($tokens:ident $span:ident >>) => {
926         $crate::__rt::push_shr(&mut $tokens, $span);
927     };
928 
929     ($tokens:ident $span:ident >>=) => {
930         $crate::__rt::push_shr_eq(&mut $tokens, $span);
931     };
932 
933     ($tokens:ident $span:ident *) => {
934         $crate::__rt::push_star(&mut $tokens, $span);
935     };
936 
937     ($tokens:ident $span:ident -) => {
938         $crate::__rt::push_sub(&mut $tokens, $span);
939     };
940 
941     ($tokens:ident $span:ident -=) => {
942         $crate::__rt::push_sub_eq(&mut $tokens, $span);
943     };
944 
945     ($tokens:ident $span:ident $other:tt) => {
946         $crate::__rt::parse(&mut $tokens, $span, stringify!($other));
947     };
948 }
949