Skip to main content

typed_quote/
lib.rs

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//! ## Cheat sheet
9//!
10//! <style>
11//! .inner-code-bg-transparent code {background:transparent}
12//! .cell-full-of-code {padding:0 !important}
13//! .cell-full-of-code > div pre, .cell-full-of-code > div code {background:transparent}
14//! .cell-full-of-code > div {margin:0 !important}
15//! .cell-full-of-code > div:not(:last-child) > pre {padding-bottom:0 !important}
16//! </style>
17//!
18//! <div><table>
19//! <tr><th>Type</th><th>derived Traits</th><th>value examples</th></tr>
20#![cfg_attr(
21    all(any(doc, doctest, test), feature = "alloc", feature = "proc-macro2"),
22    doc = crate::doc_macros::doc_cheat_sheet!(),
23)]
24#![cfg_attr(
25    not(all(any(doc, doctest, test), feature = "alloc", feature = "proc-macro2")),
26    doc = concat!("\
27 <tr><td colspan=3>
28
29 Please see [docs.rs](\
30 https://docs.rs/typed-quote/latest/typed-quote/index.html#cheat-sheet)
31
32 </td></tr>")
33)]
34//! </table></div>
35
36#[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
51/// Into token stream.
52///
53/// *This trait is sealed and all methods are provided.*
54pub 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
84/// To token stream.
85///
86/// *This trait is sealed and all methods are provided.*
87pub 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
143/// Into a token tree.
144///
145/// *This trait is sealed and all methods are provided.*
146pub 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
162/// To a token tree.
163///
164/// *This trait is sealed and all methods are provided.*
165pub 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
208/// A [`proc_macro::Span`] or [`proc_macro2::Span`].
209///
210/// *This trait is sealed.*
211pub trait Span: sealed::Span + Copy + maybe_span::MaybeSpan {}
212
213/// Into tokens with new span.
214///
215/// *This trait is sealed and all methods are provided.*
216pub 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
226/// To tokens with new span.
227///
228/// *This trait is sealed and all methods are provided.*
229pub 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// https://docs.rs/quote/latest/src/quote/lib.rs.html#1016
381#[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;