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