Skip to content

Commit 2de21ad

Browse files
Hash only the spans that we care ended up reading in Span::try_metavars
1 parent 69b2fc3 commit 2de21ad

File tree

5 files changed

+51
-40
lines changed

5 files changed

+51
-40
lines changed

Diff for: compiler/rustc_expand/src/mbe/transcribe.rs

+12-17
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, LitKind, Nonterminal, T
66
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_data_structures::sync::Lrc;
9-
use rustc_data_structures::unord::UnordMap;
109
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
1110
use rustc_parse::lexer::nfc_normalize;
1211
use rustc_parse::parser::ParseNtResult;
1312
use rustc_session::parse::{ParseSess, SymbolGallery};
1413
use rustc_span::hygiene::{LocalExpnId, Transparency};
1514
use rustc_span::{
16-
Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans_mut,
15+
Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans,
1716
};
1817
use smallvec::{SmallVec, smallvec};
1918

@@ -283,13 +282,13 @@ pub(super) fn transcribe<'a>(
283282
}
284283
MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => {
285284
marker.visit_span(&mut sp);
286-
with_metavar_spans_mut(|mspans| mspans.insert(ident.span, sp));
285+
with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
287286
let kind = token::NtIdent(*ident, *is_raw);
288287
TokenTree::token_alone(kind, sp)
289288
}
290289
MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => {
291290
marker.visit_span(&mut sp);
292-
with_metavar_spans_mut(|mspans| mspans.insert(ident.span, sp));
291+
with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
293292
let kind = token::NtLifetime(*ident, *is_raw);
294293
TokenTree::token_alone(kind, sp)
295294
}
@@ -299,7 +298,7 @@ pub(super) fn transcribe<'a>(
299298
// `Interpolated` is currently used for such groups in rustc parser.
300299
marker.visit_span(&mut sp);
301300
let use_span = nt.use_span();
302-
with_metavar_spans_mut(|mspans| mspans.insert(use_span, sp));
301+
with_metavar_spans(|mspans| mspans.insert(use_span, sp));
303302
TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
304303
}
305304
MatchedSeq(..) => {
@@ -415,19 +414,15 @@ fn maybe_use_metavar_location(
415414
return orig_tt.clone();
416415
}
417416

418-
let insert = |mspans: &mut UnordMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
419-
Ok(_) => true,
420-
Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success
421-
};
422417
marker.visit_span(&mut metavar_span);
423418
let no_collision = match orig_tt {
424419
TokenTree::Token(token, ..) => {
425-
with_metavar_spans_mut(|mspans| insert(mspans, token.span, metavar_span))
420+
with_metavar_spans(|mspans| mspans.insert(token.span, metavar_span))
426421
}
427-
TokenTree::Delimited(dspan, ..) => with_metavar_spans_mut(|mspans| {
428-
insert(mspans, dspan.open, metavar_span)
429-
&& insert(mspans, dspan.close, metavar_span)
430-
&& insert(mspans, dspan.entire(), metavar_span)
422+
TokenTree::Delimited(dspan, ..) => with_metavar_spans(|mspans| {
423+
mspans.insert(dspan.open, metavar_span)
424+
&& mspans.insert(dspan.close, metavar_span)
425+
&& mspans.insert(dspan.entire(), metavar_span)
431426
}),
432427
};
433428
if no_collision || psess.source_map().is_imported(metavar_span) {
@@ -439,14 +434,14 @@ fn maybe_use_metavar_location(
439434
match orig_tt {
440435
TokenTree::Token(Token { kind, span }, spacing) => {
441436
let span = metavar_span.with_ctxt(span.ctxt());
442-
with_metavar_spans_mut(|mspans| insert(mspans, span, metavar_span));
437+
with_metavar_spans(|mspans| mspans.insert(span, metavar_span));
443438
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
444439
}
445440
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
446441
let open = metavar_span.with_ctxt(dspan.open.ctxt());
447442
let close = metavar_span.with_ctxt(dspan.close.ctxt());
448-
with_metavar_spans_mut(|mspans| {
449-
insert(mspans, open, metavar_span) && insert(mspans, close, metavar_span)
443+
with_metavar_spans(|mspans| {
444+
mspans.insert(open, metavar_span) && mspans.insert(close, metavar_span)
450445
});
451446
let dspan = DelimSpan::from_pair(open, close);
452447
TokenTree::Delimited(dspan, *dspacing, *delimiter, tts.clone())

Diff for: compiler/rustc_middle/src/hir/map/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ use rustc_hir::*;
1212
use rustc_hir_pretty as pprust_hir;
1313
use rustc_middle::hir::nested_filter;
1414
use rustc_span::def_id::StableCrateId;
15-
use rustc_span::{
16-
ErrorGuaranteed, Ident, Span, Symbol, freeze_metavar_spans, kw, sym, with_metavar_spans,
17-
};
15+
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym, with_metavar_spans};
1816

1917
use crate::hir::ModuleItems;
2018
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -1089,9 +1087,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
10891087
.map(DebuggerVisualizerFile::path_erased)
10901088
.collect();
10911089

1092-
// Freeze metavars since we do not expect any more expansion after this.
1093-
freeze_metavar_spans();
1094-
10951090
let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
10961091
let mut stable_hasher = StableHasher::new();
10971092
hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher);
@@ -1122,7 +1117,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
11221117
// and combining it with other hashes here.
11231118
resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
11241119
with_metavar_spans(|mspans| {
1125-
mspans.hash_stable(&mut hcx, &mut stable_hasher);
1120+
mspans.freeze_and_get_read_spans().hash_stable(&mut hcx, &mut stable_hasher);
11261121
});
11271122
stable_hasher.finish()
11281123
});

Diff for: compiler/rustc_span/src/lib.rs

+35-14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(hash_set_entry)]
2626
#![feature(if_let_guard)]
2727
#![feature(let_chains)]
28+
#![feature(map_try_insert)]
2829
#![feature(negative_impls)]
2930
#![feature(read_buf)]
3031
#![feature(round_char_boundary)]
@@ -103,7 +104,7 @@ pub struct SessionGlobals {
103104
span_interner: Lock<span_encoding::SpanInterner>,
104105
/// Maps a macro argument token into use of the corresponding metavariable in the macro body.
105106
/// Collisions are possible and processed in `maybe_use_metavar_location` on best effort basis.
106-
metavar_spans: FreezeLock<UnordMap<Span, Span>>,
107+
metavar_spans: MetavarSpansMap,
107108
hygiene_data: Lock<hygiene::HygieneData>,
108109

109110
/// 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 {
177178
// deserialization.
178179
scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
179180

180-
#[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-
}
181+
#[derive(Default)]
182+
pub struct MetavarSpansMap(FreezeLock<UnordMap<Span, (Span, bool)>>);
184183

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()))
184+
impl MetavarSpansMap {
185+
pub fn insert(&self, span: Span, var_span: Span) -> bool {
186+
match self.0.write().try_insert(span, (var_span, false)) {
187+
Ok(_) => true,
188+
Err(entry) => entry.entry.get().0 == var_span,
189+
}
190+
}
191+
192+
/// Read a span and record that it was read.
193+
pub fn get(&self, span: Span) -> Option<Span> {
194+
if let Some(mut mspans) = self.0.try_write() {
195+
if let Some((var_span, read)) = mspans.get_mut(&span) {
196+
*read = true;
197+
Some(*var_span)
198+
} else {
199+
None
200+
}
201+
} else {
202+
if let Some((span, true)) = self.0.read().get(&span) { Some(*span) } else { None }
203+
}
204+
}
205+
206+
/// Freeze the set, and return the spans which have been read.
207+
///
208+
/// After this is frozen, no spans that have not been read can be read.
209+
pub fn freeze_and_get_read_spans(&self) -> UnordMap<Span, Span> {
210+
self.0.freeze().items().filter(|(_, (_, b))| *b).map(|(s1, (s2, _))| (*s1, *s2)).collect()
211+
}
188212
}
189213

