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