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