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