1 use crate::detection::inside_proc_macro;
2 use crate::{fallback, Delimiter, Punct, Spacing, TokenTree};
3 use std::fmt;
4 use std::iter;
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         self.stream.extend(self.extra.drain(..));
50     }
51 
into_token_stream(mut self) -> proc_macro::TokenStream52     fn into_token_stream(mut self) -> proc_macro::TokenStream {
53         self.evaluate_now();
54         self.stream
55     }
56 }
57 
58 impl TokenStream {
new() -> TokenStream59     pub fn new() -> TokenStream {
60         if inside_proc_macro() {
61             TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new()))
62         } else {
63             TokenStream::Fallback(fallback::TokenStream::new())
64         }
65     }
66 
is_empty(&self) -> bool67     pub fn is_empty(&self) -> bool {
68         match self {
69             TokenStream::Compiler(tts) => tts.is_empty(),
70             TokenStream::Fallback(tts) => tts.is_empty(),
71         }
72     }
73 
unwrap_nightly(self) -> proc_macro::TokenStream74     fn unwrap_nightly(self) -> proc_macro::TokenStream {
75         match self {
76             TokenStream::Compiler(s) => s.into_token_stream(),
77             TokenStream::Fallback(_) => mismatch(),
78         }
79     }
80 
unwrap_stable(self) -> fallback::TokenStream81     fn unwrap_stable(self) -> fallback::TokenStream {
82         match self {
83             TokenStream::Compiler(_) => mismatch(),
84             TokenStream::Fallback(s) => s,
85         }
86     }
87 }
88 
89 impl FromStr for TokenStream {
90     type Err = LexError;
91 
from_str(src: &str) -> Result<TokenStream, LexError>92     fn from_str(src: &str) -> Result<TokenStream, LexError> {
93         if inside_proc_macro() {
94             Ok(TokenStream::Compiler(DeferredTokenStream::new(
95                 proc_macro_parse(src)?,
96             )))
97         } else {
98             Ok(TokenStream::Fallback(src.parse()?))
99         }
100     }
101 }
102 
103 // Work around https://github.com/rust-lang/rust/issues/58736.
proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError>104 fn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> {
105     panic::catch_unwind(|| src.parse().map_err(LexError::Compiler))
106         .unwrap_or(Err(LexError::Fallback(fallback::LexError)))
107 }
108 
109 impl fmt::Display for TokenStream {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result110     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111         match self {
112             TokenStream::Compiler(tts) => tts.clone().into_token_stream().fmt(f),
113             TokenStream::Fallback(tts) => tts.fmt(f),
114         }
115     }
116 }
117 
118 impl From<proc_macro::TokenStream> for TokenStream {
from(inner: proc_macro::TokenStream) -> TokenStream119     fn from(inner: proc_macro::TokenStream) -> TokenStream {
120         TokenStream::Compiler(DeferredTokenStream::new(inner))
121     }
122 }
123 
124 impl From<TokenStream> for proc_macro::TokenStream {
from(inner: TokenStream) -> proc_macro::TokenStream125     fn from(inner: TokenStream) -> proc_macro::TokenStream {
126         match inner {
127             TokenStream::Compiler(inner) => inner.into_token_stream(),
128             TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(),
129         }
130     }
131 }
132 
133 impl From<fallback::TokenStream> for TokenStream {
from(inner: fallback::TokenStream) -> TokenStream134     fn from(inner: fallback::TokenStream) -> TokenStream {
135         TokenStream::Fallback(inner)
136     }
137 }
138 
139 // Assumes inside_proc_macro().
into_compiler_token(token: TokenTree) -> proc_macro::TokenTree140 fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
141     match token {
142         TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
143         TokenTree::Punct(tt) => {
144             let spacing = match tt.spacing() {
145                 Spacing::Joint => proc_macro::Spacing::Joint,
146                 Spacing::Alone => proc_macro::Spacing::Alone,
147             };
148             let mut op = proc_macro::Punct::new(tt.as_char(), spacing);
149             op.set_span(tt.span().inner.unwrap_nightly());
150             op.into()
151         }
152         TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
153         TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
154     }
155 }
156 
157 impl From<TokenTree> for TokenStream {
from(token: TokenTree) -> TokenStream158     fn from(token: TokenTree) -> TokenStream {
159         if inside_proc_macro() {
160             TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into()))
161         } else {
162             TokenStream::Fallback(token.into())
163         }
164     }
165 }
166 
167 impl iter::FromIterator<TokenTree> for TokenStream {
from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self168     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
169         if inside_proc_macro() {
170             TokenStream::Compiler(DeferredTokenStream::new(
171                 trees.into_iter().map(into_compiler_token).collect(),
172             ))
173         } else {
174             TokenStream::Fallback(trees.into_iter().collect())
175         }
176     }
177 }
178 
179 impl iter::FromIterator<TokenStream> for TokenStream {
from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self180     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
181         let mut streams = streams.into_iter();
182         match streams.next() {
183             Some(TokenStream::Compiler(mut first)) => {
184                 first.evaluate_now();
185                 first.stream.extend(streams.map(|s| match s {
186                     TokenStream::Compiler(s) => s.into_token_stream(),
187                     TokenStream::Fallback(_) => mismatch(),
188                 }));
189                 TokenStream::Compiler(first)
190             }
191             Some(TokenStream::Fallback(mut first)) => {
192                 first.extend(streams.map(|s| match s {
193                     TokenStream::Fallback(s) => s,
194                     TokenStream::Compiler(_) => mismatch(),
195                 }));
196                 TokenStream::Fallback(first)
197             }
198             None => TokenStream::new(),
199         }
200     }
201 }
202 
203 impl Extend<TokenTree> for TokenStream {
extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I)204     fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
205         match self {
206             TokenStream::Compiler(tts) => {
207                 // Here is the reason for DeferredTokenStream.
208                 tts.extra
209                     .extend(streams.into_iter().map(into_compiler_token));
210             }
211             TokenStream::Fallback(tts) => tts.extend(streams),
212         }
213     }
214 }
215 
216 impl Extend<TokenStream> for TokenStream {
extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I)217     fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
218         match self {
219             TokenStream::Compiler(tts) => {
220                 tts.evaluate_now();
221                 tts.stream
222                     .extend(streams.into_iter().map(|stream| stream.unwrap_nightly()));
223             }
224             TokenStream::Fallback(tts) => {
225                 tts.extend(streams.into_iter().map(|stream| stream.unwrap_stable()));
226             }
227         }
228     }
229 }
230 
231 impl fmt::Debug for TokenStream {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result232     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233         match self {
234             TokenStream::Compiler(tts) => tts.clone().into_token_stream().fmt(f),
235             TokenStream::Fallback(tts) => tts.fmt(f),
236         }
237     }
238 }
239 
240 impl From<proc_macro::LexError> for LexError {
from(e: proc_macro::LexError) -> LexError241     fn from(e: proc_macro::LexError) -> LexError {
242         LexError::Compiler(e)
243     }
244 }
245 
246 impl From<fallback::LexError> for LexError {
from(e: fallback::LexError) -> LexError247     fn from(e: fallback::LexError) -> LexError {
248         LexError::Fallback(e)
249     }
250 }
251 
252 impl fmt::Debug for LexError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result253     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
254         match self {
255             LexError::Compiler(e) => e.fmt(f),
256             LexError::Fallback(e) => e.fmt(f),
257         }
258     }
259 }
260 
261 #[derive(Clone)]
262 pub(crate) enum TokenTreeIter {
263     Compiler(proc_macro::token_stream::IntoIter),
264     Fallback(fallback::TokenTreeIter),
265 }
266 
267 impl IntoIterator for TokenStream {
268     type Item = TokenTree;
269     type IntoIter = TokenTreeIter;
270 
into_iter(self) -> TokenTreeIter271     fn into_iter(self) -> TokenTreeIter {
272         match self {
273             TokenStream::Compiler(tts) => {
274                 TokenTreeIter::Compiler(tts.into_token_stream().into_iter())
275             }
276             TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()),
277         }
278     }
279 }
280 
281 impl Iterator for TokenTreeIter {
282     type Item = TokenTree;
283 
next(&mut self) -> Option<TokenTree>284     fn next(&mut self) -> Option<TokenTree> {
285         let token = match self {
286             TokenTreeIter::Compiler(iter) => iter.next()?,
287             TokenTreeIter::Fallback(iter) => return iter.next(),
288         };
289         Some(match token {
290             proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
291             proc_macro::TokenTree::Punct(tt) => {
292                 let spacing = match tt.spacing() {
293                     proc_macro::Spacing::Joint => Spacing::Joint,
294                     proc_macro::Spacing::Alone => Spacing::Alone,
295                 };
296                 let mut o = Punct::new(tt.as_char(), spacing);
297                 o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
298                 o.into()
299             }
300             proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
301             proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
302         })
303     }
304 
size_hint(&self) -> (usize, Option<usize>)305     fn size_hint(&self) -> (usize, Option<usize>) {
306         match self {
307             TokenTreeIter::Compiler(tts) => tts.size_hint(),
308             TokenTreeIter::Fallback(tts) => tts.size_hint(),
309         }
310     }
311 }
312 
313 impl fmt::Debug for TokenTreeIter {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result314     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
315         f.debug_struct("TokenTreeIter").finish()
316     }
317 }
318 
319 #[derive(Clone, PartialEq, Eq)]
320 #[cfg(super_unstable)]
321 pub(crate) enum SourceFile {
322     Compiler(proc_macro::SourceFile),
323     Fallback(fallback::SourceFile),
324 }
325 
326 #[cfg(super_unstable)]
327 impl SourceFile {
nightly(sf: proc_macro::SourceFile) -> Self328     fn nightly(sf: proc_macro::SourceFile) -> Self {
329         SourceFile::Compiler(sf)
330     }
331 
332     /// Get the path to this source file as a string.
path(&self) -> PathBuf333     pub fn path(&self) -> PathBuf {
334         match self {
335             SourceFile::Compiler(a) => a.path(),
336             SourceFile::Fallback(a) => a.path(),
337         }
338     }
339 
is_real(&self) -> bool340     pub fn is_real(&self) -> bool {
341         match self {
342             SourceFile::Compiler(a) => a.is_real(),
343             SourceFile::Fallback(a) => a.is_real(),
344         }
345     }
346 }
347 
348 #[cfg(super_unstable)]
349 impl fmt::Debug for SourceFile {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result350     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
351         match self {
352             SourceFile::Compiler(a) => a.fmt(f),
353             SourceFile::Fallback(a) => a.fmt(f),
354         }
355     }
356 }
357 
358 #[cfg(any(super_unstable, feature = "span-locations"))]
359 pub(crate) struct LineColumn {
360     pub line: usize,
361     pub column: usize,
362 }
363 
364 #[derive(Copy, Clone)]
365 pub(crate) enum Span {
366     Compiler(proc_macro::Span),
367     Fallback(fallback::Span),
368 }
369 
370 impl Span {
call_site() -> Span371     pub fn call_site() -> Span {
372         if inside_proc_macro() {
373             Span::Compiler(proc_macro::Span::call_site())
374         } else {
375             Span::Fallback(fallback::Span::call_site())
376         }
377     }
378 
379     #[cfg(super_unstable)]
def_site() -> Span380     pub fn def_site() -> Span {
381         if inside_proc_macro() {
382             Span::Compiler(proc_macro::Span::def_site())
383         } else {
384             Span::Fallback(fallback::Span::def_site())
385         }
386     }
387 
388     #[cfg(super_unstable)]
resolved_at(&self, other: Span) -> Span389     pub fn resolved_at(&self, other: Span) -> Span {
390         match (self, other) {
391             (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)),
392             (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)),
393             _ => mismatch(),
394         }
395     }
396 
397     #[cfg(super_unstable)]
located_at(&self, other: Span) -> Span398     pub fn located_at(&self, other: Span) -> Span {
399         match (self, other) {
400             (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)),
401             (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)),
402             _ => mismatch(),
403         }
404     }
405 
unwrap(self) -> proc_macro::Span406     pub fn unwrap(self) -> proc_macro::Span {
407         match self {
408             Span::Compiler(s) => s,
409             Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"),
410         }
411     }
412 
413     #[cfg(super_unstable)]
source_file(&self) -> SourceFile414     pub fn source_file(&self) -> SourceFile {
415         match self {
416             Span::Compiler(s) => SourceFile::nightly(s.source_file()),
417             Span::Fallback(s) => SourceFile::Fallback(s.source_file()),
418         }
419     }
420 
421     #[cfg(any(super_unstable, feature = "span-locations"))]
start(&self) -> LineColumn422     pub fn start(&self) -> LineColumn {
423         match self {
424             #[cfg(proc_macro_span)]
425             Span::Compiler(s) => {
426                 let proc_macro::LineColumn { line, column } = s.start();
427                 LineColumn { line, column }
428             }
429             #[cfg(not(proc_macro_span))]
430             Span::Compiler(_) => LineColumn { line: 0, column: 0 },
431             Span::Fallback(s) => {
432                 let fallback::LineColumn { line, column } = s.start();
433                 LineColumn { line, column }
434             }
435         }
436     }
437 
438     #[cfg(any(super_unstable, feature = "span-locations"))]
end(&self) -> LineColumn439     pub fn end(&self) -> LineColumn {
440         match self {
441             #[cfg(proc_macro_span)]
442             Span::Compiler(s) => {
443                 let proc_macro::LineColumn { line, column } = s.end();
444                 LineColumn { line, column }
445             }
446             #[cfg(not(proc_macro_span))]
447             Span::Compiler(_) => LineColumn { line: 0, column: 0 },
448             Span::Fallback(s) => {
449                 let fallback::LineColumn { line, column } = s.end();
450                 LineColumn { line, column }
451             }
452         }
453     }
454 
join(&self, other: Span) -> Option<Span>455     pub fn join(&self, other: Span) -> Option<Span> {
456         let ret = match (self, other) {
457             #[cfg(proc_macro_span)]
458             (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?),
459             (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?),
460             _ => return None,
461         };
462         Some(ret)
463     }
464 
465     #[cfg(super_unstable)]
eq(&self, other: &Span) -> bool466     pub fn eq(&self, other: &Span) -> bool {
467         match (self, other) {
468             (Span::Compiler(a), Span::Compiler(b)) => a.eq(b),
469             (Span::Fallback(a), Span::Fallback(b)) => a.eq(b),
470             _ => false,
471         }
472     }
473 
unwrap_nightly(self) -> proc_macro::Span474     fn unwrap_nightly(self) -> proc_macro::Span {
475         match self {
476             Span::Compiler(s) => s,
477             Span::Fallback(_) => mismatch(),
478         }
479     }
480 }
481 
482 impl From<proc_macro::Span> for crate::Span {
from(proc_span: proc_macro::Span) -> crate::Span483     fn from(proc_span: proc_macro::Span) -> crate::Span {
484         crate::Span::_new(Span::Compiler(proc_span))
485     }
486 }
487 
488 impl From<fallback::Span> for Span {
from(inner: fallback::Span) -> Span489     fn from(inner: fallback::Span) -> Span {
490         Span::Fallback(inner)
491     }
492 }
493 
494 impl fmt::Debug for Span {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result495     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496         match self {
497             Span::Compiler(s) => s.fmt(f),
498             Span::Fallback(s) => s.fmt(f),
499         }
500     }
501 }
502 
debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span)503 pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) {
504     match span {
505         Span::Compiler(s) => {
506             debug.field("span", &s);
507         }
508         Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s),
509     }
510 }
511 
512 #[derive(Clone)]
513 pub(crate) enum Group {
514     Compiler(proc_macro::Group),
515     Fallback(fallback::Group),
516 }
517 
518 impl Group {
new(delimiter: Delimiter, stream: TokenStream) -> Group519     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
520         match stream {
521             TokenStream::Compiler(tts) => {
522                 let delimiter = match delimiter {
523                     Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
524                     Delimiter::Bracket => proc_macro::Delimiter::Bracket,
525                     Delimiter::Brace => proc_macro::Delimiter::Brace,
526                     Delimiter::None => proc_macro::Delimiter::None,
527                 };
528                 Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream()))
529             }
530             TokenStream::Fallback(stream) => {
531                 Group::Fallback(fallback::Group::new(delimiter, stream))
532             }
533         }
534     }
535 
delimiter(&self) -> Delimiter536     pub fn delimiter(&self) -> Delimiter {
537         match self {
538             Group::Compiler(g) => match g.delimiter() {
539                 proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
540                 proc_macro::Delimiter::Bracket => Delimiter::Bracket,
541                 proc_macro::Delimiter::Brace => Delimiter::Brace,
542                 proc_macro::Delimiter::None => Delimiter::None,
543             },
544             Group::Fallback(g) => g.delimiter(),
545         }
546     }
547 
stream(&self) -> TokenStream548     pub fn stream(&self) -> TokenStream {
549         match self {
550             Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())),
551             Group::Fallback(g) => TokenStream::Fallback(g.stream()),
552         }
553     }
554 
span(&self) -> Span555     pub fn span(&self) -> Span {
556         match self {
557             Group::Compiler(g) => Span::Compiler(g.span()),
558             Group::Fallback(g) => Span::Fallback(g.span()),
559         }
560     }
561 
span_open(&self) -> Span562     pub fn span_open(&self) -> Span {
563         match self {
564             #[cfg(proc_macro_span)]
565             Group::Compiler(g) => Span::Compiler(g.span_open()),
566             #[cfg(not(proc_macro_span))]
567             Group::Compiler(g) => Span::Compiler(g.span()),
568             Group::Fallback(g) => Span::Fallback(g.span_open()),
569         }
570     }
571 
span_close(&self) -> Span572     pub fn span_close(&self) -> Span {
573         match self {
574             #[cfg(proc_macro_span)]
575             Group::Compiler(g) => Span::Compiler(g.span_close()),
576             #[cfg(not(proc_macro_span))]
577             Group::Compiler(g) => Span::Compiler(g.span()),
578             Group::Fallback(g) => Span::Fallback(g.span_close()),
579         }
580     }
581 
set_span(&mut self, span: Span)582     pub fn set_span(&mut self, span: Span) {
583         match (self, span) {
584             (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s),
585             (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s),
586             _ => mismatch(),
587         }
588     }
589 
unwrap_nightly(self) -> proc_macro::Group590     fn unwrap_nightly(self) -> proc_macro::Group {
591         match self {
592             Group::Compiler(g) => g,
593             Group::Fallback(_) => mismatch(),
594         }
595     }
596 }
597 
598 impl From<fallback::Group> for Group {
from(g: fallback::Group) -> Self599     fn from(g: fallback::Group) -> Self {
600         Group::Fallback(g)
601     }
602 }
603 
604 impl fmt::Display for Group {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result605     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
606         match self {
607             Group::Compiler(group) => group.fmt(formatter),
608             Group::Fallback(group) => group.fmt(formatter),
609         }
610     }
611 }
612 
613 impl fmt::Debug for Group {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result614     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
615         match self {
616             Group::Compiler(group) => group.fmt(formatter),
617             Group::Fallback(group) => group.fmt(formatter),
618         }
619     }
620 }
621 
622 #[derive(Clone)]
623 pub(crate) enum Ident {
624     Compiler(proc_macro::Ident),
625     Fallback(fallback::Ident),
626 }
627 
628 impl Ident {
new(string: &str, span: Span) -> Ident629     pub fn new(string: &str, span: Span) -> Ident {
630         match span {
631             Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)),
632             Span::Fallback(s) => Ident::Fallback(fallback::Ident::new(string, s)),
633         }
634     }
635 
new_raw(string: &str, span: Span) -> Ident636     pub fn new_raw(string: &str, span: Span) -> Ident {
637         match span {
638             Span::Compiler(s) => {
639                 let p: proc_macro::TokenStream = string.parse().unwrap();
640                 let ident = match p.into_iter().next() {
641                     Some(proc_macro::TokenTree::Ident(mut i)) => {
642                         i.set_span(s);
643                         i
644                     }
645                     _ => panic!(),
646                 };
647                 Ident::Compiler(ident)
648             }
649             Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw(string, s)),
650         }
651     }
652 
span(&self) -> Span653     pub fn span(&self) -> Span {
654         match self {
655             Ident::Compiler(t) => Span::Compiler(t.span()),
656             Ident::Fallback(t) => Span::Fallback(t.span()),
657         }
658     }
659 
set_span(&mut self, span: Span)660     pub fn set_span(&mut self, span: Span) {
661         match (self, span) {
662             (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s),
663             (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s),
664             _ => mismatch(),
665         }
666     }
667 
unwrap_nightly(self) -> proc_macro::Ident668     fn unwrap_nightly(self) -> proc_macro::Ident {
669         match self {
670             Ident::Compiler(s) => s,
671             Ident::Fallback(_) => mismatch(),
672         }
673     }
674 }
675 
676 impl PartialEq for Ident {
eq(&self, other: &Ident) -> bool677     fn eq(&self, other: &Ident) -> bool {
678         match (self, other) {
679             (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(),
680             (Ident::Fallback(t), Ident::Fallback(o)) => t == o,
681             _ => mismatch(),
682         }
683     }
684 }
685 
686 impl<T> PartialEq<T> for Ident
687 where
688     T: ?Sized + AsRef<str>,
689 {
eq(&self, other: &T) -> bool690     fn eq(&self, other: &T) -> bool {
691         let other = other.as_ref();
692         match self {
693             Ident::Compiler(t) => t.to_string() == other,
694             Ident::Fallback(t) => t == other,
695         }
696     }
697 }
698 
699 impl fmt::Display for Ident {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result700     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
701         match self {
702             Ident::Compiler(t) => t.fmt(f),
703             Ident::Fallback(t) => t.fmt(f),
704         }
705     }
706 }
707 
708 impl fmt::Debug for Ident {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result709     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
710         match self {
711             Ident::Compiler(t) => t.fmt(f),
712             Ident::Fallback(t) => t.fmt(f),
713         }
714     }
715 }
716 
717 #[derive(Clone)]
718 pub(crate) enum Literal {
719     Compiler(proc_macro::Literal),
720     Fallback(fallback::Literal),
721 }
722 
723 macro_rules! suffixed_numbers {
724     ($($name:ident => $kind:ident,)*) => ($(
725         pub fn $name(n: $kind) -> Literal {
726             if inside_proc_macro() {
727                 Literal::Compiler(proc_macro::Literal::$name(n))
728             } else {
729                 Literal::Fallback(fallback::Literal::$name(n))
730             }
731         }
732     )*)
733 }
734 
735 macro_rules! unsuffixed_integers {
736     ($($name:ident => $kind:ident,)*) => ($(
737         pub fn $name(n: $kind) -> Literal {
738             if inside_proc_macro() {
739                 Literal::Compiler(proc_macro::Literal::$name(n))
740             } else {
741                 Literal::Fallback(fallback::Literal::$name(n))
742             }
743         }
744     )*)
745 }
746 
747 impl Literal {
748     suffixed_numbers! {
749         u8_suffixed => u8,
750         u16_suffixed => u16,
751         u32_suffixed => u32,
752         u64_suffixed => u64,
753         u128_suffixed => u128,
754         usize_suffixed => usize,
755         i8_suffixed => i8,
756         i16_suffixed => i16,
757         i32_suffixed => i32,
758         i64_suffixed => i64,
759         i128_suffixed => i128,
760         isize_suffixed => isize,
761 
762         f32_suffixed => f32,
763         f64_suffixed => f64,
764     }
765 
766     unsuffixed_integers! {
767         u8_unsuffixed => u8,
768         u16_unsuffixed => u16,
769         u32_unsuffixed => u32,
770         u64_unsuffixed => u64,
771         u128_unsuffixed => u128,
772         usize_unsuffixed => usize,
773         i8_unsuffixed => i8,
774         i16_unsuffixed => i16,
775         i32_unsuffixed => i32,
776         i64_unsuffixed => i64,
777         i128_unsuffixed => i128,
778         isize_unsuffixed => isize,
779     }
780 
f32_unsuffixed(f: f32) -> Literal781     pub fn f32_unsuffixed(f: f32) -> Literal {
782         if inside_proc_macro() {
783             Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f))
784         } else {
785             Literal::Fallback(fallback::Literal::f32_unsuffixed(f))
786         }
787     }
788 
f64_unsuffixed(f: f64) -> Literal789     pub fn f64_unsuffixed(f: f64) -> Literal {
790         if inside_proc_macro() {
791             Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f))
792         } else {
793             Literal::Fallback(fallback::Literal::f64_unsuffixed(f))
794         }
795     }
796 
string(t: &str) -> Literal797     pub fn string(t: &str) -> Literal {
798         if inside_proc_macro() {
799             Literal::Compiler(proc_macro::Literal::string(t))
800         } else {
801             Literal::Fallback(fallback::Literal::string(t))
802         }
803     }
804 
character(t: char) -> Literal805     pub fn character(t: char) -> Literal {
806         if inside_proc_macro() {
807             Literal::Compiler(proc_macro::Literal::character(t))
808         } else {
809             Literal::Fallback(fallback::Literal::character(t))
810         }
811     }
812 
byte_string(bytes: &[u8]) -> Literal813     pub fn byte_string(bytes: &[u8]) -> Literal {
814         if inside_proc_macro() {
815             Literal::Compiler(proc_macro::Literal::byte_string(bytes))
816         } else {
817             Literal::Fallback(fallback::Literal::byte_string(bytes))
818         }
819     }
820 
span(&self) -> Span821     pub fn span(&self) -> Span {
822         match self {
823             Literal::Compiler(lit) => Span::Compiler(lit.span()),
824             Literal::Fallback(lit) => Span::Fallback(lit.span()),
825         }
826     }
827 
set_span(&mut self, span: Span)828     pub fn set_span(&mut self, span: Span) {
829         match (self, span) {
830             (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s),
831             (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s),
832             _ => mismatch(),
833         }
834     }
835 
subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span>836     pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
837         match self {
838             #[cfg(proc_macro_span)]
839             Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler),
840             #[cfg(not(proc_macro_span))]
841             Literal::Compiler(_lit) => None,
842             Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback),
843         }
844     }
845 
unwrap_nightly(self) -> proc_macro::Literal846     fn unwrap_nightly(self) -> proc_macro::Literal {
847         match self {
848             Literal::Compiler(s) => s,
849             Literal::Fallback(_) => mismatch(),
850         }
851     }
852 }
853 
854 impl From<fallback::Literal> for Literal {
from(s: fallback::Literal) -> Literal855     fn from(s: fallback::Literal) -> Literal {
856         Literal::Fallback(s)
857     }
858 }
859 
860 impl fmt::Display for Literal {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result861     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
862         match self {
863             Literal::Compiler(t) => t.fmt(f),
864             Literal::Fallback(t) => t.fmt(f),
865         }
866     }
867 }
868 
869 impl fmt::Debug for Literal {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result870     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
871         match self {
872             Literal::Compiler(t) => t.fmt(f),
873             Literal::Fallback(t) => t.fmt(f),
874         }
875     }
876 }
877