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