190214
#[inline]
191-
pub fn freeze_metavar_spans() {
192-
with_session_globals(|session_globals| {
193-
session_globals.metavar_spans.freeze();
194-
});
215+
pub fn with_metavar_spans<R>(f: impl FnOnce(&MetavarSpansMap) -> R) -> R {
216+
with_session_globals(|session_globals| f(&session_globals.metavar_spans))
195217
}
196218

197219
// FIXME: We should use this enum or something like it to get rid of the
@@ -884,8 +906,7 @@ impl Span {
884906

885907
/// Check if you can select metavar spans for the given spans to get matching contexts.
886908
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();
888-
match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) {
909+
match with_metavar_spans(|mspans| (mspans.get(a_orig), mspans.get(b_orig))) {
889910
(None, None) => {}
890911
(Some(meta_a), None) => {
891912
let meta_a = meta_a.data();

Diff for: tests/ui/expr/if/if-let.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ warning: irrefutable `if let` pattern
1818
--> $DIR/if-let.rs:6:16
1919
|
2020
LL | if let $p = $e $b
21-
| ^^^^^^^^^^^
21+
| ^^^
2222
...
2323
LL | / bar!(a, 1, {
2424
LL | | println!("irrefutable pattern");

Diff for: tests/ui/for-loop-while/while-let-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ warning: irrefutable `while let` pattern
1818
--> $DIR/while-let-2.rs:7:19
1919
|
2020
LL | while let $p = $e $b
21-
| ^^^^^^^^^^^
21+
| ^^^
2222
...
2323
LL | / bar!(_a, 1, {
2424
LL | | println!("irrefutable pattern");

0 commit comments

Comments
 (0)