1 //! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote) 2 //! 3 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github 4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust 5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs 6 //! 7 //! <br> 8 //! 9 //! This crate provides the [`quote!`] macro for turning Rust syntax tree data 10 //! structures into tokens of source code. 11 //! 12 //! Procedural macros in Rust receive a stream of tokens as input, execute 13 //! arbitrary Rust code to determine how to manipulate those tokens, and produce 14 //! a stream of tokens to hand back to the compiler to compile into the caller's 15 //! crate. Quasi-quoting is a solution to one piece of that — producing 16 //! tokens to return to the compiler. 17 //! 18 //! The idea of quasi-quoting is that we write *code* that we treat as *data*. 19 //! Within the `quote!` macro, we can write what looks like code to our text 20 //! editor or IDE. We get all the benefits of the editor's brace matching, 21 //! syntax highlighting, indentation, and maybe autocompletion. But rather than 22 //! compiling that as code into the current crate, we can treat it as data, pass 23 //! it around, mutate it, and eventually hand it back to the compiler as tokens 24 //! to compile into the macro caller's crate. 25 //! 26 //! This crate is motivated by the procedural macro use case, but is a 27 //! general-purpose Rust quasi-quoting library and is not specific to procedural 28 //! macros. 29 //! 30 //! ```toml 31 //! [dependencies] 32 //! quote = "1.0" 33 //! ``` 34 //! 35 //! <br> 36 //! 37 //! # Example 38 //! 39 //! The following quasi-quoted block of code is something you might find in [a] 40 //! procedural macro having to do with data structure serialization. The `#var` 41 //! syntax performs interpolation of runtime variables into the quoted tokens. 42 //! Check out the documentation of the [`quote!`] macro for more detail about 43 //! the syntax. See also the [`quote_spanned!`] macro which is important for 44 //! implementing hygienic procedural macros. 45 //! 46 //! [a]: https://serde.rs/ 47 //! 48 //! ``` 49 //! # use quote::quote; 50 //! # 51 //! # let generics = ""; 52 //! # let where_clause = ""; 53 //! # let field_ty = ""; 54 //! # let item_ty = ""; 55 //! # let path = ""; 56 //! # let value = ""; 57 //! # 58 //! let tokens = quote! { 59 //! struct SerializeWith #generics #where_clause { 60 //! value: &'a #field_ty, 61 //! phantom: core::marker::PhantomData<#item_ty>, 62 //! } 63 //! 64 //! impl #generics serde::Serialize for SerializeWith #generics #where_clause { 65 //! fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 66 //! where 67 //! S: serde::Serializer, 68 //! { 69 //! #path(self.value, serializer) 70 //! } 71 //! } 72 //! 73 //! SerializeWith { 74 //! value: #value, 75 //! phantom: core::marker::PhantomData::<#item_ty>, 76 //! } 77 //! }; 78 //! ``` 79 //! 80 //! <br> 81 //! 82 //! # Non-macro code generators 83 //! 84 //! When using `quote` in a build.rs or main.rs and writing the output out to a 85 //! file, consider having the code generator pass the tokens through 86 //! [prettyplease] before writing. This way if an error occurs in the generated 87 //! code it is convenient for a human to read and debug. 88 //! 89 //! [prettyplease]: https://github.com/dtolnay/prettyplease 90 91 // Quote types in rustdoc of other crates get linked to here. 92 #![doc(html_root_url = "https://docs.rs/quote/1.0.40")] 93 #![allow( 94 clippy::doc_markdown, 95 clippy::elidable_lifetime_names, 96 clippy::missing_errors_doc, 97 clippy::missing_panics_doc, 98 clippy::module_name_repetitions, 99 clippy::needless_lifetimes, 100 // false positive https://github.com/rust-lang/rust-clippy/issues/6983 101 clippy::wrong_self_convention, 102 )] 103 104 extern crate alloc; 105 106 #[cfg(feature = "proc-macro")] 107 extern crate proc_macro; 108 109 mod ext; 110 mod format; 111 mod ident_fragment; 112 mod to_tokens; 113 114 // Not public API. 115 #[doc(hidden)] 116 #[path = "runtime.rs"] 117 pub mod __private; 118 119 pub use crate::ext::TokenStreamExt; 120 pub use crate::ident_fragment::IdentFragment; 121 pub use crate::to_tokens::ToTokens; 122 123 // Not public API. 124 #[doc(hidden)] 125 pub mod spanned; 126 127 macro_rules! __quote { 128 ($quote:item) => { 129 /// The whole point. 130 /// 131 /// Performs variable interpolation against the input and produces it as 132 /// [`proc_macro2::TokenStream`]. 133 /// 134 /// Note: for returning tokens to the compiler in a procedural macro, use 135 /// `.into()` on the result to convert to [`proc_macro::TokenStream`]. 136 /// 137 /// <br> 138 /// 139 /// # Interpolation 140 /// 141 /// Variable interpolation is done with `#var` (similar to `$var` in 142 /// `macro_rules!` macros). This grabs the `var` variable that is currently in 143 /// scope and inserts it in that location in the output tokens. Any type 144 /// implementing the [`ToTokens`] trait can be interpolated. This includes most 145 /// Rust primitive types as well as most of the syntax tree types from the [Syn] 146 /// crate. 147 /// 148 /// [Syn]: https://github.com/dtolnay/syn 149 /// 150 /// Repetition is done using `#(...)*` or `#(...),*` again similar to 151 /// `macro_rules!`. This iterates through the elements of any variable 152 /// interpolated within the repetition and inserts a copy of the repetition body 153 /// for each one. The variables in an interpolation may be a `Vec`, slice, 154 /// `BTreeSet`, or any `Iterator`. 155 /// 156 /// - `#(#var)*` — no separators 157 /// - `#(#var),*` — the character before the asterisk is used as a separator 158 /// - `#( struct #var; )*` — the repetition can contain other tokens 159 /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations 160 /// 161 /// <br> 162 /// 163 /// # Hygiene 164 /// 165 /// Any interpolated tokens preserve the `Span` information provided by their 166 /// `ToTokens` implementation. Tokens that originate within the `quote!` 167 /// invocation are spanned with [`Span::call_site()`]. 168 /// 169 /// [`Span::call_site()`]: proc_macro2::Span::call_site 170 /// 171 /// A different span can be provided through the [`quote_spanned!`] macro. 172 /// 173 /// <br> 174 /// 175 /// # Return type 176 /// 177 /// The macro evaluates to an expression of type `proc_macro2::TokenStream`. 178 /// Meanwhile Rust procedural macros are expected to return the type 179 /// `proc_macro::TokenStream`. 180 /// 181 /// The difference between the two types is that `proc_macro` types are entirely 182 /// specific to procedural macros and cannot ever exist in code outside of a 183 /// procedural macro, while `proc_macro2` types may exist anywhere including 184 /// tests and non-macro code like main.rs and build.rs. This is why even the 185 /// procedural macro ecosystem is largely built around `proc_macro2`, because 186 /// that ensures the libraries are unit testable and accessible in non-macro 187 /// contexts. 188 /// 189 /// There is a [`From`]-conversion in both directions so returning the output of 190 /// `quote!` from a procedural macro usually looks like `tokens.into()` or 191 /// `proc_macro::TokenStream::from(tokens)`. 192 /// 193 /// <br> 194 /// 195 /// # Examples 196 /// 197 /// ### Procedural macro 198 /// 199 /// The structure of a basic procedural macro is as follows. Refer to the [Syn] 200 /// crate for further useful guidance on using `quote!` as part of a procedural 201 /// macro. 202 /// 203 /// [Syn]: https://github.com/dtolnay/syn 204 /// 205 /// ``` 206 /// # #[cfg(any())] 207 /// extern crate proc_macro; 208 /// # extern crate proc_macro2; 209 /// 210 /// # #[cfg(any())] 211 /// use proc_macro::TokenStream; 212 /// # use proc_macro2::TokenStream; 213 /// use quote::quote; 214 /// 215 /// # const IGNORE_TOKENS: &'static str = stringify! { 216 /// #[proc_macro_derive(HeapSize)] 217 /// # }; 218 /// pub fn derive_heap_size(input: TokenStream) -> TokenStream { 219 /// // Parse the input and figure out what implementation to generate... 220 /// # const IGNORE_TOKENS: &'static str = stringify! { 221 /// let name = /* ... */; 222 /// let expr = /* ... */; 223 /// # }; 224 /// # 225 /// # let name = 0; 226 /// # let expr = 0; 227 /// 228 /// let expanded = quote! { 229 /// // The generated impl. 230 /// impl heapsize::HeapSize for #name { 231 /// fn heap_size_of_children(&self) -> usize { 232 /// #expr 233 /// } 234 /// } 235 /// }; 236 /// 237 /// // Hand the output tokens back to the compiler. 238 /// TokenStream::from(expanded) 239 /// } 240 /// ``` 241 /// 242 /// <p><br></p> 243 /// 244 /// ### Combining quoted fragments 245 /// 246 /// Usually you don't end up constructing an entire final `TokenStream` in one 247 /// piece. Different parts may come from different helper functions. The tokens 248 /// produced by `quote!` themselves implement `ToTokens` and so can be 249 /// interpolated into later `quote!` invocations to build up a final result. 250 /// 251 /// ``` 252 /// # use quote::quote; 253 /// # 254 /// let type_definition = quote! {...}; 255 /// let methods = quote! {...}; 256 /// 257 /// let tokens = quote! { 258 /// #type_definition 259 /// #methods 260 /// }; 261 /// ``` 262 /// 263 /// <p><br></p> 264 /// 265 /// ### Constructing identifiers 266 /// 267 /// Suppose we have an identifier `ident` which came from somewhere in a macro 268 /// input and we need to modify it in some way for the macro output. Let's 269 /// consider prepending the identifier with an underscore. 270 /// 271 /// Simply interpolating the identifier next to an underscore will not have the 272 /// behavior of concatenating them. The underscore and the identifier will 273 /// continue to be two separate tokens as if you had written `_ x`. 274 /// 275 /// ``` 276 /// # use proc_macro2::{self as syn, Span}; 277 /// # use quote::quote; 278 /// # 279 /// # let ident = syn::Ident::new("i", Span::call_site()); 280 /// # 281 /// // incorrect 282 /// quote! { 283 /// let mut _#ident = 0; 284 /// } 285 /// # ; 286 /// ``` 287 /// 288 /// The solution is to build a new identifier token with the correct value. As 289 /// this is such a common case, the [`format_ident!`] macro provides a 290 /// convenient utility for doing so correctly. 291 /// 292 /// ``` 293 /// # use proc_macro2::{Ident, Span}; 294 /// # use quote::{format_ident, quote}; 295 /// # 296 /// # let ident = Ident::new("i", Span::call_site()); 297 /// # 298 /// let varname = format_ident!("_{}", ident); 299 /// quote! { 300 /// let mut #varname = 0; 301 /// } 302 /// # ; 303 /// ``` 304 /// 305 /// Alternatively, the APIs provided by Syn and proc-macro2 can be used to 306 /// directly build the identifier. This is roughly equivalent to the above, but 307 /// will not handle `ident` being a raw identifier. 308 /// 309 /// ``` 310 /// # use proc_macro2::{self as syn, Span}; 311 /// # use quote::quote; 312 /// # 313 /// # let ident = syn::Ident::new("i", Span::call_site()); 314 /// # 315 /// let concatenated = format!("_{}", ident); 316 /// let varname = syn::Ident::new(&concatenated, ident.span()); 317 /// quote! { 318 /// let mut #varname = 0; 319 /// } 320 /// # ; 321 /// ``` 322 /// 323 /// <p><br></p> 324 /// 325 /// ### Making method calls 326 /// 327 /// Let's say our macro requires some type specified in the macro input to have 328 /// a constructor called `new`. We have the type in a variable called 329 /// `field_type` of type `syn::Type` and want to invoke the constructor. 330 /// 331 /// ``` 332 /// # use quote::quote; 333 /// # 334 /// # let field_type = quote!(...); 335 /// # 336 /// // incorrect 337 /// quote! { 338 /// let value = #field_type::new(); 339 /// } 340 /// # ; 341 /// ``` 342 /// 343 /// This works only sometimes. If `field_type` is `String`, the expanded code 344 /// contains `String::new()` which is fine. But if `field_type` is something 345 /// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid 346 /// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()` 347 /// but for macros often the following is more convenient. 348 /// 349 /// ``` 350 /// # use quote::quote; 351 /// # 352 /// # let field_type = quote!(...); 353 /// # 354 /// quote! { 355 /// let value = <#field_type>::new(); 356 /// } 357 /// # ; 358 /// ``` 359 /// 360 /// This expands to `<Vec<i32>>::new()` which behaves correctly. 361 /// 362 /// A similar pattern is appropriate for trait methods. 363 /// 364 /// ``` 365 /// # use quote::quote; 366 /// # 367 /// # let field_type = quote!(...); 368 /// # 369 /// quote! { 370 /// let value = <#field_type as core::default::Default>::default(); 371 /// } 372 /// # ; 373 /// ``` 374 /// 375 /// <p><br></p> 376 /// 377 /// ### Interpolating text inside of doc comments 378 /// 379 /// Neither doc comments nor string literals get interpolation behavior in 380 /// quote: 381 /// 382 /// ```compile_fail 383 /// quote! { 384 /// /// try to interpolate: #ident 385 /// /// 386 /// /// ... 387 /// } 388 /// ``` 389 /// 390 /// ```compile_fail 391 /// quote! { 392 /// #[doc = "try to interpolate: #ident"] 393 /// } 394 /// ``` 395 /// 396 /// Instead the best way to build doc comments that involve variables is by 397 /// formatting the doc string literal outside of quote. 398 /// 399 /// ```rust 400 /// # use proc_macro2::{Ident, Span}; 401 /// # use quote::quote; 402 /// # 403 /// # const IGNORE: &str = stringify! { 404 /// let msg = format!(...); 405 /// # }; 406 /// # 407 /// # let ident = Ident::new("var", Span::call_site()); 408 /// # let msg = format!("try to interpolate: {}", ident); 409 /// quote! { 410 /// #[doc = #msg] 411 /// /// 412 /// /// ... 413 /// } 414 /// # ; 415 /// ``` 416 /// 417 /// <p><br></p> 418 /// 419 /// ### Indexing into a tuple struct 420 /// 421 /// When interpolating indices of a tuple or tuple struct, we need them not to 422 /// appears suffixed as integer literals by interpolating them as [`syn::Index`] 423 /// instead. 424 /// 425 /// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html 426 /// 427 /// ```compile_fail 428 /// let i = 0usize..self.fields.len(); 429 /// 430 /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ... 431 /// // which is not valid syntax 432 /// quote! { 433 /// 0 #( + self.#i.heap_size() )* 434 /// } 435 /// ``` 436 /// 437 /// ``` 438 /// # use proc_macro2::{Ident, TokenStream}; 439 /// # use quote::quote; 440 /// # 441 /// # mod syn { 442 /// # use proc_macro2::{Literal, TokenStream}; 443 /// # use quote::{ToTokens, TokenStreamExt}; 444 /// # 445 /// # pub struct Index(usize); 446 /// # 447 /// # impl From<usize> for Index { 448 /// # fn from(i: usize) -> Self { 449 /// # Index(i) 450 /// # } 451 /// # } 452 /// # 453 /// # impl ToTokens for Index { 454 /// # fn to_tokens(&self, tokens: &mut TokenStream) { 455 /// # tokens.append(Literal::usize_unsuffixed(self.0)); 456 /// # } 457 /// # } 458 /// # } 459 /// # 460 /// # struct Struct { 461 /// # fields: Vec<Ident>, 462 /// # } 463 /// # 464 /// # impl Struct { 465 /// # fn example(&self) -> TokenStream { 466 /// let i = (0..self.fields.len()).map(syn::Index::from); 467 /// 468 /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ... 469 /// quote! { 470 /// 0 #( + self.#i.heap_size() )* 471 /// } 472 /// # } 473 /// # } 474 /// ``` 475 $quote 476 }; 477 } 478 479 #[cfg(doc)] 480 __quote![ 481 #[macro_export] 482 macro_rules! quote { 483 ($($tt:tt)*) => { 484 ... 485 }; 486 } 487 ]; 488 489 #[cfg(not(doc))] 490 __quote![ 491 #[macro_export] 492 macro_rules! quote { 493 () => { 494 $crate::__private::TokenStream::new() 495 }; 496 497 // Special case rule for a single tt, for performance. 498 ($tt:tt) => {{ 499 let mut _s = $crate::__private::TokenStream::new(); 500 $crate::quote_token!{$tt _s} 501 _s 502 }}; 503 504 // Special case rules for two tts, for performance. 505 (# $var:ident) => {{ 506 let mut _s = $crate::__private::TokenStream::new(); 507 $crate::ToTokens::to_tokens(&$var, &mut _s); 508 _s 509 }}; 510 ($tt1:tt $tt2:tt) => {{ 511 let mut _s = $crate::__private::TokenStream::new(); 512 $crate::quote_token!{$tt1 _s} 513 $crate::quote_token!{$tt2 _s} 514 _s 515 }}; 516 517 // Rule for any other number of tokens. 518 ($($tt:tt)*) => {{ 519 let mut _s = $crate::__private::TokenStream::new(); 520 $crate::quote_each_token!{_s $($tt)*} 521 _s 522 }}; 523 } 524 ]; 525 526 macro_rules! __quote_spanned { 527 ($quote_spanned:item) => { 528 /// Same as `quote!`, but applies a given span to all tokens originating within 529 /// the macro invocation. 530 /// 531 /// <br> 532 /// 533 /// # Syntax 534 /// 535 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens 536 /// to quote. The span expression should be brief — use a variable for 537 /// anything more than a few characters. There should be no space before the 538 /// `=>` token. 539 /// 540 /// [`Span`]: proc_macro2::Span 541 /// 542 /// ``` 543 /// # use proc_macro2::Span; 544 /// # use quote::quote_spanned; 545 /// # 546 /// # const IGNORE_TOKENS: &'static str = stringify! { 547 /// let span = /* ... */; 548 /// # }; 549 /// # let span = Span::call_site(); 550 /// # let init = 0; 551 /// 552 /// // On one line, use parentheses. 553 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init))); 554 /// 555 /// // On multiple lines, place the span at the top and use braces. 556 /// let tokens = quote_spanned! {span=> 557 /// Box::into_raw(Box::new(#init)) 558 /// }; 559 /// ``` 560 /// 561 /// The lack of space before the `=>` should look jarring to Rust programmers 562 /// and this is intentional. The formatting is designed to be visibly 563 /// off-balance and draw the eye a particular way, due to the span expression 564 /// being evaluated in the context of the procedural macro and the remaining 565 /// tokens being evaluated in the generated code. 566 /// 567 /// <br> 568 /// 569 /// # Hygiene 570 /// 571 /// Any interpolated tokens preserve the `Span` information provided by their 572 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!` 573 /// invocation are spanned with the given span argument. 574 /// 575 /// <br> 576 /// 577 /// # Example 578 /// 579 /// The following procedural macro code uses `quote_spanned!` to assert that a 580 /// particular Rust type implements the [`Sync`] trait so that references can be 581 /// safely shared between threads. 582 /// 583 /// ``` 584 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens}; 585 /// # use proc_macro2::{Span, TokenStream}; 586 /// # 587 /// # struct Type; 588 /// # 589 /// # impl Type { 590 /// # fn span(&self) -> Span { 591 /// # Span::call_site() 592 /// # } 593 /// # } 594 /// # 595 /// # impl ToTokens for Type { 596 /// # fn to_tokens(&self, _tokens: &mut TokenStream) {} 597 /// # } 598 /// # 599 /// # let ty = Type; 600 /// # let call_site = Span::call_site(); 601 /// # 602 /// let ty_span = ty.span(); 603 /// let assert_sync = quote_spanned! {ty_span=> 604 /// struct _AssertSync where #ty: Sync; 605 /// }; 606 /// ``` 607 /// 608 /// If the assertion fails, the user will see an error like the following. The 609 /// input span of their type is highlighted in the error. 610 /// 611 /// ```text 612 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied 613 /// --> src/main.rs:10:21 614 /// | 615 /// 10 | static ref PTR: *const () = &(); 616 /// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely 617 /// ``` 618 /// 619 /// In this example it is important for the where-clause to be spanned with the 620 /// line/column information of the user's input type so that error messages are 621 /// placed appropriately by the compiler. 622 $quote_spanned 623 }; 624 } 625 626 #[cfg(doc)] 627 __quote_spanned![ 628 #[macro_export] 629 macro_rules! quote_spanned { 630 ($span:expr=> $($tt:tt)*) => { 631 ... 632 }; 633 } 634 ]; 635 636 #[cfg(not(doc))] 637 __quote_spanned![ 638 #[macro_export] 639 macro_rules! quote_spanned { 640 ($span:expr=>) => {{ 641 let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); 642 $crate::__private::TokenStream::new() 643 }}; 644 645 // Special case rule for a single tt, for performance. 646 ($span:expr=> $tt:tt) => {{ 647 let mut _s = $crate::__private::TokenStream::new(); 648 let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); 649 $crate::quote_token_spanned!{$tt _s _span} 650 _s 651 }}; 652 653 // Special case rules for two tts, for performance. 654 ($span:expr=> # $var:ident) => {{ 655 let mut _s = $crate::__private::TokenStream::new(); 656 let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); 657 $crate::ToTokens::to_tokens(&$var, &mut _s); 658 _s 659 }}; 660 ($span:expr=> $tt1:tt $tt2:tt) => {{ 661 let mut _s = $crate::__private::TokenStream::new(); 662 let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); 663 $crate::quote_token_spanned!{$tt1 _s _span} 664 $crate::quote_token_spanned!{$tt2 _s _span} 665 _s 666 }}; 667 668 // Rule for any other number of tokens. 669 ($span:expr=> $($tt:tt)*) => {{ 670 let mut _s = $crate::__private::TokenStream::new(); 671 let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); 672 $crate::quote_each_token_spanned!{_s _span $($tt)*} 673 _s 674 }}; 675 } 676 ]; 677 678 // Extract the names of all #metavariables and pass them to the $call macro. 679 // 680 // in: pounded_var_names!(then!(...) a #b c #( #d )* #e) 681 // out: then!(... b); 682 // then!(... d); 683 // then!(... e); 684 #[macro_export] 685 #[doc(hidden)] 686 macro_rules! pounded_var_names { 687 ($call:ident! $extra:tt $($tts:tt)*) => { 688 $crate::pounded_var_names_with_context!{$call! $extra 689 (@ $($tts)*) 690 ($($tts)* @) 691 } 692 }; 693 } 694 695 #[macro_export] 696 #[doc(hidden)] 697 macro_rules! pounded_var_names_with_context { 698 ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => { 699 $( 700 $crate::pounded_var_with_context!{$call! $extra $b1 $curr} 701 )* 702 }; 703 } 704 705 #[macro_export] 706 #[doc(hidden)] 707 macro_rules! pounded_var_with_context { 708 ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => { 709 $crate::pounded_var_names!{$call! $extra $($inner)*} 710 }; 711 712 ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => { 713 $crate::pounded_var_names!{$call! $extra $($inner)*} 714 }; 715 716 ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => { 717 $crate::pounded_var_names!{$call! $extra $($inner)*} 718 }; 719 720 ($call:ident!($($extra:tt)*) # $var:ident) => { 721 $crate::$call!($($extra)* $var); 722 }; 723 724 ($call:ident! $extra:tt $b1:tt $curr:tt) => {}; 725 } 726 727 #[macro_export] 728 #[doc(hidden)] 729 macro_rules! quote_bind_into_iter { 730 ($has_iter:ident $var:ident) => { 731 // `mut` may be unused if $var occurs multiple times in the list. 732 #[allow(unused_mut)] 733 let (mut $var, i) = $var.quote_into_iter(); 734 let $has_iter = $has_iter | i; 735 }; 736 } 737 738 #[macro_export] 739 #[doc(hidden)] 740 macro_rules! quote_bind_next_or_break { 741 ($var:ident) => { 742 let $var = match $var.next() { 743 Some(_x) => $crate::__private::RepInterp(_x), 744 None => break, 745 }; 746 }; 747 } 748 749 // The obvious way to write this macro is as a tt muncher. This implementation 750 // does something more complex for two reasons. 751 // 752 // - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which 753 // this implementation avoids because it isn't tail recursive. 754 // 755 // - Compile times for a tt muncher are quadratic relative to the length of 756 // the input. This implementation is linear, so it will be faster 757 // (potentially much faster) for big inputs. However, the constant factors 758 // of this implementation are higher than that of a tt muncher, so it is 759 // somewhat slower than a tt muncher if there are many invocations with 760 // short inputs. 761 // 762 // An invocation like this: 763 // 764 // quote_each_token!(_s a b c d e f g h i j); 765 // 766 // expands to this: 767 // 768 // quote_tokens_with_context!(_s 769 // (@ @ @ @ @ @ a b c d e f g h i j) 770 // (@ @ @ @ @ a b c d e f g h i j @) 771 // (@ @ @ @ a b c d e f g h i j @ @) 772 // (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @) 773 // (@ @ a b c d e f g h i j @ @ @ @) 774 // (@ a b c d e f g h i j @ @ @ @ @) 775 // (a b c d e f g h i j @ @ @ @ @ @) 776 // ); 777 // 778 // which gets transposed and expanded to this: 779 // 780 // quote_token_with_context!(_s @ @ @ @ @ @ a); 781 // quote_token_with_context!(_s @ @ @ @ @ a b); 782 // quote_token_with_context!(_s @ @ @ @ a b c); 783 // quote_token_with_context!(_s @ @ @ (a) b c d); 784 // quote_token_with_context!(_s @ @ a (b) c d e); 785 // quote_token_with_context!(_s @ a b (c) d e f); 786 // quote_token_with_context!(_s a b c (d) e f g); 787 // quote_token_with_context!(_s b c d (e) f g h); 788 // quote_token_with_context!(_s c d e (f) g h i); 789 // quote_token_with_context!(_s d e f (g) h i j); 790 // quote_token_with_context!(_s e f g (h) i j @); 791 // quote_token_with_context!(_s f g h (i) j @ @); 792 // quote_token_with_context!(_s g h i (j) @ @ @); 793 // quote_token_with_context!(_s h i j @ @ @ @); 794 // quote_token_with_context!(_s i j @ @ @ @ @); 795 // quote_token_with_context!(_s j @ @ @ @ @ @); 796 // 797 // Without having used muncher-style recursion, we get one invocation of 798 // quote_token_with_context for each original tt, with three tts of context on 799 // either side. This is enough for the longest possible interpolation form (a 800 // repetition with separator, as in `# (#var) , *`) to be fully represented with 801 // the first or last tt in the middle. 802 // 803 // The middle tt (surrounded by parentheses) is the tt being processed. 804 // 805 // - When it is a `#`, quote_token_with_context can do an interpolation. The 806 // interpolation kind will depend on the three subsequent tts. 807 // 808 // - When it is within a later part of an interpolation, it can be ignored 809 // because the interpolation has already been done. 810 // 811 // - When it is not part of an interpolation it can be pushed as a single 812 // token into the output. 813 // 814 // - When the middle token is an unparenthesized `@`, that call is one of the 815 // first 3 or last 3 calls of quote_token_with_context and does not 816 // correspond to one of the original input tokens, so turns into nothing. 817 #[macro_export] 818 #[doc(hidden)] 819 macro_rules! quote_each_token { 820 ($tokens:ident $($tts:tt)*) => { 821 $crate::quote_tokens_with_context!{$tokens 822 (@ @ @ @ @ @ $($tts)*) 823 (@ @ @ @ @ $($tts)* @) 824 (@ @ @ @ $($tts)* @ @) 825 (@ @ @ $(($tts))* @ @ @) 826 (@ @ $($tts)* @ @ @ @) 827 (@ $($tts)* @ @ @ @ @) 828 ($($tts)* @ @ @ @ @ @) 829 } 830 }; 831 } 832 833 // See the explanation on quote_each_token. 834 #[macro_export] 835 #[doc(hidden)] 836 macro_rules! quote_each_token_spanned { 837 ($tokens:ident $span:ident $($tts:tt)*) => { 838 $crate::quote_tokens_with_context_spanned!{$tokens $span 839 (@ @ @ @ @ @ $($tts)*) 840 (@ @ @ @ @ $($tts)* @) 841 (@ @ @ @ $($tts)* @ @) 842 (@ @ @ $(($tts))* @ @ @) 843 (@ @ $($tts)* @ @ @ @) 844 (@ $($tts)* @ @ @ @ @) 845 ($($tts)* @ @ @ @ @ @) 846 } 847 }; 848 } 849 850 // See the explanation on quote_each_token. 851 #[macro_export] 852 #[doc(hidden)] 853 macro_rules! quote_tokens_with_context { 854 ($tokens:ident 855 ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) 856 ($($curr:tt)*) 857 ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) 858 ) => { 859 $( 860 $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3} 861 )* 862 }; 863 } 864 865 // See the explanation on quote_each_token. 866 #[macro_export] 867 #[doc(hidden)] 868 macro_rules! quote_tokens_with_context_spanned { 869 ($tokens:ident $span:ident 870 ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) 871 ($($curr:tt)*) 872 ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) 873 ) => { 874 $( 875 $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3} 876 )* 877 }; 878 } 879 880 // See the explanation on quote_each_token. 881 #[macro_export] 882 #[doc(hidden)] 883 macro_rules! quote_token_with_context { 884 // Unparenthesized `@` indicates this call does not correspond to one of the 885 // original input tokens. Ignore it. 886 ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; 887 888 // A repetition with no separator. 889 ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ 890 use $crate::__private::ext::*; 891 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 892 $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} 893 let _: $crate::__private::HasIterator = has_iter; 894 // This is `while true` instead of `loop` because if there are no 895 // iterators used inside of this repetition then the body would not 896 // contain any `break`, so the compiler would emit unreachable code 897 // warnings on anything below the loop. We use has_iter to detect and 898 // fail to compile when there are no iterators, so here we just work 899 // around the unneeded extra warning. 900 while true { 901 $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} 902 $crate::quote_each_token!{$tokens $($inner)*} 903 } 904 }}; 905 // ... and one step later. 906 ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; 907 // ... and one step later. 908 ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; 909 910 // A repetition with separator. 911 ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ 912 use $crate::__private::ext::*; 913 let mut _i = 0usize; 914 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 915 $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} 916 let _: $crate::__private::HasIterator = has_iter; 917 while true { 918 $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} 919 if _i > 0 { 920 $crate::quote_token!{$sep $tokens} 921 } 922 _i += 1; 923 $crate::quote_each_token!{$tokens $($inner)*} 924 } 925 }}; 926 // ... and one step later. 927 ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; 928 // ... and one step later. 929 ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; 930 // (A special case for `#(var)**`, where the first `*` is treated as the 931 // repetition symbol and the second `*` is treated as an ordinary token.) 932 ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { 933 // https://github.com/dtolnay/quote/issues/130 934 $crate::quote_token!{* $tokens} 935 }; 936 // ... and one step later. 937 ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; 938 939 // A non-repetition interpolation. 940 ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { 941 $crate::ToTokens::to_tokens(&$var, &mut $tokens); 942 }; 943 // ... and one step later. 944 ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; 945 946 // An ordinary token, not part of any interpolation. 947 ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { 948 $crate::quote_token!{$curr $tokens} 949 }; 950 } 951 952 // See the explanation on quote_each_token, and on the individual rules of 953 // quote_token_with_context. 954 #[macro_export] 955 #[doc(hidden)] 956 macro_rules! quote_token_with_context_spanned { 957 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; 958 959 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ 960 use $crate::__private::ext::*; 961 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 962 $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} 963 let _: $crate::__private::HasIterator = has_iter; 964 while true { 965 $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} 966 $crate::quote_each_token_spanned!{$tokens $span $($inner)*} 967 } 968 }}; 969 ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; 970 ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; 971 972 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ 973 use $crate::__private::ext::*; 974 let mut _i = 0usize; 975 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 976 $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} 977 let _: $crate::__private::HasIterator = has_iter; 978 while true { 979 $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} 980 if _i > 0 { 981 $crate::quote_token_spanned!{$sep $tokens $span} 982 } 983 _i += 1; 984 $crate::quote_each_token_spanned!{$tokens $span $($inner)*} 985 } 986 }}; 987 ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; 988 ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; 989 ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { 990 // https://github.com/dtolnay/quote/issues/130 991 $crate::quote_token_spanned!{* $tokens $span} 992 }; 993 ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; 994 995 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { 996 $crate::ToTokens::to_tokens(&$var, &mut $tokens); 997 }; 998 ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; 999 1000 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { 1001 $crate::quote_token_spanned!{$curr $tokens $span} 1002 }; 1003 } 1004 1005 // These rules are ordered by approximate token frequency, at least for the 1006 // first 10 or so, to improve compile times. Having `ident` first is by far the 1007 // most important because it's typically 2-3x more common than the next most 1008 // common token. 1009 // 1010 // Separately, we put the token being matched in the very front so that failing 1011 // rules may fail to match as quickly as possible. 1012 #[macro_export] 1013 #[doc(hidden)] 1014 macro_rules! quote_token { 1015 ($ident:ident $tokens:ident) => { 1016 $crate::__private::push_ident(&mut $tokens, stringify!($ident)); 1017 }; 1018 1019 (:: $tokens:ident) => { 1020 $crate::__private::push_colon2(&mut $tokens); 1021 }; 1022 1023 (( $($inner:tt)* ) $tokens:ident) => { 1024 $crate::__private::push_group( 1025 &mut $tokens, 1026 $crate::__private::Delimiter::Parenthesis, 1027 $crate::quote!($($inner)*), 1028 ); 1029 }; 1030 1031 ([ $($inner:tt)* ] $tokens:ident) => { 1032 $crate::__private::push_group( 1033 &mut $tokens, 1034 $crate::__private::Delimiter::Bracket, 1035 $crate::quote!($($inner)*), 1036 ); 1037 }; 1038 1039 ({ $($inner:tt)* } $tokens:ident) => { 1040 $crate::__private::push_group( 1041 &mut $tokens, 1042 $crate::__private::Delimiter::Brace, 1043 $crate::quote!($($inner)*), 1044 ); 1045 }; 1046 1047 (# $tokens:ident) => { 1048 $crate::__private::push_pound(&mut $tokens); 1049 }; 1050 1051 (, $tokens:ident) => { 1052 $crate::__private::push_comma(&mut $tokens); 1053 }; 1054 1055 (. $tokens:ident) => { 1056 $crate::__private::push_dot(&mut $tokens); 1057 }; 1058 1059 (; $tokens:ident) => { 1060 $crate::__private::push_semi(&mut $tokens); 1061 }; 1062 1063 (: $tokens:ident) => { 1064 $crate::__private::push_colon(&mut $tokens); 1065 }; 1066 1067 (+ $tokens:ident) => { 1068 $crate::__private::push_add(&mut $tokens); 1069 }; 1070 1071 (+= $tokens:ident) => { 1072 $crate::__private::push_add_eq(&mut $tokens); 1073 }; 1074 1075 (& $tokens:ident) => { 1076 $crate::__private::push_and(&mut $tokens); 1077 }; 1078 1079 (&& $tokens:ident) => { 1080 $crate::__private::push_and_and(&mut $tokens); 1081 }; 1082 1083 (&= $tokens:ident) => { 1084 $crate::__private::push_and_eq(&mut $tokens); 1085 }; 1086 1087 (@ $tokens:ident) => { 1088 $crate::__private::push_at(&mut $tokens); 1089 }; 1090 1091 (! $tokens:ident) => { 1092 $crate::__private::push_bang(&mut $tokens); 1093 }; 1094 1095 (^ $tokens:ident) => { 1096 $crate::__private::push_caret(&mut $tokens); 1097 }; 1098 1099 (^= $tokens:ident) => { 1100 $crate::__private::push_caret_eq(&mut $tokens); 1101 }; 1102 1103 (/ $tokens:ident) => { 1104 $crate::__private::push_div(&mut $tokens); 1105 }; 1106 1107 (/= $tokens:ident) => { 1108 $crate::__private::push_div_eq(&mut $tokens); 1109 }; 1110 1111 (.. $tokens:ident) => { 1112 $crate::__private::push_dot2(&mut $tokens); 1113 }; 1114 1115 (... $tokens:ident) => { 1116 $crate::__private::push_dot3(&mut $tokens); 1117 }; 1118 1119 (..= $tokens:ident) => { 1120 $crate::__private::push_dot_dot_eq(&mut $tokens); 1121 }; 1122 1123 (= $tokens:ident) => { 1124 $crate::__private::push_eq(&mut $tokens); 1125 }; 1126 1127 (== $tokens:ident) => { 1128 $crate::__private::push_eq_eq(&mut $tokens); 1129 }; 1130 1131 (>= $tokens:ident) => { 1132 $crate::__private::push_ge(&mut $tokens); 1133 }; 1134 1135 (> $tokens:ident) => { 1136 $crate::__private::push_gt(&mut $tokens); 1137 }; 1138 1139 (<= $tokens:ident) => { 1140 $crate::__private::push_le(&mut $tokens); 1141 }; 1142 1143 (< $tokens:ident) => { 1144 $crate::__private::push_lt(&mut $tokens); 1145 }; 1146 1147 (*= $tokens:ident) => { 1148 $crate::__private::push_mul_eq(&mut $tokens); 1149 }; 1150 1151 (!= $tokens:ident) => { 1152 $crate::__private::push_ne(&mut $tokens); 1153 }; 1154 1155 (| $tokens:ident) => { 1156 $crate::__private::push_or(&mut $tokens); 1157 }; 1158 1159 (|= $tokens:ident) => { 1160 $crate::__private::push_or_eq(&mut $tokens); 1161 }; 1162 1163 (|| $tokens:ident) => { 1164 $crate::__private::push_or_or(&mut $tokens); 1165 }; 1166 1167 (? $tokens:ident) => { 1168 $crate::__private::push_question(&mut $tokens); 1169 }; 1170 1171 (-> $tokens:ident) => { 1172 $crate::__private::push_rarrow(&mut $tokens); 1173 }; 1174 1175 (<- $tokens:ident) => { 1176 $crate::__private::push_larrow(&mut $tokens); 1177 }; 1178 1179 (% $tokens:ident) => { 1180 $crate::__private::push_rem(&mut $tokens); 1181 }; 1182 1183 (%= $tokens:ident) => { 1184 $crate::__private::push_rem_eq(&mut $tokens); 1185 }; 1186 1187 (=> $tokens:ident) => { 1188 $crate::__private::push_fat_arrow(&mut $tokens); 1189 }; 1190 1191 (<< $tokens:ident) => { 1192 $crate::__private::push_shl(&mut $tokens); 1193 }; 1194 1195 (<<= $tokens:ident) => { 1196 $crate::__private::push_shl_eq(&mut $tokens); 1197 }; 1198 1199 (>> $tokens:ident) => { 1200 $crate::__private::push_shr(&mut $tokens); 1201 }; 1202 1203 (>>= $tokens:ident) => { 1204 $crate::__private::push_shr_eq(&mut $tokens); 1205 }; 1206 1207 (* $tokens:ident) => { 1208 $crate::__private::push_star(&mut $tokens); 1209 }; 1210 1211 (- $tokens:ident) => { 1212 $crate::__private::push_sub(&mut $tokens); 1213 }; 1214 1215 (-= $tokens:ident) => { 1216 $crate::__private::push_sub_eq(&mut $tokens); 1217 }; 1218 1219 ($lifetime:lifetime $tokens:ident) => { 1220 $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime)); 1221 }; 1222 1223 (_ $tokens:ident) => { 1224 $crate::__private::push_underscore(&mut $tokens); 1225 }; 1226 1227 ($other:tt $tokens:ident) => { 1228 $crate::__private::parse(&mut $tokens, stringify!($other)); 1229 }; 1230 } 1231 1232 // See the comment above `quote_token!` about the rule ordering. 1233 #[macro_export] 1234 #[doc(hidden)] 1235 macro_rules! quote_token_spanned { 1236 ($ident:ident $tokens:ident $span:ident) => { 1237 $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident)); 1238 }; 1239 1240 (:: $tokens:ident $span:ident) => { 1241 $crate::__private::push_colon2_spanned(&mut $tokens, $span); 1242 }; 1243 1244 (( $($inner:tt)* ) $tokens:ident $span:ident) => { 1245 $crate::__private::push_group_spanned( 1246 &mut $tokens, 1247 $span, 1248 $crate::__private::Delimiter::Parenthesis, 1249 $crate::quote_spanned!($span=> $($inner)*), 1250 ); 1251 }; 1252 1253 ([ $($inner:tt)* ] $tokens:ident $span:ident) => { 1254 $crate::__private::push_group_spanned( 1255 &mut $tokens, 1256 $span, 1257 $crate::__private::Delimiter::Bracket, 1258 $crate::quote_spanned!($span=> $($inner)*), 1259 ); 1260 }; 1261 1262 ({ $($inner:tt)* } $tokens:ident $span:ident) => { 1263 $crate::__private::push_group_spanned( 1264 &mut $tokens, 1265 $span, 1266 $crate::__private::Delimiter::Brace, 1267 $crate::quote_spanned!($span=> $($inner)*), 1268 ); 1269 }; 1270 1271 (# $tokens:ident $span:ident) => { 1272 $crate::__private::push_pound_spanned(&mut $tokens, $span); 1273 }; 1274 1275 (, $tokens:ident $span:ident) => { 1276 $crate::__private::push_comma_spanned(&mut $tokens, $span); 1277 }; 1278 1279 (. $tokens:ident $span:ident) => { 1280 $crate::__private::push_dot_spanned(&mut $tokens, $span); 1281 }; 1282 1283 (; $tokens:ident $span:ident) => { 1284 $crate::__private::push_semi_spanned(&mut $tokens, $span); 1285 }; 1286 1287 (: $tokens:ident $span:ident) => { 1288 $crate::__private::push_colon_spanned(&mut $tokens, $span); 1289 }; 1290 1291 (+ $tokens:ident $span:ident) => { 1292 $crate::__private::push_add_spanned(&mut $tokens, $span); 1293 }; 1294 1295 (+= $tokens:ident $span:ident) => { 1296 $crate::__private::push_add_eq_spanned(&mut $tokens, $span); 1297 }; 1298 1299 (& $tokens:ident $span:ident) => { 1300 $crate::__private::push_and_spanned(&mut $tokens, $span); 1301 }; 1302 1303 (&& $tokens:ident $span:ident) => { 1304 $crate::__private::push_and_and_spanned(&mut $tokens, $span); 1305 }; 1306 1307 (&= $tokens:ident $span:ident) => { 1308 $crate::__private::push_and_eq_spanned(&mut $tokens, $span); 1309 }; 1310 1311 (@ $tokens:ident $span:ident) => { 1312 $crate::__private::push_at_spanned(&mut $tokens, $span); 1313 }; 1314 1315 (! $tokens:ident $span:ident) => { 1316 $crate::__private::push_bang_spanned(&mut $tokens, $span); 1317 }; 1318 1319 (^ $tokens:ident $span:ident) => { 1320 $crate::__private::push_caret_spanned(&mut $tokens, $span); 1321 }; 1322 1323 (^= $tokens:ident $span:ident) => { 1324 $crate::__private::push_caret_eq_spanned(&mut $tokens, $span); 1325 }; 1326 1327 (/ $tokens:ident $span:ident) => { 1328 $crate::__private::push_div_spanned(&mut $tokens, $span); 1329 }; 1330 1331 (/= $tokens:ident $span:ident) => { 1332 $crate::__private::push_div_eq_spanned(&mut $tokens, $span); 1333 }; 1334 1335 (.. $tokens:ident $span:ident) => { 1336 $crate::__private::push_dot2_spanned(&mut $tokens, $span); 1337 }; 1338 1339 (... $tokens:ident $span:ident) => { 1340 $crate::__private::push_dot3_spanned(&mut $tokens, $span); 1341 }; 1342 1343 (..= $tokens:ident $span:ident) => { 1344 $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span); 1345 }; 1346 1347 (= $tokens:ident $span:ident) => { 1348 $crate::__private::push_eq_spanned(&mut $tokens, $span); 1349 }; 1350 1351 (== $tokens:ident $span:ident) => { 1352 $crate::__private::push_eq_eq_spanned(&mut $tokens, $span); 1353 }; 1354 1355 (>= $tokens:ident $span:ident) => { 1356 $crate::__private::push_ge_spanned(&mut $tokens, $span); 1357 }; 1358 1359 (> $tokens:ident $span:ident) => { 1360 $crate::__private::push_gt_spanned(&mut $tokens, $span); 1361 }; 1362 1363 (<= $tokens:ident $span:ident) => { 1364 $crate::__private::push_le_spanned(&mut $tokens, $span); 1365 }; 1366 1367 (< $tokens:ident $span:ident) => { 1368 $crate::__private::push_lt_spanned(&mut $tokens, $span); 1369 }; 1370 1371 (*= $tokens:ident $span:ident) => { 1372 $crate::__private::push_mul_eq_spanned(&mut $tokens, $span); 1373 }; 1374 1375 (!= $tokens:ident $span:ident) => { 1376 $crate::__private::push_ne_spanned(&mut $tokens, $span); 1377 }; 1378 1379 (| $tokens:ident $span:ident) => { 1380 $crate::__private::push_or_spanned(&mut $tokens, $span); 1381 }; 1382 1383 (|= $tokens:ident $span:ident) => { 1384 $crate::__private::push_or_eq_spanned(&mut $tokens, $span); 1385 }; 1386 1387 (|| $tokens:ident $span:ident) => { 1388 $crate::__private::push_or_or_spanned(&mut $tokens, $span); 1389 }; 1390 1391 (? $tokens:ident $span:ident) => { 1392 $crate::__private::push_question_spanned(&mut $tokens, $span); 1393 }; 1394 1395 (-> $tokens:ident $span:ident) => { 1396 $crate::__private::push_rarrow_spanned(&mut $tokens, $span); 1397 }; 1398 1399 (<- $tokens:ident $span:ident) => { 1400 $crate::__private::push_larrow_spanned(&mut $tokens, $span); 1401 }; 1402 1403 (% $tokens:ident $span:ident) => { 1404 $crate::__private::push_rem_spanned(&mut $tokens, $span); 1405 }; 1406 1407 (%= $tokens:ident $span:ident) => { 1408 $crate::__private::push_rem_eq_spanned(&mut $tokens, $span); 1409 }; 1410 1411 (=> $tokens:ident $span:ident) => { 1412 $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span); 1413 }; 1414 1415 (<< $tokens:ident $span:ident) => { 1416 $crate::__private::push_shl_spanned(&mut $tokens, $span); 1417 }; 1418 1419 (<<= $tokens:ident $span:ident) => { 1420 $crate::__private::push_shl_eq_spanned(&mut $tokens, $span); 1421 }; 1422 1423 (>> $tokens:ident $span:ident) => { 1424 $crate::__private::push_shr_spanned(&mut $tokens, $span); 1425 }; 1426 1427 (>>= $tokens:ident $span:ident) => { 1428 $crate::__private::push_shr_eq_spanned(&mut $tokens, $span); 1429 }; 1430 1431 (* $tokens:ident $span:ident) => { 1432 $crate::__private::push_star_spanned(&mut $tokens, $span); 1433 }; 1434 1435 (- $tokens:ident $span:ident) => { 1436 $crate::__private::push_sub_spanned(&mut $tokens, $span); 1437 }; 1438 1439 (-= $tokens:ident $span:ident) => { 1440 $crate::__private::push_sub_eq_spanned(&mut $tokens, $span); 1441 }; 1442 1443 ($lifetime:lifetime $tokens:ident $span:ident) => { 1444 $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime)); 1445 }; 1446 1447 (_ $tokens:ident $span:ident) => { 1448 $crate::__private::push_underscore_spanned(&mut $tokens, $span); 1449 }; 1450 1451 ($other:tt $tokens:ident $span:ident) => { 1452 $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other)); 1453 }; 1454 } 1455