17ac06127Sopenharmony_ci#[cfg(span_locations)]
27ac06127Sopenharmony_ciuse crate::location::LineColumn;
37ac06127Sopenharmony_ciuse crate::parse::{self, Cursor};
47ac06127Sopenharmony_ciuse crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut};
57ac06127Sopenharmony_ciuse crate::{Delimiter, Spacing, TokenTree};
67ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
77ac06127Sopenharmony_ciuse alloc::collections::BTreeMap;
87ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
97ac06127Sopenharmony_ciuse core::cell::RefCell;
107ac06127Sopenharmony_ci#[cfg(span_locations)]
117ac06127Sopenharmony_ciuse core::cmp;
127ac06127Sopenharmony_ciuse core::fmt::{self, Debug, Display, Write};
137ac06127Sopenharmony_ciuse core::mem::ManuallyDrop;
147ac06127Sopenharmony_ciuse core::ops::RangeBounds;
157ac06127Sopenharmony_ciuse core::ptr;
167ac06127Sopenharmony_ciuse core::str::FromStr;
177ac06127Sopenharmony_ciuse std::path::PathBuf;
187ac06127Sopenharmony_ci
197ac06127Sopenharmony_ci/// Force use of proc-macro2's fallback implementation of the API for now, even
207ac06127Sopenharmony_ci/// if the compiler's implementation is available.
217ac06127Sopenharmony_cipub fn force() {
227ac06127Sopenharmony_ci    #[cfg(wrap_proc_macro)]
237ac06127Sopenharmony_ci    crate::detection::force_fallback();
247ac06127Sopenharmony_ci}
257ac06127Sopenharmony_ci
267ac06127Sopenharmony_ci/// Resume using the compiler's implementation of the proc macro API if it is
277ac06127Sopenharmony_ci/// available.
287ac06127Sopenharmony_cipub fn unforce() {
297ac06127Sopenharmony_ci    #[cfg(wrap_proc_macro)]
307ac06127Sopenharmony_ci    crate::detection::unforce_fallback();
317ac06127Sopenharmony_ci}
327ac06127Sopenharmony_ci
337ac06127Sopenharmony_ci#[derive(Clone)]
347ac06127Sopenharmony_cipub(crate) struct TokenStream {
357ac06127Sopenharmony_ci    inner: RcVec<TokenTree>,
367ac06127Sopenharmony_ci}
377ac06127Sopenharmony_ci
387ac06127Sopenharmony_ci#[derive(Debug)]
397ac06127Sopenharmony_cipub(crate) struct LexError {
407ac06127Sopenharmony_ci    pub(crate) span: Span,
417ac06127Sopenharmony_ci}
427ac06127Sopenharmony_ci
437ac06127Sopenharmony_ciimpl LexError {
447ac06127Sopenharmony_ci    pub(crate) fn span(&self) -> Span {
457ac06127Sopenharmony_ci        self.span
467ac06127Sopenharmony_ci    }
477ac06127Sopenharmony_ci
487ac06127Sopenharmony_ci    pub(crate) fn call_site() -> Self {
497ac06127Sopenharmony_ci        LexError {
507ac06127Sopenharmony_ci            span: Span::call_site(),
517ac06127Sopenharmony_ci        }
527ac06127Sopenharmony_ci    }
537ac06127Sopenharmony_ci}
547ac06127Sopenharmony_ci
557ac06127Sopenharmony_ciimpl TokenStream {
567ac06127Sopenharmony_ci    pub fn new() -> Self {
577ac06127Sopenharmony_ci        TokenStream {
587ac06127Sopenharmony_ci            inner: RcVecBuilder::new().build(),
597ac06127Sopenharmony_ci        }
607ac06127Sopenharmony_ci    }
617ac06127Sopenharmony_ci
627ac06127Sopenharmony_ci    pub fn is_empty(&self) -> bool {
637ac06127Sopenharmony_ci        self.inner.len() == 0
647ac06127Sopenharmony_ci    }
657ac06127Sopenharmony_ci
667ac06127Sopenharmony_ci    fn take_inner(self) -> RcVecBuilder<TokenTree> {
677ac06127Sopenharmony_ci        let nodrop = ManuallyDrop::new(self);
687ac06127Sopenharmony_ci        unsafe { ptr::read(&nodrop.inner) }.make_owned()
697ac06127Sopenharmony_ci    }
707ac06127Sopenharmony_ci}
717ac06127Sopenharmony_ci
727ac06127Sopenharmony_cifn push_token_from_proc_macro(mut vec: RcVecMut<TokenTree>, token: TokenTree) {
737ac06127Sopenharmony_ci    // https://github.com/dtolnay/proc-macro2/issues/235
747ac06127Sopenharmony_ci    match token {
757ac06127Sopenharmony_ci        TokenTree::Literal(crate::Literal {
767ac06127Sopenharmony_ci            #[cfg(wrap_proc_macro)]
777ac06127Sopenharmony_ci                inner: crate::imp::Literal::Fallback(literal),
787ac06127Sopenharmony_ci            #[cfg(not(wrap_proc_macro))]
797ac06127Sopenharmony_ci                inner: literal,
807ac06127Sopenharmony_ci            ..
817ac06127Sopenharmony_ci        }) if literal.repr.starts_with('-') => {
827ac06127Sopenharmony_ci            push_negative_literal(vec, literal);
837ac06127Sopenharmony_ci        }
847ac06127Sopenharmony_ci        _ => vec.push(token),
857ac06127Sopenharmony_ci    }
867ac06127Sopenharmony_ci
877ac06127Sopenharmony_ci    #[cold]
887ac06127Sopenharmony_ci    fn push_negative_literal(mut vec: RcVecMut<TokenTree>, mut literal: Literal) {
897ac06127Sopenharmony_ci        literal.repr.remove(0);
907ac06127Sopenharmony_ci        let mut punct = crate::Punct::new('-', Spacing::Alone);
917ac06127Sopenharmony_ci        punct.set_span(crate::Span::_new_fallback(literal.span));
927ac06127Sopenharmony_ci        vec.push(TokenTree::Punct(punct));
937ac06127Sopenharmony_ci        vec.push(TokenTree::Literal(crate::Literal::_new_fallback(literal)));
947ac06127Sopenharmony_ci    }
957ac06127Sopenharmony_ci}
967ac06127Sopenharmony_ci
977ac06127Sopenharmony_ci// Nonrecursive to prevent stack overflow.
987ac06127Sopenharmony_ciimpl Drop for TokenStream {
997ac06127Sopenharmony_ci    fn drop(&mut self) {
1007ac06127Sopenharmony_ci        let mut inner = match self.inner.get_mut() {
1017ac06127Sopenharmony_ci            Some(inner) => inner,
1027ac06127Sopenharmony_ci            None => return,
1037ac06127Sopenharmony_ci        };
1047ac06127Sopenharmony_ci        while let Some(token) = inner.pop() {
1057ac06127Sopenharmony_ci            let group = match token {
1067ac06127Sopenharmony_ci                TokenTree::Group(group) => group.inner,
1077ac06127Sopenharmony_ci                _ => continue,
1087ac06127Sopenharmony_ci            };
1097ac06127Sopenharmony_ci            #[cfg(wrap_proc_macro)]
1107ac06127Sopenharmony_ci            let group = match group {
1117ac06127Sopenharmony_ci                crate::imp::Group::Fallback(group) => group,
1127ac06127Sopenharmony_ci                crate::imp::Group::Compiler(_) => continue,
1137ac06127Sopenharmony_ci            };
1147ac06127Sopenharmony_ci            inner.extend(group.stream.take_inner());
1157ac06127Sopenharmony_ci        }
1167ac06127Sopenharmony_ci    }
1177ac06127Sopenharmony_ci}
1187ac06127Sopenharmony_ci
1197ac06127Sopenharmony_cipub(crate) struct TokenStreamBuilder {
1207ac06127Sopenharmony_ci    inner: RcVecBuilder<TokenTree>,
1217ac06127Sopenharmony_ci}
1227ac06127Sopenharmony_ci
1237ac06127Sopenharmony_ciimpl TokenStreamBuilder {
1247ac06127Sopenharmony_ci    pub fn new() -> Self {
1257ac06127Sopenharmony_ci        TokenStreamBuilder {
1267ac06127Sopenharmony_ci            inner: RcVecBuilder::new(),
1277ac06127Sopenharmony_ci        }
1287ac06127Sopenharmony_ci    }
1297ac06127Sopenharmony_ci
1307ac06127Sopenharmony_ci    pub fn with_capacity(cap: usize) -> Self {
1317ac06127Sopenharmony_ci        TokenStreamBuilder {
1327ac06127Sopenharmony_ci            inner: RcVecBuilder::with_capacity(cap),
1337ac06127Sopenharmony_ci        }
1347ac06127Sopenharmony_ci    }
1357ac06127Sopenharmony_ci
1367ac06127Sopenharmony_ci    pub fn push_token_from_parser(&mut self, tt: TokenTree) {
1377ac06127Sopenharmony_ci        self.inner.push(tt);
1387ac06127Sopenharmony_ci    }
1397ac06127Sopenharmony_ci
1407ac06127Sopenharmony_ci    pub fn build(self) -> TokenStream {
1417ac06127Sopenharmony_ci        TokenStream {
1427ac06127Sopenharmony_ci            inner: self.inner.build(),
1437ac06127Sopenharmony_ci        }
1447ac06127Sopenharmony_ci    }
1457ac06127Sopenharmony_ci}
1467ac06127Sopenharmony_ci
1477ac06127Sopenharmony_ci#[cfg(span_locations)]
1487ac06127Sopenharmony_cifn get_cursor(src: &str) -> Cursor {
1497ac06127Sopenharmony_ci    #[cfg(fuzzing)]
1507ac06127Sopenharmony_ci    return Cursor { rest: src, off: 1 };
1517ac06127Sopenharmony_ci
1527ac06127Sopenharmony_ci    // Create a dummy file & add it to the source map
1537ac06127Sopenharmony_ci    #[cfg(not(fuzzing))]
1547ac06127Sopenharmony_ci    SOURCE_MAP.with(|cm| {
1557ac06127Sopenharmony_ci        let mut cm = cm.borrow_mut();
1567ac06127Sopenharmony_ci        let span = cm.add_file(src);
1577ac06127Sopenharmony_ci        Cursor {
1587ac06127Sopenharmony_ci            rest: src,
1597ac06127Sopenharmony_ci            off: span.lo,
1607ac06127Sopenharmony_ci        }
1617ac06127Sopenharmony_ci    })
1627ac06127Sopenharmony_ci}
1637ac06127Sopenharmony_ci
1647ac06127Sopenharmony_ci#[cfg(not(span_locations))]
1657ac06127Sopenharmony_cifn get_cursor(src: &str) -> Cursor {
1667ac06127Sopenharmony_ci    Cursor { rest: src }
1677ac06127Sopenharmony_ci}
1687ac06127Sopenharmony_ci
1697ac06127Sopenharmony_ciimpl FromStr for TokenStream {
1707ac06127Sopenharmony_ci    type Err = LexError;
1717ac06127Sopenharmony_ci
1727ac06127Sopenharmony_ci    fn from_str(src: &str) -> Result<TokenStream, LexError> {
1737ac06127Sopenharmony_ci        // Create a dummy file & add it to the source map
1747ac06127Sopenharmony_ci        let mut cursor = get_cursor(src);
1757ac06127Sopenharmony_ci
1767ac06127Sopenharmony_ci        // Strip a byte order mark if present
1777ac06127Sopenharmony_ci        const BYTE_ORDER_MARK: &str = "\u{feff}";
1787ac06127Sopenharmony_ci        if cursor.starts_with(BYTE_ORDER_MARK) {
1797ac06127Sopenharmony_ci            cursor = cursor.advance(BYTE_ORDER_MARK.len());
1807ac06127Sopenharmony_ci        }
1817ac06127Sopenharmony_ci
1827ac06127Sopenharmony_ci        parse::token_stream(cursor)
1837ac06127Sopenharmony_ci    }
1847ac06127Sopenharmony_ci}
1857ac06127Sopenharmony_ci
1867ac06127Sopenharmony_ciimpl Display for LexError {
1877ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1887ac06127Sopenharmony_ci        f.write_str("cannot parse string into token stream")
1897ac06127Sopenharmony_ci    }
1907ac06127Sopenharmony_ci}
1917ac06127Sopenharmony_ci
1927ac06127Sopenharmony_ciimpl Display for TokenStream {
1937ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1947ac06127Sopenharmony_ci        let mut joint = false;
1957ac06127Sopenharmony_ci        for (i, tt) in self.inner.iter().enumerate() {
1967ac06127Sopenharmony_ci            if i != 0 && !joint {
1977ac06127Sopenharmony_ci                write!(f, " ")?;
1987ac06127Sopenharmony_ci            }
1997ac06127Sopenharmony_ci            joint = false;
2007ac06127Sopenharmony_ci            match tt {
2017ac06127Sopenharmony_ci                TokenTree::Group(tt) => Display::fmt(tt, f),
2027ac06127Sopenharmony_ci                TokenTree::Ident(tt) => Display::fmt(tt, f),
2037ac06127Sopenharmony_ci                TokenTree::Punct(tt) => {
2047ac06127Sopenharmony_ci                    joint = tt.spacing() == Spacing::Joint;
2057ac06127Sopenharmony_ci                    Display::fmt(tt, f)
2067ac06127Sopenharmony_ci                }
2077ac06127Sopenharmony_ci                TokenTree::Literal(tt) => Display::fmt(tt, f),
2087ac06127Sopenharmony_ci            }?;
2097ac06127Sopenharmony_ci        }
2107ac06127Sopenharmony_ci
2117ac06127Sopenharmony_ci        Ok(())
2127ac06127Sopenharmony_ci    }
2137ac06127Sopenharmony_ci}
2147ac06127Sopenharmony_ci
2157ac06127Sopenharmony_ciimpl Debug for TokenStream {
2167ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2177ac06127Sopenharmony_ci        f.write_str("TokenStream ")?;
2187ac06127Sopenharmony_ci        f.debug_list().entries(self.clone()).finish()
2197ac06127Sopenharmony_ci    }
2207ac06127Sopenharmony_ci}
2217ac06127Sopenharmony_ci
2227ac06127Sopenharmony_ci#[cfg(feature = "proc-macro")]
2237ac06127Sopenharmony_ciimpl From<proc_macro::TokenStream> for TokenStream {
2247ac06127Sopenharmony_ci    fn from(inner: proc_macro::TokenStream) -> Self {
2257ac06127Sopenharmony_ci        inner
2267ac06127Sopenharmony_ci            .to_string()
2277ac06127Sopenharmony_ci            .parse()
2287ac06127Sopenharmony_ci            .expect("compiler token stream parse failed")
2297ac06127Sopenharmony_ci    }
2307ac06127Sopenharmony_ci}
2317ac06127Sopenharmony_ci
2327ac06127Sopenharmony_ci#[cfg(feature = "proc-macro")]
2337ac06127Sopenharmony_ciimpl From<TokenStream> for proc_macro::TokenStream {
2347ac06127Sopenharmony_ci    fn from(inner: TokenStream) -> Self {
2357ac06127Sopenharmony_ci        inner
2367ac06127Sopenharmony_ci            .to_string()
2377ac06127Sopenharmony_ci            .parse()
2387ac06127Sopenharmony_ci            .expect("failed to parse to compiler tokens")
2397ac06127Sopenharmony_ci    }
2407ac06127Sopenharmony_ci}
2417ac06127Sopenharmony_ci
2427ac06127Sopenharmony_ciimpl From<TokenTree> for TokenStream {
2437ac06127Sopenharmony_ci    fn from(tree: TokenTree) -> Self {
2447ac06127Sopenharmony_ci        let mut stream = RcVecBuilder::new();
2457ac06127Sopenharmony_ci        push_token_from_proc_macro(stream.as_mut(), tree);
2467ac06127Sopenharmony_ci        TokenStream {
2477ac06127Sopenharmony_ci            inner: stream.build(),
2487ac06127Sopenharmony_ci        }
2497ac06127Sopenharmony_ci    }
2507ac06127Sopenharmony_ci}
2517ac06127Sopenharmony_ci
2527ac06127Sopenharmony_ciimpl FromIterator<TokenTree> for TokenStream {
2537ac06127Sopenharmony_ci    fn from_iter<I: IntoIterator<Item = TokenTree>>(tokens: I) -> Self {
2547ac06127Sopenharmony_ci        let mut stream = TokenStream::new();
2557ac06127Sopenharmony_ci        stream.extend(tokens);
2567ac06127Sopenharmony_ci        stream
2577ac06127Sopenharmony_ci    }
2587ac06127Sopenharmony_ci}
2597ac06127Sopenharmony_ci
2607ac06127Sopenharmony_ciimpl FromIterator<TokenStream> for TokenStream {
2617ac06127Sopenharmony_ci    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
2627ac06127Sopenharmony_ci        let mut v = RcVecBuilder::new();
2637ac06127Sopenharmony_ci
2647ac06127Sopenharmony_ci        for stream in streams {
2657ac06127Sopenharmony_ci            v.extend(stream.take_inner());
2667ac06127Sopenharmony_ci        }
2677ac06127Sopenharmony_ci
2687ac06127Sopenharmony_ci        TokenStream { inner: v.build() }
2697ac06127Sopenharmony_ci    }
2707ac06127Sopenharmony_ci}
2717ac06127Sopenharmony_ci
2727ac06127Sopenharmony_ciimpl Extend<TokenTree> for TokenStream {
2737ac06127Sopenharmony_ci    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, tokens: I) {
2747ac06127Sopenharmony_ci        let mut vec = self.inner.make_mut();
2757ac06127Sopenharmony_ci        tokens
2767ac06127Sopenharmony_ci            .into_iter()
2777ac06127Sopenharmony_ci            .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token));
2787ac06127Sopenharmony_ci    }
2797ac06127Sopenharmony_ci}
2807ac06127Sopenharmony_ci
2817ac06127Sopenharmony_ciimpl Extend<TokenStream> for TokenStream {
2827ac06127Sopenharmony_ci    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
2837ac06127Sopenharmony_ci        self.inner.make_mut().extend(streams.into_iter().flatten());
2847ac06127Sopenharmony_ci    }
2857ac06127Sopenharmony_ci}
2867ac06127Sopenharmony_ci
2877ac06127Sopenharmony_cipub(crate) type TokenTreeIter = RcVecIntoIter<TokenTree>;
2887ac06127Sopenharmony_ci
2897ac06127Sopenharmony_ciimpl IntoIterator for TokenStream {
2907ac06127Sopenharmony_ci    type Item = TokenTree;
2917ac06127Sopenharmony_ci    type IntoIter = TokenTreeIter;
2927ac06127Sopenharmony_ci
2937ac06127Sopenharmony_ci    fn into_iter(self) -> TokenTreeIter {
2947ac06127Sopenharmony_ci        self.take_inner().into_iter()
2957ac06127Sopenharmony_ci    }
2967ac06127Sopenharmony_ci}
2977ac06127Sopenharmony_ci
2987ac06127Sopenharmony_ci#[derive(Clone, PartialEq, Eq)]
2997ac06127Sopenharmony_cipub(crate) struct SourceFile {
3007ac06127Sopenharmony_ci    path: PathBuf,
3017ac06127Sopenharmony_ci}
3027ac06127Sopenharmony_ci
3037ac06127Sopenharmony_ciimpl SourceFile {
3047ac06127Sopenharmony_ci    /// Get the path to this source file as a string.
3057ac06127Sopenharmony_ci    pub fn path(&self) -> PathBuf {
3067ac06127Sopenharmony_ci        self.path.clone()
3077ac06127Sopenharmony_ci    }
3087ac06127Sopenharmony_ci
3097ac06127Sopenharmony_ci    pub fn is_real(&self) -> bool {
3107ac06127Sopenharmony_ci        false
3117ac06127Sopenharmony_ci    }
3127ac06127Sopenharmony_ci}
3137ac06127Sopenharmony_ci
3147ac06127Sopenharmony_ciimpl Debug for SourceFile {
3157ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3167ac06127Sopenharmony_ci        f.debug_struct("SourceFile")
3177ac06127Sopenharmony_ci            .field("path", &self.path())
3187ac06127Sopenharmony_ci            .field("is_real", &self.is_real())
3197ac06127Sopenharmony_ci            .finish()
3207ac06127Sopenharmony_ci    }
3217ac06127Sopenharmony_ci}
3227ac06127Sopenharmony_ci
3237ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
3247ac06127Sopenharmony_cithread_local! {
3257ac06127Sopenharmony_ci    static SOURCE_MAP: RefCell<SourceMap> = RefCell::new(SourceMap {
3267ac06127Sopenharmony_ci        // Start with a single dummy file which all call_site() and def_site()
3277ac06127Sopenharmony_ci        // spans reference.
3287ac06127Sopenharmony_ci        files: vec![FileInfo {
3297ac06127Sopenharmony_ci            source_text: String::new(),
3307ac06127Sopenharmony_ci            span: Span { lo: 0, hi: 0 },
3317ac06127Sopenharmony_ci            lines: vec![0],
3327ac06127Sopenharmony_ci            char_index_to_byte_offset: BTreeMap::new(),
3337ac06127Sopenharmony_ci        }],
3347ac06127Sopenharmony_ci    });
3357ac06127Sopenharmony_ci}
3367ac06127Sopenharmony_ci
3377ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
3387ac06127Sopenharmony_cistruct FileInfo {
3397ac06127Sopenharmony_ci    source_text: String,
3407ac06127Sopenharmony_ci    span: Span,
3417ac06127Sopenharmony_ci    lines: Vec<usize>,
3427ac06127Sopenharmony_ci    char_index_to_byte_offset: BTreeMap<usize, usize>,
3437ac06127Sopenharmony_ci}
3447ac06127Sopenharmony_ci
3457ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
3467ac06127Sopenharmony_ciimpl FileInfo {
3477ac06127Sopenharmony_ci    fn offset_line_column(&self, offset: usize) -> LineColumn {
3487ac06127Sopenharmony_ci        assert!(self.span_within(Span {
3497ac06127Sopenharmony_ci            lo: offset as u32,
3507ac06127Sopenharmony_ci            hi: offset as u32,
3517ac06127Sopenharmony_ci        }));
3527ac06127Sopenharmony_ci        let offset = offset - self.span.lo as usize;
3537ac06127Sopenharmony_ci        match self.lines.binary_search(&offset) {
3547ac06127Sopenharmony_ci            Ok(found) => LineColumn {
3557ac06127Sopenharmony_ci                line: found + 1,
3567ac06127Sopenharmony_ci                column: 0,
3577ac06127Sopenharmony_ci            },
3587ac06127Sopenharmony_ci            Err(idx) => LineColumn {
3597ac06127Sopenharmony_ci                line: idx,
3607ac06127Sopenharmony_ci                column: offset - self.lines[idx - 1],
3617ac06127Sopenharmony_ci            },
3627ac06127Sopenharmony_ci        }
3637ac06127Sopenharmony_ci    }
3647ac06127Sopenharmony_ci
3657ac06127Sopenharmony_ci    fn span_within(&self, span: Span) -> bool {
3667ac06127Sopenharmony_ci        span.lo >= self.span.lo && span.hi <= self.span.hi
3677ac06127Sopenharmony_ci    }
3687ac06127Sopenharmony_ci
3697ac06127Sopenharmony_ci    fn source_text(&mut self, span: Span) -> String {
3707ac06127Sopenharmony_ci        let lo_char = (span.lo - self.span.lo) as usize;
3717ac06127Sopenharmony_ci
3727ac06127Sopenharmony_ci        // Look up offset of the largest already-computed char index that is
3737ac06127Sopenharmony_ci        // less than or equal to the current requested one. We resume counting
3747ac06127Sopenharmony_ci        // chars from that point.
3757ac06127Sopenharmony_ci        let (&last_char_index, &last_byte_offset) = self
3767ac06127Sopenharmony_ci            .char_index_to_byte_offset
3777ac06127Sopenharmony_ci            .range(..=lo_char)
3787ac06127Sopenharmony_ci            .next_back()
3797ac06127Sopenharmony_ci            .unwrap_or((&0, &0));
3807ac06127Sopenharmony_ci
3817ac06127Sopenharmony_ci        let lo_byte = if last_char_index == lo_char {
3827ac06127Sopenharmony_ci            last_byte_offset
3837ac06127Sopenharmony_ci        } else {
3847ac06127Sopenharmony_ci            let total_byte_offset = match self.source_text[last_byte_offset..]
3857ac06127Sopenharmony_ci                .char_indices()
3867ac06127Sopenharmony_ci                .nth(lo_char - last_char_index)
3877ac06127Sopenharmony_ci            {
3887ac06127Sopenharmony_ci                Some((additional_offset, _ch)) => last_byte_offset + additional_offset,
3897ac06127Sopenharmony_ci                None => self.source_text.len(),
3907ac06127Sopenharmony_ci            };
3917ac06127Sopenharmony_ci            self.char_index_to_byte_offset
3927ac06127Sopenharmony_ci                .insert(lo_char, total_byte_offset);
3937ac06127Sopenharmony_ci            total_byte_offset
3947ac06127Sopenharmony_ci        };
3957ac06127Sopenharmony_ci
3967ac06127Sopenharmony_ci        let trunc_lo = &self.source_text[lo_byte..];
3977ac06127Sopenharmony_ci        let char_len = (span.hi - span.lo) as usize;
3987ac06127Sopenharmony_ci        let source_text = match trunc_lo.char_indices().nth(char_len) {
3997ac06127Sopenharmony_ci            Some((offset, _ch)) => &trunc_lo[..offset],
4007ac06127Sopenharmony_ci            None => trunc_lo,
4017ac06127Sopenharmony_ci        };
4027ac06127Sopenharmony_ci        source_text.to_owned()
4037ac06127Sopenharmony_ci    }
4047ac06127Sopenharmony_ci}
4057ac06127Sopenharmony_ci
4067ac06127Sopenharmony_ci/// Computes the offsets of each line in the given source string
4077ac06127Sopenharmony_ci/// and the total number of characters
4087ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
4097ac06127Sopenharmony_cifn lines_offsets(s: &str) -> (usize, Vec<usize>) {
4107ac06127Sopenharmony_ci    let mut lines = vec![0];
4117ac06127Sopenharmony_ci    let mut total = 0;
4127ac06127Sopenharmony_ci
4137ac06127Sopenharmony_ci    for ch in s.chars() {
4147ac06127Sopenharmony_ci        total += 1;
4157ac06127Sopenharmony_ci        if ch == '\n' {
4167ac06127Sopenharmony_ci            lines.push(total);
4177ac06127Sopenharmony_ci        }
4187ac06127Sopenharmony_ci    }
4197ac06127Sopenharmony_ci
4207ac06127Sopenharmony_ci    (total, lines)
4217ac06127Sopenharmony_ci}
4227ac06127Sopenharmony_ci
4237ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
4247ac06127Sopenharmony_cistruct SourceMap {
4257ac06127Sopenharmony_ci    files: Vec<FileInfo>,
4267ac06127Sopenharmony_ci}
4277ac06127Sopenharmony_ci
4287ac06127Sopenharmony_ci#[cfg(all(span_locations, not(fuzzing)))]
4297ac06127Sopenharmony_ciimpl SourceMap {
4307ac06127Sopenharmony_ci    fn next_start_pos(&self) -> u32 {
4317ac06127Sopenharmony_ci        // Add 1 so there's always space between files.
4327ac06127Sopenharmony_ci        //
4337ac06127Sopenharmony_ci        // We'll always have at least 1 file, as we initialize our files list
4347ac06127Sopenharmony_ci        // with a dummy file.
4357ac06127Sopenharmony_ci        self.files.last().unwrap().span.hi + 1
4367ac06127Sopenharmony_ci    }
4377ac06127Sopenharmony_ci
4387ac06127Sopenharmony_ci    fn add_file(&mut self, src: &str) -> Span {
4397ac06127Sopenharmony_ci        let (len, lines) = lines_offsets(src);
4407ac06127Sopenharmony_ci        let lo = self.next_start_pos();
4417ac06127Sopenharmony_ci        let span = Span {
4427ac06127Sopenharmony_ci            lo,
4437ac06127Sopenharmony_ci            hi: lo + (len as u32),
4447ac06127Sopenharmony_ci        };
4457ac06127Sopenharmony_ci
4467ac06127Sopenharmony_ci        self.files.push(FileInfo {
4477ac06127Sopenharmony_ci            source_text: src.to_owned(),
4487ac06127Sopenharmony_ci            span,
4497ac06127Sopenharmony_ci            lines,
4507ac06127Sopenharmony_ci            // Populated lazily by source_text().
4517ac06127Sopenharmony_ci            char_index_to_byte_offset: BTreeMap::new(),
4527ac06127Sopenharmony_ci        });
4537ac06127Sopenharmony_ci
4547ac06127Sopenharmony_ci        span
4557ac06127Sopenharmony_ci    }
4567ac06127Sopenharmony_ci
4577ac06127Sopenharmony_ci    #[cfg(procmacro2_semver_exempt)]
4587ac06127Sopenharmony_ci    fn filepath(&self, span: Span) -> PathBuf {
4597ac06127Sopenharmony_ci        for (i, file) in self.files.iter().enumerate() {
4607ac06127Sopenharmony_ci            if file.span_within(span) {
4617ac06127Sopenharmony_ci                return PathBuf::from(if i == 0 {
4627ac06127Sopenharmony_ci                    "<unspecified>".to_owned()
4637ac06127Sopenharmony_ci                } else {
4647ac06127Sopenharmony_ci                    format!("<parsed string {}>", i)
4657ac06127Sopenharmony_ci                });
4667ac06127Sopenharmony_ci            }
4677ac06127Sopenharmony_ci        }
4687ac06127Sopenharmony_ci        unreachable!("Invalid span with no related FileInfo!");
4697ac06127Sopenharmony_ci    }
4707ac06127Sopenharmony_ci
4717ac06127Sopenharmony_ci    fn fileinfo(&self, span: Span) -> &FileInfo {
4727ac06127Sopenharmony_ci        for file in &self.files {
4737ac06127Sopenharmony_ci            if file.span_within(span) {
4747ac06127Sopenharmony_ci                return file;
4757ac06127Sopenharmony_ci            }
4767ac06127Sopenharmony_ci        }
4777ac06127Sopenharmony_ci        unreachable!("Invalid span with no related FileInfo!");
4787ac06127Sopenharmony_ci    }
4797ac06127Sopenharmony_ci
4807ac06127Sopenharmony_ci    fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo {
4817ac06127Sopenharmony_ci        for file in &mut self.files {
4827ac06127Sopenharmony_ci            if file.span_within(span) {
4837ac06127Sopenharmony_ci                return file;
4847ac06127Sopenharmony_ci            }
4857ac06127Sopenharmony_ci        }
4867ac06127Sopenharmony_ci        unreachable!("Invalid span with no related FileInfo!");
4877ac06127Sopenharmony_ci    }
4887ac06127Sopenharmony_ci}
4897ac06127Sopenharmony_ci
4907ac06127Sopenharmony_ci#[derive(Clone, Copy, PartialEq, Eq)]
4917ac06127Sopenharmony_cipub(crate) struct Span {
4927ac06127Sopenharmony_ci    #[cfg(span_locations)]
4937ac06127Sopenharmony_ci    pub(crate) lo: u32,
4947ac06127Sopenharmony_ci    #[cfg(span_locations)]
4957ac06127Sopenharmony_ci    pub(crate) hi: u32,
4967ac06127Sopenharmony_ci}
4977ac06127Sopenharmony_ci
4987ac06127Sopenharmony_ciimpl Span {
4997ac06127Sopenharmony_ci    #[cfg(not(span_locations))]
5007ac06127Sopenharmony_ci    pub fn call_site() -> Self {
5017ac06127Sopenharmony_ci        Span {}
5027ac06127Sopenharmony_ci    }
5037ac06127Sopenharmony_ci
5047ac06127Sopenharmony_ci    #[cfg(span_locations)]
5057ac06127Sopenharmony_ci    pub fn call_site() -> Self {
5067ac06127Sopenharmony_ci        Span { lo: 0, hi: 0 }
5077ac06127Sopenharmony_ci    }
5087ac06127Sopenharmony_ci
5097ac06127Sopenharmony_ci    pub fn mixed_site() -> Self {
5107ac06127Sopenharmony_ci        Span::call_site()
5117ac06127Sopenharmony_ci    }
5127ac06127Sopenharmony_ci
5137ac06127Sopenharmony_ci    #[cfg(procmacro2_semver_exempt)]
5147ac06127Sopenharmony_ci    pub fn def_site() -> Self {
5157ac06127Sopenharmony_ci        Span::call_site()
5167ac06127Sopenharmony_ci    }
5177ac06127Sopenharmony_ci
5187ac06127Sopenharmony_ci    pub fn resolved_at(&self, _other: Span) -> Span {
5197ac06127Sopenharmony_ci        // Stable spans consist only of line/column information, so
5207ac06127Sopenharmony_ci        // `resolved_at` and `located_at` only select which span the
5217ac06127Sopenharmony_ci        // caller wants line/column information from.
5227ac06127Sopenharmony_ci        *self
5237ac06127Sopenharmony_ci    }
5247ac06127Sopenharmony_ci
5257ac06127Sopenharmony_ci    pub fn located_at(&self, other: Span) -> Span {
5267ac06127Sopenharmony_ci        other
5277ac06127Sopenharmony_ci    }
5287ac06127Sopenharmony_ci
5297ac06127Sopenharmony_ci    #[cfg(procmacro2_semver_exempt)]
5307ac06127Sopenharmony_ci    pub fn source_file(&self) -> SourceFile {
5317ac06127Sopenharmony_ci        #[cfg(fuzzing)]
5327ac06127Sopenharmony_ci        return SourceFile {
5337ac06127Sopenharmony_ci            path: PathBuf::from("<unspecified>"),
5347ac06127Sopenharmony_ci        };
5357ac06127Sopenharmony_ci
5367ac06127Sopenharmony_ci        #[cfg(not(fuzzing))]
5377ac06127Sopenharmony_ci        SOURCE_MAP.with(|cm| {
5387ac06127Sopenharmony_ci            let cm = cm.borrow();
5397ac06127Sopenharmony_ci            let path = cm.filepath(*self);
5407ac06127Sopenharmony_ci            SourceFile { path }
5417ac06127Sopenharmony_ci        })
5427ac06127Sopenharmony_ci    }
5437ac06127Sopenharmony_ci
5447ac06127Sopenharmony_ci    #[cfg(span_locations)]
5457ac06127Sopenharmony_ci    pub fn start(&self) -> LineColumn {
5467ac06127Sopenharmony_ci        #[cfg(fuzzing)]
5477ac06127Sopenharmony_ci        return LineColumn { line: 0, column: 0 };
5487ac06127Sopenharmony_ci
5497ac06127Sopenharmony_ci        #[cfg(not(fuzzing))]
5507ac06127Sopenharmony_ci        SOURCE_MAP.with(|cm| {
5517ac06127Sopenharmony_ci            let cm = cm.borrow();
5527ac06127Sopenharmony_ci            let fi = cm.fileinfo(*self);
5537ac06127Sopenharmony_ci            fi.offset_line_column(self.lo as usize)
5547ac06127Sopenharmony_ci        })
5557ac06127Sopenharmony_ci    }
5567ac06127Sopenharmony_ci
5577ac06127Sopenharmony_ci    #[cfg(span_locations)]
5587ac06127Sopenharmony_ci    pub fn end(&self) -> LineColumn {
5597ac06127Sopenharmony_ci        #[cfg(fuzzing)]
5607ac06127Sopenharmony_ci        return LineColumn { line: 0, column: 0 };
5617ac06127Sopenharmony_ci
5627ac06127Sopenharmony_ci        #[cfg(not(fuzzing))]
5637ac06127Sopenharmony_ci        SOURCE_MAP.with(|cm| {
5647ac06127Sopenharmony_ci            let cm = cm.borrow();
5657ac06127Sopenharmony_ci            let fi = cm.fileinfo(*self);
5667ac06127Sopenharmony_ci            fi.offset_line_column(self.hi as usize)
5677ac06127Sopenharmony_ci        })
5687ac06127Sopenharmony_ci    }
5697ac06127Sopenharmony_ci
5707ac06127Sopenharmony_ci    #[cfg(not(span_locations))]
5717ac06127Sopenharmony_ci    pub fn join(&self, _other: Span) -> Option<Span> {
5727ac06127Sopenharmony_ci        Some(Span {})
5737ac06127Sopenharmony_ci    }
5747ac06127Sopenharmony_ci
5757ac06127Sopenharmony_ci    #[cfg(span_locations)]
5767ac06127Sopenharmony_ci    pub fn join(&self, other: Span) -> Option<Span> {
5777ac06127Sopenharmony_ci        #[cfg(fuzzing)]
5787ac06127Sopenharmony_ci        return {
5797ac06127Sopenharmony_ci            let _ = other;
5807ac06127Sopenharmony_ci            None
5817ac06127Sopenharmony_ci        };
5827ac06127Sopenharmony_ci
5837ac06127Sopenharmony_ci        #[cfg(not(fuzzing))]
5847ac06127Sopenharmony_ci        SOURCE_MAP.with(|cm| {
5857ac06127Sopenharmony_ci            let cm = cm.borrow();
5867ac06127Sopenharmony_ci            // If `other` is not within the same FileInfo as us, return None.
5877ac06127Sopenharmony_ci            if !cm.fileinfo(*self).span_within(other) {
5887ac06127Sopenharmony_ci                return None;
5897ac06127Sopenharmony_ci            }
5907ac06127Sopenharmony_ci            Some(Span {
5917ac06127Sopenharmony_ci                lo: cmp::min(self.lo, other.lo),
5927ac06127Sopenharmony_ci                hi: cmp::max(self.hi, other.hi),
5937ac06127Sopenharmony_ci            })
5947ac06127Sopenharmony_ci        })
5957ac06127Sopenharmony_ci    }
5967ac06127Sopenharmony_ci
5977ac06127Sopenharmony_ci    #[cfg(not(span_locations))]
5987ac06127Sopenharmony_ci    pub fn source_text(&self) -> Option<String> {
5997ac06127Sopenharmony_ci        None
6007ac06127Sopenharmony_ci    }
6017ac06127Sopenharmony_ci
6027ac06127Sopenharmony_ci    #[cfg(span_locations)]
6037ac06127Sopenharmony_ci    pub fn source_text(&self) -> Option<String> {
6047ac06127Sopenharmony_ci        #[cfg(fuzzing)]
6057ac06127Sopenharmony_ci        return None;
6067ac06127Sopenharmony_ci
6077ac06127Sopenharmony_ci        #[cfg(not(fuzzing))]
6087ac06127Sopenharmony_ci        {
6097ac06127Sopenharmony_ci            if self.is_call_site() {
6107ac06127Sopenharmony_ci                None
6117ac06127Sopenharmony_ci            } else {
6127ac06127Sopenharmony_ci                Some(SOURCE_MAP.with(|cm| cm.borrow_mut().fileinfo_mut(*self).source_text(*self)))
6137ac06127Sopenharmony_ci            }
6147ac06127Sopenharmony_ci        }
6157ac06127Sopenharmony_ci    }
6167ac06127Sopenharmony_ci
6177ac06127Sopenharmony_ci    #[cfg(not(span_locations))]
6187ac06127Sopenharmony_ci    pub(crate) fn first_byte(self) -> Self {
6197ac06127Sopenharmony_ci        self
6207ac06127Sopenharmony_ci    }
6217ac06127Sopenharmony_ci
6227ac06127Sopenharmony_ci    #[cfg(span_locations)]
6237ac06127Sopenharmony_ci    pub(crate) fn first_byte(self) -> Self {
6247ac06127Sopenharmony_ci        Span {
6257ac06127Sopenharmony_ci            lo: self.lo,
6267ac06127Sopenharmony_ci            hi: cmp::min(self.lo.saturating_add(1), self.hi),
6277ac06127Sopenharmony_ci        }
6287ac06127Sopenharmony_ci    }
6297ac06127Sopenharmony_ci
6307ac06127Sopenharmony_ci    #[cfg(not(span_locations))]
6317ac06127Sopenharmony_ci    pub(crate) fn last_byte(self) -> Self {
6327ac06127Sopenharmony_ci        self
6337ac06127Sopenharmony_ci    }
6347ac06127Sopenharmony_ci
6357ac06127Sopenharmony_ci    #[cfg(span_locations)]
6367ac06127Sopenharmony_ci    pub(crate) fn last_byte(self) -> Self {
6377ac06127Sopenharmony_ci        Span {
6387ac06127Sopenharmony_ci            lo: cmp::max(self.hi.saturating_sub(1), self.lo),
6397ac06127Sopenharmony_ci            hi: self.hi,
6407ac06127Sopenharmony_ci        }
6417ac06127Sopenharmony_ci    }
6427ac06127Sopenharmony_ci
6437ac06127Sopenharmony_ci    #[cfg(span_locations)]
6447ac06127Sopenharmony_ci    fn is_call_site(&self) -> bool {
6457ac06127Sopenharmony_ci        self.lo == 0 && self.hi == 0
6467ac06127Sopenharmony_ci    }
6477ac06127Sopenharmony_ci}
6487ac06127Sopenharmony_ci
6497ac06127Sopenharmony_ciimpl Debug for Span {
6507ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6517ac06127Sopenharmony_ci        #[cfg(span_locations)]
6527ac06127Sopenharmony_ci        return write!(f, "bytes({}..{})", self.lo, self.hi);
6537ac06127Sopenharmony_ci
6547ac06127Sopenharmony_ci        #[cfg(not(span_locations))]
6557ac06127Sopenharmony_ci        write!(f, "Span")
6567ac06127Sopenharmony_ci    }
6577ac06127Sopenharmony_ci}
6587ac06127Sopenharmony_ci
6597ac06127Sopenharmony_cipub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) {
6607ac06127Sopenharmony_ci    #[cfg(span_locations)]
6617ac06127Sopenharmony_ci    {
6627ac06127Sopenharmony_ci        if span.is_call_site() {
6637ac06127Sopenharmony_ci            return;
6647ac06127Sopenharmony_ci        }
6657ac06127Sopenharmony_ci    }
6667ac06127Sopenharmony_ci
6677ac06127Sopenharmony_ci    if cfg!(span_locations) {
6687ac06127Sopenharmony_ci        debug.field("span", &span);
6697ac06127Sopenharmony_ci    }
6707ac06127Sopenharmony_ci}
6717ac06127Sopenharmony_ci
6727ac06127Sopenharmony_ci#[derive(Clone)]
6737ac06127Sopenharmony_cipub(crate) struct Group {
6747ac06127Sopenharmony_ci    delimiter: Delimiter,
6757ac06127Sopenharmony_ci    stream: TokenStream,
6767ac06127Sopenharmony_ci    span: Span,
6777ac06127Sopenharmony_ci}
6787ac06127Sopenharmony_ci
6797ac06127Sopenharmony_ciimpl Group {
6807ac06127Sopenharmony_ci    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
6817ac06127Sopenharmony_ci        Group {
6827ac06127Sopenharmony_ci            delimiter,
6837ac06127Sopenharmony_ci            stream,
6847ac06127Sopenharmony_ci            span: Span::call_site(),
6857ac06127Sopenharmony_ci        }
6867ac06127Sopenharmony_ci    }
6877ac06127Sopenharmony_ci
6887ac06127Sopenharmony_ci    pub fn delimiter(&self) -> Delimiter {
6897ac06127Sopenharmony_ci        self.delimiter
6907ac06127Sopenharmony_ci    }
6917ac06127Sopenharmony_ci
6927ac06127Sopenharmony_ci    pub fn stream(&self) -> TokenStream {
6937ac06127Sopenharmony_ci        self.stream.clone()
6947ac06127Sopenharmony_ci    }
6957ac06127Sopenharmony_ci
6967ac06127Sopenharmony_ci    pub fn span(&self) -> Span {
6977ac06127Sopenharmony_ci        self.span
6987ac06127Sopenharmony_ci    }
6997ac06127Sopenharmony_ci
7007ac06127Sopenharmony_ci    pub fn span_open(&self) -> Span {
7017ac06127Sopenharmony_ci        self.span.first_byte()
7027ac06127Sopenharmony_ci    }
7037ac06127Sopenharmony_ci
7047ac06127Sopenharmony_ci    pub fn span_close(&self) -> Span {
7057ac06127Sopenharmony_ci        self.span.last_byte()
7067ac06127Sopenharmony_ci    }
7077ac06127Sopenharmony_ci
7087ac06127Sopenharmony_ci    pub fn set_span(&mut self, span: Span) {
7097ac06127Sopenharmony_ci        self.span = span;
7107ac06127Sopenharmony_ci    }
7117ac06127Sopenharmony_ci}
7127ac06127Sopenharmony_ci
7137ac06127Sopenharmony_ciimpl Display for Group {
7147ac06127Sopenharmony_ci    // We attempt to match libproc_macro's formatting.
7157ac06127Sopenharmony_ci    // Empty parens: ()
7167ac06127Sopenharmony_ci    // Nonempty parens: (...)
7177ac06127Sopenharmony_ci    // Empty brackets: []
7187ac06127Sopenharmony_ci    // Nonempty brackets: [...]
7197ac06127Sopenharmony_ci    // Empty braces: { }
7207ac06127Sopenharmony_ci    // Nonempty braces: { ... }
7217ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7227ac06127Sopenharmony_ci        let (open, close) = match self.delimiter {
7237ac06127Sopenharmony_ci            Delimiter::Parenthesis => ("(", ")"),
7247ac06127Sopenharmony_ci            Delimiter::Brace => ("{ ", "}"),
7257ac06127Sopenharmony_ci            Delimiter::Bracket => ("[", "]"),
7267ac06127Sopenharmony_ci            Delimiter::None => ("", ""),
7277ac06127Sopenharmony_ci        };
7287ac06127Sopenharmony_ci
7297ac06127Sopenharmony_ci        f.write_str(open)?;
7307ac06127Sopenharmony_ci        Display::fmt(&self.stream, f)?;
7317ac06127Sopenharmony_ci        if self.delimiter == Delimiter::Brace && !self.stream.inner.is_empty() {
7327ac06127Sopenharmony_ci            f.write_str(" ")?;
7337ac06127Sopenharmony_ci        }
7347ac06127Sopenharmony_ci        f.write_str(close)?;
7357ac06127Sopenharmony_ci
7367ac06127Sopenharmony_ci        Ok(())
7377ac06127Sopenharmony_ci    }
7387ac06127Sopenharmony_ci}
7397ac06127Sopenharmony_ci
7407ac06127Sopenharmony_ciimpl Debug for Group {
7417ac06127Sopenharmony_ci    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
7427ac06127Sopenharmony_ci        let mut debug = fmt.debug_struct("Group");
7437ac06127Sopenharmony_ci        debug.field("delimiter", &self.delimiter);
7447ac06127Sopenharmony_ci        debug.field("stream", &self.stream);
7457ac06127Sopenharmony_ci        debug_span_field_if_nontrivial(&mut debug, self.span);
7467ac06127Sopenharmony_ci        debug.finish()
7477ac06127Sopenharmony_ci    }
7487ac06127Sopenharmony_ci}
7497ac06127Sopenharmony_ci
7507ac06127Sopenharmony_ci#[derive(Clone)]
7517ac06127Sopenharmony_cipub(crate) struct Ident {
7527ac06127Sopenharmony_ci    sym: String,
7537ac06127Sopenharmony_ci    span: Span,
7547ac06127Sopenharmony_ci    raw: bool,
7557ac06127Sopenharmony_ci}
7567ac06127Sopenharmony_ci
7577ac06127Sopenharmony_ciimpl Ident {
7587ac06127Sopenharmony_ci    #[track_caller]
7597ac06127Sopenharmony_ci    pub fn new_checked(string: &str, span: Span) -> Self {
7607ac06127Sopenharmony_ci        validate_ident(string);
7617ac06127Sopenharmony_ci        Ident::new_unchecked(string, span)
7627ac06127Sopenharmony_ci    }
7637ac06127Sopenharmony_ci
7647ac06127Sopenharmony_ci    pub fn new_unchecked(string: &str, span: Span) -> Self {
7657ac06127Sopenharmony_ci        Ident {
7667ac06127Sopenharmony_ci            sym: string.to_owned(),
7677ac06127Sopenharmony_ci            span,
7687ac06127Sopenharmony_ci            raw: false,
7697ac06127Sopenharmony_ci        }
7707ac06127Sopenharmony_ci    }
7717ac06127Sopenharmony_ci
7727ac06127Sopenharmony_ci    #[track_caller]
7737ac06127Sopenharmony_ci    pub fn new_raw_checked(string: &str, span: Span) -> Self {
7747ac06127Sopenharmony_ci        validate_ident_raw(string);
7757ac06127Sopenharmony_ci        Ident::new_raw_unchecked(string, span)
7767ac06127Sopenharmony_ci    }
7777ac06127Sopenharmony_ci
7787ac06127Sopenharmony_ci    pub fn new_raw_unchecked(string: &str, span: Span) -> Self {
7797ac06127Sopenharmony_ci        Ident {
7807ac06127Sopenharmony_ci            sym: string.to_owned(),
7817ac06127Sopenharmony_ci            span,
7827ac06127Sopenharmony_ci            raw: true,
7837ac06127Sopenharmony_ci        }
7847ac06127Sopenharmony_ci    }
7857ac06127Sopenharmony_ci
7867ac06127Sopenharmony_ci    pub fn span(&self) -> Span {
7877ac06127Sopenharmony_ci        self.span
7887ac06127Sopenharmony_ci    }
7897ac06127Sopenharmony_ci
7907ac06127Sopenharmony_ci    pub fn set_span(&mut self, span: Span) {
7917ac06127Sopenharmony_ci        self.span = span;
7927ac06127Sopenharmony_ci    }
7937ac06127Sopenharmony_ci}
7947ac06127Sopenharmony_ci
7957ac06127Sopenharmony_cipub(crate) fn is_ident_start(c: char) -> bool {
7967ac06127Sopenharmony_ci    c == '_' || unicode_ident::is_xid_start(c)
7977ac06127Sopenharmony_ci}
7987ac06127Sopenharmony_ci
7997ac06127Sopenharmony_cipub(crate) fn is_ident_continue(c: char) -> bool {
8007ac06127Sopenharmony_ci    unicode_ident::is_xid_continue(c)
8017ac06127Sopenharmony_ci}
8027ac06127Sopenharmony_ci
8037ac06127Sopenharmony_ci#[track_caller]
8047ac06127Sopenharmony_cifn validate_ident(string: &str) {
8057ac06127Sopenharmony_ci    if string.is_empty() {
8067ac06127Sopenharmony_ci        panic!("Ident is not allowed to be empty; use Option<Ident>");
8077ac06127Sopenharmony_ci    }
8087ac06127Sopenharmony_ci
8097ac06127Sopenharmony_ci    if string.bytes().all(|digit| b'0' <= digit && digit <= b'9') {
8107ac06127Sopenharmony_ci        panic!("Ident cannot be a number; use Literal instead");
8117ac06127Sopenharmony_ci    }
8127ac06127Sopenharmony_ci
8137ac06127Sopenharmony_ci    fn ident_ok(string: &str) -> bool {
8147ac06127Sopenharmony_ci        let mut chars = string.chars();
8157ac06127Sopenharmony_ci        let first = chars.next().unwrap();
8167ac06127Sopenharmony_ci        if !is_ident_start(first) {
8177ac06127Sopenharmony_ci            return false;
8187ac06127Sopenharmony_ci        }
8197ac06127Sopenharmony_ci        for ch in chars {
8207ac06127Sopenharmony_ci            if !is_ident_continue(ch) {
8217ac06127Sopenharmony_ci                return false;
8227ac06127Sopenharmony_ci            }
8237ac06127Sopenharmony_ci        }
8247ac06127Sopenharmony_ci        true
8257ac06127Sopenharmony_ci    }
8267ac06127Sopenharmony_ci
8277ac06127Sopenharmony_ci    if !ident_ok(string) {
8287ac06127Sopenharmony_ci        panic!("{:?} is not a valid Ident", string);
8297ac06127Sopenharmony_ci    }
8307ac06127Sopenharmony_ci}
8317ac06127Sopenharmony_ci
8327ac06127Sopenharmony_ci#[track_caller]
8337ac06127Sopenharmony_cifn validate_ident_raw(string: &str) {
8347ac06127Sopenharmony_ci    validate_ident(string);
8357ac06127Sopenharmony_ci
8367ac06127Sopenharmony_ci    match string {
8377ac06127Sopenharmony_ci        "_" | "super" | "self" | "Self" | "crate" => {
8387ac06127Sopenharmony_ci            panic!("`r#{}` cannot be a raw identifier", string);
8397ac06127Sopenharmony_ci        }
8407ac06127Sopenharmony_ci        _ => {}
8417ac06127Sopenharmony_ci    }
8427ac06127Sopenharmony_ci}
8437ac06127Sopenharmony_ci
8447ac06127Sopenharmony_ciimpl PartialEq for Ident {
8457ac06127Sopenharmony_ci    fn eq(&self, other: &Ident) -> bool {
8467ac06127Sopenharmony_ci        self.sym == other.sym && self.raw == other.raw
8477ac06127Sopenharmony_ci    }
8487ac06127Sopenharmony_ci}
8497ac06127Sopenharmony_ci
8507ac06127Sopenharmony_ciimpl<T> PartialEq<T> for Ident
8517ac06127Sopenharmony_ciwhere
8527ac06127Sopenharmony_ci    T: ?Sized + AsRef<str>,
8537ac06127Sopenharmony_ci{
8547ac06127Sopenharmony_ci    fn eq(&self, other: &T) -> bool {
8557ac06127Sopenharmony_ci        let other = other.as_ref();
8567ac06127Sopenharmony_ci        if self.raw {
8577ac06127Sopenharmony_ci            other.starts_with("r#") && self.sym == other[2..]
8587ac06127Sopenharmony_ci        } else {
8597ac06127Sopenharmony_ci            self.sym == other
8607ac06127Sopenharmony_ci        }
8617ac06127Sopenharmony_ci    }
8627ac06127Sopenharmony_ci}
8637ac06127Sopenharmony_ci
8647ac06127Sopenharmony_ciimpl Display for Ident {
8657ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8667ac06127Sopenharmony_ci        if self.raw {
8677ac06127Sopenharmony_ci            f.write_str("r#")?;
8687ac06127Sopenharmony_ci        }
8697ac06127Sopenharmony_ci        Display::fmt(&self.sym, f)
8707ac06127Sopenharmony_ci    }
8717ac06127Sopenharmony_ci}
8727ac06127Sopenharmony_ci
8737ac06127Sopenharmony_ci#[allow(clippy::missing_fields_in_debug)]
8747ac06127Sopenharmony_ciimpl Debug for Ident {
8757ac06127Sopenharmony_ci    // Ident(proc_macro), Ident(r#union)
8767ac06127Sopenharmony_ci    #[cfg(not(span_locations))]
8777ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8787ac06127Sopenharmony_ci        let mut debug = f.debug_tuple("Ident");
8797ac06127Sopenharmony_ci        debug.field(&format_args!("{}", self));
8807ac06127Sopenharmony_ci        debug.finish()
8817ac06127Sopenharmony_ci    }
8827ac06127Sopenharmony_ci
8837ac06127Sopenharmony_ci    // Ident {
8847ac06127Sopenharmony_ci    //     sym: proc_macro,
8857ac06127Sopenharmony_ci    //     span: bytes(128..138)
8867ac06127Sopenharmony_ci    // }
8877ac06127Sopenharmony_ci    #[cfg(span_locations)]
8887ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8897ac06127Sopenharmony_ci        let mut debug = f.debug_struct("Ident");
8907ac06127Sopenharmony_ci        debug.field("sym", &format_args!("{}", self));
8917ac06127Sopenharmony_ci        debug_span_field_if_nontrivial(&mut debug, self.span);
8927ac06127Sopenharmony_ci        debug.finish()
8937ac06127Sopenharmony_ci    }
8947ac06127Sopenharmony_ci}
8957ac06127Sopenharmony_ci
8967ac06127Sopenharmony_ci#[derive(Clone)]
8977ac06127Sopenharmony_cipub(crate) struct Literal {
8987ac06127Sopenharmony_ci    repr: String,
8997ac06127Sopenharmony_ci    span: Span,
9007ac06127Sopenharmony_ci}
9017ac06127Sopenharmony_ci
9027ac06127Sopenharmony_cimacro_rules! suffixed_numbers {
9037ac06127Sopenharmony_ci    ($($name:ident => $kind:ident,)*) => ($(
9047ac06127Sopenharmony_ci        pub fn $name(n: $kind) -> Literal {
9057ac06127Sopenharmony_ci            Literal::_new(format!(concat!("{}", stringify!($kind)), n))
9067ac06127Sopenharmony_ci        }
9077ac06127Sopenharmony_ci    )*)
9087ac06127Sopenharmony_ci}
9097ac06127Sopenharmony_ci
9107ac06127Sopenharmony_cimacro_rules! unsuffixed_numbers {
9117ac06127Sopenharmony_ci    ($($name:ident => $kind:ident,)*) => ($(
9127ac06127Sopenharmony_ci        pub fn $name(n: $kind) -> Literal {
9137ac06127Sopenharmony_ci            Literal::_new(n.to_string())
9147ac06127Sopenharmony_ci        }
9157ac06127Sopenharmony_ci    )*)
9167ac06127Sopenharmony_ci}
9177ac06127Sopenharmony_ci
9187ac06127Sopenharmony_ciimpl Literal {
9197ac06127Sopenharmony_ci    pub(crate) fn _new(repr: String) -> Self {
9207ac06127Sopenharmony_ci        Literal {
9217ac06127Sopenharmony_ci            repr,
9227ac06127Sopenharmony_ci            span: Span::call_site(),
9237ac06127Sopenharmony_ci        }
9247ac06127Sopenharmony_ci    }
9257ac06127Sopenharmony_ci
9267ac06127Sopenharmony_ci    pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self {
9277ac06127Sopenharmony_ci        Literal::_new(repr.to_owned())
9287ac06127Sopenharmony_ci    }
9297ac06127Sopenharmony_ci
9307ac06127Sopenharmony_ci    suffixed_numbers! {
9317ac06127Sopenharmony_ci        u8_suffixed => u8,
9327ac06127Sopenharmony_ci        u16_suffixed => u16,
9337ac06127Sopenharmony_ci        u32_suffixed => u32,
9347ac06127Sopenharmony_ci        u64_suffixed => u64,
9357ac06127Sopenharmony_ci        u128_suffixed => u128,
9367ac06127Sopenharmony_ci        usize_suffixed => usize,
9377ac06127Sopenharmony_ci        i8_suffixed => i8,
9387ac06127Sopenharmony_ci        i16_suffixed => i16,
9397ac06127Sopenharmony_ci        i32_suffixed => i32,
9407ac06127Sopenharmony_ci        i64_suffixed => i64,
9417ac06127Sopenharmony_ci        i128_suffixed => i128,
9427ac06127Sopenharmony_ci        isize_suffixed => isize,
9437ac06127Sopenharmony_ci
9447ac06127Sopenharmony_ci        f32_suffixed => f32,
9457ac06127Sopenharmony_ci        f64_suffixed => f64,
9467ac06127Sopenharmony_ci    }
9477ac06127Sopenharmony_ci
9487ac06127Sopenharmony_ci    unsuffixed_numbers! {
9497ac06127Sopenharmony_ci        u8_unsuffixed => u8,
9507ac06127Sopenharmony_ci        u16_unsuffixed => u16,
9517ac06127Sopenharmony_ci        u32_unsuffixed => u32,
9527ac06127Sopenharmony_ci        u64_unsuffixed => u64,
9537ac06127Sopenharmony_ci        u128_unsuffixed => u128,
9547ac06127Sopenharmony_ci        usize_unsuffixed => usize,
9557ac06127Sopenharmony_ci        i8_unsuffixed => i8,
9567ac06127Sopenharmony_ci        i16_unsuffixed => i16,
9577ac06127Sopenharmony_ci        i32_unsuffixed => i32,
9587ac06127Sopenharmony_ci        i64_unsuffixed => i64,
9597ac06127Sopenharmony_ci        i128_unsuffixed => i128,
9607ac06127Sopenharmony_ci        isize_unsuffixed => isize,
9617ac06127Sopenharmony_ci    }
9627ac06127Sopenharmony_ci
9637ac06127Sopenharmony_ci    pub fn f32_unsuffixed(f: f32) -> Literal {
9647ac06127Sopenharmony_ci        let mut s = f.to_string();
9657ac06127Sopenharmony_ci        if !s.contains('.') {
9667ac06127Sopenharmony_ci            s.push_str(".0");
9677ac06127Sopenharmony_ci        }
9687ac06127Sopenharmony_ci        Literal::_new(s)
9697ac06127Sopenharmony_ci    }
9707ac06127Sopenharmony_ci
9717ac06127Sopenharmony_ci    pub fn f64_unsuffixed(f: f64) -> Literal {
9727ac06127Sopenharmony_ci        let mut s = f.to_string();
9737ac06127Sopenharmony_ci        if !s.contains('.') {
9747ac06127Sopenharmony_ci            s.push_str(".0");
9757ac06127Sopenharmony_ci        }
9767ac06127Sopenharmony_ci        Literal::_new(s)
9777ac06127Sopenharmony_ci    }
9787ac06127Sopenharmony_ci
9797ac06127Sopenharmony_ci    pub fn string(t: &str) -> Literal {
9807ac06127Sopenharmony_ci        let mut repr = String::with_capacity(t.len() + 2);
9817ac06127Sopenharmony_ci        repr.push('"');
9827ac06127Sopenharmony_ci        let mut chars = t.chars();
9837ac06127Sopenharmony_ci        while let Some(ch) = chars.next() {
9847ac06127Sopenharmony_ci            if ch == '\0' {
9857ac06127Sopenharmony_ci                repr.push_str(
9867ac06127Sopenharmony_ci                    if chars
9877ac06127Sopenharmony_ci                        .as_str()
9887ac06127Sopenharmony_ci                        .starts_with(|next| '0' <= next && next <= '7')
9897ac06127Sopenharmony_ci                    {
9907ac06127Sopenharmony_ci                        // circumvent clippy::octal_escapes lint
9917ac06127Sopenharmony_ci                        "\\x00"
9927ac06127Sopenharmony_ci                    } else {
9937ac06127Sopenharmony_ci                        "\\0"
9947ac06127Sopenharmony_ci                    },
9957ac06127Sopenharmony_ci                );
9967ac06127Sopenharmony_ci            } else if ch == '\'' {
9977ac06127Sopenharmony_ci                // escape_debug turns this into "\'" which is unnecessary.
9987ac06127Sopenharmony_ci                repr.push(ch);
9997ac06127Sopenharmony_ci            } else {
10007ac06127Sopenharmony_ci                repr.extend(ch.escape_debug());
10017ac06127Sopenharmony_ci            }
10027ac06127Sopenharmony_ci        }
10037ac06127Sopenharmony_ci        repr.push('"');
10047ac06127Sopenharmony_ci        Literal::_new(repr)
10057ac06127Sopenharmony_ci    }
10067ac06127Sopenharmony_ci
10077ac06127Sopenharmony_ci    pub fn character(t: char) -> Literal {
10087ac06127Sopenharmony_ci        let mut repr = String::new();
10097ac06127Sopenharmony_ci        repr.push('\'');
10107ac06127Sopenharmony_ci        if t == '"' {
10117ac06127Sopenharmony_ci            // escape_debug turns this into '\"' which is unnecessary.
10127ac06127Sopenharmony_ci            repr.push(t);
10137ac06127Sopenharmony_ci        } else {
10147ac06127Sopenharmony_ci            repr.extend(t.escape_debug());
10157ac06127Sopenharmony_ci        }
10167ac06127Sopenharmony_ci        repr.push('\'');
10177ac06127Sopenharmony_ci        Literal::_new(repr)
10187ac06127Sopenharmony_ci    }
10197ac06127Sopenharmony_ci
10207ac06127Sopenharmony_ci    pub fn byte_string(bytes: &[u8]) -> Literal {
10217ac06127Sopenharmony_ci        let mut escaped = "b\"".to_string();
10227ac06127Sopenharmony_ci        let mut bytes = bytes.iter();
10237ac06127Sopenharmony_ci        while let Some(&b) = bytes.next() {
10247ac06127Sopenharmony_ci            #[allow(clippy::match_overlapping_arm)]
10257ac06127Sopenharmony_ci            match b {
10267ac06127Sopenharmony_ci                b'\0' => escaped.push_str(match bytes.as_slice().first() {
10277ac06127Sopenharmony_ci                    // circumvent clippy::octal_escapes lint
10287ac06127Sopenharmony_ci                    Some(b'0'..=b'7') => r"\x00",
10297ac06127Sopenharmony_ci                    _ => r"\0",
10307ac06127Sopenharmony_ci                }),
10317ac06127Sopenharmony_ci                b'\t' => escaped.push_str(r"\t"),
10327ac06127Sopenharmony_ci                b'\n' => escaped.push_str(r"\n"),
10337ac06127Sopenharmony_ci                b'\r' => escaped.push_str(r"\r"),
10347ac06127Sopenharmony_ci                b'"' => escaped.push_str("\\\""),
10357ac06127Sopenharmony_ci                b'\\' => escaped.push_str("\\\\"),
10367ac06127Sopenharmony_ci                b'\x20'..=b'\x7E' => escaped.push(b as char),
10377ac06127Sopenharmony_ci                _ => {
10387ac06127Sopenharmony_ci                    let _ = write!(escaped, "\\x{:02X}", b);
10397ac06127Sopenharmony_ci                }
10407ac06127Sopenharmony_ci            }
10417ac06127Sopenharmony_ci        }
10427ac06127Sopenharmony_ci        escaped.push('"');
10437ac06127Sopenharmony_ci        Literal::_new(escaped)
10447ac06127Sopenharmony_ci    }
10457ac06127Sopenharmony_ci
10467ac06127Sopenharmony_ci    pub fn span(&self) -> Span {
10477ac06127Sopenharmony_ci        self.span
10487ac06127Sopenharmony_ci    }
10497ac06127Sopenharmony_ci
10507ac06127Sopenharmony_ci    pub fn set_span(&mut self, span: Span) {
10517ac06127Sopenharmony_ci        self.span = span;
10527ac06127Sopenharmony_ci    }
10537ac06127Sopenharmony_ci
10547ac06127Sopenharmony_ci    pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
10557ac06127Sopenharmony_ci        #[cfg(not(span_locations))]
10567ac06127Sopenharmony_ci        {
10577ac06127Sopenharmony_ci            let _ = range;
10587ac06127Sopenharmony_ci            None
10597ac06127Sopenharmony_ci        }
10607ac06127Sopenharmony_ci
10617ac06127Sopenharmony_ci        #[cfg(span_locations)]
10627ac06127Sopenharmony_ci        {
10637ac06127Sopenharmony_ci            use core::ops::Bound;
10647ac06127Sopenharmony_ci
10657ac06127Sopenharmony_ci            let lo = match range.start_bound() {
10667ac06127Sopenharmony_ci                Bound::Included(start) => {
10677ac06127Sopenharmony_ci                    let start = u32::try_from(*start).ok()?;
10687ac06127Sopenharmony_ci                    self.span.lo.checked_add(start)?
10697ac06127Sopenharmony_ci                }
10707ac06127Sopenharmony_ci                Bound::Excluded(start) => {
10717ac06127Sopenharmony_ci                    let start = u32::try_from(*start).ok()?;
10727ac06127Sopenharmony_ci                    self.span.lo.checked_add(start)?.checked_add(1)?
10737ac06127Sopenharmony_ci                }
10747ac06127Sopenharmony_ci                Bound::Unbounded => self.span.lo,
10757ac06127Sopenharmony_ci            };
10767ac06127Sopenharmony_ci            let hi = match range.end_bound() {
10777ac06127Sopenharmony_ci                Bound::Included(end) => {
10787ac06127Sopenharmony_ci                    let end = u32::try_from(*end).ok()?;
10797ac06127Sopenharmony_ci                    self.span.lo.checked_add(end)?.checked_add(1)?
10807ac06127Sopenharmony_ci                }
10817ac06127Sopenharmony_ci                Bound::Excluded(end) => {
10827ac06127Sopenharmony_ci                    let end = u32::try_from(*end).ok()?;
10837ac06127Sopenharmony_ci                    self.span.lo.checked_add(end)?
10847ac06127Sopenharmony_ci                }
10857ac06127Sopenharmony_ci                Bound::Unbounded => self.span.hi,
10867ac06127Sopenharmony_ci            };
10877ac06127Sopenharmony_ci            if lo <= hi && hi <= self.span.hi {
10887ac06127Sopenharmony_ci                Some(Span { lo, hi })
10897ac06127Sopenharmony_ci            } else {
10907ac06127Sopenharmony_ci                None
10917ac06127Sopenharmony_ci            }
10927ac06127Sopenharmony_ci        }
10937ac06127Sopenharmony_ci    }
10947ac06127Sopenharmony_ci}
10957ac06127Sopenharmony_ci
10967ac06127Sopenharmony_ciimpl FromStr for Literal {
10977ac06127Sopenharmony_ci    type Err = LexError;
10987ac06127Sopenharmony_ci
10997ac06127Sopenharmony_ci    fn from_str(repr: &str) -> Result<Self, Self::Err> {
11007ac06127Sopenharmony_ci        let mut cursor = get_cursor(repr);
11017ac06127Sopenharmony_ci        #[cfg(span_locations)]
11027ac06127Sopenharmony_ci        let lo = cursor.off;
11037ac06127Sopenharmony_ci
11047ac06127Sopenharmony_ci        let negative = cursor.starts_with_char('-');
11057ac06127Sopenharmony_ci        if negative {
11067ac06127Sopenharmony_ci            cursor = cursor.advance(1);
11077ac06127Sopenharmony_ci            if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) {
11087ac06127Sopenharmony_ci                return Err(LexError::call_site());
11097ac06127Sopenharmony_ci            }
11107ac06127Sopenharmony_ci        }
11117ac06127Sopenharmony_ci
11127ac06127Sopenharmony_ci        if let Ok((rest, mut literal)) = parse::literal(cursor) {
11137ac06127Sopenharmony_ci            if rest.is_empty() {
11147ac06127Sopenharmony_ci                if negative {
11157ac06127Sopenharmony_ci                    literal.repr.insert(0, '-');
11167ac06127Sopenharmony_ci                }
11177ac06127Sopenharmony_ci                literal.span = Span {
11187ac06127Sopenharmony_ci                    #[cfg(span_locations)]
11197ac06127Sopenharmony_ci                    lo,
11207ac06127Sopenharmony_ci                    #[cfg(span_locations)]
11217ac06127Sopenharmony_ci                    hi: rest.off,
11227ac06127Sopenharmony_ci                };
11237ac06127Sopenharmony_ci                return Ok(literal);
11247ac06127Sopenharmony_ci            }
11257ac06127Sopenharmony_ci        }
11267ac06127Sopenharmony_ci        Err(LexError::call_site())
11277ac06127Sopenharmony_ci    }
11287ac06127Sopenharmony_ci}
11297ac06127Sopenharmony_ci
11307ac06127Sopenharmony_ciimpl Display for Literal {
11317ac06127Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11327ac06127Sopenharmony_ci        Display::fmt(&self.repr, f)
11337ac06127Sopenharmony_ci    }
11347ac06127Sopenharmony_ci}
11357ac06127Sopenharmony_ci
11367ac06127Sopenharmony_ciimpl Debug for Literal {
11377ac06127Sopenharmony_ci    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
11387ac06127Sopenharmony_ci        let mut debug = fmt.debug_struct("Literal");
11397ac06127Sopenharmony_ci        debug.field("lit", &format_args!("{}", self.repr));
11407ac06127Sopenharmony_ci        debug_span_field_if_nontrivial(&mut debug, self.span);
11417ac06127Sopenharmony_ci        debug.finish()
11427ac06127Sopenharmony_ci    }
11437ac06127Sopenharmony_ci}
1144