about summary refs log tree commit diff
path: root/compiler/rustc_span
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_span')
-rw-r--r--compiler/rustc_span/Cargo.toml2
-rw-r--r--compiler/rustc_span/src/def_id.rs16
-rw-r--r--compiler/rustc_span/src/edition.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs35
-rw-r--r--compiler/rustc_span/src/lib.rs7
-rw-r--r--compiler/rustc_span/src/profiling.rs2
-rw-r--r--compiler/rustc_span/src/source_map.rs29
-rw-r--r--compiler/rustc_span/src/span_encoding.rs86
-rw-r--r--compiler/rustc_span/src/symbol.rs13
9 files changed, 117 insertions, 75 deletions
diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml
index 48a2ab0f904..5ce2577b63c 100644
--- a/compiler/rustc_span/Cargo.toml
+++ b/compiler/rustc_span/Cargo.toml
@@ -13,7 +13,7 @@ rustc_index = { path = "../rustc_index" }
 rustc_arena = { path = "../rustc_arena" }
 scoped-tls = "1.0"
 unicode-width = "0.1.4"
-cfg-if = "0.1.2"
+cfg-if = "1.0"
 tracing = "0.1"
 sha1 = { package = "sha-1", version = "0.10.0" }
 sha2 = "0.10.1"
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index e62ce2c266a..7c5e1427d1e 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -10,10 +10,9 @@ use std::fmt;
 use std::hash::{Hash, Hasher};
 
 rustc_index::newtype_index! {
-    pub struct CrateNum {
-        ENCODABLE = custom
-        DEBUG_FORMAT = "crate{}"
-    }
+    #[custom_encodable]
+    #[debug_format = "crate{}"]
+    pub struct CrateNum {}
 }
 
 /// Item definitions in the currently-compiled crate would have the `CrateNum`
@@ -194,13 +193,12 @@ rustc_index::newtype_index! {
     /// A DefIndex is an index into the hir-map for a crate, identifying a
     /// particular definition. It should really be considered an interned
     /// shorthand for a particular DefPath.
+    #[custom_encodable] // (only encodable in metadata)
+    #[debug_format = "DefIndex({})"]
     pub struct DefIndex {
-        ENCODABLE = custom // (only encodable in metadata)
-
-        DEBUG_FORMAT = "DefIndex({})",
         /// The crate root is always assigned index 0 by the AST Map code,
         /// thanks to `NodeCollector::new`.
-        const CRATE_DEF_INDEX = 0,
+        const CRATE_DEF_INDEX = 0;
     }
 }
 
@@ -305,7 +303,7 @@ impl DefId {
         // i.e. don't use closures.
         match self.as_local() {
             Some(local_def_id) => local_def_id,
-            None => panic!("DefId::expect_local: `{:?}` isn't local", self),
+            None => panic!("DefId::expect_local: `{self:?}` isn't local"),
         }
     }
 
diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs
index 065d3660e50..b43183916bc 100644
--- a/compiler/rustc_span/src/edition.rs
+++ b/compiler/rustc_span/src/edition.rs
@@ -44,7 +44,7 @@ impl fmt::Display for Edition {
             Edition::Edition2021 => "2021",
             Edition::Edition2024 => "2024",
         };
-        write!(f, "{}", s)
+        write!(f, "{s}")
     }
 }
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 038699154c7..a9a9a3fbf9d 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -61,9 +61,8 @@ pub struct SyntaxContextData {
 
 rustc_index::newtype_index! {
     /// A unique ID associated with a macro invocation and expansion.
-    pub struct ExpnIndex {
-        ENCODABLE = custom
-    }
+    #[custom_encodable]
+    pub struct ExpnIndex {}
 }
 
 /// A unique ID associated with a macro invocation and expansion.
@@ -82,11 +81,10 @@ impl fmt::Debug for ExpnId {
 
 rustc_index::newtype_index! {
     /// A unique ID associated with a macro invocation and expansion.
-    pub struct LocalExpnId {
-        ENCODABLE = custom
-        ORD_IMPL = custom
-        DEBUG_FORMAT = "expn{}"
-    }
+    #[custom_encodable]
+    #[no_ord_impl]
+    #[debug_format = "expn{}"]
+    pub struct LocalExpnId {}
 }
 
 // To ensure correctness of incremental compilation,
@@ -106,9 +104,13 @@ fn assert_default_hashing_controls<CTX: HashStableContext>(ctx: &CTX, msg: &str)
         // `-Z incremental-ignore-spans` option. Normally, this option is disabled,
         // which will cause us to require that this method always be called with `Span` hashing
         // enabled.
+        //
+        // Span hashing can also be disabled without `-Z incremental-ignore-spans`.
+        // This is the case for instance when building a hash for name mangling.
+        // Such configuration must not be used for metadata.
         HashingControls { hash_spans }
             if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {}
-        other => panic!("Attempted hashing of {msg} with non-default HashingControls: {:?}", other),
+        other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"),
     }
 }
 
