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