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