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