proc_macro2/
wrapper.rs

1use crate::detection::inside_proc_macro;
2use crate::{fallback, Delimiter, Punct, Spacing, TokenTree};
3use core::fmt::{self, Debug, Display};
4use core::iter::FromIterator;
5use core::ops::RangeBounds;
6use core::str::FromStr;
7use std::panic;
8#[cfg(super_unstable)]
9use std::path::PathBuf;
10
11#[derive(Clone)]
12pub(crate) enum TokenStream {
13    Compiler(DeferredTokenStream),
14    Fallback(fallback::TokenStream),
15}
16
17// Work around https://github.com/rust-lang/rust/issues/65080.
18// In `impl Extend<TokenTree> for TokenStream` which is used heavily by quote,
19// we hold on to the appended tokens and do proc_macro::TokenStream::extend as
20// late as possible to batch together consecutive uses of the Extend impl.
21#[derive(Clone)]
22pub(crate) struct DeferredTokenStream {
23    stream: proc_macro::TokenStream,
24    extra: Vec<proc_macro::TokenTree>,
25}
26
27pub(crate) enum LexError {
28    Compiler(proc_macro::LexError),
29    Fallback(fallback::LexError),
30}
31
32impl LexError {
33    fn call_site() -> Self {
34        LexError::Fallback(fallback::LexError {
35            span: fallback::Span::call_site(),
36        })
37    }
38}
39
40fn mismatch() -> ! {
41    panic!("stable/nightly mismatch")
42}
43
44impl DeferredTokenStream {
45    fn new(stream: proc_macro::TokenStream) -> Self {
46        DeferredTokenStream {
47            stream,
48            extra: Vec::new(),
49        }
50    }
51
52    fn is_empty(&self) -> bool {
53        self.stream.is_empty() && self.extra.is_empty()
54    }
55
56    fn evaluate_now(&mut self) {
57        // If-check provides a fast short circuit for the common case of `extra`
58        // being empty, which saves a round trip over the proc macro bridge.
59        // Improves macro expansion time in winrt by 6% in debug mode.
60        if !self.extra.is_empty() {
61            self.stream.extend(self.extra.drain(..));
62        }
63    }
64
65    fn into_token_stream(mut self) -> proc_macro::TokenStream {
66        self.evaluate_now();
67        self.stream
68    }
69}
70
71impl TokenStream {
72    pub fn new() -> Self {
73        if inside_proc_macro() {
74            TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new()))
75        } else {
76            TokenStream::Fallback(fallback::TokenStream::new())
77        }
78    }
79
80    pub fn is_empty(&self) -> bool {
81        match self {
82            TokenStream::Compiler(tts) => tts.is_empty(),
83            TokenStream::Fallback(tts) => tts.is_empty(),
84        }
85    }
86
87    fn unwrap_nightly(self) -> proc_macro::TokenStream {
88        match self {
89            TokenStream::Compiler(s) => s.into_token_stream(),
90            TokenStream::Fallback(_) => mismatch(),
91        }
92    }
93
94    fn unwrap_stable(self) -> fallback::TokenStream {
95        match self {
96            TokenStream::Compiler(_) => mismatch(),
97            TokenStream::Fallback(s) => s,
98        }
99    }
100}
101
102impl FromStr for TokenStream {
103    type Err = LexError;
104
105    fn from_str(src: &str) -> Result<TokenStream, LexError> {
106        if inside_proc_macro() {
107            Ok(TokenStream::Compiler(DeferredTokenStream::new(
108                proc_macro_parse(src)?,
109            )))
110        } else {
111            Ok(TokenStream::Fallback(src.parse()?))
112        }
113    }
114}
115
116// Work around https://github.com/rust-lang/rust/issues/58736.
117fn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> {
118    let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler));
119    result.unwrap_or_else(|_| Err(LexError::call_site()))
120}
121
122impl Display for TokenStream {
123    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124        match self {
125            TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f),
126            TokenStream::Fallback(tts) => Display::fmt(tts, f),
127        }
128    }
129}
130
131impl From<proc_macro::TokenStream> for TokenStream {
132    fn from(inner: proc_macro::TokenStream) -> TokenStream {
133        TokenStream::Compiler(DeferredTokenStream::new(inner))
134    }
135}
136
137impl From<TokenStream> for proc_macro::TokenStream {
138    fn from(inner: TokenStream) -> proc_macro::TokenStream {
139        match inner {
140            TokenStream::Compiler(inner) => inner.into_token_stream(),
141            TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(),
142        }
143    }
144}
145
146impl From<fallback::TokenStream> for TokenStream {
147    fn from(inner: fallback::TokenStream) -> TokenStream {
148        TokenStream::Fallback(inner)
149    }
150}
151
152// Assumes inside_proc_macro().
153fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
154    match token {
155        TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
156        TokenTree::Punct(tt) => {
157            let spacing = match tt.spacing() {
158                Spacing::Joint => proc_macro::Spacing::Joint,
159                Spacing::Alone => proc_macro::Spacing::Alone,
160            };
161            let mut punct = proc_macro::Punct::new(tt.as_char(), spacing);
162            punct.set_span(tt.span().inner.unwrap_nightly());
163            punct.into()
164        }
165        TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
166        TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
167    }
168}
169
170impl From<TokenTree> for TokenStream {
171    fn from(token: TokenTree) -> TokenStream {
172        if inside_proc_macro() {
173            TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into()))
174        } else {
175            TokenStream::Fallback(token.into())
176        }
177    }
178}
179
180impl FromIterator<TokenTree> for TokenStream {
181    fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
182        if inside_proc_macro() {
183            TokenStream::Compiler(DeferredTokenStream::new(
184                trees.into_iter().map(into_compiler_token).collect(),
185            ))
186        } else {
187            TokenStream::Fallback(trees.into_iter().collect())
188        }
189    }
190}
191
192impl FromIterator<TokenStream> for TokenStream {
193    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
194        let mut streams = streams.into_iter();
195        match streams.next() {
196            Some(TokenStream::Compiler(mut first)) => {
197                first.evaluate_now();
198                first.stream.extend(streams.map(|s| match s {
199                    TokenStream::Compiler(s) => s.into_token_stream(),
200                    TokenStream::Fallback(_) => mismatch(),
201                }));
202                TokenStream::Compiler(first)
203            }
204            Some(TokenStream::Fallback(mut first)) => {
205                first.extend(streams.map(|s| match s {
206                    TokenStream::Fallback(s) => s,
207                    TokenStream::Compiler(_) => mismatch(),
208                }));
209                TokenStream::Fallback(first)
210            }
211            None => TokenStream::new(),
212        }
213    }
214}
215
216impl Extend<TokenTree> for TokenStream {
217    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, stream: I) {
218        match self {
219            TokenStream::Compiler(tts) => {
220                // Here is the reason for DeferredTokenStream.
221                for token in stream {
222                    tts.extra.push(into_compiler_token(token));
223                }
224            }
225            TokenStream::Fallback(tts) => tts.extend(stream),
226        }
227    }
228}
229
230impl Extend<TokenStream> for TokenStream {
231    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
232        match self {
233            TokenStream::Compiler(tts) => {
234                tts.evaluate_now();
235                tts.stream
236                    .extend(streams.into_iter().map(TokenStream::unwrap_nightly));
237            }
238            TokenStream::Fallback(tts) => {
239                tts.extend(streams.into_iter().map(TokenStream::unwrap_stable));
240            }
241        }
242    }
243}
244
245impl Debug for TokenStream {
246    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247        match self {
248            TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f),
249            TokenStream::Fallback(tts) => Debug::fmt(tts, f),
250        }
251    }
252}
253
254impl LexError {
255    pub(crate) fn span(&self) -> Span {
256        match self {
257            LexError::Compiler(_) => Span::call_site(),
258            LexError::Fallback(e) => Span::Fallback(e.span()),
259        }
260    }
261}
262
263impl From<proc_macro::LexError> for LexError {
264    fn from(e: proc_macro::LexError) -> LexError {
265        LexError::Compiler(e)
266    }
267}
268
269impl From<fallback::LexError> for LexError {
270    fn from(e: fallback::LexError) -> LexError {
271        LexError::Fallback(e)
272    }
273}
274
275impl Debug for LexError {
276    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277        match self {
278            LexError::Compiler(e) => Debug::fmt(e, f),
279            LexError::Fallback(e) => Debug::fmt(e, f),
280        }
281    }
282}
283
284impl Display for LexError {
285    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
286        match self {
287            #[cfg(not(no_lexerror_display))]
288            LexError::Compiler(e) => Display::fmt(e, f),
289            #[cfg(no_lexerror_display)]
290            LexError::Compiler(_e) => Display::fmt(
291                &fallback::LexError {
292                    span: fallback::Span::call_site(),
293                },
294                f,
295            ),
296            LexError::Fallback(e) => Display::fmt(e, f),
297        }
298    }
299}
300
301#[derive(Clone)]
302pub(crate) enum TokenTreeIter {
303    Compiler(proc_macro::token_stream::IntoIter),
304    Fallback(fallback::TokenTreeIter),
305}
306
307impl IntoIterator for TokenStream {
308    type Item = TokenTree;
309    type IntoIter = TokenTreeIter;
310
311    fn into_iter(self) -> TokenTreeIter {
312        match self {
313            TokenStream::Compiler(tts) => {
314                TokenTreeIter::Compiler(tts.into_token_stream().into_iter())
315            }
316            TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()),
317        }
318    }
319}
320
321impl Iterator for TokenTreeIter {
322    type Item = TokenTree;
323
324    fn next(&mut self) -> Option<TokenTree> {
325        let token = match self {
326            TokenTreeIter::Compiler(iter) => iter.next()?,
327            TokenTreeIter::Fallback(iter) => return iter.next(),
328        };
329        Some(match token {
330            proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
331            proc_macro::TokenTree::Punct(tt) => {
332                let spacing = match tt.spacing() {
333                    proc_macro::Spacing::Joint => Spacing::Joint,
334                    proc_macro::Spacing::Alone => Spacing::Alone,
335                };
336                let mut o = Punct::new(tt.as_char(), spacing);
337                o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
338                o.into()
339            }
340            proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
341            proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
342        })
343    }
344
345    fn size_hint(&self) -> (usize, Option<usize>) {
346        match self {
347            TokenTreeIter::Compiler(tts) => tts.size_hint(),
348            TokenTreeIter::Fallback(tts) => tts.size_hint(),
349        }
350    }
351}
352
353#[derive(Clone, PartialEq, Eq)]
354#[cfg(super_unstable)]
355pub(crate) enum SourceFile {
356    Compiler(proc_macro::SourceFile),
357    Fallback(fallback::SourceFile),
358}
359
360#[cfg(super_unstable)]
361impl SourceFile {
362    fn nightly(sf: proc_macro::SourceFile) -> Self {
363        SourceFile::Compiler(sf)
364    }
365
366    /// Get the path to this source file as a string.
367    pub fn path(&self) -> PathBuf {
368        match self {
369            SourceFile::Compiler(a) => a.path(),
370            SourceFile::Fallback(a) => a.path(),
371        }
372    }
373
374    pub fn is_real(&self) -> bool {
375        match self {
376            SourceFile::Compiler(a) => a.is_real(),
377            SourceFile::Fallback(a) => a.is_real(),
378        }
379    }
380}
381
382#[cfg(super_unstable)]
383impl Debug for SourceFile {
384    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
385        match self {
386            SourceFile::Compiler(a) => Debug::fmt(a, f),
387            SourceFile::Fallback(a) => Debug::fmt(a, f),
388        }
389    }
390}
391
392#[cfg(any(super_unstable, feature = "span-locations"))]
393pub(crate) struct LineColumn {
394    pub line: usize,
395    pub column: usize,
396}
397
398#[derive(Copy, Clone)]
399pub(crate) enum Span {
400    Compiler(proc_macro::Span),
401    Fallback(fallback::Span),
402}
403
404impl Span {
405    pub fn call_site() -> Self {
406        if inside_proc_macro() {
407            Span::Compiler(proc_macro::Span::call_site())
408        } else {
409            Span::Fallback(fallback::Span::call_site())
410        }
411    }
412
413    #[cfg(not(no_hygiene))]
414    pub fn mixed_site() -> Self {
415        if inside_proc_macro() {
416            Span::Compiler(proc_macro::Span::mixed_site())
417        } else {
418            Span::Fallback(fallback::Span::mixed_site())
419        }
420    }
421
422    #[cfg(super_unstable)]
423    pub fn def_site() -> Self {
424        if inside_proc_macro() {
425            Span::Compiler(proc_macro::Span::def_site())
426        } else {
427            Span::Fallback(fallback::Span::def_site())
428        }
429    }
430
431    pub fn resolved_at(&self, other: Span) -> Span {
432        match (self, other) {
433            #[cfg(not(no_hygiene))]
434            (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)),
435
436            // Name resolution affects semantics, but location is only cosmetic
437            #[cfg(no_hygiene)]
438            (Span::Compiler(_), Span::Compiler(_)) => other,
439
440            (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)),
441            _ => mismatch(),
442        }
443    }
444
445    pub fn located_at(&self, other: Span) -> Span {
446        match (self, other) {
447            #[cfg(not(no_hygiene))]
448            (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)),
449
450            // Name resolution affects semantics, but location is only cosmetic
451            #[cfg(no_hygiene)]
452            (Span::Compiler(_), Span::Compiler(_)) => *self,
453
454            (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)),
455            _ => mismatch(),
456        }
457    }
458
459    pub fn unwrap(self) -> proc_macro::Span {
460        match self {
461            Span::Compiler(s) => s,
462            Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"),
463        }
464    }
465
466    #[cfg(super_unstable)]
467    pub fn source_file(&self) -> SourceFile {
468        match self {
469            Span::Compiler(s) => SourceFile::nightly(s.source_file()),
470            Span::Fallback(s) => SourceFile::Fallback(s.source_file()),
471        }
472    }
473
474    #[cfg(any(super_unstable, feature = "span-locations"))]
475    pub fn start(&self) -> LineColumn {
476        match self {
477            #[cfg(proc_macro_span)]
478            Span::Compiler(s) => {
479                let proc_macro::LineColumn { line, column } = s.start();
480                LineColumn { line, column }
481            }
482            #[cfg(not(proc_macro_span))]
483            Span::Compiler(_) => LineColumn { line: 0, column: 0 },
484            Span::Fallback(s) => {
485                let fallback::LineColumn { line, column } = s.start();
486                LineColumn { line, column }
487            }
488        }
489    }
490
491    #[cfg(any(super_unstable, feature = "span-locations"))]
492    pub fn end(&self) -> LineColumn {
493        match self {
494            #[cfg(proc_macro_span)]
495            Span::Compiler(s) => {
496                let proc_macro::LineColumn { line, column } = s.end();
497                LineColumn { line, column }
498            }
499            #[cfg(not(proc_macro_span))]
500            Span::Compiler(_) => LineColumn { line: 0, column: 0 },
501            Span::Fallback(s) => {
502                let fallback::LineColumn { line, column } = s.end();
503                LineColumn { line, column }
504            }
505        }
506    }
507
508    #[cfg(super_unstable)]
509    pub fn before(&self) -> Span {
510        match self {
511            Span::Compiler(s) => Span::Compiler(s.before()),
512            Span::Fallback(s) => Span::Fallback(s.before()),
513        }
514    }
515
516    #[cfg(super_unstable)]
517    pub fn after(&self) -> Span {
518        match self {
519            Span::Compiler(s) => Span::Compiler(s.after()),
520            Span::Fallback(s) => Span::Fallback(s.after()),
521        }
522    }
523
524    pub fn join(&self, other: Span) -> Option<Span> {
525        let ret = match (self, other) {
526            #[cfg(proc_macro_span)]
527            (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?),
528            (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?),
529            _ => return None,
530        };
531        Some(ret)
532    }
533
534    #[cfg(super_unstable)]
535    pub fn eq(&self, other: &Span) -> bool {
536        match (self, other) {
537            (Span::Compiler(a), Span::Compiler(b)) => a.eq(b),
538            (Span::Fallback(a), Span::Fallback(b)) => a.eq(b),
539            _ => false,
540        }
541    }
542
543    fn unwrap_nightly(self) -> proc_macro::Span {
544        match self {
545            Span::Compiler(s) => s,
546            Span::Fallback(_) => mismatch(),
547        }
548    }
549}
550
551impl From<proc_macro::Span> for crate::Span {
552    fn from(proc_span: proc_macro::Span) -> crate::Span {
553        crate::Span::_new(Span::Compiler(proc_span))
554    }
555}
556
557impl From<fallback::Span> for Span {
558    fn from(inner: fallback::Span) -> Span {
559        Span::Fallback(inner)
560    }
561}
562
563impl Debug for Span {
564    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
565        match self {
566            Span::Compiler(s) => Debug::fmt(s, f),
567            Span::Fallback(s) => Debug::fmt(s, f),
568        }
569    }
570}
571
572pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) {
573    match span {
574        Span::Compiler(s) => {
575            debug.field("span", &s);
576        }
577        Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s),
578    }
579}
580
581#[derive(Clone)]
582pub(crate) enum Group {
583    Compiler(proc_macro::Group),
584    Fallback(fallback::Group),
585}
586
587impl Group {
588    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
589        match stream {
590            TokenStream::Compiler(tts) => {
591                let delimiter = match delimiter {
592                    Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
593                    Delimiter::Bracket => proc_macro::Delimiter::Bracket,
594                    Delimiter::Brace => proc_macro::Delimiter::Brace,
595                    Delimiter::None => proc_macro::Delimiter::None,
596                };
597                Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream()))
598            }
599            TokenStream::Fallback(stream) => {
600                Group::Fallback(fallback::Group::new(delimiter, stream))
601            }
602        }
603    }
604
605    pub fn delimiter(&self) -> Delimiter {
606        match self {
607            Group::Compiler(g) => match g.delimiter() {
608                proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
609                proc_macro::Delimiter::Bracket => Delimiter::Bracket,
610                proc_macro::Delimiter::Brace => Delimiter::Brace,
611                proc_macro::Delimiter::None => Delimiter::None,
612            },
613            Group::Fallback(g) => g.delimiter(),
614        }
615    }
616
617    pub fn stream(&self) -> TokenStream {
618        match self {
619            Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())),
620            Group::Fallback(g) => TokenStream::Fallback(g.stream()),
621        }
622    }
623
624    pub fn span(&self) -> Span {
625        match self {
626            Group::Compiler(g) => Span::Compiler(g.span()),
627            Group::Fallback(g) => Span::Fallback(g.span()),
628        }
629    }
630
631    pub fn span_open(&self) -> Span {
632        match self {
633            #[cfg(not(no_group_open_close))]
634            Group::Compiler(g) => Span::Compiler(g.span_open()),
635            #[cfg(no_group_open_close)]
636            Group::Compiler(g) => Span::Compiler(g.span()),
637            Group::Fallback(g) => Span::Fallback(g.span_open()),
638        }
639    }
640
641    pub fn span_close(&self) -> Span {
642        match self {
643            #[cfg(not(no_group_open_close))]
644            Group::Compiler(g) => Span::Compiler(g.span_close()),
645            #[cfg(no_group_open_close)]
646            Group::Compiler(g) => Span::Compiler(g.span()),
647            Group::Fallback(g) => Span::Fallback(g.span_close()),
648        }
649    }
650
651    pub fn set_span(&mut self, span: Span) {
652        match (self, span) {
653            (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s),
654            (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s),
655            _ => mismatch(),
656        }
657    }
658
659    fn unwrap_nightly(self) -> proc_macro::Group {
660        match self {
661            Group::Compiler(g) => g,
662            Group::Fallback(_) => mismatch(),
663        }
664    }
665}
666
667impl From<fallback::Group> for Group {
668    fn from(g: fallback::Group) -> Self {
669        Group::Fallback(g)
670    }
671}
672
673impl Display for Group {
674    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
675        match self {
676            Group::Compiler(group) => Display::fmt(group, formatter),
677            Group::Fallback(group) => Display::fmt(group, formatter),
678        }
679    }
680}
681
682impl Debug for Group {
683    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
684        match self {
685            Group::Compiler(group) => Debug::fmt(group, formatter),
686            Group::Fallback(group) => Debug::fmt(group, formatter),
687        }
688    }
689}
690
691#[derive(Clone)]
692pub(crate) enum Ident {
693    Compiler(proc_macro::Ident),
694    Fallback(fallback::Ident),
695}
696
697impl Ident {
698    pub fn new(string: &str, span: Span) -> Self {
699        match span {
700            Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)),
701            Span::Fallback(s) => Ident::Fallback(fallback::Ident::new(string, s)),
702        }
703    }
704
705    pub fn new_raw(string: &str, span: Span) -> Self {
706        match span {
707            #[cfg(not(no_ident_new_raw))]
708            Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)),
709            #[cfg(no_ident_new_raw)]
710            Span::Compiler(s) => {
711                let _ = proc_macro::Ident::new(string, s);
712                // At this point the un-r#-prefixed string is known to be a
713                // valid identifier. Try to produce a valid raw identifier by
714                // running the `TokenStream` parser, and unwrapping the first
715                // token as an `Ident`.
716                let raw_prefixed = format!("r#{}", string);
717                if let Ok(ts) = raw_prefixed.parse::<proc_macro::TokenStream>() {
718                    let mut iter = ts.into_iter();
719                    if let (Some(proc_macro::TokenTree::Ident(mut id)), None) =
720                        (iter.next(), iter.next())
721                    {
722                        id.set_span(s);
723                        return Ident::Compiler(id);
724                    }
725                }
726                panic!("not allowed as a raw identifier: `{}`", raw_prefixed)
727            }
728            Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw(string, s)),
729        }
730    }
731
732    pub fn span(&self) -> Span {
733        match self {
734            Ident::Compiler(t) => Span::Compiler(t.span()),
735            Ident::Fallback(t) => Span::Fallback(t.span()),
736        }
737    }
738
739    pub fn set_span(&mut self, span: Span) {
740        match (self, span) {
741            (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s),
742            (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s),
743            _ => mismatch(),
744        }
745    }
746
747    fn unwrap_nightly(self) -> proc_macro::Ident {
748        match self {
749            Ident::Compiler(s) => s,
750            Ident::Fallback(_) => mismatch(),
751        }
752    }
753}
754
755impl PartialEq for Ident {
756    fn eq(&self, other: &Ident) -> bool {
757        match (self, other) {
758            (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(),
759            (Ident::Fallback(t), Ident::Fallback(o)) => t == o,
760            _ => mismatch(),
761        }
762    }
763}
764
765impl<T> PartialEq<T> for Ident
766where
767    T: ?Sized + AsRef<str>,
768{
769    fn eq(&self, other: &T) -> bool {
770        let other = other.as_ref();
771        match self {
772            Ident::Compiler(t) => t.to_string() == other,
773            Ident::Fallback(t) => t == other,
774        }
775    }
776}
777
778impl Display for Ident {
779    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
780        match self {
781            Ident::Compiler(t) => Display::fmt(t, f),
782            Ident::Fallback(t) => Display::fmt(t, f),
783        }
784    }
785}
786
787impl Debug for Ident {
788    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
789        match self {
790            Ident::Compiler(t) => Debug::fmt(t, f),
791            Ident::Fallback(t) => Debug::fmt(t, f),
792        }
793    }
794}
795
796#[derive(Clone)]
797pub(crate) enum Literal {
798    Compiler(proc_macro::Literal),
799    Fallback(fallback::Literal),
800}
801
802macro_rules! suffixed_numbers {
803    ($($name:ident => $kind:ident,)*) => ($(
804        pub fn $name(n: $kind) -> Literal {
805            if inside_proc_macro() {
806                Literal::Compiler(proc_macro::Literal::$name(n))
807            } else {
808                Literal::Fallback(fallback::Literal::$name(n))
809            }
810        }
811    )*)
812}
813
814macro_rules! unsuffixed_integers {
815    ($($name:ident => $kind:ident,)*) => ($(
816        pub fn $name(n: $kind) -> Literal {
817            if inside_proc_macro() {
818                Literal::Compiler(proc_macro::Literal::$name(n))
819            } else {
820                Literal::Fallback(fallback::Literal::$name(n))
821            }
822        }
823    )*)
824}
825
826impl Literal {
827    pub unsafe fn from_str_unchecked(repr: &str) -> Self {
828        if inside_proc_macro() {
829            Literal::Compiler(compiler_literal_from_str(repr).expect("invalid literal"))
830        } else {
831            Literal::Fallback(fallback::Literal::from_str_unchecked(repr))
832        }
833    }
834
835    suffixed_numbers! {
836        u8_suffixed => u8,
837        u16_suffixed => u16,
838        u32_suffixed => u32,
839        u64_suffixed => u64,
840        u128_suffixed => u128,
841        usize_suffixed => usize,
842        i8_suffixed => i8,
843        i16_suffixed => i16,
844        i32_suffixed => i32,
845        i64_suffixed => i64,
846        i128_suffixed => i128,
847        isize_suffixed => isize,
848
849        f32_suffixed => f32,
850        f64_suffixed => f64,
851    }
852
853    unsuffixed_integers! {
854        u8_unsuffixed => u8,
855        u16_unsuffixed => u16,
856        u32_unsuffixed => u32,
857        u64_unsuffixed => u64,
858        u128_unsuffixed => u128,
859        usize_unsuffixed => usize,
860        i8_unsuffixed => i8,
861        i16_unsuffixed => i16,
862        i32_unsuffixed => i32,
863        i64_unsuffixed => i64,
864        i128_unsuffixed => i128,
865        isize_unsuffixed => isize,
866    }
867
868    pub fn f32_unsuffixed(f: f32) -> Literal {
869        if inside_proc_macro() {
870            Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f))
871        } else {
872            Literal::Fallback(fallback::Literal::f32_unsuffixed(f))
873        }
874    }
875
876    pub fn f64_unsuffixed(f: f64) -> Literal {
877        if inside_proc_macro() {
878            Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f))
879        } else {
880            Literal::Fallback(fallback::Literal::f64_unsuffixed(f))
881        }
882    }
883
884    pub fn string(t: &str) -> Literal {
885        if inside_proc_macro() {
886            Literal::Compiler(proc_macro::Literal::string(t))
887        } else {
888            Literal::Fallback(fallback::Literal::string(t))
889        }
890    }
891
892    pub fn character(t: char) -> Literal {
893        if inside_proc_macro() {
894            Literal::Compiler(proc_macro::Literal::character(t))
895        } else {
896            Literal::Fallback(fallback::Literal::character(t))
897        }
898    }
899
900    pub fn byte_string(bytes: &[u8]) -> Literal {
901        if inside_proc_macro() {
902            Literal::Compiler(proc_macro::Literal::byte_string(bytes))
903        } else {
904            Literal::Fallback(fallback::Literal::byte_string(bytes))
905        }
906    }
907
908    pub fn span(&self) -> Span {
909        match self {
910            Literal::Compiler(lit) => Span::Compiler(lit.span()),
911            Literal::Fallback(lit) => Span::Fallback(lit.span()),
912        }
913    }
914
915    pub fn set_span(&mut self, span: Span) {
916        match (self, span) {
917            (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s),
918            (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s),
919            _ => mismatch(),
920        }
921    }
922
923    pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
924        match self {
925            #[cfg(proc_macro_span)]
926            Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler),
927            #[cfg(not(proc_macro_span))]
928            Literal::Compiler(_lit) => None,
929            Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback),
930        }
931    }
932
933    fn unwrap_nightly(self) -> proc_macro::Literal {
934        match self {
935            Literal::Compiler(s) => s,
936            Literal::Fallback(_) => mismatch(),
937        }
938    }
939}
940
941impl From<fallback::Literal> for Literal {
942    fn from(s: fallback::Literal) -> Literal {
943        Literal::Fallback(s)
944    }
945}
946
947impl FromStr for Literal {
948    type Err = LexError;
949
950    fn from_str(repr: &str) -> Result<Self, Self::Err> {
951        if inside_proc_macro() {
952            compiler_literal_from_str(repr).map(Literal::Compiler)
953        } else {
954            let literal = fallback::Literal::from_str(repr)?;
955            Ok(Literal::Fallback(literal))
956        }
957    }
958}
959
960fn compiler_literal_from_str(repr: &str) -> Result<proc_macro::Literal, LexError> {
961    #[cfg(not(no_literal_from_str))]
962    {
963        proc_macro::Literal::from_str(repr).map_err(LexError::Compiler)
964    }
965    #[cfg(no_literal_from_str)]
966    {
967        let tokens = proc_macro_parse(repr)?;
968        let mut iter = tokens.into_iter();
969        if let (Some(proc_macro::TokenTree::Literal(literal)), None) = (iter.next(), iter.next()) {
970            if literal.to_string().len() == repr.len() {
971                return Ok(literal);
972            }
973        }
974        Err(LexError::call_site())
975    }
976}
977
978impl Display for Literal {
979    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
980        match self {
981            Literal::Compiler(t) => Display::fmt(t, f),
982            Literal::Fallback(t) => Display::fmt(t, f),
983        }
984    }
985}
986
987impl Debug for Literal {
988    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
989        match self {
990            Literal::Compiler(t) => Debug::fmt(t, f),
991            Literal::Fallback(t) => Debug::fmt(t, f),
992        }
993    }
994}