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