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