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.13")] 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 #[path = "runtime.rs"] 102 pub mod __rt; 103 104 /// The whole point. 105 /// 106 /// Performs variable interpolation against the input and produces it as 107 /// [`TokenStream`]. For returning tokens to the compiler in a procedural macro, use 108 /// `into()` to build a `TokenStream`. 109 /// 110 /// [`TokenStream`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.TokenStream.html 111 /// 112 /// # Interpolation 113 /// 114 /// Variable interpolation is done with `#var` (similar to `$var` in 115 /// `macro_rules!` macros). This grabs the `var` variable that is currently in 116 /// scope and inserts it in that location in the output tokens. Any type 117 /// implementing the [`ToTokens`] trait can be interpolated. This includes most 118 /// Rust primitive types as well as most of the syntax tree types from the [Syn] 119 /// crate. 120 /// 121 /// [`ToTokens`]: trait.ToTokens.html 122 /// [Syn]: https://github.com/dtolnay/syn 123 /// 124 /// Repetition is done using `#(...)*` or `#(...),*` again similar to 125 /// `macro_rules!`. This iterates through the elements of any variable 126 /// interpolated within the repetition and inserts a copy of the repetition body 127 /// for each one. The variables in an interpolation may be anything that 128 /// implements `IntoIterator`, including `Vec` or a pre-existing iterator. 129 /// 130 /// - `#(#var)*` — no separators 131 /// - `#(#var),*` — the character before the asterisk is used as a separator 132 /// - `#( struct #var; )*` — the repetition can contain other tokens 133 /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations 134 /// 135 /// There are two limitations around interpolations in a repetition: 136 /// 137 /// - Every interpolation inside of a repetition must be a distinct variable. 138 /// That is, `#(#a #a)*` is not allowed. Work around this by collecting `a` 139 /// into a vector and taking references `a1 = &a` and `a2 = &a` which you use 140 /// inside the repetition: `#(#a1 #a2)*`. Where possible, use meaningful names 141 /// that indicate the distinct role of each copy. 142 /// 143 /// - Every interpolation inside of a repetition must be iterable. If we have 144 /// `vec` which is a vector and `ident` which is a single identifier, 145 /// `#(#ident #vec)*` is not allowed. Work around this by using 146 /// `std::iter::repeat(ident)` to produce an iterable that can be used from 147 /// within the repetition. 148 /// 149 /// # Hygiene 150 /// 151 /// Any interpolated tokens preserve the `Span` information provided by their 152 /// `ToTokens` implementation. Tokens that originate within the `quote!` 153 /// invocation are spanned with [`Span::call_site()`]. 154 /// 155 /// [`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site 156 /// 157 /// A different span can be provided through the [`quote_spanned!`] macro. 158 /// 159 /// [`quote_spanned!`]: macro.quote_spanned.html 160 /// 161 /// # Return type 162 /// 163 /// The macro evaluates to an expression of type `proc_macro2::TokenStream`. 164 /// Meanwhile Rust procedural macros are expected to return the type 165 /// `proc_macro::TokenStream`. 166 /// 167 /// The difference between the two types is that `proc_macro` types are entirely 168 /// specific to procedural macros and cannot ever exist in code outside of a 169 /// procedural macro, while `proc_macro2` types may exist anywhere including 170 /// tests and non-macro code like main.rs and build.rs. This is why even the 171 /// procedural macro ecosystem is largely built around `proc_macro2`, because 172 /// that ensures the libraries are unit testable and accessible in non-macro 173 /// contexts. 174 /// 175 /// There is a [`From`]-conversion in both directions so returning the output of 176 /// `quote!` from a procedural macro usually looks like `tokens.into()` or 177 /// `proc_macro::TokenStream::from(tokens)`. 178 /// 179 /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html 180 /// 181 /// # Examples 182 /// 183 /// ## Procedural macro 184 /// 185 /// The structure of a basic procedural macro is as follows. Refer to the [Syn] 186 /// crate for further useful guidance on using `quote!` as part of a procedural 187 /// macro. 188 /// 189 /// [Syn]: https://github.com/dtolnay/syn 190 /// 191 /// ```edition2018 192 /// # #[cfg(any())] 193 /// extern crate proc_macro; 194 /// # use proc_macro2 as proc_macro; 195 /// 196 /// use proc_macro::TokenStream; 197 /// use quote::quote; 198 /// 199 /// # const IGNORE_TOKENS: &'static str = stringify! { 200 /// #[proc_macro_derive(HeapSize)] 201 /// # }; 202 /// pub fn derive_heap_size(input: TokenStream) -> TokenStream { 203 /// // Parse the input and figure out what implementation to generate... 204 /// # const IGNORE_TOKENS: &'static str = stringify! { 205 /// let name = /* ... */; 206 /// let expr = /* ... */; 207 /// # }; 208 /// # 209 /// # let name = 0; 210 /// # let expr = 0; 211 /// 212 /// let expanded = quote! { 213 /// // The generated impl. 214 /// impl heapsize::HeapSize for #name { 215 /// fn heap_size_of_children(&self) -> usize { 216 /// #expr 217 /// } 218 /// } 219 /// }; 220 /// 221 /// // Hand the output tokens back to the compiler. 222 /// TokenStream::from(expanded) 223 /// } 224 /// ``` 225 /// 226 /// ## Combining quoted fragments 227 /// 228 /// Usually you don't end up constructing an entire final `TokenStream` in one 229 /// piece. Different parts may come from different helper functions. The tokens 230 /// produced by `quote!` themselves implement `ToTokens` and so can be 231 /// interpolated into later `quote!` invocations to build up a final result. 232 /// 233 /// ```edition2018 234 /// # use quote::quote; 235 /// # 236 /// let type_definition = quote! {...}; 237 /// let methods = quote! {...}; 238 /// 239 /// let tokens = quote! { 240 /// #type_definition 241 /// #methods 242 /// }; 243 /// ``` 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 /// ```edition2018 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 perform token-level manipulations using the APIs provided 269 /// by Syn and proc-macro2. 270 /// 271 /// ```edition2018 272 /// # use proc_macro2::{self as syn, Span}; 273 /// # use quote::quote; 274 /// # 275 /// # let ident = syn::Ident::new("i", Span::call_site()); 276 /// # 277 /// let concatenated = format!("_{}", ident); 278 /// let varname = syn::Ident::new(&concatenated, ident.span()); 279 /// quote! { 280 /// let mut #varname = 0; 281 /// } 282 /// # ; 283 /// ``` 284 /// 285 /// ## Making method calls 286 /// 287 /// Let's say our macro requires some type specified in the macro input to have 288 /// a constructor called `new`. We have the type in a variable called 289 /// `field_type` of type `syn::Type` and want to invoke the constructor. 290 /// 291 /// ```edition2018 292 /// # use quote::quote; 293 /// # 294 /// # let field_type = quote!(...); 295 /// # 296 /// // incorrect 297 /// quote! { 298 /// let value = #field_type::new(); 299 /// } 300 /// # ; 301 /// ``` 302 /// 303 /// This works only sometimes. If `field_type` is `String`, the expanded code 304 /// contains `String::new()` which is fine. But if `field_type` is something 305 /// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid 306 /// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()` 307 /// but for macros often the following is more convenient. 308 /// 309 /// ```edition2018 310 /// # use quote::quote; 311 /// # 312 /// # let field_type = quote!(...); 313 /// # 314 /// quote! { 315 /// let value = <#field_type>::new(); 316 /// } 317 /// # ; 318 /// ``` 319 /// 320 /// This expands to `<Vec<i32>>::new()` which behaves correctly. 321 /// 322 /// A similar pattern is appropriate for trait methods. 323 /// 324 /// ```edition2018 325 /// # use quote::quote; 326 /// # 327 /// # let field_type = quote!(...); 328 /// # 329 /// quote! { 330 /// let value = <#field_type as core::default::Default>::default(); 331 /// } 332 /// # ; 333 /// ``` 334 #[macro_export(local_inner_macros)] 335 macro_rules! quote { 336 ($($tt:tt)*) => { 337 quote_spanned!($crate::__rt::Span::call_site()=> $($tt)*) 338 }; 339 } 340 341 /// Same as `quote!`, but applies a given span to all tokens originating within 342 /// the macro invocation. 343 /// 344 /// # Syntax 345 /// 346 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens 347 /// to quote. The span expression should be brief -- use a variable for anything 348 /// more than a few characters. There should be no space before the `=>` token. 349 /// 350 /// [`Span`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html 351 /// 352 /// ```edition2018 353 /// # use proc_macro2::Span; 354 /// # use quote::quote_spanned; 355 /// # 356 /// # const IGNORE_TOKENS: &'static str = stringify! { 357 /// let span = /* ... */; 358 /// # }; 359 /// # let span = Span::call_site(); 360 /// # let init = 0; 361 /// 362 /// // On one line, use parentheses. 363 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init))); 364 /// 365 /// // On multiple lines, place the span at the top and use braces. 366 /// let tokens = quote_spanned! {span=> 367 /// Box::into_raw(Box::new(#init)) 368 /// }; 369 /// ``` 370 /// 371 /// The lack of space before the `=>` should look jarring to Rust programmers 372 /// and this is intentional. The formatting is designed to be visibly 373 /// off-balance and draw the eye a particular way, due to the span expression 374 /// being evaluated in the context of the procedural macro and the remaining 375 /// tokens being evaluated in the generated code. 376 /// 377 /// # Hygiene 378 /// 379 /// Any interpolated tokens preserve the `Span` information provided by their 380 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!` 381 /// invocation are spanned with the given span argument. 382 /// 383 /// # Example 384 /// 385 /// The following procedural macro code uses `quote_spanned!` to assert that a 386 /// particular Rust type implements the [`Sync`] trait so that references can be 387 /// safely shared between threads. 388 /// 389 /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html 390 /// 391 /// ```edition2018 392 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens}; 393 /// # use proc_macro2::{Span, TokenStream}; 394 /// # 395 /// # struct Type; 396 /// # 397 /// # impl Type { 398 /// # fn span(&self) -> Span { 399 /// # Span::call_site() 400 /// # } 401 /// # } 402 /// # 403 /// # impl ToTokens for Type { 404 /// # fn to_tokens(&self, _tokens: &mut TokenStream) {} 405 /// # } 406 /// # 407 /// # let ty = Type; 408 /// # let call_site = Span::call_site(); 409 /// # 410 /// let ty_span = ty.span(); 411 /// let assert_sync = quote_spanned! {ty_span=> 412 /// struct _AssertSync where #ty: Sync; 413 /// }; 414 /// ``` 415 /// 416 /// If the assertion fails, the user will see an error like the following. The 417 /// input span of their type is hightlighted in the error. 418 /// 419 /// ```text 420 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied 421 /// --> src/main.rs:10:21 422 /// | 423 /// 10 | static ref PTR: *const () = &(); 424 /// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely 425 /// ``` 426 /// 427 /// In this example it is important for the where-clause to be spanned with the 428 /// line/column information of the user's input type so that error messages are 429 /// placed appropriately by the compiler. But it is also incredibly important 430 /// that `Sync` resolves at the macro definition site and not the macro call 431 /// site. If we resolve `Sync` at the same span that the user's type is going to 432 /// be resolved, then they could bypass our check by defining their own trait 433 /// named `Sync` that is implemented for their type. 434 #[macro_export(local_inner_macros)] 435 macro_rules! quote_spanned { 436 ($span:expr=> $($tt:tt)*) => {{ 437 let mut _s = $crate::__rt::TokenStream::new(); 438 let _span = $span; 439 quote_each_token!(_s _span $($tt)*); 440 _s 441 }}; 442 } 443 444 // Extract the names of all #metavariables and pass them to the $finish macro. 445 // 446 // in: pounded_var_names!(then () a #b c #( #d )* #e) 447 // out: then!(() b d e) 448 #[macro_export(local_inner_macros)] 449 #[doc(hidden)] 450 macro_rules! pounded_var_names { 451 ($finish:ident ($($found:ident)*) # ( $($inner:tt)* ) $($rest:tt)*) => { 452 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) 453 }; 454 455 ($finish:ident ($($found:ident)*) # [ $($inner:tt)* ] $($rest:tt)*) => { 456 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) 457 }; 458 459 ($finish:ident ($($found:ident)*) # { $($inner:tt)* } $($rest:tt)*) => { 460 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) 461 }; 462 463 ($finish:ident ($($found:ident)*) # $first:ident $($rest:tt)*) => { 464 pounded_var_names!($finish ($($found)* $first) $($rest)*) 465 }; 466 467 ($finish:ident ($($found:ident)*) ( $($inner:tt)* ) $($rest:tt)*) => { 468 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) 469 }; 470 471 ($finish:ident ($($found:ident)*) [ $($inner:tt)* ] $($rest:tt)*) => { 472 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) 473 }; 474 475 ($finish:ident ($($found:ident)*) { $($inner:tt)* } $($rest:tt)*) => { 476 pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*) 477 }; 478 479 ($finish:ident ($($found:ident)*) $ignore:tt $($rest:tt)*) => { 480 pounded_var_names!($finish ($($found)*) $($rest)*) 481 }; 482 483 ($finish:ident ($($found:ident)*)) => { 484 $finish!(() $($found)*) 485 }; 486 } 487 488 // in: nested_tuples_pat!(() a b c d e) 489 // out: ((((a b) c) d) e) 490 // 491 // in: nested_tuples_pat!(() a) 492 // out: a 493 #[macro_export(local_inner_macros)] 494 #[doc(hidden)] 495 macro_rules! nested_tuples_pat { 496 (()) => { 497 &() 498 }; 499 500 (() $first:ident $($rest:ident)*) => { 501 nested_tuples_pat!(($first) $($rest)*) 502 }; 503 504 (($pat:pat) $first:ident $($rest:ident)*) => { 505 nested_tuples_pat!((($pat, $first)) $($rest)*) 506 }; 507 508 (($done:pat)) => { 509 $done 510 }; 511 } 512 513 // in: multi_zip_expr!(() a b c d e) 514 // out: a.into_iter().zip(b).zip(c).zip(d).zip(e) 515 // 516 // in: multi_zip_iter!(() a) 517 // out: a 518 #[macro_export(local_inner_macros)] 519 #[doc(hidden)] 520 macro_rules! multi_zip_expr { 521 (()) => { 522 &[] 523 }; 524 525 (() $single:ident) => { 526 $single 527 }; 528 529 (() $first:ident $($rest:ident)*) => { 530 multi_zip_expr!(($first.into_iter()) $($rest)*) 531 }; 532 533 (($zips:expr) $first:ident $($rest:ident)*) => { 534 multi_zip_expr!(($zips.zip($first)) $($rest)*) 535 }; 536 537 (($done:expr)) => { 538 $done 539 }; 540 } 541 542 #[macro_export(local_inner_macros)] 543 #[doc(hidden)] 544 macro_rules! quote_each_token { 545 ($tokens:ident $span:ident) => {}; 546 547 ($tokens:ident $span:ident # ! $($rest:tt)*) => { 548 quote_each_token!($tokens $span #); 549 quote_each_token!($tokens $span !); 550 quote_each_token!($tokens $span $($rest)*); 551 }; 552 553 ($tokens:ident $span:ident # ( $($inner:tt)* ) * $($rest:tt)*) => { 554 for pounded_var_names!(nested_tuples_pat () $($inner)*) 555 in pounded_var_names!(multi_zip_expr () $($inner)*) { 556 quote_each_token!($tokens $span $($inner)*); 557 } 558 quote_each_token!($tokens $span $($rest)*); 559 }; 560 561 ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt * $($rest:tt)*) => { 562 for (_i, pounded_var_names!(nested_tuples_pat () $($inner)*)) 563 in pounded_var_names!(multi_zip_expr () $($inner)*).into_iter().enumerate() { 564 if _i > 0 { 565 quote_each_token!($tokens $span $sep); 566 } 567 quote_each_token!($tokens $span $($inner)*); 568 } 569 quote_each_token!($tokens $span $($rest)*); 570 }; 571 572 ($tokens:ident $span:ident # [ $($inner:tt)* ] $($rest:tt)*) => { 573 quote_each_token!($tokens $span #); 574 $tokens.extend({ 575 let mut g = $crate::__rt::Group::new( 576 $crate::__rt::Delimiter::Bracket, 577 quote_spanned!($span=> $($inner)*), 578 ); 579 g.set_span($span); 580 Some($crate::__rt::TokenTree::from(g)) 581 }); 582 quote_each_token!($tokens $span $($rest)*); 583 }; 584 585 ($tokens:ident $span:ident # $first:ident $($rest:tt)*) => { 586 $crate::ToTokens::to_tokens(&$first, &mut $tokens); 587 quote_each_token!($tokens $span $($rest)*); 588 }; 589 590 ($tokens:ident $span:ident ( $($first:tt)* ) $($rest:tt)*) => { 591 $tokens.extend({ 592 let mut g = $crate::__rt::Group::new( 593 $crate::__rt::Delimiter::Parenthesis, 594 quote_spanned!($span=> $($first)*), 595 ); 596 g.set_span($span); 597 Some($crate::__rt::TokenTree::from(g)) 598 }); 599 quote_each_token!($tokens $span $($rest)*); 600 }; 601 602 ($tokens:ident $span:ident [ $($first:tt)* ] $($rest:tt)*) => { 603 $tokens.extend({ 604 let mut g = $crate::__rt::Group::new( 605 $crate::__rt::Delimiter::Bracket, 606 quote_spanned!($span=> $($first)*), 607 ); 608 g.set_span($span); 609 Some($crate::__rt::TokenTree::from(g)) 610 }); 611 quote_each_token!($tokens $span $($rest)*); 612 }; 613 614 ($tokens:ident $span:ident { $($first:tt)* } $($rest:tt)*) => { 615 $tokens.extend({ 616 let mut g = $crate::__rt::Group::new( 617 $crate::__rt::Delimiter::Brace, 618 quote_spanned!($span=> $($first)*), 619 ); 620 g.set_span($span); 621 Some($crate::__rt::TokenTree::from(g)) 622 }); 623 quote_each_token!($tokens $span $($rest)*); 624 }; 625 626 ($tokens:ident $span:ident + $($rest:tt)*) => { 627 $crate::__rt::push_add(&mut $tokens, $span); 628 quote_each_token!($tokens $span $($rest)*); 629 }; 630 631 ($tokens:ident $span:ident += $($rest:tt)*) => { 632 $crate::__rt::push_add_eq(&mut $tokens, $span); 633 quote_each_token!($tokens $span $($rest)*); 634 }; 635 636 ($tokens:ident $span:ident & $($rest:tt)*) => { 637 $crate::__rt::push_and(&mut $tokens, $span); 638 quote_each_token!($tokens $span $($rest)*); 639 }; 640 641 ($tokens:ident $span:ident && $($rest:tt)*) => { 642 $crate::__rt::push_and_and(&mut $tokens, $span); 643 quote_each_token!($tokens $span $($rest)*); 644 }; 645 646 ($tokens:ident $span:ident &= $($rest:tt)*) => { 647 $crate::__rt::push_and_eq(&mut $tokens, $span); 648 quote_each_token!($tokens $span $($rest)*); 649 }; 650 651 ($tokens:ident $span:ident @ $($rest:tt)*) => { 652 $crate::__rt::push_at(&mut $tokens, $span); 653 quote_each_token!($tokens $span $($rest)*); 654 }; 655 656 ($tokens:ident $span:ident ! $($rest:tt)*) => { 657 $crate::__rt::push_bang(&mut $tokens, $span); 658 quote_each_token!($tokens $span $($rest)*); 659 }; 660 661 ($tokens:ident $span:ident ^ $($rest:tt)*) => { 662 $crate::__rt::push_caret(&mut $tokens, $span); 663 quote_each_token!($tokens $span $($rest)*); 664 }; 665 666 ($tokens:ident $span:ident ^= $($rest:tt)*) => { 667 $crate::__rt::push_caret_eq(&mut $tokens, $span); 668 quote_each_token!($tokens $span $($rest)*); 669 }; 670 671 ($tokens:ident $span:ident : $($rest:tt)*) => { 672 $crate::__rt::push_colon(&mut $tokens, $span); 673 quote_each_token!($tokens $span $($rest)*); 674 }; 675 676 ($tokens:ident $span:ident :: $($rest:tt)*) => { 677 $crate::__rt::push_colon2(&mut $tokens, $span); 678 quote_each_token!($tokens $span $($rest)*); 679 }; 680 681 ($tokens:ident $span:ident , $($rest:tt)*) => { 682 $crate::__rt::push_comma(&mut $tokens, $span); 683 quote_each_token!($tokens $span $($rest)*); 684 }; 685 686 ($tokens:ident $span:ident / $($rest:tt)*) => { 687 $crate::__rt::push_div(&mut $tokens, $span); 688 quote_each_token!($tokens $span $($rest)*); 689 }; 690 691 ($tokens:ident $span:ident /= $($rest:tt)*) => { 692 $crate::__rt::push_div_eq(&mut $tokens, $span); 693 quote_each_token!($tokens $span $($rest)*); 694 }; 695 696 ($tokens:ident $span:ident . $($rest:tt)*) => { 697 $crate::__rt::push_dot(&mut $tokens, $span); 698 quote_each_token!($tokens $span $($rest)*); 699 }; 700 701 ($tokens:ident $span:ident .. $($rest:tt)*) => { 702 $crate::__rt::push_dot2(&mut $tokens, $span); 703 quote_each_token!($tokens $span $($rest)*); 704 }; 705 706 ($tokens:ident $span:ident ... $($rest:tt)*) => { 707 $crate::__rt::push_dot3(&mut $tokens, $span); 708 quote_each_token!($tokens $span $($rest)*); 709 }; 710 711 ($tokens:ident $span:ident ..= $($rest:tt)*) => { 712 $crate::__rt::push_dot_dot_eq(&mut $tokens, $span); 713 quote_each_token!($tokens $span $($rest)*); 714 }; 715 716 ($tokens:ident $span:ident = $($rest:tt)*) => { 717 $crate::__rt::push_eq(&mut $tokens, $span); 718 quote_each_token!($tokens $span $($rest)*); 719 }; 720 721 ($tokens:ident $span:ident == $($rest:tt)*) => { 722 $crate::__rt::push_eq_eq(&mut $tokens, $span); 723 quote_each_token!($tokens $span $($rest)*); 724 }; 725 726 ($tokens:ident $span:ident >= $($rest:tt)*) => { 727 $crate::__rt::push_ge(&mut $tokens, $span); 728 quote_each_token!($tokens $span $($rest)*); 729 }; 730 731 ($tokens:ident $span:ident > $($rest:tt)*) => { 732 $crate::__rt::push_gt(&mut $tokens, $span); 733 quote_each_token!($tokens $span $($rest)*); 734 }; 735 736 ($tokens:ident $span:ident <= $($rest:tt)*) => { 737 $crate::__rt::push_le(&mut $tokens, $span); 738 quote_each_token!($tokens $span $($rest)*); 739 }; 740 741 ($tokens:ident $span:ident < $($rest:tt)*) => { 742 $crate::__rt::push_lt(&mut $tokens, $span); 743 quote_each_token!($tokens $span $($rest)*); 744 }; 745 746 ($tokens:ident $span:ident *= $($rest:tt)*) => { 747 $crate::__rt::push_mul_eq(&mut $tokens, $span); 748 quote_each_token!($tokens $span $($rest)*); 749 }; 750 751 ($tokens:ident $span:ident != $($rest:tt)*) => { 752 $crate::__rt::push_ne(&mut $tokens, $span); 753 quote_each_token!($tokens $span $($rest)*); 754 }; 755 756 ($tokens:ident $span:ident | $($rest:tt)*) => { 757 $crate::__rt::push_or(&mut $tokens, $span); 758 quote_each_token!($tokens $span $($rest)*); 759 }; 760 761 ($tokens:ident $span:ident |= $($rest:tt)*) => { 762 $crate::__rt::push_or_eq(&mut $tokens, $span); 763 quote_each_token!($tokens $span $($rest)*); 764 }; 765 766 ($tokens:ident $span:ident || $($rest:tt)*) => { 767 $crate::__rt::push_or_or(&mut $tokens, $span); 768 quote_each_token!($tokens $span $($rest)*); 769 }; 770 771 ($tokens:ident $span:ident # $($rest:tt)*) => { 772 $crate::__rt::push_pound(&mut $tokens, $span); 773 quote_each_token!($tokens $span $($rest)*); 774 }; 775 776 ($tokens:ident $span:ident ? $($rest:tt)*) => { 777 $crate::__rt::push_question(&mut $tokens, $span); 778 quote_each_token!($tokens $span $($rest)*); 779 }; 780 781 ($tokens:ident $span:ident -> $($rest:tt)*) => { 782 $crate::__rt::push_rarrow(&mut $tokens, $span); 783 quote_each_token!($tokens $span $($rest)*); 784 }; 785 786 ($tokens:ident $span:ident <- $($rest:tt)*) => { 787 $crate::__rt::push_larrow(&mut $tokens, $span); 788 quote_each_token!($tokens $span $($rest)*); 789 }; 790 791 ($tokens:ident $span:ident % $($rest:tt)*) => { 792 $crate::__rt::push_rem(&mut $tokens, $span); 793 quote_each_token!($tokens $span $($rest)*); 794 }; 795 796 ($tokens:ident $span:ident %= $($rest:tt)*) => { 797 $crate::__rt::push_rem_eq(&mut $tokens, $span); 798 quote_each_token!($tokens $span $($rest)*); 799 }; 800 801 ($tokens:ident $span:ident => $($rest:tt)*) => { 802 $crate::__rt::push_fat_arrow(&mut $tokens, $span); 803 quote_each_token!($tokens $span $($rest)*); 804 }; 805 806 ($tokens:ident $span:ident ; $($rest:tt)*) => { 807 $crate::__rt::push_semi(&mut $tokens, $span); 808 quote_each_token!($tokens $span $($rest)*); 809 }; 810 811 ($tokens:ident $span:ident << $($rest:tt)*) => { 812 $crate::__rt::push_shl(&mut $tokens, $span); 813 quote_each_token!($tokens $span $($rest)*); 814 }; 815 816 ($tokens:ident $span:ident <<= $($rest:tt)*) => { 817 $crate::__rt::push_shl_eq(&mut $tokens, $span); 818 quote_each_token!($tokens $span $($rest)*); 819 }; 820 821 ($tokens:ident $span:ident >> $($rest:tt)*) => { 822 $crate::__rt::push_shr(&mut $tokens, $span); 823 quote_each_token!($tokens $span $($rest)*); 824 }; 825 826 ($tokens:ident $span:ident >>= $($rest:tt)*) => { 827 $crate::__rt::push_shr_eq(&mut $tokens, $span); 828 quote_each_token!($tokens $span $($rest)*); 829 }; 830 831 ($tokens:ident $span:ident * $($rest:tt)*) => { 832 $crate::__rt::push_star(&mut $tokens, $span); 833 quote_each_token!($tokens $span $($rest)*); 834 }; 835 836 ($tokens:ident $span:ident - $($rest:tt)*) => { 837 $crate::__rt::push_sub(&mut $tokens, $span); 838 quote_each_token!($tokens $span $($rest)*); 839 }; 840 841 ($tokens:ident $span:ident -= $($rest:tt)*) => { 842 $crate::__rt::push_sub_eq(&mut $tokens, $span); 843 quote_each_token!($tokens $span $($rest)*); 844 }; 845 846 ($tokens:ident $span:ident $first:tt $($rest:tt)*) => { 847 $crate::__rt::parse(&mut $tokens, $span, quote_stringify!($first)); 848 quote_each_token!($tokens $span $($rest)*); 849 }; 850 } 851 852 // Unhygienically invoke whatever `stringify` the caller has in scope i.e. not a 853 // local macro. The macros marked `local_inner_macros` above cannot invoke 854 // `stringify` directly. 855 #[macro_export] 856 #[doc(hidden)] 857 macro_rules! quote_stringify { 858 ($tt:tt) => { 859 stringify!($tt) 860 }; 861 } 862