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