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