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