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