@@ -318,6 +320,7 @@ impl ExpnId {
             // Stop going up the backtrace once include! is encountered
             if expn_data.is_root()
                 || expn_data.kind == ExpnKind::Macro(MacroKind::Bang, sym::include)
+                || expn_data.kind == ExpnKind::Inlined
             {
                 break;
             }
@@ -626,7 +629,7 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb
 pub fn debug_hygiene_data(verbose: bool) -> String {
     HygieneData::with(|data| {
         if verbose {
-            format!("{:#?}", data)
+            format!("{data:#?}")
         } else {
             let mut s = String::from("Expansions:");
             let mut debug_expn_data = |(id, expn_data): (&ExpnId, &ExpnData)| {
@@ -1064,9 +1067,9 @@ impl ExpnKind {
         match *self {
             ExpnKind::Root => kw::PathRoot.to_string(),
             ExpnKind::Macro(macro_kind, name) => match macro_kind {
-                MacroKind::Bang => format!("{}!", name),
-                MacroKind::Attr => format!("#[{}]", name),
-                MacroKind::Derive => format!("#[derive({})]", name),
+                MacroKind::Bang => format!("{name}!"),
+                MacroKind::Attr => format!("#[{name}]"),
+                MacroKind::Derive => format!("#[derive({name})]"),
             },
             ExpnKind::AstPass(kind) => kind.descr().to_string(),
             ExpnKind::Desugaring(kind) => format!("desugaring of {}", kind.descr()),
@@ -1463,11 +1466,7 @@ impl<D: Decoder> Decodable<D> for SyntaxContext {
 /// collisions are only possible between `ExpnId`s within the same crate.
 fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContext) -> ExpnHash {
     // This disambiguator should not have been set yet.
-    assert_eq!(
-        expn_data.disambiguator, 0,
-        "Already set disambiguator for ExpnData: {:?}",
-        expn_data
-    );
+    assert_eq!(expn_data.disambiguator, 0, "Already set disambiguator for ExpnData: {expn_data:?}");
     assert_default_hashing_controls(&ctx, "ExpnData (disambiguator)");
     let mut expn_hash = expn_data.hash_expn(&mut ctx);
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 2181c090027..7e61f2f9f73 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -329,7 +329,7 @@ impl fmt::Display for FileNameDisplay<'_> {
             ProcMacroSourceCode(_) => write!(fmt, "<proc-macro source code>"),
             CfgSpec(_) => write!(fmt, "<cfgspec>"),
             CliCrateAttr(_) => write!(fmt, "<crate attribute>"),
-            Custom(ref s) => write!(fmt, "<{}>", s),
+            Custom(ref s) => write!(fmt, "<{s}>"),
             DocTest(ref path, _) => write!(fmt, "{}", path.display()),
             InlineAsm(_) => write!(fmt, "<inline asm>"),
         }
@@ -796,6 +796,9 @@ impl Span {
 
     /// Returns a `Span` that would enclose both `self` and `end`.
     ///
+    /// Note that this can also be used to extend the span "backwards":
+    /// `start.to(end)` and `end.to(start)` return the same `Span`.
+    ///
     /// ```text
     ///     ____             ___
     ///     self lorem ipsum end
@@ -1071,7 +1074,7 @@ impl NonNarrowChar {
             0 => NonNarrowChar::ZeroWidth(pos),
             2 => NonNarrowChar::Wide(pos),
             4 => NonNarrowChar::Tab(pos),
-            _ => panic!("width {} given for non-narrow character", width),
+            _ => panic!("width {width} given for non-narrow character"),
         }
     }
 
diff --git a/compiler/rustc_span/src/profiling.rs b/compiler/rustc_span/src/profiling.rs
index f169007fab4..0ab890b9f01 100644
--- a/compiler/rustc_span/src/profiling.rs
+++ b/compiler/rustc_span/src/profiling.rs
@@ -27,7 +27,7 @@ impl SpannedEventArgRecorder for EventArgRecorder<'_> {
             if let Some(source_map) = &*session_globals.source_map.borrow() {
                 source_map.span_to_embeddable_string(span)
             } else {
-                format!("{:?}", span)
+                format!("{span:?}")
             }
         });
         self.record_arg(span_arg);
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index d9c87ac0ba8..fa09b4faa44 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -964,45 +964,40 @@ impl SourceMap {
 
     /// Finds the width of the character, either before or after the end of provided span,
     /// depending on the `forwards` parameter.
+    #[instrument(skip(self, sp))]
     fn find_width_of_character_at_span(&self, sp: Span, forwards: bool) -> u32 {
         let sp = sp.data();
 
         if sp.lo == sp.hi && !forwards {
-            debug!("find_width_of_character_at_span: early return empty span");
+            debug!("early return empty span");
             return 1;
         }
 
         let local_begin = self.lookup_byte_offset(sp.lo);
         let local_end = self.lookup_byte_offset(sp.hi);
-        debug!(
-            "find_width_of_character_at_span: local_begin=`{:?}`, local_end=`{:?}`",
-            local_begin, local_end
-        );
+        debug!("local_begin=`{:?}`, local_end=`{:?}`", local_begin, local_end);
 
         if local_begin.sf.start_pos != local_end.sf.start_pos {
-            debug!("find_width_of_character_at_span: begin and end are in different files");
+            debug!("begin and end are in different files");
             return 1;
         }
 
         let start_index = local_begin.pos.to_usize();
         let end_index = local_end.pos.to_usize();
-        debug!(
-            "find_width_of_character_at_span: start_index=`{:?}`, end_index=`{:?}`",
-            start_index, end_index
-        );
+        debug!("start_index=`{:?}`, end_index=`{:?}`", start_index, end_index);
 
         // Disregard indexes that are at the start or end of their spans, they can't fit bigger
         // characters.
         if (!forwards && end_index == usize::MIN) || (forwards && start_index == usize::MAX) {
-            debug!("find_width_of_character_at_span: start or end of span, cannot be multibyte");
+            debug!("start or end of span, cannot be multibyte");
             return 1;
         }
 
         let source_len = (local_begin.sf.end_pos - local_begin.sf.start_pos).to_usize();
-        debug!("find_width_of_character_at_span: source_len=`{:?}`", source_len);
+        debug!("source_len=`{:?}`", source_len);
         // Ensure indexes are also not malformed.
         if start_index > end_index || end_index > source_len - 1 {
-            debug!("find_width_of_character_at_span: source indexes are malformed");
+            debug!("source indexes are malformed");
             return 1;
         }
 
@@ -1017,10 +1012,10 @@ impl SourceMap {
         } else {
             return 1;
         };
-        debug!("find_width_of_character_at_span: snippet=`{:?}`", snippet);
+        debug!("snippet=`{:?}`", snippet);
 
         let mut target = if forwards { end_index + 1 } else { end_index - 1 };
-        debug!("find_width_of_character_at_span: initial target=`{:?}`", target);
+        debug!("initial target=`{:?}`", target);
 
         while !snippet.is_char_boundary(target - start_index) && target < source_len {
             target = if forwards {
@@ -1033,9 +1028,9 @@ impl SourceMap {
                     }
                 }
             };
-            debug!("find_width_of_character_at_span: target=`{:?}`", target);
+            debug!("target=`{:?}`", target);
         }
-        debug!("find_width_of_character_at_span: final target=`{:?}`", target);
+        debug!("final target=`{:?}`", target);
 
         if forwards { (target - end_index) as u32 } else { (end_index - target) as u32 }
     }
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index f0e91e5a6a9..d48c4f7e5a8 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -4,7 +4,7 @@
 // The encoding format for inline spans were obtained by optimizing over crates in rustc/libstd.
 // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28
 
-use crate::def_id::LocalDefId;
+use crate::def_id::{DefIndex, LocalDefId};
 use crate::hygiene::SyntaxContext;
 use crate::SPAN_TRACK;
 use crate::{BytePos, SpanData};
@@ -13,8 +13,8 @@ use rustc_data_structures::fx::FxIndexSet;
 
 /// A compressed span.
 ///
-/// Whereas [`SpanData`] is 12 bytes, which is a bit too big to stick everywhere, `Span`
-/// is a form that only takes up 8 bytes, with less space for the length and
+/// Whereas [`SpanData`] is 16 bytes, which is a bit too big to stick everywhere, `Span`
+/// is a form that only takes up 8 bytes, with less space for the length, parent and
 /// context. The vast majority (99.9%+) of `SpanData` instances will fit within
 /// those 8 bytes; any `SpanData` whose fields don't fit into a `Span` are
 /// stored in a separate interner table, and the `Span` will index into that
@@ -25,7 +25,7 @@ use rustc_data_structures::fx::FxIndexSet;
 /// slower because only 80--90% of spans could be stored inline (even less in
 /// very large crates) and so the interner was used a lot more.
 ///
-/// Inline (compressed) format:
+/// Inline (compressed) format with no parent:
 /// - `span.base_or_index == span_data.lo`
 /// - `span.len_or_tag == len == span_data.hi - span_data.lo` (must be `<= MAX_LEN`)
 /// - `span.ctxt_or_tag == span_data.ctxt` (must be `<= MAX_CTXT`)
@@ -35,6 +35,12 @@ use rustc_data_structures::fx::FxIndexSet;
 /// - `span.len_or_tag == LEN_TAG` (high bit set, all other bits are zero)
 /// - `span.ctxt_or_tag == span_data.ctxt` (must be `<= MAX_CTXT`)
 ///
+/// Inline (compressed) format with root context:
+/// - `span.base_or_index == span_data.lo`
+/// - `span.len_or_tag == len == span_data.hi - span_data.lo` (must be `<= MAX_LEN`)
+/// - `span.len_or_tag` has top bit (`PARENT_MASK`) set
+/// - `span.ctxt == span_data.parent` (must be `<= MAX_CTXT`)
+///
 /// Interned format:
 /// - `span.base_or_index == index` (indexes into the interner table)
 /// - `span.len_or_tag == LEN_TAG` (high bit set, all other bits are zero)
@@ -73,7 +79,8 @@ pub struct Span {
     ctxt_or_tag: u16,
 }
 
-const LEN_TAG: u16 = 0b1000_0000_0000_0000;
+const LEN_TAG: u16 = 0b1111_1111_1111_1111;
+const PARENT_MASK: u16 = 0b1000_0000_0000_0000;
 const MAX_LEN: u32 = 0b0111_1111_1111_1111;
 const CTXT_TAG: u32 = 0b1111_1111_1111_1111;
 const MAX_CTXT: u32 = CTXT_TAG - 1;
@@ -95,16 +102,32 @@ impl Span {
 
         let (base, len, ctxt2) = (lo.0, hi.0 - lo.0, ctxt.as_u32());
 
-        if len <= MAX_LEN && ctxt2 <= MAX_CTXT && parent.is_none() {
-            // Inline format.
-            Span { base_or_index: base, len_or_tag: len as u16, ctxt_or_tag: ctxt2 as u16 }
-        } else {
-            // Interned format.
-            let index =
-                with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent }));
-            let ctxt_or_tag = if ctxt2 <= MAX_CTXT { ctxt2 } else { CTXT_TAG } as u16;
-            Span { base_or_index: index, len_or_tag: LEN_TAG, ctxt_or_tag }
+        if len <= MAX_LEN && ctxt2 <= MAX_CTXT {
+            let len_or_tag = len as u16;
+            debug_assert_eq!(len_or_tag & PARENT_MASK, 0);
+
+            if let Some(parent) = parent {
+                // Inline format with parent.
+                let len_or_tag = len_or_tag | PARENT_MASK;
+                let parent2 = parent.local_def_index.as_u32();
+                if ctxt2 == SyntaxContext::root().as_u32() && parent2 <= MAX_CTXT {
+                    return Span { base_or_index: base, len_or_tag, ctxt_or_tag: parent2 as u16 };
+                }
+            } else {
+                // Inline format with ctxt.
+                return Span {
+                    base_or_index: base,
+                    len_or_tag: len as u16,
+                    ctxt_or_tag: ctxt2 as u16,
+                };
+            }
         }
+
+        // Interned format.
+        let index =
+            with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent }));
+        let ctxt_or_tag = if ctxt2 <= MAX_CTXT { ctxt2 } else { CTXT_TAG } as u16;
+        Span { base_or_index: index, len_or_tag: LEN_TAG, ctxt_or_tag }
     }
 
     #[inline]
@@ -122,12 +145,25 @@ impl Span {
     pub fn data_untracked(self) -> SpanData {
         if self.len_or_tag != LEN_TAG {
             // Inline format.
-            debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
-            SpanData {
-                lo: BytePos(self.base_or_index),
-                hi: BytePos(self.base_or_index + self.len_or_tag as u32),
-                ctxt: SyntaxContext::from_u32(self.ctxt_or_tag as u32),
-                parent: None,
+            if self.len_or_tag & PARENT_MASK == 0 {
+                debug_assert!(self.len_or_tag as u32 <= MAX_LEN);
+                SpanData {
+                    lo: BytePos(self.base_or_index),
+                    hi: BytePos(self.base_or_index + self.len_or_tag as u32),
+                    ctxt: SyntaxContext::from_u32(self.ctxt_or_tag as u32),
+                    parent: None,
+                }
+            } else {
+                let len = self.len_or_tag & !PARENT_MASK;
+                debug_assert!(len as u32 <= MAX_LEN);
+                let parent =
+                    LocalDefId { local_def_index: DefIndex::from_u32(self.ctxt_or_tag as u32) };
+                SpanData {
+                    lo: BytePos(self.base_or_index),
+                    hi: BytePos(self.base_or_index + len as u32),
+                    ctxt: SyntaxContext::root(),
+                    parent: Some(parent),
+                }
             }
         } else {
             // Interned format.
@@ -141,8 +177,14 @@ impl Span {
     pub fn ctxt(self) -> SyntaxContext {
         let ctxt_or_tag = self.ctxt_or_tag as u32;
         if ctxt_or_tag <= MAX_CTXT {
-            // Inline format or interned format with inline ctxt.
-            SyntaxContext::from_u32(ctxt_or_tag)
+            if self.len_or_tag == LEN_TAG || self.len_or_tag & PARENT_MASK == 0 {
+                // Inline format or interned format with inline ctxt.
+                SyntaxContext::from_u32(ctxt_or_tag)
+            } else {
+                // Inline format or interned format with inline parent.
+                // We know that the SyntaxContext is root.
+                SyntaxContext::root()
+            }
         } else {
             // Interned format.
             let index = self.base_or_index;
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index ace095736c9..fbb12701d96 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -164,7 +164,6 @@ symbols! {
         Capture,
         Center,
         Clone,
-        Context,
         Continue,
         Copy,
         Count,
@@ -194,6 +193,7 @@ symbols! {
         FromIterator,
         FromResidual,
         Future,
+        FutureOutput,
         FxHashMap,
         FxHashSet,
         GlobalAlloc,
@@ -214,6 +214,7 @@ symbols! {
         Is,
         ItemContext,
         Iterator,
+        IteratorItem,
         Layout,
         Left,
         LinkedList,
@@ -264,6 +265,7 @@ symbols! {
         Relaxed,
         Release,
         Result,
+        ResumeTy,
         Return,
         Right,
         Rust,
@@ -376,9 +378,9 @@ symbols! {
         assert_eq_macro,
         assert_inhabited,
         assert_macro,
+        assert_mem_uninitialized_valid,
         assert_ne_macro,
         assert_receiver_is_total_eq,
-        assert_uninit_valid,
         assert_zero_valid,
         asserting,
         associated_const_equality,
@@ -611,6 +613,7 @@ symbols! {
         dispatch_from_dyn,
         div,
         div_assign,
+        do_not_recommend,
         doc,
         doc_alias,
         doc_auto_cfg,
@@ -753,6 +756,7 @@ symbols! {
         generic_associated_types_extended,
         generic_const_exprs,
         generic_param_attrs,
+        get_context,
         global_allocator,
         global_asm,
         globs,
@@ -1040,6 +1044,7 @@ symbols! {
         panic_2021,
         panic_abort,
         panic_bounds_check,
+        panic_cannot_unwind,
         panic_display,
         panic_fmt,
         panic_handler,
@@ -1047,7 +1052,7 @@ symbols! {
         panic_implementation,
         panic_info,
         panic_location,
-        panic_no_unwind,
+        panic_nounwind,
         panic_runtime,
         panic_str,
         panic_unwind,
@@ -1801,7 +1806,7 @@ impl fmt::Display for MacroRulesNormalizedIdent {
 pub struct Symbol(SymbolIndex);
 
 rustc_index::newtype_index! {
-    struct SymbolIndex { .. }
+    struct SymbolIndex {}
 }
 
 impl Symbol {