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