1 use std::fmt;
2 use std::iter;
3 use std::ops::RangeBounds;
4 use std::panic::{self, PanicInfo};
5 #[cfg(super_unstable)]
6 use std::path::PathBuf;
7 use std::str::FromStr;
8 
9 use crate::{fallback, Delimiter, Punct, Spacing, TokenTree};
10 
11 #[derive(Clone)]
12 pub 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 struct DeferredTokenStream {
23     stream: proc_macro::TokenStream,
24     extra: Vec<proc_macro::TokenTree>,
25 }
26 
27 pub enum LexError {
28     Compiler(proc_macro::LexError),
29     Fallback(fallback::LexError),
30 }
31 
nightly_works() -> bool32 fn nightly_works() -> bool {
33     use std::sync::atomic::*;
34     use std::sync::Once;
35 
36     static WORKS: AtomicUsize = AtomicUsize::new(0);
37     static INIT: Once = Once::new();
38 
39     match WORKS.load(Ordering::SeqCst) {
40         1 => return false,
41         2 => return true,
42         _ => {}
43     }
44 
45     // Swap in a null panic hook to avoid printing "thread panicked" to stderr,
46     // then use catch_unwind to determine whether the compiler's proc_macro is
47     // working. When proc-macro2 is used from outside of a procedural macro all
48     // of the proc_macro crate's APIs currently panic.
49     //
50     // The Once is to prevent the possibility of this ordering:
51     //
52     //     thread 1 calls take_hook, gets the user's original hook
53     //     thread 1 calls set_hook with the null hook
54     //     thread 2 calls take_hook, thinks null hook is the original hook
55     //     thread 2 calls set_hook with the null hook
56     //     thread 1 calls set_hook with the actual original hook
57     //     thread 2 calls set_hook with what it thinks is the original hook
58     //
59     // in which the user's hook has been lost.
60     //
61     // There is still a race condition where a panic in a different thread can
62     // happen during the interval that the user's original panic hook is
63     // unregistered such that their hook is incorrectly not called. This is
64     // sufficiently unlikely and less bad than printing panic messages to stderr
65     // on correct use of this crate. Maybe there is a libstd feature request
66     // here. For now, if a user needs to guarantee that this failure mode does
67     // not occur, they need to call e.g. `proc_macro2::Span::call_site()` from
68     // the main thread before launching any other threads.
69     INIT.call_once(|| {
70         type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static;
71 
72         let null_hook: Box<PanicHook> = Box::new(|_panic_info| { /* ignore */ });
73         let sanity_check = &*null_hook as *const PanicHook;
74         let original_hook = panic::take_hook();
75         panic::set_hook(null_hook);
76 
77         let works = panic::catch_unwind(|| proc_macro::Span::call_site()).is_ok();
78         WORKS.store(works as usize + 1, Ordering::SeqCst);
79 
80         let hopefully_null_hook = panic::take_hook();
81         panic::set_hook(original_hook);
82         if sanity_check != &*hopefully_null_hook {
83             panic!("observed race condition in proc_macro2::nightly_works");
84         }
85     });
86     nightly_works()
87 }
88 
mismatch() -> !89 fn mismatch() -> ! {
90     panic!("stable/nightly mismatch")
91 }
92 
93 impl DeferredTokenStream {
new(stream: proc_macro::TokenStream) -> Self94     fn new(stream: proc_macro::TokenStream) -> Self {
95         DeferredTokenStream {
96             stream,
97             extra: Vec::new(),
98         }
99     }
100 
is_empty(&self) -> bool101     fn is_empty(&self) -> bool {
102         self.stream.is_empty() && self.extra.is_empty()
103     }
104 
evaluate_now(&mut self)105     fn evaluate_now(&mut self) {
106         self.stream.extend(self.extra.drain(..));
107     }
108 
into_token_stream(mut self) -> proc_macro::TokenStream109     fn into_token_stream(mut self) -> proc_macro::TokenStream {
110         self.evaluate_now();
111         self.stream
112     }
113 }
114 
115 impl TokenStream {
new() -> TokenStream116     pub fn new() -> TokenStream {
117         if nightly_works() {
118             TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new()))
119         } else {
120             TokenStream::Fallback(fallback::TokenStream::new())
121         }
122     }
123 
is_empty(&self) -> bool124     pub fn is_empty(&self) -> bool {
125         match self {
126             TokenStream::Compiler(tts) => tts.is_empty(),
127             TokenStream::Fallback(tts) => tts.is_empty(),
128         }
129     }
130 
unwrap_nightly(self) -> proc_macro::TokenStream131     fn unwrap_nightly(self) -> proc_macro::TokenStream {
132         match self {
133             TokenStream::Compiler(s) => s.into_token_stream(),
134             TokenStream::Fallback(_) => mismatch(),
135         }
136     }
137 
unwrap_stable(self) -> fallback::TokenStream138     fn unwrap_stable(self) -> fallback::TokenStream {
139         match self {
140             TokenStream::Compiler(_) => mismatch(),
141             TokenStream::Fallback(s) => s,
142         }
143     }
144 }
145 
146 impl FromStr for TokenStream {
147     type Err = LexError;
148 
from_str(src: &str) -> Result<TokenStream, LexError>149     fn from_str(src: &str) -> Result<TokenStream, LexError> {
150         if nightly_works() {
151             Ok(TokenStream::Compiler(DeferredTokenStream::new(
152                 proc_macro_parse(src)?,
153             )))
154         } else {
155             Ok(TokenStream::Fallback(src.parse()?))
156         }
157     }
158 }
159 
160 // Work around https://github.com/rust-lang/rust/issues/58736.
proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError>161 fn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> {
162     panic::catch_unwind(|| src.parse().map_err(LexError::Compiler))
163         .unwrap_or(Err(LexError::Fallback(fallback::LexError)))
164 }
165 
166 impl fmt::Display for TokenStream {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result167     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168         match self {
169             TokenStream::Compiler(tts) => tts.clone().into_token_stream().fmt(f),
170             TokenStream::Fallback(tts) => tts.fmt(f),
171         }
172     }
173 }
174 
175 impl From<proc_macro::TokenStream> for TokenStream {
from(inner: proc_macro::TokenStream) -> TokenStream176     fn from(inner: proc_macro::TokenStream) -> TokenStream {
177         TokenStream::Compiler(DeferredTokenStream::new(inner))
178     }
179 }
180 
181 impl From<TokenStream> for proc_macro::TokenStream {
from(inner: TokenStream) -> proc_macro::TokenStream182     fn from(inner: TokenStream) -> proc_macro::TokenStream {
183         match inner {
184             TokenStream::Compiler(inner) => inner.into_token_stream(),
185             TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(),
186         }
187     }
188 }
189 
190 impl From<fallback::TokenStream> for TokenStream {
from(inner: fallback::TokenStream) -> TokenStream191     fn from(inner: fallback::TokenStream) -> TokenStream {
192         TokenStream::Fallback(inner)
193     }
194 }
195 
196 // Assumes nightly_works().
into_compiler_token(token: TokenTree) -> proc_macro::TokenTree197 fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
198     match token {
199         TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
200         TokenTree::Punct(tt) => {
201             let spacing = match tt.spacing() {
202                 Spacing::Joint => proc_macro::Spacing::Joint,
203                 Spacing::Alone => proc_macro::Spacing::Alone,
204             };
205             let mut op = proc_macro::Punct::new(tt.as_char(), spacing);
206             op.set_span(tt.span().inner.unwrap_nightly());
207             op.into()
208         }
209         TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
210         TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
211     }
212 }
213 
214 impl From<TokenTree> for TokenStream {
from(token: TokenTree) -> TokenStream215     fn from(token: TokenTree) -> TokenStream {
216         if nightly_works() {
217             TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into()))
218         } else {
219             TokenStream::Fallback(token.into())
220         }
221     }
222 }
223 
224 impl iter::FromIterator<TokenTree> for TokenStream {
from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self225     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
226         if nightly_works() {
227             TokenStream::Compiler(DeferredTokenStream::new(
228                 trees.into_iter().map(into_compiler_token).collect(),
229             ))
230         } else {
231             TokenStream::Fallback(trees.into_iter().collect())
232         }
233     }
234 }
235 
236 impl iter::FromIterator<TokenStream> for TokenStream {
from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self237     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
238         let mut streams = streams.into_iter();
239         match streams.next() {
240             Some(TokenStream::Compiler(mut first)) => {
241                 first.evaluate_now();
242                 first.stream.extend(streams.map(|s| match s {
243                     TokenStream::Compiler(s) => s.into_token_stream(),
244                     TokenStream::Fallback(_) => mismatch(),
245                 }));
246                 TokenStream::Compiler(first)
247             }
248             Some(TokenStream::Fallback(mut first)) => {
249                 first.extend(streams.map(|s| match s {
250                     TokenStream::Fallback(s) => s,
251                     TokenStream::Compiler(_) => mismatch(),
252                 }));
253                 TokenStream::Fallback(first)
254             }
255             None => TokenStream::new(),
256         }
257     }
258 }
259 
260 impl Extend<TokenTree> for TokenStream {
extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I)261     fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
262         match self {
263             TokenStream::Compiler(tts) => {
264                 // Here is the reason for DeferredTokenStream.
265                 tts.extra
266                     .extend(streams.into_iter().map(into_compiler_token));
267             }
268             TokenStream::Fallback(tts) => tts.extend(streams),
269         }
270     }
271 }
272 
273 impl Extend<TokenStream> for TokenStream {
extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I)274     fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
275         match self {
276             TokenStream::Compiler(tts) => {
277                 tts.evaluate_now();
278                 tts.stream
279                     .extend(streams.into_iter().map(|stream| stream.unwrap_nightly()));
280             }
281             TokenStream::Fallback(tts) => {
282                 tts.extend(streams.into_iter().map(|stream| stream.unwrap_stable()));
283             }
284         }
285     }
286 }
287 
288 impl fmt::Debug for TokenStream {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result289     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290         match self {
291             TokenStream::Compiler(tts) => tts.clone().into_token_stream().fmt(f),
292             TokenStream::Fallback(tts) => tts.fmt(f),
293         }
294     }
295 }
296 
297 impl From<proc_macro::LexError> for LexError {
from(e: proc_macro::LexError) -> LexError298     fn from(e: proc_macro::LexError) -> LexError {
299         LexError::Compiler(e)
300     }
301 }
302 
303 impl From<fallback::LexError> for LexError {
from(e: fallback::LexError) -> LexError304     fn from(e: fallback::LexError) -> LexError {
305         LexError::Fallback(e)
306     }
307 }
308 
309 impl fmt::Debug for LexError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result310     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
311         match self {
312             LexError::Compiler(e) => e.fmt(f),
313             LexError::Fallback(e) => e.fmt(f),
314         }
315     }
316 }
317 
318 #[derive(Clone)]
319 pub enum TokenTreeIter {
320     Compiler(proc_macro::token_stream::IntoIter),
321     Fallback(fallback::TokenTreeIter),
322 }
323 
324 impl IntoIterator for TokenStream {
325     type Item = TokenTree;
326     type IntoIter = TokenTreeIter;
327 
into_iter(self) -> TokenTreeIter328     fn into_iter(self) -> TokenTreeIter {
329         match self {
330             TokenStream::Compiler(tts) => {
331                 TokenTreeIter::Compiler(tts.into_token_stream().into_iter())
332             }
333             TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()),
334         }
335     }
336 }
337 
338 impl Iterator for TokenTreeIter {
339     type Item = TokenTree;
340 
next(&mut self) -> Option<TokenTree>341     fn next(&mut self) -> Option<TokenTree> {
342         let token = match self {
343             TokenTreeIter::Compiler(iter) => iter.next()?,
344             TokenTreeIter::Fallback(iter) => return iter.next(),
345         };
346         Some(match token {
347             proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
348             proc_macro::TokenTree::Punct(tt) => {
349                 let spacing = match tt.spacing() {
350                     proc_macro::Spacing::Joint => Spacing::Joint,
351                     proc_macro::Spacing::Alone => Spacing::Alone,
352                 };
353                 let mut o = Punct::new(tt.as_char(), spacing);
354                 o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
355                 o.into()
356             }
357             proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
358             proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
359         })
360     }
361 
size_hint(&self) -> (usize, Option<usize>)362     fn size_hint(&self) -> (usize, Option<usize>) {
363         match self {
364             TokenTreeIter::Compiler(tts) => tts.size_hint(),
365             TokenTreeIter::Fallback(tts) => tts.size_hint(),
366         }
367     }
368 }
369 
370 impl fmt::Debug for TokenTreeIter {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result371     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
372         f.debug_struct("TokenTreeIter").finish()
373     }
374 }
375 
376 #[derive(Clone, PartialEq, Eq)]
377 #[cfg(super_unstable)]
378 pub enum SourceFile {
379     Compiler(proc_macro::SourceFile),
380     Fallback(fallback::SourceFile),
381 }
382 
383 #[cfg(super_unstable)]
384 impl SourceFile {
nightly(sf: proc_macro::SourceFile) -> Self385     fn nightly(sf: proc_macro::SourceFile) -> Self {
386         SourceFile::Compiler(sf)
387     }
388 
389     /// Get the path to this source file as a string.
path(&self) -> PathBuf390     pub fn path(&self) -> PathBuf {
391         match self {
392             SourceFile::Compiler(a) => a.path(),
393             SourceFile::Fallback(a) => a.path(),
394         }
395     }
396 
is_real(&self) -> bool397     pub fn is_real(&self) -> bool {
398         match self {
399             SourceFile::Compiler(a) => a.is_real(),
400             SourceFile::Fallback(a) => a.is_real(),
401         }
402     }
403 }
404 
405 #[cfg(super_unstable)]
406 impl fmt::Debug for SourceFile {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result407     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
408         match self {
409             SourceFile::Compiler(a) => a.fmt(f),
410             SourceFile::Fallback(a) => a.fmt(f),
411         }
412     }
413 }
414 
415 #[cfg(any(super_unstable, feature = "span-locations"))]
416 pub struct LineColumn {
417     pub line: usize,
418     pub column: usize,
419 }
420 
421 #[derive(Copy, Clone)]
422 pub enum Span {
423     Compiler(proc_macro::Span),
424     Fallback(fallback::Span),
425 }
426 
427 impl Span {
call_site() -> Span428     pub fn call_site() -> Span {
429         if nightly_works() {
430             Span::Compiler(proc_macro::Span::call_site())
431         } else {
432             Span::Fallback(fallback::Span::call_site())
433         }
434     }
435 
436     #[cfg(super_unstable)]
def_site() -> Span437     pub fn def_site() -> Span {
438         if nightly_works() {
439             Span::Compiler(proc_macro::Span::def_site())
440         } else {
441             Span::Fallback(fallback::Span::def_site())
442         }
443     }
444 
445     #[cfg(super_unstable)]
resolved_at(&self, other: Span) -> Span446     pub fn resolved_at(&self, other: Span) -> Span {
447         match (self, other) {
448             (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)),
449             (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)),
450             _ => mismatch(),
451         }
452     }
453 
454     #[cfg(super_unstable)]
located_at(&self, other: Span) -> Span455     pub fn located_at(&self, other: Span) -> Span {
456         match (self, other) {
457             (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)),
458             (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)),
459             _ => mismatch(),
460         }
461     }
462 
unwrap(self) -> proc_macro::Span463     pub fn unwrap(self) -> proc_macro::Span {
464         match self {
465             Span::Compiler(s) => s,
466             Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"),
467         }
468     }
469 
470     #[cfg(super_unstable)]
source_file(&self) -> SourceFile471     pub fn source_file(&self) -> SourceFile {
472         match self {
473             Span::Compiler(s) => SourceFile::nightly(s.source_file()),
474             Span::Fallback(s) => SourceFile::Fallback(s.source_file()),
475         }
476     }
477 
478     #[cfg(any(super_unstable, feature = "span-locations"))]
start(&self) -> LineColumn479     pub fn start(&self) -> LineColumn {
480         match self {
481             #[cfg(proc_macro_span)]
482             Span::Compiler(s) => {
483                 let proc_macro::LineColumn { line, column } = s.start();
484                 LineColumn { line, column }
485             }
486             #[cfg(not(proc_macro_span))]
487             Span::Compiler(_) => LineColumn { line: 0, column: 0 },
488             Span::Fallback(s) => {
489                 let fallback::LineColumn { line, column } = s.start();
490                 LineColumn { line, column }
491             }
492         }
493     }
494 
495     #[cfg(any(super_unstable, feature = "span-locations"))]
end(&self) -> LineColumn496     pub fn end(&self) -> LineColumn {
497         match self {
498             #[cfg(proc_macro_span)]
499             Span::Compiler(s) => {
500                 let proc_macro::LineColumn { line, column } = s.end();
501                 LineColumn { line, column }
502             }
503             #[cfg(not(proc_macro_span))]
504             Span::Compiler(_) => LineColumn { line: 0, column: 0 },
505             Span::Fallback(s) => {
506                 let fallback::LineColumn { line, column } = s.end();
507                 LineColumn { line, column }
508             }
509         }
510     }
511 
join(&self, other: Span) -> Option<Span>512     pub fn join(&self, other: Span) -> Option<Span> {
513         let ret = match (self, other) {
514             #[cfg(proc_macro_span)]
515             (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?),
516             (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?),
517             _ => return None,
518         };
519         Some(ret)
520     }
521 
522     #[cfg(super_unstable)]
eq(&self, other: &Span) -> bool523     pub fn eq(&self, other: &Span) -> bool {
524         match (self, other) {
525             (Span::Compiler(a), Span::Compiler(b)) => a.eq(b),
526             (Span::Fallback(a), Span::Fallback(b)) => a.eq(b),
527             _ => false,
528         }
529     }
530 
unwrap_nightly(self) -> proc_macro::Span531     fn unwrap_nightly(self) -> proc_macro::Span {
532         match self {
533             Span::Compiler(s) => s,
534             Span::Fallback(_) => mismatch(),
535         }
536     }
537 }
538 
539 impl From<proc_macro::Span> for crate::Span {
from(proc_span: proc_macro::Span) -> crate::Span540     fn from(proc_span: proc_macro::Span) -> crate::Span {
541         crate::Span::_new(Span::Compiler(proc_span))
542     }
543 }
544 
545 impl From<fallback::Span> for Span {
from(inner: fallback::Span) -> Span546     fn from(inner: fallback::Span) -> Span {
547         Span::Fallback(inner)
548     }
549 }
550 
551 impl fmt::Debug for Span {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result552     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
553         match self {
554             Span::Compiler(s) => s.fmt(f),
555             Span::Fallback(s) => s.fmt(f),
556         }
557     }
558 }
559 
debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span)560 pub fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) {
561     match span {
562         Span::Compiler(s) => {
563             debug.field("span", &s);
564         }
565         Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s),
566     }
567 }
568 
569 #[derive(Clone)]
570 pub enum Group {
571     Compiler(proc_macro::Group),
572     Fallback(fallback::Group),
573 }
574 
575 impl Group {
new(delimiter: Delimiter, stream: TokenStream) -> Group576     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
577         match stream {
578             TokenStream::Compiler(tts) => {
579                 let delimiter = match delimiter {
580                     Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
581                     Delimiter::Bracket => proc_macro::Delimiter::Bracket,
582                     Delimiter::Brace => proc_macro::Delimiter::Brace,
583                     Delimiter::None => proc_macro::Delimiter::None,
584                 };
585                 Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream()))
586             }
587             TokenStream::Fallback(stream) => {
588                 Group::Fallback(fallback::Group::new(delimiter, stream))
589             }
590         }
591     }
592 
delimiter(&self) -> Delimiter593     pub fn delimiter(&self) -> Delimiter {
594         match self {
595             Group::Compiler(g) => match g.delimiter() {
596                 proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
597                 proc_macro::Delimiter::Bracket => Delimiter::Bracket,
598                 proc_macro::Delimiter::Brace => Delimiter::Brace,
599                 proc_macro::Delimiter::None => Delimiter::None,
600             },
601             Group::Fallback(g) => g.delimiter(),
602         }
603     }
604 
stream(&self) -> TokenStream605     pub fn stream(&self) -> TokenStream {
606         match self {
607             Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())),
608             Group::Fallback(g) => TokenStream::Fallback(g.stream()),
609         }
610     }
611 
span(&self) -> Span612     pub fn span(&self) -> Span {
613         match self {
614             Group::Compiler(g) => Span::Compiler(g.span()),
615             Group::Fallback(g) => Span::Fallback(g.span()),
616         }
617     }
618 
span_open(&self) -> Span619     pub fn span_open(&self) -> Span {
620         match self {
621             #[cfg(proc_macro_span)]
622             Group::Compiler(g) => Span::Compiler(g.span_open()),
623             #[cfg(not(proc_macro_span))]
624             Group::Compiler(g) => Span::Compiler(g.span()),
625             Group::Fallback(g) => Span::Fallback(g.span_open()),
626         }
627     }
628 
span_close(&self) -> Span629     pub fn span_close(&self) -> Span {
630         match self {
631             #[cfg(proc_macro_span)]
632             Group::Compiler(g) => Span::Compiler(g.span_close()),
633             #[cfg(not(proc_macro_span))]
634             Group::Compiler(g) => Span::Compiler(g.span()),
635             Group::Fallback(g) => Span::Fallback(g.span_close()),
636         }
637     }
638 
set_span(&mut self, span: Span)639     pub fn set_span(&mut self, span: Span) {
640         match (self, span) {
641             (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s),
642             (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s),
643             _ => mismatch(),
644         }
645     }
646 
unwrap_nightly(self) -> proc_macro::Group647     fn unwrap_nightly(self) -> proc_macro::Group {
648         match self {
649             Group::Compiler(g) => g,
650             Group::Fallback(_) => mismatch(),
651         }
652     }
653 }
654 
655 impl From<fallback::Group> for Group {
from(g: fallback::Group) -> Self656     fn from(g: fallback::Group) -> Self {
657         Group::Fallback(g)
658     }
659 }
660 
661 impl fmt::Display for Group {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result662     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
663         match self {
664             Group::Compiler(group) => group.fmt(formatter),
665             Group::Fallback(group) => group.fmt(formatter),
666         }
667     }
668 }
669 
670 impl fmt::Debug for Group {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result671     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
672         match self {
673             Group::Compiler(group) => group.fmt(formatter),
674             Group::Fallback(group) => group.fmt(formatter),
675         }
676     }
677 }
678 
679 #[derive(Clone)]
680 pub enum Ident {
681     Compiler(proc_macro::Ident),
682     Fallback(fallback::Ident),
683 }
684 
685 impl Ident {
new(string: &str, span: Span) -> Ident686     pub fn new(string: &str, span: Span) -> Ident {
687         match span {
688             Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)),
689             Span::Fallback(s) => Ident::Fallback(fallback::Ident::new(string, s)),
690         }
691     }
692 
new_raw(string: &str, span: Span) -> Ident693     pub fn new_raw(string: &str, span: Span) -> Ident {
694         match span {
695             Span::Compiler(s) => {
696                 let p: proc_macro::TokenStream = string.parse().unwrap();
697                 let ident = match p.into_iter().next() {
698                     Some(proc_macro::TokenTree::Ident(mut i)) => {
699                         i.set_span(s);
700                         i
701                     }
702                     _ => panic!(),
703                 };
704                 Ident::Compiler(ident)
705             }
706             Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw(string, s)),
707         }
708     }
709 
span(&self) -> Span710     pub fn span(&self) -> Span {
711         match self {
712             Ident::Compiler(t) => Span::Compiler(t.span()),
713             Ident::Fallback(t) => Span::Fallback(t.span()),
714         }
715     }
716 
set_span(&mut self, span: Span)717     pub fn set_span(&mut self, span: Span) {
718         match (self, span) {
719             (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s),
720             (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s),
721             _ => mismatch(),
722         }
723     }
724 
unwrap_nightly(self) -> proc_macro::Ident725     fn unwrap_nightly(self) -> proc_macro::Ident {
726         match self {
727             Ident::Compiler(s) => s,
728             Ident::Fallback(_) => mismatch(),
729         }
730     }
731 }
732 
733 impl PartialEq for Ident {
eq(&self, other: &Ident) -> bool734     fn eq(&self, other: &Ident) -> bool {
735         match (self, other) {
736             (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(),
737             (Ident::Fallback(t), Ident::Fallback(o)) => t == o,
738             _ => mismatch(),
739         }
740     }
741 }
742 
743 impl<T> PartialEq<T> for Ident
744 where
745     T: ?Sized + AsRef<str>,
746 {
eq(&self, other: &T) -> bool747     fn eq(&self, other: &T) -> bool {
748         let other = other.as_ref();
749         match self {
750             Ident::Compiler(t) => t.to_string() == other,
751             Ident::Fallback(t) => t == other,
752         }
753     }
754 }
755 
756 impl fmt::Display for Ident {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result757     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
758         match self {
759             Ident::Compiler(t) => t.fmt(f),
760             Ident::Fallback(t) => t.fmt(f),
761         }
762     }
763 }
764 
765 impl fmt::Debug for Ident {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result766     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
767         match self {
768             Ident::Compiler(t) => t.fmt(f),
769             Ident::Fallback(t) => t.fmt(f),
770         }
771     }
772 }
773 
774 #[derive(Clone)]
775 pub enum Literal {
776     Compiler(proc_macro::Literal),
777     Fallback(fallback::Literal),
778 }
779 
780 macro_rules! suffixed_numbers {
781     ($($name:ident => $kind:ident,)*) => ($(
782         pub fn $name(n: $kind) -> Literal {
783             if nightly_works() {
784                 Literal::Compiler(proc_macro::Literal::$name(n))
785             } else {
786                 Literal::Fallback(fallback::Literal::$name(n))
787             }
788         }
789     )*)
790 }
791 
792 macro_rules! unsuffixed_integers {
793     ($($name:ident => $kind:ident,)*) => ($(
794         pub fn $name(n: $kind) -> Literal {
795             if nightly_works() {
796                 Literal::Compiler(proc_macro::Literal::$name(n))
797             } else {
798                 Literal::Fallback(fallback::Literal::$name(n))
799             }
800         }
801     )*)
802 }
803 
804 impl Literal {
805     suffixed_numbers! {
806         u8_suffixed => u8,
807         u16_suffixed => u16,
808         u32_suffixed => u32,
809         u64_suffixed => u64,
810         u128_suffixed => u128,
811         usize_suffixed => usize,
812         i8_suffixed => i8,
813         i16_suffixed => i16,
814         i32_suffixed => i32,
815         i64_suffixed => i64,
816         i128_suffixed => i128,
817         isize_suffixed => isize,
818 
819         f32_suffixed => f32,
820         f64_suffixed => f64,
821     }
822 
823     unsuffixed_integers! {
824         u8_unsuffixed => u8,
825         u16_unsuffixed => u16,
826         u32_unsuffixed => u32,
827         u64_unsuffixed => u64,
828         u128_unsuffixed => u128,
829         usize_unsuffixed => usize,
830         i8_unsuffixed => i8,
831         i16_unsuffixed => i16,
832         i32_unsuffixed => i32,
833         i64_unsuffixed => i64,
834         i128_unsuffixed => i128,
835         isize_unsuffixed => isize,
836     }
837 
f32_unsuffixed(f: f32) -> Literal838     pub fn f32_unsuffixed(f: f32) -> Literal {
839         if nightly_works() {
840             Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f))
841         } else {
842             Literal::Fallback(fallback::Literal::f32_unsuffixed(f))
843         }
844     }
845 
f64_unsuffixed(f: f64) -> Literal846     pub fn f64_unsuffixed(f: f64) -> Literal {
847         if nightly_works() {
848             Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f))
849         } else {
850             Literal::Fallback(fallback::Literal::f64_unsuffixed(f))
851         }
852     }
853 
string(t: &str) -> Literal854     pub fn string(t: &str) -> Literal {
855         if nightly_works() {
856             Literal::Compiler(proc_macro::Literal::string(t))
857         } else {
858             Literal::Fallback(fallback::Literal::string(t))
859         }
860     }
861 
character(t: char) -> Literal862     pub fn character(t: char) -> Literal {
863         if nightly_works() {
864             Literal::Compiler(proc_macro::Literal::character(t))
865         } else {
866             Literal::Fallback(fallback::Literal::character(t))
867         }
868     }
869 
byte_string(bytes: &[u8]) -> Literal870     pub fn byte_string(bytes: &[u8]) -> Literal {
871         if nightly_works() {
872             Literal::Compiler(proc_macro::Literal::byte_string(bytes))
873         } else {
874             Literal::Fallback(fallback::Literal::byte_string(bytes))
875         }
876     }
877 
span(&self) -> Span878     pub fn span(&self) -> Span {
879         match self {
880             Literal::Compiler(lit) => Span::Compiler(lit.span()),
881             Literal::Fallback(lit) => Span::Fallback(lit.span()),
882         }
883     }
884 
set_span(&mut self, span: Span)885     pub fn set_span(&mut self, span: Span) {
886         match (self, span) {
887             (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s),
888             (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s),
889             _ => mismatch(),
890         }
891     }
892 
subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span>893     pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
894         match self {
895             #[cfg(proc_macro_span)]
896             Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler),
897             #[cfg(not(proc_macro_span))]
898             Literal::Compiler(_lit) => None,
899             Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback),
900         }
901     }
902 
unwrap_nightly(self) -> proc_macro::Literal903     fn unwrap_nightly(self) -> proc_macro::Literal {
904         match self {
905             Literal::Compiler(s) => s,
906             Literal::Fallback(_) => mismatch(),
907         }
908     }
909 }
910 
911 impl From<fallback::Literal> for Literal {
from(s: fallback::Literal) -> Literal912     fn from(s: fallback::Literal) -> Literal {
913         Literal::Fallback(s)
914     }
915 }
916 
917 impl fmt::Display for Literal {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result918     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
919         match self {
920             Literal::Compiler(t) => t.fmt(f),
921             Literal::Fallback(t) => t.fmt(f),
922         }
923     }
924 }
925 
926 impl fmt::Debug for Literal {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result927     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
928         match self {
929             Literal::Compiler(t) => t.fmt(f),
930             Literal::Fallback(t) => t.fmt(f),
931         }
932     }
933 }
934