17ac06127Sopenharmony_ciuse crate::detection::inside_proc_macro; 27ac06127Sopenharmony_ci#[cfg(span_locations)] 37ac06127Sopenharmony_ciuse crate::location::LineColumn; 47ac06127Sopenharmony_ciuse crate::{fallback, Delimiter, Punct, Spacing, TokenTree}; 57ac06127Sopenharmony_ciuse core::fmt::{self, Debug, Display}; 67ac06127Sopenharmony_ciuse core::ops::RangeBounds; 77ac06127Sopenharmony_ciuse core::str::FromStr; 87ac06127Sopenharmony_ciuse std::panic; 97ac06127Sopenharmony_ci#[cfg(super_unstable)] 107ac06127Sopenharmony_ciuse std::path::PathBuf; 117ac06127Sopenharmony_ci 127ac06127Sopenharmony_ci#[derive(Clone)] 137ac06127Sopenharmony_cipub(crate) enum TokenStream { 147ac06127Sopenharmony_ci Compiler(DeferredTokenStream), 157ac06127Sopenharmony_ci Fallback(fallback::TokenStream), 167ac06127Sopenharmony_ci} 177ac06127Sopenharmony_ci 187ac06127Sopenharmony_ci// Work around https://github.com/rust-lang/rust/issues/65080. 197ac06127Sopenharmony_ci// In `impl Extend<TokenTree> for TokenStream` which is used heavily by quote, 207ac06127Sopenharmony_ci// we hold on to the appended tokens and do proc_macro::TokenStream::extend as 217ac06127Sopenharmony_ci// late as possible to batch together consecutive uses of the Extend impl. 227ac06127Sopenharmony_ci#[derive(Clone)] 237ac06127Sopenharmony_cipub(crate) struct DeferredTokenStream { 247ac06127Sopenharmony_ci stream: proc_macro::TokenStream, 257ac06127Sopenharmony_ci extra: Vec<proc_macro::TokenTree>, 267ac06127Sopenharmony_ci} 277ac06127Sopenharmony_ci 287ac06127Sopenharmony_cipub(crate) enum LexError { 297ac06127Sopenharmony_ci Compiler(proc_macro::LexError), 307ac06127Sopenharmony_ci Fallback(fallback::LexError), 317ac06127Sopenharmony_ci 327ac06127Sopenharmony_ci // Rustc was supposed to return a LexError, but it panicked instead. 337ac06127Sopenharmony_ci // https://github.com/rust-lang/rust/issues/58736 347ac06127Sopenharmony_ci CompilerPanic, 357ac06127Sopenharmony_ci} 367ac06127Sopenharmony_ci 377ac06127Sopenharmony_ci#[cold] 387ac06127Sopenharmony_cifn mismatch(line: u32) -> ! { 397ac06127Sopenharmony_ci #[cfg(procmacro2_backtrace)] 407ac06127Sopenharmony_ci { 417ac06127Sopenharmony_ci let backtrace = std::backtrace::Backtrace::force_capture(); 427ac06127Sopenharmony_ci panic!("compiler/fallback mismatch #{}\n\n{}", line, backtrace) 437ac06127Sopenharmony_ci } 447ac06127Sopenharmony_ci #[cfg(not(procmacro2_backtrace))] 457ac06127Sopenharmony_ci { 467ac06127Sopenharmony_ci panic!("compiler/fallback mismatch #{}", line) 477ac06127Sopenharmony_ci } 487ac06127Sopenharmony_ci} 497ac06127Sopenharmony_ci 507ac06127Sopenharmony_ciimpl DeferredTokenStream { 517ac06127Sopenharmony_ci fn new(stream: proc_macro::TokenStream) -> Self { 527ac06127Sopenharmony_ci DeferredTokenStream { 537ac06127Sopenharmony_ci stream, 547ac06127Sopenharmony_ci extra: Vec::new(), 557ac06127Sopenharmony_ci } 567ac06127Sopenharmony_ci } 577ac06127Sopenharmony_ci 587ac06127Sopenharmony_ci fn is_empty(&self) -> bool { 597ac06127Sopenharmony_ci self.stream.is_empty() && self.extra.is_empty() 607ac06127Sopenharmony_ci } 617ac06127Sopenharmony_ci 627ac06127Sopenharmony_ci fn evaluate_now(&mut self) { 637ac06127Sopenharmony_ci // If-check provides a fast short circuit for the common case of `extra` 647ac06127Sopenharmony_ci // being empty, which saves a round trip over the proc macro bridge. 657ac06127Sopenharmony_ci // Improves macro expansion time in winrt by 6% in debug mode. 667ac06127Sopenharmony_ci if !self.extra.is_empty() { 677ac06127Sopenharmony_ci self.stream.extend(self.extra.drain(..)); 687ac06127Sopenharmony_ci } 697ac06127Sopenharmony_ci } 707ac06127Sopenharmony_ci 717ac06127Sopenharmony_ci fn into_token_stream(mut self) -> proc_macro::TokenStream { 727ac06127Sopenharmony_ci self.evaluate_now(); 737ac06127Sopenharmony_ci self.stream 747ac06127Sopenharmony_ci } 757ac06127Sopenharmony_ci} 767ac06127Sopenharmony_ci 777ac06127Sopenharmony_ciimpl TokenStream { 787ac06127Sopenharmony_ci pub fn new() -> Self { 797ac06127Sopenharmony_ci if inside_proc_macro() { 807ac06127Sopenharmony_ci TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) 817ac06127Sopenharmony_ci } else { 827ac06127Sopenharmony_ci TokenStream::Fallback(fallback::TokenStream::new()) 837ac06127Sopenharmony_ci } 847ac06127Sopenharmony_ci } 857ac06127Sopenharmony_ci 867ac06127Sopenharmony_ci pub fn is_empty(&self) -> bool { 877ac06127Sopenharmony_ci match self { 887ac06127Sopenharmony_ci TokenStream::Compiler(tts) => tts.is_empty(), 897ac06127Sopenharmony_ci TokenStream::Fallback(tts) => tts.is_empty(), 907ac06127Sopenharmony_ci } 917ac06127Sopenharmony_ci } 927ac06127Sopenharmony_ci 937ac06127Sopenharmony_ci fn unwrap_nightly(self) -> proc_macro::TokenStream { 947ac06127Sopenharmony_ci match self { 957ac06127Sopenharmony_ci TokenStream::Compiler(s) => s.into_token_stream(), 967ac06127Sopenharmony_ci TokenStream::Fallback(_) => mismatch(line!()), 977ac06127Sopenharmony_ci } 987ac06127Sopenharmony_ci } 997ac06127Sopenharmony_ci 1007ac06127Sopenharmony_ci fn unwrap_stable(self) -> fallback::TokenStream { 1017ac06127Sopenharmony_ci match self { 1027ac06127Sopenharmony_ci TokenStream::Compiler(_) => mismatch(line!()), 1037ac06127Sopenharmony_ci TokenStream::Fallback(s) => s, 1047ac06127Sopenharmony_ci } 1057ac06127Sopenharmony_ci } 1067ac06127Sopenharmony_ci} 1077ac06127Sopenharmony_ci 1087ac06127Sopenharmony_ciimpl FromStr for TokenStream { 1097ac06127Sopenharmony_ci type Err = LexError; 1107ac06127Sopenharmony_ci 1117ac06127Sopenharmony_ci fn from_str(src: &str) -> Result<TokenStream, LexError> { 1127ac06127Sopenharmony_ci if inside_proc_macro() { 1137ac06127Sopenharmony_ci Ok(TokenStream::Compiler(DeferredTokenStream::new( 1147ac06127Sopenharmony_ci proc_macro_parse(src)?, 1157ac06127Sopenharmony_ci ))) 1167ac06127Sopenharmony_ci } else { 1177ac06127Sopenharmony_ci Ok(TokenStream::Fallback(src.parse()?)) 1187ac06127Sopenharmony_ci } 1197ac06127Sopenharmony_ci } 1207ac06127Sopenharmony_ci} 1217ac06127Sopenharmony_ci 1227ac06127Sopenharmony_ci// Work around https://github.com/rust-lang/rust/issues/58736. 1237ac06127Sopenharmony_cifn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> { 1247ac06127Sopenharmony_ci let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler)); 1257ac06127Sopenharmony_ci result.unwrap_or_else(|_| Err(LexError::CompilerPanic)) 1267ac06127Sopenharmony_ci} 1277ac06127Sopenharmony_ci 1287ac06127Sopenharmony_ciimpl Display for TokenStream { 1297ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1307ac06127Sopenharmony_ci match self { 1317ac06127Sopenharmony_ci TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f), 1327ac06127Sopenharmony_ci TokenStream::Fallback(tts) => Display::fmt(tts, f), 1337ac06127Sopenharmony_ci } 1347ac06127Sopenharmony_ci } 1357ac06127Sopenharmony_ci} 1367ac06127Sopenharmony_ci 1377ac06127Sopenharmony_ciimpl From<proc_macro::TokenStream> for TokenStream { 1387ac06127Sopenharmony_ci fn from(inner: proc_macro::TokenStream) -> Self { 1397ac06127Sopenharmony_ci TokenStream::Compiler(DeferredTokenStream::new(inner)) 1407ac06127Sopenharmony_ci } 1417ac06127Sopenharmony_ci} 1427ac06127Sopenharmony_ci 1437ac06127Sopenharmony_ciimpl From<TokenStream> for proc_macro::TokenStream { 1447ac06127Sopenharmony_ci fn from(inner: TokenStream) -> Self { 1457ac06127Sopenharmony_ci match inner { 1467ac06127Sopenharmony_ci TokenStream::Compiler(inner) => inner.into_token_stream(), 1477ac06127Sopenharmony_ci TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(), 1487ac06127Sopenharmony_ci } 1497ac06127Sopenharmony_ci } 1507ac06127Sopenharmony_ci} 1517ac06127Sopenharmony_ci 1527ac06127Sopenharmony_ciimpl From<fallback::TokenStream> for TokenStream { 1537ac06127Sopenharmony_ci fn from(inner: fallback::TokenStream) -> Self { 1547ac06127Sopenharmony_ci TokenStream::Fallback(inner) 1557ac06127Sopenharmony_ci } 1567ac06127Sopenharmony_ci} 1577ac06127Sopenharmony_ci 1587ac06127Sopenharmony_ci// Assumes inside_proc_macro(). 1597ac06127Sopenharmony_cifn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { 1607ac06127Sopenharmony_ci match token { 1617ac06127Sopenharmony_ci TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(), 1627ac06127Sopenharmony_ci TokenTree::Punct(tt) => { 1637ac06127Sopenharmony_ci let spacing = match tt.spacing() { 1647ac06127Sopenharmony_ci Spacing::Joint => proc_macro::Spacing::Joint, 1657ac06127Sopenharmony_ci Spacing::Alone => proc_macro::Spacing::Alone, 1667ac06127Sopenharmony_ci }; 1677ac06127Sopenharmony_ci let mut punct = proc_macro::Punct::new(tt.as_char(), spacing); 1687ac06127Sopenharmony_ci punct.set_span(tt.span().inner.unwrap_nightly()); 1697ac06127Sopenharmony_ci punct.into() 1707ac06127Sopenharmony_ci } 1717ac06127Sopenharmony_ci TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(), 1727ac06127Sopenharmony_ci TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(), 1737ac06127Sopenharmony_ci } 1747ac06127Sopenharmony_ci} 1757ac06127Sopenharmony_ci 1767ac06127Sopenharmony_ciimpl From<TokenTree> for TokenStream { 1777ac06127Sopenharmony_ci fn from(token: TokenTree) -> Self { 1787ac06127Sopenharmony_ci if inside_proc_macro() { 1797ac06127Sopenharmony_ci TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into())) 1807ac06127Sopenharmony_ci } else { 1817ac06127Sopenharmony_ci TokenStream::Fallback(token.into()) 1827ac06127Sopenharmony_ci } 1837ac06127Sopenharmony_ci } 1847ac06127Sopenharmony_ci} 1857ac06127Sopenharmony_ci 1867ac06127Sopenharmony_ciimpl FromIterator<TokenTree> for TokenStream { 1877ac06127Sopenharmony_ci fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self { 1887ac06127Sopenharmony_ci if inside_proc_macro() { 1897ac06127Sopenharmony_ci TokenStream::Compiler(DeferredTokenStream::new( 1907ac06127Sopenharmony_ci trees.into_iter().map(into_compiler_token).collect(), 1917ac06127Sopenharmony_ci )) 1927ac06127Sopenharmony_ci } else { 1937ac06127Sopenharmony_ci TokenStream::Fallback(trees.into_iter().collect()) 1947ac06127Sopenharmony_ci } 1957ac06127Sopenharmony_ci } 1967ac06127Sopenharmony_ci} 1977ac06127Sopenharmony_ci 1987ac06127Sopenharmony_ciimpl FromIterator<TokenStream> for TokenStream { 1997ac06127Sopenharmony_ci fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { 2007ac06127Sopenharmony_ci let mut streams = streams.into_iter(); 2017ac06127Sopenharmony_ci match streams.next() { 2027ac06127Sopenharmony_ci Some(TokenStream::Compiler(mut first)) => { 2037ac06127Sopenharmony_ci first.evaluate_now(); 2047ac06127Sopenharmony_ci first.stream.extend(streams.map(|s| match s { 2057ac06127Sopenharmony_ci TokenStream::Compiler(s) => s.into_token_stream(), 2067ac06127Sopenharmony_ci TokenStream::Fallback(_) => mismatch(line!()), 2077ac06127Sopenharmony_ci })); 2087ac06127Sopenharmony_ci TokenStream::Compiler(first) 2097ac06127Sopenharmony_ci } 2107ac06127Sopenharmony_ci Some(TokenStream::Fallback(mut first)) => { 2117ac06127Sopenharmony_ci first.extend(streams.map(|s| match s { 2127ac06127Sopenharmony_ci TokenStream::Fallback(s) => s, 2137ac06127Sopenharmony_ci TokenStream::Compiler(_) => mismatch(line!()), 2147ac06127Sopenharmony_ci })); 2157ac06127Sopenharmony_ci TokenStream::Fallback(first) 2167ac06127Sopenharmony_ci } 2177ac06127Sopenharmony_ci None => TokenStream::new(), 2187ac06127Sopenharmony_ci } 2197ac06127Sopenharmony_ci } 2207ac06127Sopenharmony_ci} 2217ac06127Sopenharmony_ci 2227ac06127Sopenharmony_ciimpl Extend<TokenTree> for TokenStream { 2237ac06127Sopenharmony_ci fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, stream: I) { 2247ac06127Sopenharmony_ci match self { 2257ac06127Sopenharmony_ci TokenStream::Compiler(tts) => { 2267ac06127Sopenharmony_ci // Here is the reason for DeferredTokenStream. 2277ac06127Sopenharmony_ci for token in stream { 2287ac06127Sopenharmony_ci tts.extra.push(into_compiler_token(token)); 2297ac06127Sopenharmony_ci } 2307ac06127Sopenharmony_ci } 2317ac06127Sopenharmony_ci TokenStream::Fallback(tts) => tts.extend(stream), 2327ac06127Sopenharmony_ci } 2337ac06127Sopenharmony_ci } 2347ac06127Sopenharmony_ci} 2357ac06127Sopenharmony_ci 2367ac06127Sopenharmony_ciimpl Extend<TokenStream> for TokenStream { 2377ac06127Sopenharmony_ci fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) { 2387ac06127Sopenharmony_ci match self { 2397ac06127Sopenharmony_ci TokenStream::Compiler(tts) => { 2407ac06127Sopenharmony_ci tts.evaluate_now(); 2417ac06127Sopenharmony_ci tts.stream 2427ac06127Sopenharmony_ci .extend(streams.into_iter().map(TokenStream::unwrap_nightly)); 2437ac06127Sopenharmony_ci } 2447ac06127Sopenharmony_ci TokenStream::Fallback(tts) => { 2457ac06127Sopenharmony_ci tts.extend(streams.into_iter().map(TokenStream::unwrap_stable)); 2467ac06127Sopenharmony_ci } 2477ac06127Sopenharmony_ci } 2487ac06127Sopenharmony_ci } 2497ac06127Sopenharmony_ci} 2507ac06127Sopenharmony_ci 2517ac06127Sopenharmony_ciimpl Debug for TokenStream { 2527ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 2537ac06127Sopenharmony_ci match self { 2547ac06127Sopenharmony_ci TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f), 2557ac06127Sopenharmony_ci TokenStream::Fallback(tts) => Debug::fmt(tts, f), 2567ac06127Sopenharmony_ci } 2577ac06127Sopenharmony_ci } 2587ac06127Sopenharmony_ci} 2597ac06127Sopenharmony_ci 2607ac06127Sopenharmony_ciimpl LexError { 2617ac06127Sopenharmony_ci pub(crate) fn span(&self) -> Span { 2627ac06127Sopenharmony_ci match self { 2637ac06127Sopenharmony_ci LexError::Compiler(_) | LexError::CompilerPanic => Span::call_site(), 2647ac06127Sopenharmony_ci LexError::Fallback(e) => Span::Fallback(e.span()), 2657ac06127Sopenharmony_ci } 2667ac06127Sopenharmony_ci } 2677ac06127Sopenharmony_ci} 2687ac06127Sopenharmony_ci 2697ac06127Sopenharmony_ciimpl From<proc_macro::LexError> for LexError { 2707ac06127Sopenharmony_ci fn from(e: proc_macro::LexError) -> Self { 2717ac06127Sopenharmony_ci LexError::Compiler(e) 2727ac06127Sopenharmony_ci } 2737ac06127Sopenharmony_ci} 2747ac06127Sopenharmony_ci 2757ac06127Sopenharmony_ciimpl From<fallback::LexError> for LexError { 2767ac06127Sopenharmony_ci fn from(e: fallback::LexError) -> Self { 2777ac06127Sopenharmony_ci LexError::Fallback(e) 2787ac06127Sopenharmony_ci } 2797ac06127Sopenharmony_ci} 2807ac06127Sopenharmony_ci 2817ac06127Sopenharmony_ciimpl Debug for LexError { 2827ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 2837ac06127Sopenharmony_ci match self { 2847ac06127Sopenharmony_ci LexError::Compiler(e) => Debug::fmt(e, f), 2857ac06127Sopenharmony_ci LexError::Fallback(e) => Debug::fmt(e, f), 2867ac06127Sopenharmony_ci LexError::CompilerPanic => { 2877ac06127Sopenharmony_ci let fallback = fallback::LexError::call_site(); 2887ac06127Sopenharmony_ci Debug::fmt(&fallback, f) 2897ac06127Sopenharmony_ci } 2907ac06127Sopenharmony_ci } 2917ac06127Sopenharmony_ci } 2927ac06127Sopenharmony_ci} 2937ac06127Sopenharmony_ci 2947ac06127Sopenharmony_ciimpl Display for LexError { 2957ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 2967ac06127Sopenharmony_ci match self { 2977ac06127Sopenharmony_ci LexError::Compiler(e) => Display::fmt(e, f), 2987ac06127Sopenharmony_ci LexError::Fallback(e) => Display::fmt(e, f), 2997ac06127Sopenharmony_ci LexError::CompilerPanic => { 3007ac06127Sopenharmony_ci let fallback = fallback::LexError::call_site(); 3017ac06127Sopenharmony_ci Display::fmt(&fallback, f) 3027ac06127Sopenharmony_ci } 3037ac06127Sopenharmony_ci } 3047ac06127Sopenharmony_ci } 3057ac06127Sopenharmony_ci} 3067ac06127Sopenharmony_ci 3077ac06127Sopenharmony_ci#[derive(Clone)] 3087ac06127Sopenharmony_cipub(crate) enum TokenTreeIter { 3097ac06127Sopenharmony_ci Compiler(proc_macro::token_stream::IntoIter), 3107ac06127Sopenharmony_ci Fallback(fallback::TokenTreeIter), 3117ac06127Sopenharmony_ci} 3127ac06127Sopenharmony_ci 3137ac06127Sopenharmony_ciimpl IntoIterator for TokenStream { 3147ac06127Sopenharmony_ci type Item = TokenTree; 3157ac06127Sopenharmony_ci type IntoIter = TokenTreeIter; 3167ac06127Sopenharmony_ci 3177ac06127Sopenharmony_ci fn into_iter(self) -> TokenTreeIter { 3187ac06127Sopenharmony_ci match self { 3197ac06127Sopenharmony_ci TokenStream::Compiler(tts) => { 3207ac06127Sopenharmony_ci TokenTreeIter::Compiler(tts.into_token_stream().into_iter()) 3217ac06127Sopenharmony_ci } 3227ac06127Sopenharmony_ci TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()), 3237ac06127Sopenharmony_ci } 3247ac06127Sopenharmony_ci } 3257ac06127Sopenharmony_ci} 3267ac06127Sopenharmony_ci 3277ac06127Sopenharmony_ciimpl Iterator for TokenTreeIter { 3287ac06127Sopenharmony_ci type Item = TokenTree; 3297ac06127Sopenharmony_ci 3307ac06127Sopenharmony_ci fn next(&mut self) -> Option<TokenTree> { 3317ac06127Sopenharmony_ci let token = match self { 3327ac06127Sopenharmony_ci TokenTreeIter::Compiler(iter) => iter.next()?, 3337ac06127Sopenharmony_ci TokenTreeIter::Fallback(iter) => return iter.next(), 3347ac06127Sopenharmony_ci }; 3357ac06127Sopenharmony_ci Some(match token { 3367ac06127Sopenharmony_ci proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(), 3377ac06127Sopenharmony_ci proc_macro::TokenTree::Punct(tt) => { 3387ac06127Sopenharmony_ci let spacing = match tt.spacing() { 3397ac06127Sopenharmony_ci proc_macro::Spacing::Joint => Spacing::Joint, 3407ac06127Sopenharmony_ci proc_macro::Spacing::Alone => Spacing::Alone, 3417ac06127Sopenharmony_ci }; 3427ac06127Sopenharmony_ci let mut o = Punct::new(tt.as_char(), spacing); 3437ac06127Sopenharmony_ci o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); 3447ac06127Sopenharmony_ci o.into() 3457ac06127Sopenharmony_ci } 3467ac06127Sopenharmony_ci proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(), 3477ac06127Sopenharmony_ci proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(), 3487ac06127Sopenharmony_ci }) 3497ac06127Sopenharmony_ci } 3507ac06127Sopenharmony_ci 3517ac06127Sopenharmony_ci fn size_hint(&self) -> (usize, Option<usize>) { 3527ac06127Sopenharmony_ci match self { 3537ac06127Sopenharmony_ci TokenTreeIter::Compiler(tts) => tts.size_hint(), 3547ac06127Sopenharmony_ci TokenTreeIter::Fallback(tts) => tts.size_hint(), 3557ac06127Sopenharmony_ci } 3567ac06127Sopenharmony_ci } 3577ac06127Sopenharmony_ci} 3587ac06127Sopenharmony_ci 3597ac06127Sopenharmony_ci#[derive(Clone, PartialEq, Eq)] 3607ac06127Sopenharmony_ci#[cfg(super_unstable)] 3617ac06127Sopenharmony_cipub(crate) enum SourceFile { 3627ac06127Sopenharmony_ci Compiler(proc_macro::SourceFile), 3637ac06127Sopenharmony_ci Fallback(fallback::SourceFile), 3647ac06127Sopenharmony_ci} 3657ac06127Sopenharmony_ci 3667ac06127Sopenharmony_ci#[cfg(super_unstable)] 3677ac06127Sopenharmony_ciimpl SourceFile { 3687ac06127Sopenharmony_ci fn nightly(sf: proc_macro::SourceFile) -> Self { 3697ac06127Sopenharmony_ci SourceFile::Compiler(sf) 3707ac06127Sopenharmony_ci } 3717ac06127Sopenharmony_ci 3727ac06127Sopenharmony_ci /// Get the path to this source file as a string. 3737ac06127Sopenharmony_ci pub fn path(&self) -> PathBuf { 3747ac06127Sopenharmony_ci match self { 3757ac06127Sopenharmony_ci SourceFile::Compiler(a) => a.path(), 3767ac06127Sopenharmony_ci SourceFile::Fallback(a) => a.path(), 3777ac06127Sopenharmony_ci } 3787ac06127Sopenharmony_ci } 3797ac06127Sopenharmony_ci 3807ac06127Sopenharmony_ci pub fn is_real(&self) -> bool { 3817ac06127Sopenharmony_ci match self { 3827ac06127Sopenharmony_ci SourceFile::Compiler(a) => a.is_real(), 3837ac06127Sopenharmony_ci SourceFile::Fallback(a) => a.is_real(), 3847ac06127Sopenharmony_ci } 3857ac06127Sopenharmony_ci } 3867ac06127Sopenharmony_ci} 3877ac06127Sopenharmony_ci 3887ac06127Sopenharmony_ci#[cfg(super_unstable)] 3897ac06127Sopenharmony_ciimpl Debug for SourceFile { 3907ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 3917ac06127Sopenharmony_ci match self { 3927ac06127Sopenharmony_ci SourceFile::Compiler(a) => Debug::fmt(a, f), 3937ac06127Sopenharmony_ci SourceFile::Fallback(a) => Debug::fmt(a, f), 3947ac06127Sopenharmony_ci } 3957ac06127Sopenharmony_ci } 3967ac06127Sopenharmony_ci} 3977ac06127Sopenharmony_ci 3987ac06127Sopenharmony_ci#[derive(Copy, Clone)] 3997ac06127Sopenharmony_cipub(crate) enum Span { 4007ac06127Sopenharmony_ci Compiler(proc_macro::Span), 4017ac06127Sopenharmony_ci Fallback(fallback::Span), 4027ac06127Sopenharmony_ci} 4037ac06127Sopenharmony_ci 4047ac06127Sopenharmony_ciimpl Span { 4057ac06127Sopenharmony_ci pub fn call_site() -> Self { 4067ac06127Sopenharmony_ci if inside_proc_macro() { 4077ac06127Sopenharmony_ci Span::Compiler(proc_macro::Span::call_site()) 4087ac06127Sopenharmony_ci } else { 4097ac06127Sopenharmony_ci Span::Fallback(fallback::Span::call_site()) 4107ac06127Sopenharmony_ci } 4117ac06127Sopenharmony_ci } 4127ac06127Sopenharmony_ci 4137ac06127Sopenharmony_ci pub fn mixed_site() -> Self { 4147ac06127Sopenharmony_ci if inside_proc_macro() { 4157ac06127Sopenharmony_ci Span::Compiler(proc_macro::Span::mixed_site()) 4167ac06127Sopenharmony_ci } else { 4177ac06127Sopenharmony_ci Span::Fallback(fallback::Span::mixed_site()) 4187ac06127Sopenharmony_ci } 4197ac06127Sopenharmony_ci } 4207ac06127Sopenharmony_ci 4217ac06127Sopenharmony_ci #[cfg(super_unstable)] 4227ac06127Sopenharmony_ci pub fn def_site() -> Self { 4237ac06127Sopenharmony_ci if inside_proc_macro() { 4247ac06127Sopenharmony_ci Span::Compiler(proc_macro::Span::def_site()) 4257ac06127Sopenharmony_ci } else { 4267ac06127Sopenharmony_ci Span::Fallback(fallback::Span::def_site()) 4277ac06127Sopenharmony_ci } 4287ac06127Sopenharmony_ci } 4297ac06127Sopenharmony_ci 4307ac06127Sopenharmony_ci pub fn resolved_at(&self, other: Span) -> Span { 4317ac06127Sopenharmony_ci match (self, other) { 4327ac06127Sopenharmony_ci (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), 4337ac06127Sopenharmony_ci (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), 4347ac06127Sopenharmony_ci (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 4357ac06127Sopenharmony_ci (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 4367ac06127Sopenharmony_ci } 4377ac06127Sopenharmony_ci } 4387ac06127Sopenharmony_ci 4397ac06127Sopenharmony_ci pub fn located_at(&self, other: Span) -> Span { 4407ac06127Sopenharmony_ci match (self, other) { 4417ac06127Sopenharmony_ci (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), 4427ac06127Sopenharmony_ci (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), 4437ac06127Sopenharmony_ci (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 4447ac06127Sopenharmony_ci (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 4457ac06127Sopenharmony_ci } 4467ac06127Sopenharmony_ci } 4477ac06127Sopenharmony_ci 4487ac06127Sopenharmony_ci pub fn unwrap(self) -> proc_macro::Span { 4497ac06127Sopenharmony_ci match self { 4507ac06127Sopenharmony_ci Span::Compiler(s) => s, 4517ac06127Sopenharmony_ci Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"), 4527ac06127Sopenharmony_ci } 4537ac06127Sopenharmony_ci } 4547ac06127Sopenharmony_ci 4557ac06127Sopenharmony_ci #[cfg(super_unstable)] 4567ac06127Sopenharmony_ci pub fn source_file(&self) -> SourceFile { 4577ac06127Sopenharmony_ci match self { 4587ac06127Sopenharmony_ci Span::Compiler(s) => SourceFile::nightly(s.source_file()), 4597ac06127Sopenharmony_ci Span::Fallback(s) => SourceFile::Fallback(s.source_file()), 4607ac06127Sopenharmony_ci } 4617ac06127Sopenharmony_ci } 4627ac06127Sopenharmony_ci 4637ac06127Sopenharmony_ci #[cfg(span_locations)] 4647ac06127Sopenharmony_ci pub fn start(&self) -> LineColumn { 4657ac06127Sopenharmony_ci match self { 4667ac06127Sopenharmony_ci Span::Compiler(_) => LineColumn { line: 0, column: 0 }, 4677ac06127Sopenharmony_ci Span::Fallback(s) => s.start(), 4687ac06127Sopenharmony_ci } 4697ac06127Sopenharmony_ci } 4707ac06127Sopenharmony_ci 4717ac06127Sopenharmony_ci #[cfg(span_locations)] 4727ac06127Sopenharmony_ci pub fn end(&self) -> LineColumn { 4737ac06127Sopenharmony_ci match self { 4747ac06127Sopenharmony_ci Span::Compiler(_) => LineColumn { line: 0, column: 0 }, 4757ac06127Sopenharmony_ci Span::Fallback(s) => s.end(), 4767ac06127Sopenharmony_ci } 4777ac06127Sopenharmony_ci } 4787ac06127Sopenharmony_ci 4797ac06127Sopenharmony_ci pub fn join(&self, other: Span) -> Option<Span> { 4807ac06127Sopenharmony_ci let ret = match (self, other) { 4817ac06127Sopenharmony_ci #[cfg(proc_macro_span)] 4827ac06127Sopenharmony_ci (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?), 4837ac06127Sopenharmony_ci (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), 4847ac06127Sopenharmony_ci _ => return None, 4857ac06127Sopenharmony_ci }; 4867ac06127Sopenharmony_ci Some(ret) 4877ac06127Sopenharmony_ci } 4887ac06127Sopenharmony_ci 4897ac06127Sopenharmony_ci #[cfg(super_unstable)] 4907ac06127Sopenharmony_ci pub fn eq(&self, other: &Span) -> bool { 4917ac06127Sopenharmony_ci match (self, other) { 4927ac06127Sopenharmony_ci (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), 4937ac06127Sopenharmony_ci (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), 4947ac06127Sopenharmony_ci _ => false, 4957ac06127Sopenharmony_ci } 4967ac06127Sopenharmony_ci } 4977ac06127Sopenharmony_ci 4987ac06127Sopenharmony_ci pub fn source_text(&self) -> Option<String> { 4997ac06127Sopenharmony_ci match self { 5007ac06127Sopenharmony_ci #[cfg(not(no_source_text))] 5017ac06127Sopenharmony_ci Span::Compiler(s) => s.source_text(), 5027ac06127Sopenharmony_ci #[cfg(no_source_text)] 5037ac06127Sopenharmony_ci Span::Compiler(_) => None, 5047ac06127Sopenharmony_ci Span::Fallback(s) => s.source_text(), 5057ac06127Sopenharmony_ci } 5067ac06127Sopenharmony_ci } 5077ac06127Sopenharmony_ci 5087ac06127Sopenharmony_ci fn unwrap_nightly(self) -> proc_macro::Span { 5097ac06127Sopenharmony_ci match self { 5107ac06127Sopenharmony_ci Span::Compiler(s) => s, 5117ac06127Sopenharmony_ci Span::Fallback(_) => mismatch(line!()), 5127ac06127Sopenharmony_ci } 5137ac06127Sopenharmony_ci } 5147ac06127Sopenharmony_ci} 5157ac06127Sopenharmony_ci 5167ac06127Sopenharmony_ciimpl From<proc_macro::Span> for crate::Span { 5177ac06127Sopenharmony_ci fn from(proc_span: proc_macro::Span) -> Self { 5187ac06127Sopenharmony_ci crate::Span::_new(Span::Compiler(proc_span)) 5197ac06127Sopenharmony_ci } 5207ac06127Sopenharmony_ci} 5217ac06127Sopenharmony_ci 5227ac06127Sopenharmony_ciimpl From<fallback::Span> for Span { 5237ac06127Sopenharmony_ci fn from(inner: fallback::Span) -> Self { 5247ac06127Sopenharmony_ci Span::Fallback(inner) 5257ac06127Sopenharmony_ci } 5267ac06127Sopenharmony_ci} 5277ac06127Sopenharmony_ci 5287ac06127Sopenharmony_ciimpl Debug for Span { 5297ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 5307ac06127Sopenharmony_ci match self { 5317ac06127Sopenharmony_ci Span::Compiler(s) => Debug::fmt(s, f), 5327ac06127Sopenharmony_ci Span::Fallback(s) => Debug::fmt(s, f), 5337ac06127Sopenharmony_ci } 5347ac06127Sopenharmony_ci } 5357ac06127Sopenharmony_ci} 5367ac06127Sopenharmony_ci 5377ac06127Sopenharmony_cipub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { 5387ac06127Sopenharmony_ci match span { 5397ac06127Sopenharmony_ci Span::Compiler(s) => { 5407ac06127Sopenharmony_ci debug.field("span", &s); 5417ac06127Sopenharmony_ci } 5427ac06127Sopenharmony_ci Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s), 5437ac06127Sopenharmony_ci } 5447ac06127Sopenharmony_ci} 5457ac06127Sopenharmony_ci 5467ac06127Sopenharmony_ci#[derive(Clone)] 5477ac06127Sopenharmony_cipub(crate) enum Group { 5487ac06127Sopenharmony_ci Compiler(proc_macro::Group), 5497ac06127Sopenharmony_ci Fallback(fallback::Group), 5507ac06127Sopenharmony_ci} 5517ac06127Sopenharmony_ci 5527ac06127Sopenharmony_ciimpl Group { 5537ac06127Sopenharmony_ci pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { 5547ac06127Sopenharmony_ci match stream { 5557ac06127Sopenharmony_ci TokenStream::Compiler(tts) => { 5567ac06127Sopenharmony_ci let delimiter = match delimiter { 5577ac06127Sopenharmony_ci Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis, 5587ac06127Sopenharmony_ci Delimiter::Bracket => proc_macro::Delimiter::Bracket, 5597ac06127Sopenharmony_ci Delimiter::Brace => proc_macro::Delimiter::Brace, 5607ac06127Sopenharmony_ci Delimiter::None => proc_macro::Delimiter::None, 5617ac06127Sopenharmony_ci }; 5627ac06127Sopenharmony_ci Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream())) 5637ac06127Sopenharmony_ci } 5647ac06127Sopenharmony_ci TokenStream::Fallback(stream) => { 5657ac06127Sopenharmony_ci Group::Fallback(fallback::Group::new(delimiter, stream)) 5667ac06127Sopenharmony_ci } 5677ac06127Sopenharmony_ci } 5687ac06127Sopenharmony_ci } 5697ac06127Sopenharmony_ci 5707ac06127Sopenharmony_ci pub fn delimiter(&self) -> Delimiter { 5717ac06127Sopenharmony_ci match self { 5727ac06127Sopenharmony_ci Group::Compiler(g) => match g.delimiter() { 5737ac06127Sopenharmony_ci proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, 5747ac06127Sopenharmony_ci proc_macro::Delimiter::Bracket => Delimiter::Bracket, 5757ac06127Sopenharmony_ci proc_macro::Delimiter::Brace => Delimiter::Brace, 5767ac06127Sopenharmony_ci proc_macro::Delimiter::None => Delimiter::None, 5777ac06127Sopenharmony_ci }, 5787ac06127Sopenharmony_ci Group::Fallback(g) => g.delimiter(), 5797ac06127Sopenharmony_ci } 5807ac06127Sopenharmony_ci } 5817ac06127Sopenharmony_ci 5827ac06127Sopenharmony_ci pub fn stream(&self) -> TokenStream { 5837ac06127Sopenharmony_ci match self { 5847ac06127Sopenharmony_ci Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), 5857ac06127Sopenharmony_ci Group::Fallback(g) => TokenStream::Fallback(g.stream()), 5867ac06127Sopenharmony_ci } 5877ac06127Sopenharmony_ci } 5887ac06127Sopenharmony_ci 5897ac06127Sopenharmony_ci pub fn span(&self) -> Span { 5907ac06127Sopenharmony_ci match self { 5917ac06127Sopenharmony_ci Group::Compiler(g) => Span::Compiler(g.span()), 5927ac06127Sopenharmony_ci Group::Fallback(g) => Span::Fallback(g.span()), 5937ac06127Sopenharmony_ci } 5947ac06127Sopenharmony_ci } 5957ac06127Sopenharmony_ci 5967ac06127Sopenharmony_ci pub fn span_open(&self) -> Span { 5977ac06127Sopenharmony_ci match self { 5987ac06127Sopenharmony_ci Group::Compiler(g) => Span::Compiler(g.span_open()), 5997ac06127Sopenharmony_ci Group::Fallback(g) => Span::Fallback(g.span_open()), 6007ac06127Sopenharmony_ci } 6017ac06127Sopenharmony_ci } 6027ac06127Sopenharmony_ci 6037ac06127Sopenharmony_ci pub fn span_close(&self) -> Span { 6047ac06127Sopenharmony_ci match self { 6057ac06127Sopenharmony_ci Group::Compiler(g) => Span::Compiler(g.span_close()), 6067ac06127Sopenharmony_ci Group::Fallback(g) => Span::Fallback(g.span_close()), 6077ac06127Sopenharmony_ci } 6087ac06127Sopenharmony_ci } 6097ac06127Sopenharmony_ci 6107ac06127Sopenharmony_ci pub fn set_span(&mut self, span: Span) { 6117ac06127Sopenharmony_ci match (self, span) { 6127ac06127Sopenharmony_ci (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), 6137ac06127Sopenharmony_ci (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), 6147ac06127Sopenharmony_ci (Group::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 6157ac06127Sopenharmony_ci (Group::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 6167ac06127Sopenharmony_ci } 6177ac06127Sopenharmony_ci } 6187ac06127Sopenharmony_ci 6197ac06127Sopenharmony_ci fn unwrap_nightly(self) -> proc_macro::Group { 6207ac06127Sopenharmony_ci match self { 6217ac06127Sopenharmony_ci Group::Compiler(g) => g, 6227ac06127Sopenharmony_ci Group::Fallback(_) => mismatch(line!()), 6237ac06127Sopenharmony_ci } 6247ac06127Sopenharmony_ci } 6257ac06127Sopenharmony_ci} 6267ac06127Sopenharmony_ci 6277ac06127Sopenharmony_ciimpl From<fallback::Group> for Group { 6287ac06127Sopenharmony_ci fn from(g: fallback::Group) -> Self { 6297ac06127Sopenharmony_ci Group::Fallback(g) 6307ac06127Sopenharmony_ci } 6317ac06127Sopenharmony_ci} 6327ac06127Sopenharmony_ci 6337ac06127Sopenharmony_ciimpl Display for Group { 6347ac06127Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 6357ac06127Sopenharmony_ci match self { 6367ac06127Sopenharmony_ci Group::Compiler(group) => Display::fmt(group, formatter), 6377ac06127Sopenharmony_ci Group::Fallback(group) => Display::fmt(group, formatter), 6387ac06127Sopenharmony_ci } 6397ac06127Sopenharmony_ci } 6407ac06127Sopenharmony_ci} 6417ac06127Sopenharmony_ci 6427ac06127Sopenharmony_ciimpl Debug for Group { 6437ac06127Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 6447ac06127Sopenharmony_ci match self { 6457ac06127Sopenharmony_ci Group::Compiler(group) => Debug::fmt(group, formatter), 6467ac06127Sopenharmony_ci Group::Fallback(group) => Debug::fmt(group, formatter), 6477ac06127Sopenharmony_ci } 6487ac06127Sopenharmony_ci } 6497ac06127Sopenharmony_ci} 6507ac06127Sopenharmony_ci 6517ac06127Sopenharmony_ci#[derive(Clone)] 6527ac06127Sopenharmony_cipub(crate) enum Ident { 6537ac06127Sopenharmony_ci Compiler(proc_macro::Ident), 6547ac06127Sopenharmony_ci Fallback(fallback::Ident), 6557ac06127Sopenharmony_ci} 6567ac06127Sopenharmony_ci 6577ac06127Sopenharmony_ciimpl Ident { 6587ac06127Sopenharmony_ci #[track_caller] 6597ac06127Sopenharmony_ci pub fn new_checked(string: &str, span: Span) -> Self { 6607ac06127Sopenharmony_ci match span { 6617ac06127Sopenharmony_ci Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), 6627ac06127Sopenharmony_ci Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_checked(string, s)), 6637ac06127Sopenharmony_ci } 6647ac06127Sopenharmony_ci } 6657ac06127Sopenharmony_ci 6667ac06127Sopenharmony_ci pub fn new_unchecked(string: &str, span: fallback::Span) -> Self { 6677ac06127Sopenharmony_ci Ident::Fallback(fallback::Ident::new_unchecked(string, span)) 6687ac06127Sopenharmony_ci } 6697ac06127Sopenharmony_ci 6707ac06127Sopenharmony_ci #[track_caller] 6717ac06127Sopenharmony_ci pub fn new_raw_checked(string: &str, span: Span) -> Self { 6727ac06127Sopenharmony_ci match span { 6737ac06127Sopenharmony_ci Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), 6747ac06127Sopenharmony_ci Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw_checked(string, s)), 6757ac06127Sopenharmony_ci } 6767ac06127Sopenharmony_ci } 6777ac06127Sopenharmony_ci 6787ac06127Sopenharmony_ci pub fn new_raw_unchecked(string: &str, span: fallback::Span) -> Self { 6797ac06127Sopenharmony_ci Ident::Fallback(fallback::Ident::new_raw_unchecked(string, span)) 6807ac06127Sopenharmony_ci } 6817ac06127Sopenharmony_ci 6827ac06127Sopenharmony_ci pub fn span(&self) -> Span { 6837ac06127Sopenharmony_ci match self { 6847ac06127Sopenharmony_ci Ident::Compiler(t) => Span::Compiler(t.span()), 6857ac06127Sopenharmony_ci Ident::Fallback(t) => Span::Fallback(t.span()), 6867ac06127Sopenharmony_ci } 6877ac06127Sopenharmony_ci } 6887ac06127Sopenharmony_ci 6897ac06127Sopenharmony_ci pub fn set_span(&mut self, span: Span) { 6907ac06127Sopenharmony_ci match (self, span) { 6917ac06127Sopenharmony_ci (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), 6927ac06127Sopenharmony_ci (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), 6937ac06127Sopenharmony_ci (Ident::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 6947ac06127Sopenharmony_ci (Ident::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 6957ac06127Sopenharmony_ci } 6967ac06127Sopenharmony_ci } 6977ac06127Sopenharmony_ci 6987ac06127Sopenharmony_ci fn unwrap_nightly(self) -> proc_macro::Ident { 6997ac06127Sopenharmony_ci match self { 7007ac06127Sopenharmony_ci Ident::Compiler(s) => s, 7017ac06127Sopenharmony_ci Ident::Fallback(_) => mismatch(line!()), 7027ac06127Sopenharmony_ci } 7037ac06127Sopenharmony_ci } 7047ac06127Sopenharmony_ci} 7057ac06127Sopenharmony_ci 7067ac06127Sopenharmony_ciimpl PartialEq for Ident { 7077ac06127Sopenharmony_ci fn eq(&self, other: &Ident) -> bool { 7087ac06127Sopenharmony_ci match (self, other) { 7097ac06127Sopenharmony_ci (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(), 7107ac06127Sopenharmony_ci (Ident::Fallback(t), Ident::Fallback(o)) => t == o, 7117ac06127Sopenharmony_ci (Ident::Compiler(_), Ident::Fallback(_)) => mismatch(line!()), 7127ac06127Sopenharmony_ci (Ident::Fallback(_), Ident::Compiler(_)) => mismatch(line!()), 7137ac06127Sopenharmony_ci } 7147ac06127Sopenharmony_ci } 7157ac06127Sopenharmony_ci} 7167ac06127Sopenharmony_ci 7177ac06127Sopenharmony_ciimpl<T> PartialEq<T> for Ident 7187ac06127Sopenharmony_ciwhere 7197ac06127Sopenharmony_ci T: ?Sized + AsRef<str>, 7207ac06127Sopenharmony_ci{ 7217ac06127Sopenharmony_ci fn eq(&self, other: &T) -> bool { 7227ac06127Sopenharmony_ci let other = other.as_ref(); 7237ac06127Sopenharmony_ci match self { 7247ac06127Sopenharmony_ci Ident::Compiler(t) => t.to_string() == other, 7257ac06127Sopenharmony_ci Ident::Fallback(t) => t == other, 7267ac06127Sopenharmony_ci } 7277ac06127Sopenharmony_ci } 7287ac06127Sopenharmony_ci} 7297ac06127Sopenharmony_ci 7307ac06127Sopenharmony_ciimpl Display for Ident { 7317ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 7327ac06127Sopenharmony_ci match self { 7337ac06127Sopenharmony_ci Ident::Compiler(t) => Display::fmt(t, f), 7347ac06127Sopenharmony_ci Ident::Fallback(t) => Display::fmt(t, f), 7357ac06127Sopenharmony_ci } 7367ac06127Sopenharmony_ci } 7377ac06127Sopenharmony_ci} 7387ac06127Sopenharmony_ci 7397ac06127Sopenharmony_ciimpl Debug for Ident { 7407ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 7417ac06127Sopenharmony_ci match self { 7427ac06127Sopenharmony_ci Ident::Compiler(t) => Debug::fmt(t, f), 7437ac06127Sopenharmony_ci Ident::Fallback(t) => Debug::fmt(t, f), 7447ac06127Sopenharmony_ci } 7457ac06127Sopenharmony_ci } 7467ac06127Sopenharmony_ci} 7477ac06127Sopenharmony_ci 7487ac06127Sopenharmony_ci#[derive(Clone)] 7497ac06127Sopenharmony_cipub(crate) enum Literal { 7507ac06127Sopenharmony_ci Compiler(proc_macro::Literal), 7517ac06127Sopenharmony_ci Fallback(fallback::Literal), 7527ac06127Sopenharmony_ci} 7537ac06127Sopenharmony_ci 7547ac06127Sopenharmony_cimacro_rules! suffixed_numbers { 7557ac06127Sopenharmony_ci ($($name:ident => $kind:ident,)*) => ($( 7567ac06127Sopenharmony_ci pub fn $name(n: $kind) -> Literal { 7577ac06127Sopenharmony_ci if inside_proc_macro() { 7587ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::$name(n)) 7597ac06127Sopenharmony_ci } else { 7607ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::$name(n)) 7617ac06127Sopenharmony_ci } 7627ac06127Sopenharmony_ci } 7637ac06127Sopenharmony_ci )*) 7647ac06127Sopenharmony_ci} 7657ac06127Sopenharmony_ci 7667ac06127Sopenharmony_cimacro_rules! unsuffixed_integers { 7677ac06127Sopenharmony_ci ($($name:ident => $kind:ident,)*) => ($( 7687ac06127Sopenharmony_ci pub fn $name(n: $kind) -> Literal { 7697ac06127Sopenharmony_ci if inside_proc_macro() { 7707ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::$name(n)) 7717ac06127Sopenharmony_ci } else { 7727ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::$name(n)) 7737ac06127Sopenharmony_ci } 7747ac06127Sopenharmony_ci } 7757ac06127Sopenharmony_ci )*) 7767ac06127Sopenharmony_ci} 7777ac06127Sopenharmony_ci 7787ac06127Sopenharmony_ciimpl Literal { 7797ac06127Sopenharmony_ci pub unsafe fn from_str_unchecked(repr: &str) -> Self { 7807ac06127Sopenharmony_ci if inside_proc_macro() { 7817ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::from_str(repr).expect("invalid literal")) 7827ac06127Sopenharmony_ci } else { 7837ac06127Sopenharmony_ci Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) }) 7847ac06127Sopenharmony_ci } 7857ac06127Sopenharmony_ci } 7867ac06127Sopenharmony_ci 7877ac06127Sopenharmony_ci suffixed_numbers! { 7887ac06127Sopenharmony_ci u8_suffixed => u8, 7897ac06127Sopenharmony_ci u16_suffixed => u16, 7907ac06127Sopenharmony_ci u32_suffixed => u32, 7917ac06127Sopenharmony_ci u64_suffixed => u64, 7927ac06127Sopenharmony_ci u128_suffixed => u128, 7937ac06127Sopenharmony_ci usize_suffixed => usize, 7947ac06127Sopenharmony_ci i8_suffixed => i8, 7957ac06127Sopenharmony_ci i16_suffixed => i16, 7967ac06127Sopenharmony_ci i32_suffixed => i32, 7977ac06127Sopenharmony_ci i64_suffixed => i64, 7987ac06127Sopenharmony_ci i128_suffixed => i128, 7997ac06127Sopenharmony_ci isize_suffixed => isize, 8007ac06127Sopenharmony_ci 8017ac06127Sopenharmony_ci f32_suffixed => f32, 8027ac06127Sopenharmony_ci f64_suffixed => f64, 8037ac06127Sopenharmony_ci } 8047ac06127Sopenharmony_ci 8057ac06127Sopenharmony_ci unsuffixed_integers! { 8067ac06127Sopenharmony_ci u8_unsuffixed => u8, 8077ac06127Sopenharmony_ci u16_unsuffixed => u16, 8087ac06127Sopenharmony_ci u32_unsuffixed => u32, 8097ac06127Sopenharmony_ci u64_unsuffixed => u64, 8107ac06127Sopenharmony_ci u128_unsuffixed => u128, 8117ac06127Sopenharmony_ci usize_unsuffixed => usize, 8127ac06127Sopenharmony_ci i8_unsuffixed => i8, 8137ac06127Sopenharmony_ci i16_unsuffixed => i16, 8147ac06127Sopenharmony_ci i32_unsuffixed => i32, 8157ac06127Sopenharmony_ci i64_unsuffixed => i64, 8167ac06127Sopenharmony_ci i128_unsuffixed => i128, 8177ac06127Sopenharmony_ci isize_unsuffixed => isize, 8187ac06127Sopenharmony_ci } 8197ac06127Sopenharmony_ci 8207ac06127Sopenharmony_ci pub fn f32_unsuffixed(f: f32) -> Literal { 8217ac06127Sopenharmony_ci if inside_proc_macro() { 8227ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) 8237ac06127Sopenharmony_ci } else { 8247ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::f32_unsuffixed(f)) 8257ac06127Sopenharmony_ci } 8267ac06127Sopenharmony_ci } 8277ac06127Sopenharmony_ci 8287ac06127Sopenharmony_ci pub fn f64_unsuffixed(f: f64) -> Literal { 8297ac06127Sopenharmony_ci if inside_proc_macro() { 8307ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) 8317ac06127Sopenharmony_ci } else { 8327ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::f64_unsuffixed(f)) 8337ac06127Sopenharmony_ci } 8347ac06127Sopenharmony_ci } 8357ac06127Sopenharmony_ci 8367ac06127Sopenharmony_ci pub fn string(t: &str) -> Literal { 8377ac06127Sopenharmony_ci if inside_proc_macro() { 8387ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::string(t)) 8397ac06127Sopenharmony_ci } else { 8407ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::string(t)) 8417ac06127Sopenharmony_ci } 8427ac06127Sopenharmony_ci } 8437ac06127Sopenharmony_ci 8447ac06127Sopenharmony_ci pub fn character(t: char) -> Literal { 8457ac06127Sopenharmony_ci if inside_proc_macro() { 8467ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::character(t)) 8477ac06127Sopenharmony_ci } else { 8487ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::character(t)) 8497ac06127Sopenharmony_ci } 8507ac06127Sopenharmony_ci } 8517ac06127Sopenharmony_ci 8527ac06127Sopenharmony_ci pub fn byte_string(bytes: &[u8]) -> Literal { 8537ac06127Sopenharmony_ci if inside_proc_macro() { 8547ac06127Sopenharmony_ci Literal::Compiler(proc_macro::Literal::byte_string(bytes)) 8557ac06127Sopenharmony_ci } else { 8567ac06127Sopenharmony_ci Literal::Fallback(fallback::Literal::byte_string(bytes)) 8577ac06127Sopenharmony_ci } 8587ac06127Sopenharmony_ci } 8597ac06127Sopenharmony_ci 8607ac06127Sopenharmony_ci pub fn span(&self) -> Span { 8617ac06127Sopenharmony_ci match self { 8627ac06127Sopenharmony_ci Literal::Compiler(lit) => Span::Compiler(lit.span()), 8637ac06127Sopenharmony_ci Literal::Fallback(lit) => Span::Fallback(lit.span()), 8647ac06127Sopenharmony_ci } 8657ac06127Sopenharmony_ci } 8667ac06127Sopenharmony_ci 8677ac06127Sopenharmony_ci pub fn set_span(&mut self, span: Span) { 8687ac06127Sopenharmony_ci match (self, span) { 8697ac06127Sopenharmony_ci (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), 8707ac06127Sopenharmony_ci (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), 8717ac06127Sopenharmony_ci (Literal::Compiler(_), Span::Fallback(_)) => mismatch(line!()), 8727ac06127Sopenharmony_ci (Literal::Fallback(_), Span::Compiler(_)) => mismatch(line!()), 8737ac06127Sopenharmony_ci } 8747ac06127Sopenharmony_ci } 8757ac06127Sopenharmony_ci 8767ac06127Sopenharmony_ci pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { 8777ac06127Sopenharmony_ci match self { 8787ac06127Sopenharmony_ci #[cfg(proc_macro_span)] 8797ac06127Sopenharmony_ci Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler), 8807ac06127Sopenharmony_ci #[cfg(not(proc_macro_span))] 8817ac06127Sopenharmony_ci Literal::Compiler(_lit) => None, 8827ac06127Sopenharmony_ci Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback), 8837ac06127Sopenharmony_ci } 8847ac06127Sopenharmony_ci } 8857ac06127Sopenharmony_ci 8867ac06127Sopenharmony_ci fn unwrap_nightly(self) -> proc_macro::Literal { 8877ac06127Sopenharmony_ci match self { 8887ac06127Sopenharmony_ci Literal::Compiler(s) => s, 8897ac06127Sopenharmony_ci Literal::Fallback(_) => mismatch(line!()), 8907ac06127Sopenharmony_ci } 8917ac06127Sopenharmony_ci } 8927ac06127Sopenharmony_ci} 8937ac06127Sopenharmony_ci 8947ac06127Sopenharmony_ciimpl From<fallback::Literal> for Literal { 8957ac06127Sopenharmony_ci fn from(s: fallback::Literal) -> Self { 8967ac06127Sopenharmony_ci Literal::Fallback(s) 8977ac06127Sopenharmony_ci } 8987ac06127Sopenharmony_ci} 8997ac06127Sopenharmony_ci 9007ac06127Sopenharmony_ciimpl FromStr for Literal { 9017ac06127Sopenharmony_ci type Err = LexError; 9027ac06127Sopenharmony_ci 9037ac06127Sopenharmony_ci fn from_str(repr: &str) -> Result<Self, Self::Err> { 9047ac06127Sopenharmony_ci if inside_proc_macro() { 9057ac06127Sopenharmony_ci let literal = proc_macro::Literal::from_str(repr)?; 9067ac06127Sopenharmony_ci Ok(Literal::Compiler(literal)) 9077ac06127Sopenharmony_ci } else { 9087ac06127Sopenharmony_ci let literal = fallback::Literal::from_str(repr)?; 9097ac06127Sopenharmony_ci Ok(Literal::Fallback(literal)) 9107ac06127Sopenharmony_ci } 9117ac06127Sopenharmony_ci } 9127ac06127Sopenharmony_ci} 9137ac06127Sopenharmony_ci 9147ac06127Sopenharmony_ciimpl Display for Literal { 9157ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 9167ac06127Sopenharmony_ci match self { 9177ac06127Sopenharmony_ci Literal::Compiler(t) => Display::fmt(t, f), 9187ac06127Sopenharmony_ci Literal::Fallback(t) => Display::fmt(t, f), 9197ac06127Sopenharmony_ci } 9207ac06127Sopenharmony_ci } 9217ac06127Sopenharmony_ci} 9227ac06127Sopenharmony_ci 9237ac06127Sopenharmony_ciimpl Debug for Literal { 9247ac06127Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 9257ac06127Sopenharmony_ci match self { 9267ac06127Sopenharmony_ci Literal::Compiler(t) => Debug::fmt(t, f), 9277ac06127Sopenharmony_ci Literal::Fallback(t) => Debug::fmt(t, f), 9287ac06127Sopenharmony_ci } 9297ac06127Sopenharmony_ci } 9307ac06127Sopenharmony_ci} 931