about summary refs log tree commit diff
path: root/compiler/rustc_span
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-12-21 20:37:24 +0000
committerMichael Goulet <michael@errs.io>2024-12-21 20:37:27 +0000
commit2de21ad7d4a14894463816ac5dedc337ae3a2941 (patch)
tree9d9353d2faef4b5ec83cfeb45e00191072cff978 /compiler/rustc_span
parent69b2fc3e2f961b54fdae6c2a810c5792b19851f5 (diff)
downloadrust-2de21ad7d4a14894463816ac5dedc337ae3a2941.tar.gz
rust-2de21ad7d4a14894463816ac5dedc337ae3a2941.zip
Hash only the spans that we care ended up reading in Span::try_metavars
Diffstat (limited to 'compiler/rustc_span')
-rw-r--r--compiler/rustc_span/src/lib.rs49
1 files changed, 35 insertions, 14 deletions
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 8eab28cce82..7a13e52af44 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -25,6 +25,7 @@
 #![feature(hash_set_entry)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
+#![feature(map_try_insert)]
 #![feature(negative_impls)]
 #![feature(read_buf)]
 #![feature(round_char_boundary)]
@@ -103,7 +104,7 @@ pub struct SessionGlobals {
     span_interner: Lock<span_encoding::SpanInterner>,
     /// Maps a macro argument token into use of the corresponding metavariable in the macro body.
     /// Collisions are possible and processed in `maybe_use_metavar_location` on best effort basis.
-    metavar_spans: FreezeLock<UnordMap<Span, Span>>,
+    metavar_spans: MetavarSpansMap,
     hygiene_data: Lock<hygiene::HygieneData>,
 
     /// The session's source map, if there is one. This field should only be
@@ -177,21 +178,42 @@ pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
 // deserialization.
 scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
 
-#[inline]
-pub fn with_metavar_spans_mut<R>(f: impl FnOnce(&mut UnordMap<Span, Span>) -> R) -> R {
-    with_session_globals(|session_globals| f(&mut session_globals.metavar_spans.write()))
-}
+#[derive(Default)]
+pub struct MetavarSpansMap(FreezeLock<UnordMap<Span, (Span, bool)>>);
 
-#[inline]
-pub fn with_metavar_spans<R>(f: impl FnOnce(&UnordMap<Span, Span>) -> R) -> R {
-    with_session_globals(|session_globals| f(&session_globals.metavar_spans.read()))
+impl MetavarSpansMap {
+    pub fn insert(&self, span: Span, var_span: Span) -> bool {
+        match self.0.write().try_insert(span, (var_span, false)) {
+            Ok(_) => true,
+            Err(entry) => entry.entry.get().0 == var_span,
+        }
+    }
+
+    /// Read a span and record that it was read.
+    pub fn get(&self, span: Span) -> Option<Span> {
+        if let Some(mut mspans) = self.0.try_write() {
+            if let Some((var_span, read)) = mspans.get_mut(&span) {
+                *read = true;
+                Some(*var_span)
+            } else {
+                None
+            }
+        } else {
+            if let Some((span, true)) = self.0.read().get(&span) { Some(*span) } else { None }
+        }
+    }
+
+    /// Freeze the set, and return the spans which have been read.
+    ///
+    /// After this is frozen, no spans that have not been read can be read.
+    pub fn freeze_and_get_read_spans(&self) -> UnordMap<Span, Span> {
+        self.0.freeze().items().filter(|(_, (_, b))| *b).map(|(s1, (s2, _))| (*s1, *s2)).collect()
+    }
 }
 
 #[inline]
-pub fn freeze_metavar_spans() {
-    with_session_globals(|session_globals| {
-        session_globals.metavar_spans.freeze();
-    });
+pub fn with_metavar_spans<R>(f: impl FnOnce(&MetavarSpansMap) -> R) -> R {
+    with_session_globals(|session_globals| f(&session_globals.metavar_spans))
 }
 
 // FIXME: We should use this enum or something like it to get rid of the
@@ -884,8 +906,7 @@ impl Span {
 
     /// Check if you can select metavar spans for the given spans to get matching contexts.
     fn try_metavars(a: SpanData, b: SpanData, a_orig: Span, b_orig: Span) -> (SpanData, SpanData) {
-        let get = |mspans: &UnordMap<_, _>, s| mspans.get(&s).copied();
-        match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) {
+        match with_metavar_spans(|mspans| (mspans.get(a_orig), mspans.get(b_orig))) {
             (None, None) => {}
             (Some(meta_a), None) => {
                 let meta_a = meta_a.data();