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