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&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K 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.15")] 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 /// Macro calls in a doc attribute are not valid syntax: 393 /// 394 /// ```compile_fail 395 /// quote! { 396 /// #[doc = concat!("try to interpolate: ", stringify!(#ident))] 397 /// } 398 /// ``` 399 /// 400 /// Instead the best way to build doc comments that involve variables is by 401 /// formatting the doc string literal outside of quote. 402 /// 403 /// ```rust 404 /// # use proc_macro2::{Ident, Span}; 405 /// # use quote::quote; 406 /// # 407 /// # const IGNORE: &str = stringify! { 408 /// let msg = format!(...); 409 /// # }; 410 /// # 411 /// # let ident = Ident::new("var", Span::call_site()); 412 /// # let msg = format!("try to interpolate: {}", ident); 413 /// quote! { 414 /// #[doc = #msg] 415 /// /// 416 /// /// ... 417 /// } 418 /// # ; 419 /// ``` 420 /// 421 /// <p><br></p> 422 /// 423 /// ### Indexing into a tuple struct 424 /// 425 /// When interpolating indices of a tuple or tuple struct, we need them not to 426 /// appears suffixed as integer literals by interpolating them as [`syn::Index`] 427 /// instead. 428 /// 429 /// [`syn::Index`]: https://docs.rs/syn/1.0/syn/struct.Index.html 430 /// 431 /// ```compile_fail 432 /// let i = 0usize..self.fields.len(); 433 /// 434 /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ... 435 /// // which is not valid syntax 436 /// quote! { 437 /// 0 #( + self.#i.heap_size() )* 438 /// } 439 /// ``` 440 /// 441 /// ``` 442 /// # use proc_macro2::{Ident, TokenStream}; 443 /// # use quote::quote; 444 /// # 445 /// # mod syn { 446 /// # use proc_macro2::{Literal, TokenStream}; 447 /// # use quote::{ToTokens, TokenStreamExt}; 448 /// # 449 /// # pub struct Index(usize); 450 /// # 451 /// # impl From<usize> for Index { 452 /// # fn from(i: usize) -> Self { 453 /// # Index(i) 454 /// # } 455 /// # } 456 /// # 457 /// # impl ToTokens for Index { 458 /// # fn to_tokens(&self, tokens: &mut TokenStream) { 459 /// # tokens.append(Literal::usize_unsuffixed(self.0)); 460 /// # } 461 /// # } 462 /// # } 463 /// # 464 /// # struct Struct { 465 /// # fields: Vec<Ident>, 466 /// # } 467 /// # 468 /// # impl Struct { 469 /// # fn example(&self) -> TokenStream { 470 /// let i = (0..self.fields.len()).map(syn::Index::from); 471 /// 472 /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ... 473 /// quote! { 474 /// 0 #( + self.#i.heap_size() )* 475 /// } 476 /// # } 477 /// # } 478 /// ``` 479 #[macro_export] 480 macro_rules! quote { 481 () => { 482 $crate::__private::TokenStream::new() 483 }; 484 ($($tt:tt)*) => {{ 485 let mut _s = $crate::__private::TokenStream::new(); 486 $crate::quote_each_token!(_s $($tt)*); 487 _s 488 }}; 489 } 490 491 /// Same as `quote!`, but applies a given span to all tokens originating within 492 /// the macro invocation. 493 /// 494 /// <br> 495 /// 496 /// # Syntax 497 /// 498 /// A span expression of type [`Span`], followed by `=>`, followed by the tokens 499 /// to quote. The span expression should be brief — use a variable for 500 /// anything more than a few characters. There should be no space before the 501 /// `=>` token. 502 /// 503 /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html 504 /// 505 /// ``` 506 /// # use proc_macro2::Span; 507 /// # use quote::quote_spanned; 508 /// # 509 /// # const IGNORE_TOKENS: &'static str = stringify! { 510 /// let span = /* ... */; 511 /// # }; 512 /// # let span = Span::call_site(); 513 /// # let init = 0; 514 /// 515 /// // On one line, use parentheses. 516 /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init))); 517 /// 518 /// // On multiple lines, place the span at the top and use braces. 519 /// let tokens = quote_spanned! {span=> 520 /// Box::into_raw(Box::new(#init)) 521 /// }; 522 /// ``` 523 /// 524 /// The lack of space before the `=>` should look jarring to Rust programmers 525 /// and this is intentional. The formatting is designed to be visibly 526 /// off-balance and draw the eye a particular way, due to the span expression 527 /// being evaluated in the context of the procedural macro and the remaining 528 /// tokens being evaluated in the generated code. 529 /// 530 /// <br> 531 /// 532 /// # Hygiene 533 /// 534 /// Any interpolated tokens preserve the `Span` information provided by their 535 /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!` 536 /// invocation are spanned with the given span argument. 537 /// 538 /// <br> 539 /// 540 /// # Example 541 /// 542 /// The following procedural macro code uses `quote_spanned!` to assert that a 543 /// particular Rust type implements the [`Sync`] trait so that references can be 544 /// safely shared between threads. 545 /// 546 /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html 547 /// 548 /// ``` 549 /// # use quote::{quote_spanned, TokenStreamExt, ToTokens}; 550 /// # use proc_macro2::{Span, TokenStream}; 551 /// # 552 /// # struct Type; 553 /// # 554 /// # impl Type { 555 /// # fn span(&self) -> Span { 556 /// # Span::call_site() 557 /// # } 558 /// # } 559 /// # 560 /// # impl ToTokens for Type { 561 /// # fn to_tokens(&self, _tokens: &mut TokenStream) {} 562 /// # } 563 /// # 564 /// # let ty = Type; 565 /// # let call_site = Span::call_site(); 566 /// # 567 /// let ty_span = ty.span(); 568 /// let assert_sync = quote_spanned! {ty_span=> 569 /// struct _AssertSync where #ty: Sync; 570 /// }; 571 /// ``` 572 /// 573 /// If the assertion fails, the user will see an error like the following. The 574 /// input span of their type is highlighted in the error. 575 /// 576 /// ```text 577 /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied 578 /// --> src/main.rs:10:21 579 /// | 580 /// 10 | static ref PTR: *const () = &(); 581 /// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely 582 /// ``` 583 /// 584 /// In this example it is important for the where-clause to be spanned with the 585 /// line/column information of the user's input type so that error messages are 586 /// placed appropriately by the compiler. 587 #[macro_export] 588 macro_rules! quote_spanned { 589 ($span:expr=>) => {{ 590 let _: $crate::__private::Span = $span; 591 $crate::__private::TokenStream::new() 592 }}; 593 ($span:expr=> $($tt:tt)*) => {{ 594 let mut _s = $crate::__private::TokenStream::new(); 595 let _span: $crate::__private::Span = $span; 596 $crate::quote_each_token_spanned!(_s _span $($tt)*); 597 _s 598 }}; 599 } 600 601 // Extract the names of all #metavariables and pass them to the $call macro. 602 // 603 // in: pounded_var_names!(then!(...) a #b c #( #d )* #e) 604 // out: then!(... b); 605 // then!(... d); 606 // then!(... e); 607 #[macro_export] 608 #[doc(hidden)] 609 macro_rules! pounded_var_names { 610 ($call:ident! $extra:tt $($tts:tt)*) => { 611 $crate::pounded_var_names_with_context!($call! $extra 612 (@ $($tts)*) 613 ($($tts)* @) 614 ) 615 }; 616 } 617 618 #[macro_export] 619 #[doc(hidden)] 620 macro_rules! pounded_var_names_with_context { 621 ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => { 622 $( 623 $crate::pounded_var_with_context!($call! $extra $b1 $curr); 624 )* 625 }; 626 } 627 628 #[macro_export] 629 #[doc(hidden)] 630 macro_rules! pounded_var_with_context { 631 ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => { 632 $crate::pounded_var_names!($call! $extra $($inner)*); 633 }; 634 635 ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => { 636 $crate::pounded_var_names!($call! $extra $($inner)*); 637 }; 638 639 ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => { 640 $crate::pounded_var_names!($call! $extra $($inner)*); 641 }; 642 643 ($call:ident!($($extra:tt)*) # $var:ident) => { 644 $crate::$call!($($extra)* $var); 645 }; 646 647 ($call:ident! $extra:tt $b1:tt $curr:tt) => {}; 648 } 649 650 #[macro_export] 651 #[doc(hidden)] 652 macro_rules! quote_bind_into_iter { 653 ($has_iter:ident $var:ident) => { 654 // `mut` may be unused if $var occurs multiple times in the list. 655 #[allow(unused_mut)] 656 let (mut $var, i) = $var.quote_into_iter(); 657 let $has_iter = $has_iter | i; 658 }; 659 } 660 661 #[macro_export] 662 #[doc(hidden)] 663 macro_rules! quote_bind_next_or_break { 664 ($var:ident) => { 665 let $var = match $var.next() { 666 Some(_x) => $crate::__private::RepInterp(_x), 667 None => break, 668 }; 669 }; 670 } 671 672 #[macro_export] 673 #[doc(hidden)] 674 macro_rules! quote_each_token { 675 ($tokens:ident $($tts:tt)*) => { 676 $crate::quote_tokens_with_context!($tokens 677 (@ @ @ @ @ @ $($tts)*) 678 (@ @ @ @ @ $($tts)* @) 679 (@ @ @ @ $($tts)* @ @) 680 (@ @ @ $(($tts))* @ @ @) 681 (@ @ $($tts)* @ @ @ @) 682 (@ $($tts)* @ @ @ @ @) 683 ($($tts)* @ @ @ @ @ @) 684 ); 685 }; 686 } 687 688 #[macro_export] 689 #[doc(hidden)] 690 macro_rules! quote_each_token_spanned { 691 ($tokens:ident $span:ident $($tts:tt)*) => { 692 $crate::quote_tokens_with_context_spanned!($tokens $span 693 (@ @ @ @ @ @ $($tts)*) 694 (@ @ @ @ @ $($tts)* @) 695 (@ @ @ @ $($tts)* @ @) 696 (@ @ @ $(($tts))* @ @ @) 697 (@ @ $($tts)* @ @ @ @) 698 (@ $($tts)* @ @ @ @ @) 699 ($($tts)* @ @ @ @ @ @) 700 ); 701 }; 702 } 703 704 #[macro_export] 705 #[doc(hidden)] 706 macro_rules! quote_tokens_with_context { 707 ($tokens:ident 708 ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) 709 ($($curr:tt)*) 710 ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) 711 ) => { 712 $( 713 $crate::quote_token_with_context!($tokens $b3 $b2 $b1 $curr $a1 $a2 $a3); 714 )* 715 }; 716 } 717 718 #[macro_export] 719 #[doc(hidden)] 720 macro_rules! quote_tokens_with_context_spanned { 721 ($tokens:ident $span:ident 722 ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) 723 ($($curr:tt)*) 724 ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) 725 ) => { 726 $( 727 $crate::quote_token_with_context_spanned!($tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3); 728 )* 729 }; 730 } 731 732 #[macro_export] 733 #[doc(hidden)] 734 macro_rules! quote_token_with_context { 735 ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; 736 737 ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ 738 use $crate::__private::ext::*; 739 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 740 $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*); 741 let _: $crate::__private::HasIterator = has_iter; 742 // This is `while true` instead of `loop` because if there are no 743 // iterators used inside of this repetition then the body would not 744 // contain any `break`, so the compiler would emit unreachable code 745 // warnings on anything below the loop. We use has_iter to detect and 746 // fail to compile when there are no iterators, so here we just work 747 // around the unneeded extra warning. 748 // 749 // FIXME: temporariliy working around Clippy regression. 750 // https://github.com/rust-lang/rust-clippy/issues/7768 751 loop { 752 $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*); 753 $crate::quote_each_token!($tokens $($inner)*); 754 if false { 755 break; 756 } 757 } 758 }}; 759 ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; 760 ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; 761 762 ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ 763 use $crate::__private::ext::*; 764 let mut _i = 0usize; 765 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 766 $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*); 767 let _: $crate::__private::HasIterator = has_iter; 768 loop { 769 $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*); 770 if _i > 0 { 771 $crate::quote_token!($tokens $sep); 772 } 773 _i += 1; 774 $crate::quote_each_token!($tokens $($inner)*); 775 if false { 776 break; 777 } 778 } 779 }}; 780 ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; 781 ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; 782 ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { 783 // https://github.com/dtolnay/quote/issues/130 784 $crate::quote_token!($tokens *); 785 }; 786 ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; 787 788 ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { 789 $crate::ToTokens::to_tokens(&$var, &mut $tokens); 790 }; 791 ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; 792 ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { 793 $crate::quote_token!($tokens $curr); 794 }; 795 } 796 797 #[macro_export] 798 #[doc(hidden)] 799 macro_rules! quote_token_with_context_spanned { 800 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; 801 802 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ 803 use $crate::__private::ext::*; 804 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 805 $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*); 806 let _: $crate::__private::HasIterator = has_iter; 807 // This is `while true` instead of `loop` because if there are no 808 // iterators used inside of this repetition then the body would not 809 // contain any `break`, so the compiler would emit unreachable code 810 // warnings on anything below the loop. We use has_iter to detect and 811 // fail to compile when there are no iterators, so here we just work 812 // around the unneeded extra warning. 813 // 814 // FIXME: temporariliy working around Clippy regression. 815 // https://github.com/rust-lang/rust-clippy/issues/7768 816 loop { 817 $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*); 818 $crate::quote_each_token_spanned!($tokens $span $($inner)*); 819 if false { 820 break; 821 } 822 } 823 }}; 824 ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; 825 ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; 826 827 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ 828 use $crate::__private::ext::*; 829 let mut _i = 0usize; 830 let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; 831 $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*); 832 let _: $crate::__private::HasIterator = has_iter; 833 loop { 834 $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*); 835 if _i > 0 { 836 $crate::quote_token_spanned!($tokens $span $sep); 837 } 838 _i += 1; 839 $crate::quote_each_token_spanned!($tokens $span $($inner)*); 840 if false { 841 break; 842 } 843 } 844 }}; 845 ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; 846 ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; 847 ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { 848 // https://github.com/dtolnay/quote/issues/130 849 $crate::quote_token_spanned!($tokens $span *); 850 }; 851 ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; 852 853 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { 854 $crate::ToTokens::to_tokens(&$var, &mut $tokens); 855 }; 856 ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; 857 ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { 858 $crate::quote_token_spanned!($tokens $span $curr); 859 }; 860 } 861 862 #[macro_export] 863 #[doc(hidden)] 864 macro_rules! quote_token { 865 ($tokens:ident ( $($inner:tt)* )) => { 866 $crate::__private::push_group( 867 &mut $tokens, 868 $crate::__private::Delimiter::Parenthesis, 869 $crate::quote!($($inner)*), 870 ); 871 }; 872 873 ($tokens:ident [ $($inner:tt)* ]) => { 874 $crate::__private::push_group( 875 &mut $tokens, 876 $crate::__private::Delimiter::Bracket, 877 $crate::quote!($($inner)*), 878 ); 879 }; 880 881 ($tokens:ident { $($inner:tt)* }) => { 882 $crate::__private::push_group( 883 &mut $tokens, 884 $crate::__private::Delimiter::Brace, 885 $crate::quote!($($inner)*), 886 ); 887 }; 888 889 ($tokens:ident +) => { 890 $crate::__private::push_add(&mut $tokens); 891 }; 892 893 ($tokens:ident +=) => { 894 $crate::__private::push_add_eq(&mut $tokens); 895 }; 896 897 ($tokens:ident &) => { 898 $crate::__private::push_and(&mut $tokens); 899 }; 900 901 ($tokens:ident &&) => { 902 $crate::__private::push_and_and(&mut $tokens); 903 }; 904 905 ($tokens:ident &=) => { 906 $crate::__private::push_and_eq(&mut $tokens); 907 }; 908 909 ($tokens:ident @) => { 910 $crate::__private::push_at(&mut $tokens); 911 }; 912 913 ($tokens:ident !) => { 914 $crate::__private::push_bang(&mut $tokens); 915 }; 916 917 ($tokens:ident ^) => { 918 $crate::__private::push_caret(&mut $tokens); 919 }; 920 921 ($tokens:ident ^=) => { 922 $crate::__private::push_caret_eq(&mut $tokens); 923 }; 924 925 ($tokens:ident :) => { 926 $crate::__private::push_colon(&mut $tokens); 927 }; 928 929 ($tokens:ident ::) => { 930 $crate::__private::push_colon2(&mut $tokens); 931 }; 932 933 ($tokens:ident ,) => { 934 $crate::__private::push_comma(&mut $tokens); 935 }; 936 937 ($tokens:ident /) => { 938 $crate::__private::push_div(&mut $tokens); 939 }; 940 941 ($tokens:ident /=) => { 942 $crate::__private::push_div_eq(&mut $tokens); 943 }; 944 945 ($tokens:ident .) => { 946 $crate::__private::push_dot(&mut $tokens); 947 }; 948 949 ($tokens:ident ..) => { 950 $crate::__private::push_dot2(&mut $tokens); 951 }; 952 953 ($tokens:ident ...) => { 954 $crate::__private::push_dot3(&mut $tokens); 955 }; 956 957 ($tokens:ident ..=) => { 958 $crate::__private::push_dot_dot_eq(&mut $tokens); 959 }; 960 961 ($tokens:ident =) => { 962 $crate::__private::push_eq(&mut $tokens); 963 }; 964 965 ($tokens:ident ==) => { 966 $crate::__private::push_eq_eq(&mut $tokens); 967 }; 968 969 ($tokens:ident >=) => { 970 $crate::__private::push_ge(&mut $tokens); 971 }; 972 973 ($tokens:ident >) => { 974 $crate::__private::push_gt(&mut $tokens); 975 }; 976 977 ($tokens:ident <=) => { 978 $crate::__private::push_le(&mut $tokens); 979 }; 980 981 ($tokens:ident <) => { 982 $crate::__private::push_lt(&mut $tokens); 983 }; 984 985 ($tokens:ident *=) => { 986 $crate::__private::push_mul_eq(&mut $tokens); 987 }; 988 989 ($tokens:ident !=) => { 990 $crate::__private::push_ne(&mut $tokens); 991 }; 992 993 ($tokens:ident |) => { 994 $crate::__private::push_or(&mut $tokens); 995 }; 996 997 ($tokens:ident |=) => { 998 $crate::__private::push_or_eq(&mut $tokens); 999 }; 1000 1001 ($tokens:ident ||) => { 1002 $crate::__private::push_or_or(&mut $tokens); 1003 }; 1004 1005 ($tokens:ident #) => { 1006 $crate::__private::push_pound(&mut $tokens); 1007 }; 1008 1009 ($tokens:ident ?) => { 1010 $crate::__private::push_question(&mut $tokens); 1011 }; 1012 1013 ($tokens:ident ->) => { 1014 $crate::__private::push_rarrow(&mut $tokens); 1015 }; 1016 1017 ($tokens:ident <-) => { 1018 $crate::__private::push_larrow(&mut $tokens); 1019 }; 1020 1021 ($tokens:ident %) => { 1022 $crate::__private::push_rem(&mut $tokens); 1023 }; 1024 1025 ($tokens:ident %=) => { 1026 $crate::__private::push_rem_eq(&mut $tokens); 1027 }; 1028 1029 ($tokens:ident =>) => { 1030 $crate::__private::push_fat_arrow(&mut $tokens); 1031 }; 1032 1033 ($tokens:ident ;) => { 1034 $crate::__private::push_semi(&mut $tokens); 1035 }; 1036 1037 ($tokens:ident <<) => { 1038 $crate::__private::push_shl(&mut $tokens); 1039 }; 1040 1041 ($tokens:ident <<=) => { 1042 $crate::__private::push_shl_eq(&mut $tokens); 1043 }; 1044 1045 ($tokens:ident >>) => { 1046 $crate::__private::push_shr(&mut $tokens); 1047 }; 1048 1049 ($tokens:ident >>=) => { 1050 $crate::__private::push_shr_eq(&mut $tokens); 1051 }; 1052 1053 ($tokens:ident *) => { 1054 $crate::__private::push_star(&mut $tokens); 1055 }; 1056 1057 ($tokens:ident -) => { 1058 $crate::__private::push_sub(&mut $tokens); 1059 }; 1060 1061 ($tokens:ident -=) => { 1062 $crate::__private::push_sub_eq(&mut $tokens); 1063 }; 1064 1065 ($tokens:ident $ident:ident) => { 1066 $crate::__private::push_ident(&mut $tokens, stringify!($ident)); 1067 }; 1068 1069 ($tokens:ident $lifetime:lifetime) => { 1070 $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime)); 1071 }; 1072 1073 ($tokens:ident _) => { 1074 $crate::__private::push_underscore(&mut $tokens); 1075 }; 1076 1077 ($tokens:ident $other:tt) => { 1078 $crate::__private::parse(&mut $tokens, stringify!($other)); 1079 }; 1080 } 1081 1082 #[macro_export] 1083 #[doc(hidden)] 1084 macro_rules! quote_token_spanned { 1085 ($tokens:ident $span:ident ( $($inner:tt)* )) => { 1086 $crate::__private::push_group_spanned( 1087 &mut $tokens, 1088 $span, 1089 $crate::__private::Delimiter::Parenthesis, 1090 $crate::quote_spanned!($span=> $($inner)*), 1091 ); 1092 }; 1093 1094 ($tokens:ident $span:ident [ $($inner:tt)* ]) => { 1095 $crate::__private::push_group_spanned( 1096 &mut $tokens, 1097 $span, 1098 $crate::__private::Delimiter::Bracket, 1099 $crate::quote_spanned!($span=> $($inner)*), 1100 ); 1101 }; 1102 1103 ($tokens:ident $span:ident { $($inner:tt)* }) => { 1104 $crate::__private::push_group_spanned( 1105 &mut $tokens, 1106 $span, 1107 $crate::__private::Delimiter::Brace, 1108 $crate::quote_spanned!($span=> $($inner)*), 1109 ); 1110 }; 1111 1112 ($tokens:ident $span:ident +) => { 1113 $crate::__private::push_add_spanned(&mut $tokens, $span); 1114 }; 1115 1116 ($tokens:ident $span:ident +=) => { 1117 $crate::__private::push_add_eq_spanned(&mut $tokens, $span); 1118 }; 1119 1120 ($tokens:ident $span:ident &) => { 1121 $crate::__private::push_and_spanned(&mut $tokens, $span); 1122 }; 1123 1124 ($tokens:ident $span:ident &&) => { 1125 $crate::__private::push_and_and_spanned(&mut $tokens, $span); 1126 }; 1127 1128 ($tokens:ident $span:ident &=) => { 1129 $crate::__private::push_and_eq_spanned(&mut $tokens, $span); 1130 }; 1131 1132 ($tokens:ident $span:ident @) => { 1133 $crate::__private::push_at_spanned(&mut $tokens, $span); 1134 }; 1135 1136 ($tokens:ident $span:ident !) => { 1137 $crate::__private::push_bang_spanned(&mut $tokens, $span); 1138 }; 1139 1140 ($tokens:ident $span:ident ^) => { 1141 $crate::__private::push_caret_spanned(&mut $tokens, $span); 1142 }; 1143 1144 ($tokens:ident $span:ident ^=) => { 1145 $crate::__private::push_caret_eq_spanned(&mut $tokens, $span); 1146 }; 1147 1148 ($tokens:ident $span:ident :) => { 1149 $crate::__private::push_colon_spanned(&mut $tokens, $span); 1150 }; 1151 1152 ($tokens:ident $span:ident ::) => { 1153 $crate::__private::push_colon2_spanned(&mut $tokens, $span); 1154 }; 1155 1156 ($tokens:ident $span:ident ,) => { 1157 $crate::__private::push_comma_spanned(&mut $tokens, $span); 1158 }; 1159 1160 ($tokens:ident $span:ident /) => { 1161 $crate::__private::push_div_spanned(&mut $tokens, $span); 1162 }; 1163 1164 ($tokens:ident $span:ident /=) => { 1165 $crate::__private::push_div_eq_spanned(&mut $tokens, $span); 1166 }; 1167 1168 ($tokens:ident $span:ident .) => { 1169 $crate::__private::push_dot_spanned(&mut $tokens, $span); 1170 }; 1171 1172 ($tokens:ident $span:ident ..) => { 1173 $crate::__private::push_dot2_spanned(&mut $tokens, $span); 1174 }; 1175 1176 ($tokens:ident $span:ident ...) => { 1177 $crate::__private::push_dot3_spanned(&mut $tokens, $span); 1178 }; 1179 1180 ($tokens:ident $span:ident ..=) => { 1181 $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span); 1182 }; 1183 1184 ($tokens:ident $span:ident =) => { 1185 $crate::__private::push_eq_spanned(&mut $tokens, $span); 1186 }; 1187 1188 ($tokens:ident $span:ident ==) => { 1189 $crate::__private::push_eq_eq_spanned(&mut $tokens, $span); 1190 }; 1191 1192 ($tokens:ident $span:ident >=) => { 1193 $crate::__private::push_ge_spanned(&mut $tokens, $span); 1194 }; 1195 1196 ($tokens:ident $span:ident >) => { 1197 $crate::__private::push_gt_spanned(&mut $tokens, $span); 1198 }; 1199 1200 ($tokens:ident $span:ident <=) => { 1201 $crate::__private::push_le_spanned(&mut $tokens, $span); 1202 }; 1203 1204 ($tokens:ident $span:ident <) => { 1205 $crate::__private::push_lt_spanned(&mut $tokens, $span); 1206 }; 1207 1208 ($tokens:ident $span:ident *=) => { 1209 $crate::__private::push_mul_eq_spanned(&mut $tokens, $span); 1210 }; 1211 1212 ($tokens:ident $span:ident !=) => { 1213 $crate::__private::push_ne_spanned(&mut $tokens, $span); 1214 }; 1215 1216 ($tokens:ident $span:ident |) => { 1217 $crate::__private::push_or_spanned(&mut $tokens, $span); 1218 }; 1219 1220 ($tokens:ident $span:ident |=) => { 1221 $crate::__private::push_or_eq_spanned(&mut $tokens, $span); 1222 }; 1223 1224 ($tokens:ident $span:ident ||) => { 1225 $crate::__private::push_or_or_spanned(&mut $tokens, $span); 1226 }; 1227 1228 ($tokens:ident $span:ident #) => { 1229 $crate::__private::push_pound_spanned(&mut $tokens, $span); 1230 }; 1231 1232 ($tokens:ident $span:ident ?) => { 1233 $crate::__private::push_question_spanned(&mut $tokens, $span); 1234 }; 1235 1236 ($tokens:ident $span:ident ->) => { 1237 $crate::__private::push_rarrow_spanned(&mut $tokens, $span); 1238 }; 1239 1240 ($tokens:ident $span:ident <-) => { 1241 $crate::__private::push_larrow_spanned(&mut $tokens, $span); 1242 }; 1243 1244 ($tokens:ident $span:ident %) => { 1245 $crate::__private::push_rem_spanned(&mut $tokens, $span); 1246 }; 1247 1248 ($tokens:ident $span:ident %=) => { 1249 $crate::__private::push_rem_eq_spanned(&mut $tokens, $span); 1250 }; 1251 1252 ($tokens:ident $span:ident =>) => { 1253 $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span); 1254 }; 1255 1256 ($tokens:ident $span:ident ;) => { 1257 $crate::__private::push_semi_spanned(&mut $tokens, $span); 1258 }; 1259 1260 ($tokens:ident $span:ident <<) => { 1261 $crate::__private::push_shl_spanned(&mut $tokens, $span); 1262 }; 1263 1264 ($tokens:ident $span:ident <<=) => { 1265 $crate::__private::push_shl_eq_spanned(&mut $tokens, $span); 1266 }; 1267 1268 ($tokens:ident $span:ident >>) => { 1269 $crate::__private::push_shr_spanned(&mut $tokens, $span); 1270 }; 1271 1272 ($tokens:ident $span:ident >>=) => { 1273 $crate::__private::push_shr_eq_spanned(&mut $tokens, $span); 1274 }; 1275 1276 ($tokens:ident $span:ident *) => { 1277 $crate::__private::push_star_spanned(&mut $tokens, $span); 1278 }; 1279 1280 ($tokens:ident $span:ident -) => { 1281 $crate::__private::push_sub_spanned(&mut $tokens, $span); 1282 }; 1283 1284 ($tokens:ident $span:ident -=) => { 1285 $crate::__private::push_sub_eq_spanned(&mut $tokens, $span); 1286 }; 1287 1288 ($tokens:ident $span:ident $ident:ident) => { 1289 $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident)); 1290 }; 1291 1292 ($tokens:ident $span:ident $lifetime:lifetime) => { 1293 $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime)); 1294 }; 1295 1296 ($tokens:ident $span:ident _) => { 1297 $crate::__private::push_underscore_spanned(&mut $tokens, $span); 1298 }; 1299 1300 ($tokens:ident $span:ident $other:tt) => { 1301 $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other)); 1302 }; 1303 } 1304