Skip to content

Commit 112a3ad

Browse files
Hash only the spans that we care ended up reading in Span::try_metavars
1 parent 6d29557 commit 112a3ad

File tree

3 files changed

+42
-20
lines changed

3 files changed

+42
-20
lines changed

compiler/rustc_expand/src/mbe/transcribe.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_parse::parser::ParseNtResult;
1313
use rustc_session::parse::{ParseSess, SymbolGallery};
1414
use rustc_span::hygiene::{LocalExpnId, Transparency};
1515
use rustc_span::{
16-
Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans_mut,
16+
Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans,
1717
};
1818
use smallvec::{SmallVec, smallvec};
1919

@@ -283,13 +283,17 @@ pub(super) fn transcribe<'a>(
283283
}
284284
MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => {
285285
marker.visit_span(&mut sp);
286-
with_metavar_spans_mut(|mspans| mspans.insert(ident.span, sp));
286+
with_metavar_spans(|mspans| {
287+
mspans.write().insert(ident.span, (sp, false))
288+
});
287289
let kind = token::NtIdent(*ident, *is_raw);
288290
TokenTree::token_alone(kind, sp)
289291
}
290292
MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => {
291293
marker.visit_span(&mut sp);
292-
with_metavar_spans_mut(|mspans| mspans.insert(ident.span, sp));
294+
with_metavar_spans(|mspans| {
295+
mspans.write().insert(ident.span, (sp, false))
296+
});
293297
let kind = token::NtLifetime(*ident, *is_raw);
294298
TokenTree::token_alone(kind, sp)
295299
}
@@ -299,7 +303,9 @@ pub(super) fn transcribe<'a>(
299303
// `Interpolated` is currently used for such groups in rustc parser.
300304
marker.visit_span(&mut sp);
301305
let use_span = nt.use_span();
302-
with_metavar_spans_mut(|mspans| mspans.insert(use_span, sp));
306+
with_metavar_spans(|mspans| {
307+
mspans.write().insert(use_span, (sp, false))
308+
});
303309
TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
304310
}
305311
MatchedSeq(..) => {
@@ -415,16 +421,17 @@ fn maybe_use_metavar_location(
415421
return orig_tt.clone();
416422
}
417423

418-
let insert = |mspans: &mut UnordMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
424+
let insert = |mspans: &mut UnordMap<_, _>, s, ms| match mspans.try_insert(s, (ms, false)) {
419425
Ok(_) => true,
420-
Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success
426+
Err(err) => err.entry.get().0 == ms, // Tried to insert the same span, still success
421427
};
422428
marker.visit_span(&mut metavar_span);
423429
let no_collision = match orig_tt {
424430
TokenTree::Token(token, ..) => {
425-
with_metavar_spans_mut(|mspans| insert(mspans, token.span, metavar_span))
431+
with_metavar_spans(|mspans| insert(&mut mspans.write(), token.span, metavar_span))
426432
}
427-
TokenTree::Delimited(dspan, ..) => with_metavar_spans_mut(|mspans| {
433+
TokenTree::Delimited(dspan, ..) => with_metavar_spans(|mspans| {
434+
let mspans = &mut mspans.write();
428435
insert(mspans, dspan.open, metavar_span)
429436
&& insert(mspans, dspan.close, metavar_span)
430437
&& insert(mspans, dspan.entire(), metavar_span)
@@ -439,13 +446,14 @@ fn maybe_use_metavar_location(
439446
match orig_tt {
440447
TokenTree::Token(Token { kind, span }, spacing) => {
441448
let span = metavar_span.with_ctxt(span.ctxt());
442-
with_metavar_spans_mut(|mspans| insert(mspans, span, metavar_span));
449+
with_metavar_spans(|mspans| insert(&mut mspans.write(), span, metavar_span));
443450
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
444451
}
445452
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
446453
let open = metavar_span.with_ctxt(dspan.open.ctxt());
447454
let close = metavar_span.with_ctxt(dspan.close.ctxt());
448-
with_metavar_spans_mut(|mspans| {
455+
with_metavar_spans(|mspans| {
456+
let mspans = &mut mspans.write();
449457
insert(mspans, open, metavar_span) && insert(mspans, close, metavar_span)
450458
});
451459
let dspan = DelimSpan::from_pair(open, close);

compiler/rustc_middle/src/hir/map/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
44
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
55
use rustc_data_structures::svh::Svh;
66
use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in};
7+
use rustc_data_structures::unord::UnordMap;
78
use rustc_hir::def::{DefKind, Res};
89
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
910
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@@ -1122,7 +1123,14 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
11221123
// and combining it with other hashes here.
11231124
resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
11241125
with_metavar_spans(|mspans| {
1125-
mspans.hash_stable(&mut hcx, &mut stable_hasher);
1126+
// Only hash the spans we ended up using.
1127+
let filtered_spans: UnordMap<_, _> = mspans
1128+
.read()
1129+
.items()
1130+
.filter(|(_, (_, b))| *b)
1131+
.map(|(s1, (s2, _))| (*s1, *s2))
1132+
.collect();
1133+
filtered_spans.hash_stable(&mut hcx, &mut stable_hasher);
11261134
});
11271135
stable_hasher.finish()
11281136
});

compiler/rustc_span/src/lib.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub struct SessionGlobals {
103103
span_interner: Lock<span_encoding::SpanInterner>,
104104
/// Maps a macro argument token into use of the corresponding metavariable in the macro body.
105105
/// Collisions are possible and processed in `maybe_use_metavar_location` on best effort basis.
106-
metavar_spans: FreezeLock<UnordMap<Span, Span>>,
106+
metavar_spans: FreezeLock<UnordMap<Span, (Span, bool)>>,
107107
hygiene_data: Lock<hygiene::HygieneData>,
108108

109109
/// The session's source map, if there is one. This field should only be
@@ -178,13 +178,8 @@ pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
178178
scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
179179

180180
#[inline]
181-
pub fn with_metavar_spans_mut<R>(f: impl FnOnce(&mut UnordMap<Span, Span>) -> R) -> R {
182-
with_session_globals(|session_globals| f(&mut session_globals.metavar_spans.write()))
183-
}
184-
185-
#[inline]
186-
pub fn with_metavar_spans<R>(f: impl FnOnce(&UnordMap<Span, Span>) -> R) -> R {
187-
with_session_globals(|session_globals| f(&session_globals.metavar_spans.read()))
181+
pub fn with_metavar_spans<R>(f: impl FnOnce(&FreezeLock<UnordMap<Span, (Span, bool)>>) -> R) -> R {
182+
with_session_globals(|session_globals| f(&session_globals.metavar_spans))
188183
}
189184

190185
#[inline]
@@ -884,7 +879,18 @@ impl Span {
884879

885880
/// Check if you can select metavar spans for the given spans to get matching contexts.
886881
fn try_metavars(a: SpanData, b: SpanData, a_orig: Span, b_orig: Span) -> (SpanData, SpanData) {
887-
let get = |mspans: &UnordMap<_, _>, s| mspans.get(&s).copied();
882+
let get = |mspans: &FreezeLock<UnordMap<_, _>>, s| {
883+
if let Some(mut mspans) = mspans.try_write() {
884+
if let Some((span, read)) = mspans.get_mut(&s) {
885+
*read = true;
886+
Some(*span)
887+
} else {
888+
None
889+
}
890+
} else {
891+
if let Some((span, true)) = mspans.read().get(&s) { Some(*span) } else { None }
892+
}
893+
};
888894
match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) {
889895
(None, None) => {}
890896
(Some(meta_a), None) => {

0 commit comments

Comments
 (0)