1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(any(
4 all(feature = "proc-macro", feature = "proc-macro2"),
5 not(doctest),
6), doc = include_str!("../README.md"))]
7
8#![cfg_attr(
21 all(any(doc, doctest, test), feature = "alloc", feature = "proc-macro2"),
22 doc = crate::doc_macros::doc_cheat_sheet!(),
23)]
24#
31
32 </td></tr>")
33)]
34#[cfg(all(any(doc, doctest, test), feature = "alloc", feature = "proc-macro2"))]
37mod doc_macros;
38
39#[cfg(feature = "alloc")]
40extern crate alloc;
41
42#[cfg(feature = "proc-macro")]
43extern crate proc_macro;
44
45#[cfg(feature = "proc-macro")]
46use proc_macro::{TokenStream, TokenTree};
47
48#[cfg(feature = "proc-macro2")]
49use proc_macro2::{TokenStream as TokenStream2, TokenTree as TokenTree2};
50
51pub trait IntoTokens: sealed::IntoTokens {
55 #[cfg(feature = "proc-macro")]
56 fn into_tokens(self, tokens: &mut TokenStream);
57 #[cfg(feature = "proc-macro")]
58 fn into_token_stream(self) -> TokenStream;
59
60 #[cfg(feature = "proc-macro2")]
61 fn into_tokens2(self, tokens: &mut TokenStream2);
62 #[cfg(feature = "proc-macro2")]
63 fn into_token_stream2(self) -> TokenStream2;
64
65 #[doc(hidden)]
66 #[cfg(feature = "alloc")]
67 #[cfg(feature = "proc-macro")]
68 fn box_into_tokens(self: ::alloc::boxed::Box<Self>, tokens: &mut TokenStream);
69 #[doc(hidden)]
70 #[cfg(feature = "alloc")]
71 #[cfg(feature = "proc-macro")]
72 fn box_into_token_stream(self: ::alloc::boxed::Box<Self>) -> TokenStream;
73
74 #[doc(hidden)]
75 #[cfg(feature = "alloc")]
76 #[cfg(feature = "proc-macro2")]
77 fn box_into_tokens2(self: ::alloc::boxed::Box<Self>, tokens: &mut TokenStream2);
78 #[doc(hidden)]
79 #[cfg(feature = "alloc")]
80 #[cfg(feature = "proc-macro2")]
81 fn box_into_token_stream2(self: ::alloc::boxed::Box<Self>) -> TokenStream2;
82}
83
84pub trait ToTokens: IntoTokens + sealed::ToTokens {
88 #[cfg(feature = "proc-macro")]
89 fn to_tokens(&self, tokens: &mut TokenStream);
90 #[cfg(feature = "proc-macro")]
91 fn to_token_stream(&self) -> TokenStream;
92
93 #[cfg(feature = "proc-macro2")]
94 fn to_tokens2(&self, tokens: &mut TokenStream2);
95 #[cfg(feature = "proc-macro2")]
96 fn to_token_stream2(&self) -> TokenStream2;
97}
98
99impl<T: ?Sized + ToTokens> sealed::ToTokens for &T {}
100impl<T: ?Sized + ToTokens> ToTokens for &T {
101 #[cfg(feature = "proc-macro")]
102 fn to_tokens(&self, tokens: &mut TokenStream) {
103 T::to_tokens(self, tokens)
104 }
105
106 #[cfg(feature = "proc-macro")]
107 fn to_token_stream(&self) -> TokenStream {
108 T::to_token_stream(self)
109 }
110
111 #[cfg(feature = "proc-macro2")]
112 fn to_tokens2(&self, tokens: &mut TokenStream2) {
113 T::to_tokens2(self, tokens)
114 }
115
116 #[cfg(feature = "proc-macro2")]
117 fn to_token_stream2(&self) -> TokenStream2 {
118 T::to_token_stream2(self)
119 }
120}
121impl<T: ?Sized + ToTokens> sealed::IntoTokens for &T {}
122impl<T: ?Sized + ToTokens> IntoTokens for &T {
123 #[cfg(feature = "proc-macro")]
124 fn into_tokens(self, tokens: &mut TokenStream) {
125 T::to_tokens(self, tokens)
126 }
127 #[cfg(feature = "proc-macro")]
128 fn into_token_stream(self) -> TokenStream {
129 T::to_token_stream(self)
130 }
131 #[cfg(feature = "proc-macro2")]
132 fn into_tokens2(self, tokens: &mut TokenStream2) {
133 T::to_tokens2(self, tokens)
134 }
135 #[cfg(feature = "proc-macro2")]
136 fn into_token_stream2(self) -> TokenStream2 {
137 T::to_token_stream2(self)
138 }
139
140 crate::impl_box_into_tokens! {}
141}
142
143pub trait IntoTokenTree: IntoTokens + sealed::IntoTokenTree {
147 #[cfg(feature = "proc-macro")]
148 fn into_token_tree(self) -> TokenTree;
149 #[cfg(feature = "proc-macro2")]
150 fn into_token_tree2(self) -> TokenTree2;
151
152 #[doc(hidden)]
153 #[cfg(feature = "alloc")]
154 #[cfg(feature = "proc-macro")]
155 fn box_into_token_tree(self: ::alloc::boxed::Box<Self>) -> TokenTree;
156 #[doc(hidden)]
157 #[cfg(feature = "alloc")]
158 #[cfg(feature = "proc-macro2")]
159 fn box_into_token_tree2(self: ::alloc::boxed::Box<Self>) -> TokenTree2;
160}
161
162pub trait ToTokenTree: IntoTokenTree + ToTokens + sealed::ToTokenTree {
166 #[cfg(feature = "proc-macro")]
167 fn to_token_tree(&self) -> TokenTree;
168 #[cfg(feature = "proc-macro2")]
169 fn to_token_tree2(&self) -> TokenTree2;
170}
171
172impl<T: ?Sized + ToTokenTree> sealed::ToTokenTree for &T {}
173impl<T: ?Sized + ToTokenTree> ToTokenTree for &T {
174 #[cfg(feature = "proc-macro")]
175 fn to_token_tree(&self) -> TokenTree {
176 T::to_token_tree(self)
177 }
178
179 #[cfg(feature = "proc-macro2")]
180 fn to_token_tree2(&self) -> TokenTree2 {
181 T::to_token_tree2(self)
182 }
183}
184
185impl<T: ?Sized + ToTokenTree> sealed::IntoTokenTree for &T {}
186impl<T: ?Sized + ToTokenTree> IntoTokenTree for &T {
187 #[cfg(feature = "proc-macro")]
188 fn into_token_tree(self) -> TokenTree {
189 T::to_token_tree(self)
190 }
191 #[cfg(feature = "proc-macro2")]
192 fn into_token_tree2(self) -> TokenTree2 {
193 T::to_token_tree2(self)
194 }
195
196 #[cfg(feature = "alloc")]
197 #[cfg(feature = "proc-macro")]
198 fn box_into_token_tree(self: ::alloc::boxed::Box<Self>) -> TokenTree {
199 T::to_token_tree(&self)
200 }
201 #[cfg(feature = "alloc")]
202 #[cfg(feature = "proc-macro2")]
203 fn box_into_token_tree2(self: ::alloc::boxed::Box<Self>) -> TokenTree2 {
204 T::to_token_tree2(&self)
205 }
206}
207
208pub trait Span: sealed::Span + Copy + maybe_span::MaybeSpan {}
212
213pub trait WithSpan: IntoTokens + sealed::WithSpan {
217 type WithDefaultSpan<S: Span>: IntoTokens + WithSpan;
218
219 fn with_default_span<S: Span>(self, span: S) -> Self::WithDefaultSpan<S>;
220
221 type WithReplacedSpan<S: Span>: IntoTokens + WithSpan;
222
223 fn with_replaced_span<S: Span>(self, span: S) -> Self::WithReplacedSpan<S>;
224}
225
226pub trait RefWithSpan: WithSpan + ToTokens + sealed::RefWithSpan {
230 type RefWithDefaultSpan<'a, S: Span>: ToTokens + Copy + RefWithSpan
231 where
232 Self: 'a;
233
234 fn ref_with_default_span<S: Span>(&self, span: S) -> Self::RefWithDefaultSpan<'_, S>;
235
236 type RefWithReplacedSpan<'a, S: Span>: ToTokens + Copy + RefWithSpan
237 where
238 Self: 'a;
239
240 fn ref_with_replaced_span<S: Span>(&self, span: S) -> Self::RefWithReplacedSpan<'_, S>;
241}
242
243impl<T: ?Sized + RefWithSpan> sealed::RefWithSpan for &T {}
244impl<'this, T: ?Sized + RefWithSpan> RefWithSpan for &'this T {
245 type RefWithDefaultSpan<'a, S: Span>
246 = T::RefWithDefaultSpan<'this, S>
247 where
248 Self: 'a;
249
250 fn ref_with_default_span<S: Span>(&self, span: S) -> Self::RefWithDefaultSpan<'_, S> {
251 T::ref_with_default_span(*self, span)
252 }
253
254 type RefWithReplacedSpan<'a, S: Span>
255 = T::RefWithReplacedSpan<'this, S>
256 where
257 Self: 'a;
258
259 fn ref_with_replaced_span<S: Span>(&self, span: S) -> Self::RefWithReplacedSpan<'_, S> {
260 T::ref_with_replaced_span(*self, span)
261 }
262}
263
264impl<T: ?Sized + RefWithSpan> sealed::WithSpan for &T {}
265impl<'a, T: ?Sized + RefWithSpan> WithSpan for &'a T {
266 type WithDefaultSpan<S: Span> = T::RefWithDefaultSpan<'a, S>;
267
268 fn with_default_span<S: Span>(self, span: S) -> Self::WithDefaultSpan<S> {
269 T::ref_with_default_span(self, span)
270 }
271
272 type WithReplacedSpan<S: Span> = T::RefWithReplacedSpan<'a, S>;
273
274 fn with_replaced_span<S: Span>(self, span: S) -> Self::WithReplacedSpan<S> {
275 T::ref_with_replaced_span(self, span)
276 }
277}
278
279mod sealed {
280 #[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
281 use crate::replace_span_of::ReplaceSpanOf;
282
283 #[doc(hidden)]
284 pub trait IntoTokens {}
285 #[doc(hidden)]
286 pub trait ToTokens {}
287
288 #[doc(hidden)]
289 pub trait IntoTokenTree {}
290 #[doc(hidden)]
291 pub trait ToTokenTree {}
292
293 #[doc(hidden)]
294 pub trait MaybeSpan {}
295
296 #[cfg(feature = "proc-macro")]
297 #[cfg(feature = "proc-macro2")]
298 #[doc(hidden)]
299 pub trait Span:
300 ReplaceSpanOf<proc_macro::TokenStream>
301 + ReplaceSpanOf<proc_macro::TokenTree>
302 + ReplaceSpanOf<proc_macro::Group>
303 + ReplaceSpanOf<proc_macro::Ident>
304 + ReplaceSpanOf<proc_macro::Punct>
305 + ReplaceSpanOf<proc_macro::Literal>
306 + ReplaceSpanOf<proc_macro2::TokenStream>
307 + ReplaceSpanOf<proc_macro2::TokenTree>
308 + ReplaceSpanOf<proc_macro2::Group>
309 + ReplaceSpanOf<proc_macro2::Ident>
310 + ReplaceSpanOf<proc_macro2::Punct>
311 + ReplaceSpanOf<proc_macro2::Literal>
312 {
313 }
314
315 #[cfg(feature = "proc-macro")]
316 #[cfg(not(feature = "proc-macro2"))]
317 #[doc(hidden)]
318 pub trait Span:
319 ReplaceSpanOf<proc_macro::TokenStream>
320 + ReplaceSpanOf<proc_macro::TokenTree>
321 + ReplaceSpanOf<proc_macro::Group>
322 + ReplaceSpanOf<proc_macro::Ident>
323 + ReplaceSpanOf<proc_macro::Punct>
324 + ReplaceSpanOf<proc_macro::Literal>
325 {
326 }
327
328 #[cfg(not(feature = "proc-macro"))]
329 #[cfg(feature = "proc-macro2")]
330 #[doc(hidden)]
331 pub trait Span:
332 ReplaceSpanOf<proc_macro2::TokenStream>
333 + ReplaceSpanOf<proc_macro2::TokenTree>
334 + ReplaceSpanOf<proc_macro2::Group>
335 + ReplaceSpanOf<proc_macro2::Ident>
336 + ReplaceSpanOf<proc_macro2::Punct>
337 + ReplaceSpanOf<proc_macro2::Literal>
338 {
339 }
340
341 #[cfg(not(feature = "proc-macro"))]
342 #[cfg(not(feature = "proc-macro2"))]
343 #[doc(hidden)]
344 pub trait Span {}
345
346 #[doc(hidden)]
347 pub trait WithSpan {}
348 #[doc(hidden)]
349 pub trait RefWithSpan {}
350}
351
352#[macro_export]
353macro_rules! quote {
354 (#$quoted:ident) => {
355 $quoted
356 };
357 (#$quoted:ident $($rest:tt)+) => {
358 $crate::tokens::Concat(
359 $quoted,
360 $crate::quote!($($rest)+),
361 )
362 };
363 () => {
364 $crate::tokens::Empty
365 };
366 ($only:tt) => {
367 $crate::quote_token!($only)
368 };
369 ($head:tt $($tail:tt)+) => {
370 $crate::tokens::Concat(
371 $crate::quote_token!($head),
372 $crate::quote!($($tail)+),
373 )
374 };
375}
376
377#[doc(no_inline)]
378pub use quote as typed_quote;
379
380#[macro_export]
382macro_rules! quote_token {
383 ($ident:ident) => {const {
384 enum Ident {}
385 impl $crate::tokens::HasConstIdent for Ident {
386 const IDENT: $crate::tokens::Ident<'static> =
387 $crate::tokens::__private::ident($crate::tokens::__private::stringify!($ident));
388 }
389 $crate::tokens::ConstIdent::<Ident>::new()
390 }};
391 (::) => {
392 $crate::tokens::puncts::Colon2($crate::maybe_span::NoSpan)
393 };
394 (( $($content:tt)* )) => {
395 $crate::tokens::Parenthesis {
396 stream: $crate::quote!($($content)*),
397 delimiter_span: $crate::maybe_span::NoSpan,
398 }
399 };
400 ([ $($content:tt)* ]) => {
401 $crate::tokens::Bracket {
402 stream: $crate::quote!($($content)*),
403 delimiter_span: $crate::maybe_span::NoSpan,
404 }
405 };
406 ({ $($content:tt)* }) => {
407 $crate::tokens::Brace {
408 stream: $crate::quote!($($content)*),
409 delimiter_span: $crate::maybe_span::NoSpan,
410 }
411 };
412 (#) => {
413 $crate::tokens::punct::Pound($crate::maybe_span::NoSpan)
414 };
415 (,) => {
416 $crate::tokens::punct::Comma($crate::maybe_span::NoSpan)
417 };
418 (.) => {
419 $crate::tokens::punct::Dot($crate::maybe_span::NoSpan)
420 };
421 (;) => {
422 $crate::tokens::punct::Semi($crate::maybe_span::NoSpan)
423 };
424 (:) => {
425 $crate::tokens::punct::Colon($crate::maybe_span::NoSpan)
426 };
427 (+) => {
428 $crate::tokens::punct::Add($crate::maybe_span::NoSpan)
429 };
430 (+=) => {
431 $crate::tokens::puncts::AddEq($crate::maybe_span::NoSpan)
432 };
433 (&) => {
434 $crate::tokens::punct::And($crate::maybe_span::NoSpan)
435 };
436 (&&) => {
437 $crate::tokens::puncts::AndAnd($crate::maybe_span::NoSpan)
438 };
439 (&=) => {
440 $crate::tokens::puncts::AndEq($crate::maybe_span::NoSpan)
441 };
442 (@) => {
443 $crate::tokens::punct::At($crate::maybe_span::NoSpan)
444 };
445 (!) => {
446 $crate::tokens::punct::Bang($crate::maybe_span::NoSpan)
447 };
448 (^) => {
449 $crate::tokens::punct::Caret($crate::maybe_span::NoSpan)
450 };
451 (^=) => {
452 $crate::tokens::puncts::CaretEq($crate::maybe_span::NoSpan)
453 };
454 (/) => {
455 $crate::tokens::punct::Div($crate::maybe_span::NoSpan)
456 };
457 (/=) => {
458 $crate::tokens::puncts::DivEq($crate::maybe_span::NoSpan)
459 };
460 (..) => {
461 $crate::tokens::puncts::Dot2($crate::maybe_span::NoSpan)
462 };
463 (...) => {
464 $crate::tokens::puncts::Dot3($crate::maybe_span::NoSpan)
465 };
466 (..=) => {
467 $crate::tokens::puncts::DotDotEq($crate::maybe_span::NoSpan)
468 };
469 (=) => {
470 $crate::tokens::punct::Eq($crate::maybe_span::NoSpan)
471 };
472 (==) => {
473 $crate::tokens::puncts::EqEq($crate::maybe_span::NoSpan)
474 };
475 (>=) => {
476 $crate::tokens::puncts::Ge($crate::maybe_span::NoSpan)
477 };
478 (>) => {
479 $crate::tokens::punct::Gt($crate::maybe_span::NoSpan)
480 };
481 (<=) => {
482 $crate::tokens::puncts::Le($crate::maybe_span::NoSpan)
483 };
484 (<) => {
485 $crate::tokens::punct::Lt($crate::maybe_span::NoSpan)
486 };
487 (*=) => {
488 $crate::tokens::puncts::MulEq($crate::maybe_span::NoSpan)
489 };
490 (!=) => {
491 $crate::tokens::puncts::Ne($crate::maybe_span::NoSpan)
492 };
493 (|) => {
494 $crate::tokens::punct::Or($crate::maybe_span::NoSpan)
495 };
496 (|=) => {
497 $crate::tokens::puncts::OrEq($crate::maybe_span::NoSpan)
498 };
499 (||) => {
500 $crate::tokens::puncts::OrOr($crate::maybe_span::NoSpan)
501 };
502 (?) => {
503 $crate::tokens::punct::Question($crate::maybe_span::NoSpan)
504 };
505 (->) => {
506 $crate::tokens::puncts::RArrow($crate::maybe_span::NoSpan)
507 };
508 (<-) => {
509 $crate::tokens::puncts::LArrow($crate::maybe_span::NoSpan)
510 };
511 (%) => {
512 $crate::tokens::punct::Rem($crate::maybe_span::NoSpan)
513 };
514 (%=) => {
515 $crate::tokens::puncts::RemEq($crate::maybe_span::NoSpan)
516 };
517 (=>) => {
518 $crate::tokens::puncts::FatArrow($crate::maybe_span::NoSpan)
519 };
520 (<<) => {
521 $crate::tokens::puncts::Shl($crate::maybe_span::NoSpan)
522 };
523 (<<=) => {
524 $crate::tokens::puncts::ShlEq($crate::maybe_span::NoSpan)
525 };
526 (>>) => {
527 $crate::tokens::puncts::Shr($crate::maybe_span::NoSpan)
528 };
529 (>>=) => {
530 $crate::tokens::puncts::ShrEq($crate::maybe_span::NoSpan)
531 };
532 (*) => {
533 $crate::tokens::punct::Star($crate::maybe_span::NoSpan)
534 };
535 (-) => {
536 $crate::tokens::punct::Sub($crate::maybe_span::NoSpan)
537 };
538 (-=) => {
539 $crate::tokens::puncts::SubEq($crate::maybe_span::NoSpan)
540 };
541 ($lifetime:lifetime) => {const {
542 enum Lifetime {}
543
544 impl $crate::tokens::HasConstLifetime for Lifetime {
545 const LIFETIME: $crate::tokens::Lifetime<'static> =
546 $crate::tokens::__private::lifetime($crate::tokens::__private::stringify!($lifetime));
547 }
548
549 $crate::tokens::ConstLifetime::<Lifetime>::new()
550 }};
551 (_) => {
552 $crate::tokens::ConstIdent::UNDERSCORE
553 };
554 ($) => {
555 $crate::tokens::punct::Dollar($crate::maybe_span::NoSpan)
556 };
557 (~) => {
558 $crate::tokens::punct::Tilde($crate::maybe_span::NoSpan)
559 };
560 ($lit:literal) => {const {
561 enum Literal {}
562 impl $crate::tokens::HasConstLiteral for Literal {
563 const LITERAL: $crate::tokens::Literal<'static> =
564 $crate::tokens::__private::literal($crate::tokens::__private::stringify!($lit));
565 }
566 $crate::tokens::ConstLiteral::<Literal>::new()
567 }};
568}
569
570pub mod maybe_span;
571
572pub mod tokens;
573
574#[derive(Debug, Clone, Copy)]
575pub enum Never {}
576
577#[derive(Debug, Clone, Copy)]
578pub enum Either<A, B> {
579 A(A),
580 B(B),
581}
582
583pub mod prelude;
584
585macro_rules! impl_many {
586 (
587 impl<__> $Trait:ident for each_of![
588 $($ForTy:ty),+ $(,)?
589 ] $impl_body:tt
590 ) => {
591 $(
592 impl $Trait for $ForTy
593 $impl_body
594 )+
595 };
596 (
597 impl<__> $Trait:ident for each_of_with_generics![
598 $([$($generics:tt)*] $ForTy:ty),+ $(,)?
599 ] $impl_body:tt
600 ) => {
601 $(
602 impl<$($generics)*> $Trait for $ForTy
603 $impl_body
604 )+
605 };
606 ({
607 $defs:tt
608 $($imps:tt)*
609 }) => {
610 crate::impl_many! {
611 @__defs
612 $defs
613 {$($imps)*}
614 }
615 };
616 (@__defs { $($(#$def_attr:tt)* {$($defs:tt)*})+ } $imps:tt) => {
617 $(
618 $(#$def_attr)*
619 const _: () = {
620 $($defs)*
621
622 crate::impl_many! {
623 @__unwrap $imps
624 }
625 };
626 )+
627 };
628 (@__unwrap {$($t:tt)*}) => {
629 $($t)*
630 }
631}
632
633macro_rules! impl_to_tokens {
634 (copy) => {
635 crate::impl_to_tokens! {
636 |self, ts| <(Self, &mut _) as crate::into_st::IntoST<()>>::into_st((*self, ts)),
637 <Self as crate::into_st::IntoST<_>>::into_st(*self),
638 }
639 };
640 (tt) => {
641 #[cfg(feature = "proc-macro")]
642 fn to_tokens(&self, tokens: &mut ::proc_macro::TokenStream) {
643 tokens.extend(Some(self.to_token_tree()));
644 }
645 #[cfg(feature = "proc-macro")]
646 fn to_token_stream(&self) -> ::proc_macro::TokenStream {
647 self.to_token_tree().into()
648 }
649
650 #[cfg(feature = "proc-macro2")]
651 fn to_tokens2(&self, tokens: &mut ::proc_macro2::TokenStream) {
652 tokens.extend(Some(self.to_token_tree2()));
653 }
654 #[cfg(feature = "proc-macro2")]
655 fn to_token_stream2(&self) -> ::proc_macro2::TokenStream {
656 self.to_token_tree2().into()
657 }
658 };
659 (#[proxy] |$self_:ident| $proxy:expr) => {
660 crate::impl_to_tokens! {
661 |$self_, ts| crate::into_st::IntoST::<()>::into_st(($proxy, ts)),
662 crate::into_st::IntoST::<_>::into_st($proxy),
663 }
664 };
665 (
666 |$self_:ident, $tokens:pat_param $(,)?| $to_tokens:expr
667 $(, $to:expr)?
668 $(,)?
669 ) => {
670 #[cfg(feature = "proc-macro")]
671 fn to_tokens(&$self_, $tokens: &mut ::proc_macro::TokenStream) {
672 #[allow(unused_imports)]
673 use ::proc_macro as pm;
674
675 $to_tokens
676 }
677
678 #[cfg(feature = "proc-macro")]
679 fn to_token_stream(&$self_) -> ::proc_macro::TokenStream {
680 crate::expand_or! {
681 [$($to)?]
682 {
683 let mut ts = Default::default();
684 $self_.to_tokens(&mut ts);
685 ts
686 }
687 }
688 }
689
690 #[cfg(feature = "proc-macro2")]
691 fn to_tokens2(&$self_, $tokens: &mut ::proc_macro2::TokenStream) {
692 #[allow(unused_imports)]
693 use ::proc_macro2 as pm;
694
695 $to_tokens
696 }
697
698 #[cfg(feature = "proc-macro2")]
699 fn to_token_stream2(&$self_) -> ::proc_macro2::TokenStream {
700 crate::expand_or! {
701 [$($to)?]
702 {
703 let mut ts = Default::default();
704 $self_.to_tokens2(&mut ts);
705 ts
706 }
707 }
708 }
709 };
710}
711
712macro_rules! impl_into_tokens {
713 (tt) => {
714 #[cfg(feature = "proc-macro")]
715 fn into_tokens(self, tokens: &mut ::proc_macro::TokenStream) {
716 tokens.extend(Some(self.into_token_tree()));
717 }
718 #[cfg(feature = "proc-macro")]
719 fn into_token_stream(self) -> ::proc_macro::TokenStream {
720 self.into_token_tree().into()
721 }
722 #[cfg(feature = "proc-macro2")]
723 fn into_tokens2(self, tokens: &mut ::proc_macro2::TokenStream) {
724 tokens.extend(Some(self.into_token_tree2()));
725 }
726 #[cfg(feature = "proc-macro2")]
727 fn into_token_stream2(self) -> ::proc_macro2::TokenStream {
728 self.into_token_tree2().into()
729 }
730
731 crate::impl_box_into_tokens! {}
732 };
733 (#[proxy] |$self_:ident| $proxy:expr) => {
734 crate::impl_into_tokens! {
735 |$self_, ts| crate::into_st::IntoST::<()>::into_st(($proxy, ts)),
736 crate::into_st::IntoST::<_>::into_st($proxy),
737 }
738 };
739 (
740 |$self_:ident, $tokens:pat_param $(,)?| $into_tokens:expr
741 $(, $into:expr)?
742 $(,)?
743 ) => {
744 #[cfg(feature = "proc-macro")]
745 fn into_tokens($self_, $tokens: &mut ::proc_macro::TokenStream) {
746 #[allow(unused_imports)]
747 use ::proc_macro as pm;
748 $into_tokens
749 }
750
751 #[cfg(feature = "proc-macro")]
752 fn into_token_stream($self_) -> ::proc_macro::TokenStream {
753 crate::expand_or! {
754 [$(
755 #[allow(unused_imports)]
756 use ::proc_macro as pm;
757 $into
758 )?]
759 {
760 let mut ts = Default::default();
761 $self_.into_tokens(&mut ts);
762 ts
763 }
764 }
765 }
766
767 #[cfg(feature = "proc-macro2")]
768 fn into_tokens2($self_, $tokens: &mut ::proc_macro2::TokenStream) {
769 #[allow(unused_imports)]
770 use ::proc_macro2 as pm;
771 $into_tokens
772 }
773
774 #[cfg(feature = "proc-macro2")]
775 fn into_token_stream2($self_) -> ::proc_macro2::TokenStream {
776 crate::expand_or! {
777 [$(
778 #[allow(unused_imports)]
779 use ::proc_macro2 as pm;
780 $into
781 )?]
782 {
783 let mut ts = Default::default();
784 $self_.into_tokens2(&mut ts);
785 ts
786 }
787 }
788 }
789
790 crate::impl_box_into_tokens! {}
791 };
792}
793
794macro_rules! impl_box_into_tokens {
795 () => {
796 #[cfg(feature = "alloc")]
797 #[cfg(feature = "proc-macro")]
798 fn box_into_tokens(
799 self: ::alloc::boxed::Box<Self>,
800 tokens: &mut ::proc_macro::TokenStream,
801 ) {
802 Self::into_tokens(*self, tokens)
803 }
804 #[cfg(feature = "alloc")]
805 #[cfg(feature = "proc-macro")]
806 fn box_into_token_stream(self: ::alloc::boxed::Box<Self>) -> ::proc_macro::TokenStream {
807 Self::into_token_stream(*self)
808 }
809
810 #[cfg(feature = "alloc")]
811 #[cfg(feature = "proc-macro2")]
812 fn box_into_tokens2(
813 self: ::alloc::boxed::Box<Self>,
814 tokens: &mut ::proc_macro2::TokenStream,
815 ) {
816 Self::into_tokens2(*self, tokens)
817 }
818 #[cfg(feature = "alloc")]
819 #[cfg(feature = "proc-macro2")]
820 fn box_into_token_stream2(self: ::alloc::boxed::Box<Self>) -> ::proc_macro2::TokenStream {
821 Self::into_token_stream2(*self)
822 }
823 };
824}
825
826macro_rules! impl_to_token_tree {
827 (copy) => {
828 #[cfg(feature = "proc-macro")]
829 fn to_token_tree(&self) -> ::proc_macro::TokenTree {
830 <Self as crate::IntoTokenTree>::into_token_tree(*self)
831 }
832
833 #[cfg(feature = "proc-macro2")]
834 fn to_token_tree2(&self) -> ::proc_macro2::TokenTree {
835 <Self as crate::IntoTokenTree>::into_token_tree2(*self)
836 }
837 };
838 (
839 |$self_:ident| $to:expr
840 $(,)?
841 ) => {
842 #[cfg(feature = "proc-macro")]
843 fn to_token_tree(&$self_) -> ::proc_macro::TokenTree {
844 #[allow(unused_imports)]
845 use ::proc_macro as pm;
846 $to
847 }
848
849 #[cfg(feature = "proc-macro2")]
850 fn to_token_tree2(&$self_) -> ::proc_macro2::TokenTree {
851 #[allow(unused_imports)]
852 use ::proc_macro2 as pm;
853 $to
854 }
855 };
856}
857
858macro_rules! impl_into_token_tree {
859 (
860 |$self_:ident| $into:expr
861 $(,)?
862 ) => {
863 #[cfg(feature = "proc-macro")]
864 fn into_token_tree($self_) -> ::proc_macro::TokenTree {
865 #[allow(unused_imports)]
866 use ::proc_macro as pm;
867
868 $into
869 }
870
871 #[cfg(feature = "proc-macro2")]
872 fn into_token_tree2($self_) -> ::proc_macro2::TokenTree {
873 #[allow(unused_imports)]
874 use ::proc_macro2 as pm;
875
876 $into
877 }
878
879 crate::impl_box_into_token_tree! {}
880 };
881 (to) => {
882 crate::impl_into_token_tree! {
883 |self| crate::into_st::IntoST::<_>::into_st(&self)
884 }
885 };
886}
887
888macro_rules! impl_box_into_token_tree {
889 () => {
890 #[cfg(feature = "alloc")]
891 #[cfg(feature = "proc-macro")]
892 fn box_into_token_tree(self: ::alloc::boxed::Box<Self>) -> ::proc_macro::TokenTree {
893 Self::into_token_tree(*self)
894 }
895 #[cfg(feature = "alloc")]
896 #[cfg(feature = "proc-macro2")]
897 fn box_into_token_tree2(self: ::alloc::boxed::Box<Self>) -> ::proc_macro2::TokenTree {
898 Self::into_token_tree2(*self)
899 }
900 };
901}
902
903macro_rules! impl_ref_with_span {
904 (copy) => {
905 type RefWithDefaultSpan<'ref_with_span, S: crate::Span>
906 = <Self as crate::WithSpan>::WithDefaultSpan<S>
907 where
908 Self: 'ref_with_span;
909
910 fn ref_with_default_span<S: crate::Span>(
911 &self,
912 span: S,
913 ) -> Self::RefWithDefaultSpan<'_, S> {
914 <Self as crate::WithSpan>::with_default_span(*self, span)
915 }
916
917 type RefWithReplacedSpan<'ref_with_span, S: crate::Span>
918 = <Self as crate::WithSpan>::WithReplacedSpan<S>
919 where
920 Self: 'ref_with_span;
921
922 fn ref_with_replaced_span<S: crate::Span>(
923 &self,
924 span: S,
925 ) -> Self::RefWithReplacedSpan<'_, S> {
926 <Self as crate::WithSpan>::with_replaced_span(*self, span)
927 }
928 };
929}
930
931macro_rules! expand_or {
932 ([ ]$($or:tt)*) => [ $($or)* ];
933 ([$($e:tt)+]$($or:tt)*) => [ $($e)+ ];
934}
935
936use {
937 expand_or, impl_box_into_token_tree, impl_box_into_tokens, impl_into_token_tree,
938 impl_into_tokens, impl_many, impl_ref_with_span, impl_to_token_tree, impl_to_tokens,
939};
940
941#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
942mod into_st;
943
944#[cfg(feature = "alloc")]
945mod alloc_imp;
946
947#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
948mod replace_span_of;
949
950#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
951mod proc_macro_n;
952
953#[cfg(test)]
954mod tests;