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 ($lit:literal) => {const {
413 enum Literal {}
414 impl $crate::tokens::HasConstLiteral for Literal {
415 const LITERAL: $crate::tokens::Literal<'static> =
416 $crate::tokens::__private::literal($crate::tokens::__private::stringify!($lit));
417 }
418 $crate::tokens::ConstLiteral::<Literal>::new()
419 }};
420 (#) => {
421 $crate::tokens::punct::Pound($crate::maybe_span::NoSpan)
422 };
423 (,) => {
424 $crate::tokens::punct::Comma($crate::maybe_span::NoSpan)
425 };
426 (.) => {
427 $crate::tokens::punct::Dot($crate::maybe_span::NoSpan)
428 };
429 (;) => {
430 $crate::tokens::punct::Semi($crate::maybe_span::NoSpan)
431 };
432 (:) => {
433 $crate::tokens::punct::Colon($crate::maybe_span::NoSpan)
434 };
435 (+) => {
436 $crate::tokens::punct::Add($crate::maybe_span::NoSpan)
437 };
438 (+=) => {
439 $crate::tokens::puncts::AddEq($crate::maybe_span::NoSpan)
440 };
441 (&) => {
442 $crate::tokens::punct::And($crate::maybe_span::NoSpan)
443 };
444 (&&) => {
445 $crate::tokens::puncts::AndAnd($crate::maybe_span::NoSpan)
446 };
447 (&=) => {
448 $crate::tokens::puncts::AndEq($crate::maybe_span::NoSpan)
449 };
450 (@) => {
451 $crate::tokens::punct::At($crate::maybe_span::NoSpan)
452 };
453 (!) => {
454 $crate::tokens::punct::Bang($crate::maybe_span::NoSpan)
455 };
456 (^) => {
457 $crate::tokens::punct::Caret($crate::maybe_span::NoSpan)
458 };
459 (^=) => {
460 $crate::tokens::puncts::CaretEq($crate::maybe_span::NoSpan)
461 };
462 (/) => {
463 $crate::tokens::punct::Div($crate::maybe_span::NoSpan)
464 };
465 (/=) => {
466 $crate::tokens::puncts::DivEq($crate::maybe_span::NoSpan)
467 };
468 (..) => {
469 $crate::tokens::puncts::Dot2($crate::maybe_span::NoSpan)
470 };
471 (...) => {
472 $crate::tokens::puncts::Dot3($crate::maybe_span::NoSpan)
473 };
474 (..=) => {
475 $crate::tokens::puncts::DotDotEq($crate::maybe_span::NoSpan)
476 };
477 (=) => {
478 $crate::tokens::punct::Eq($crate::maybe_span::NoSpan)
479 };
480 (==) => {
481 $crate::tokens::puncts::EqEq($crate::maybe_span::NoSpan)
482 };
483 (>=) => {
484 $crate::tokens::puncts::Ge($crate::maybe_span::NoSpan)
485 };
486 (>) => {
487 $crate::tokens::punct::Gt($crate::maybe_span::NoSpan)
488 };
489 (<=) => {
490 $crate::tokens::puncts::Le($crate::maybe_span::NoSpan)
491 };
492 (<) => {
493 $crate::tokens::punct::Lt($crate::maybe_span::NoSpan)
494 };
495 (*=) => {
496 $crate::tokens::puncts::MulEq($crate::maybe_span::NoSpan)
497 };
498 (!=) => {
499 $crate::tokens::puncts::Ne($crate::maybe_span::NoSpan)
500 };
501 (|) => {
502 $crate::tokens::punct::Or($crate::maybe_span::NoSpan)
503 };
504 (|=) => {
505 $crate::tokens::puncts::OrEq($crate::maybe_span::NoSpan)
506 };
507 (||) => {
508 $crate::tokens::puncts::OrOr($crate::maybe_span::NoSpan)
509 };
510 (?) => {
511 $crate::tokens::punct::Question($crate::maybe_span::NoSpan)
512 };
513 (->) => {
514 $crate::tokens::puncts::RArrow($crate::maybe_span::NoSpan)
515 };
516 (<-) => {
517 $crate::tokens::puncts::LArrow($crate::maybe_span::NoSpan)
518 };
519 (%) => {
520 $crate::tokens::punct::Rem($crate::maybe_span::NoSpan)
521 };
522 (%=) => {
523 $crate::tokens::puncts::RemEq($crate::maybe_span::NoSpan)
524 };
525 (=>) => {
526 $crate::tokens::puncts::FatArrow($crate::maybe_span::NoSpan)
527 };
528 (<<) => {
529 $crate::tokens::puncts::Shl($crate::maybe_span::NoSpan)
530 };
531 (<<=) => {
532 $crate::tokens::puncts::ShlEq($crate::maybe_span::NoSpan)
533 };
534 (>>) => {
535 $crate::tokens::puncts::Shr($crate::maybe_span::NoSpan)
536 };
537 (>>=) => {
538 $crate::tokens::puncts::ShrEq($crate::maybe_span::NoSpan)
539 };
540 (*) => {
541 $crate::tokens::punct::Star($crate::maybe_span::NoSpan)
542 };
543 (-) => {
544 $crate::tokens::punct::Sub($crate::maybe_span::NoSpan)
545 };
546 (-=) => {
547 $crate::tokens::puncts::SubEq($crate::maybe_span::NoSpan)
548 };
549 ($lifetime:lifetime) => {const {
550 enum Lifetime {}
551
552 impl $crate::tokens::HasConstLifetime for Lifetime {
553 const LIFETIME: $crate::tokens::Lifetime<'static> =
554 $crate::tokens::__private::lifetime($crate::tokens::__private::stringify!($lifetime));
555 }
556
557 $crate::tokens::ConstLifetime::<Lifetime>::new()
558 }};
559 (_) => {
560 $crate::tokens::ConstIdent::UNDERSCORE
561 };
562 ($) => {
563 $crate::tokens::punct::Dollar($crate::maybe_span::NoSpan)
564 };
565 (~) => {
566 $crate::tokens::punct::Tilde($crate::maybe_span::NoSpan)
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;