Skip to content

Commit 69b2fc3

Browse files
Hash the untracked macro variable expansions
1 parent 28a997f commit 69b2fc3

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

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

+10-9
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ 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;
910
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
1011
use rustc_parse::lexer::nfc_normalize;
1112
use rustc_parse::parser::ParseNtResult;
1213
use rustc_session::parse::{ParseSess, SymbolGallery};
1314
use rustc_span::hygiene::{LocalExpnId, Transparency};
1415
use rustc_span::{
15-
Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans,
16+
Ident, MacroRulesNormalizedIdent, Span, Symbol, SyntaxContext, sym, with_metavar_spans_mut,
1617
};
1718
use smallvec::{SmallVec, smallvec};
1819

@@ -282,13 +283,13 @@ pub(super) fn transcribe<'a>(
282283
}
283284
MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => {
284285
marker.visit_span(&mut sp);
285-
with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
286+
with_metavar_spans_mut(|mspans| mspans.insert(ident.span, sp));
286287
let kind = token::NtIdent(*ident, *is_raw);
287288
TokenTree::token_alone(kind, sp)
288289
}
289290
MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => {
290291
marker.visit_span(&mut sp);
291-
with_metavar_spans(|mspans| mspans.insert(ident.span, sp));
292+
with_metavar_spans_mut(|mspans| mspans.insert(ident.span, sp));
292293
let kind = token::NtLifetime(*ident, *is_raw);
293294
TokenTree::token_alone(kind, sp)
294295
}
@@ -298,7 +299,7 @@ pub(super) fn transcribe<'a>(
298299
// `Interpolated` is currently used for such groups in rustc parser.
299300
marker.visit_span(&mut sp);
300301
let use_span = nt.use_span();
301-
with_metavar_spans(|mspans| mspans.insert(use_span, sp));
302+
with_metavar_spans_mut(|mspans| mspans.insert(use_span, sp));
302303
TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
303304
}
304305
MatchedSeq(..) => {
@@ -414,16 +415,16 @@ fn maybe_use_metavar_location(
414415
return orig_tt.clone();
415416
}
416417

417-
let insert = |mspans: &mut FxHashMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
418+
let insert = |mspans: &mut UnordMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
418419
Ok(_) => true,
419420
Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success
420421
};
421422
marker.visit_span(&mut metavar_span);
422423
let no_collision = match orig_tt {
423424
TokenTree::Token(token, ..) => {
424-
with_metavar_spans(|mspans| insert(mspans, token.span, metavar_span))
425+
with_metavar_spans_mut(|mspans| insert(mspans, token.span, metavar_span))
425426
}
426-
TokenTree::Delimited(dspan, ..) => with_metavar_spans(|mspans| {
427+
TokenTree::Delimited(dspan, ..) => with_metavar_spans_mut(|mspans| {
427428
insert(mspans, dspan.open, metavar_span)
428429
&& insert(mspans, dspan.close, metavar_span)
429430
&& insert(mspans, dspan.entire(), metavar_span)
@@ -438,13 +439,13 @@ fn maybe_use_metavar_location(
438439
match orig_tt {
439440
TokenTree::Token(Token { kind, span }, spacing) => {
440441
let span = metavar_span.with_ctxt(span.ctxt());
441-
with_metavar_spans(|mspans| insert(mspans, span, metavar_span));
442+
with_metavar_spans_mut(|mspans| insert(mspans, span, metavar_span));
442443
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
443444
}
444445
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
445446
let open = metavar_span.with_ctxt(dspan.open.ctxt());
446447
let close = metavar_span.with_ctxt(dspan.close.ctxt());
447-
with_metavar_spans(|mspans| {
448+
with_metavar_spans_mut(|mspans| {
448449
insert(mspans, open, metavar_span) && insert(mspans, close, metavar_span)
449450
});
450451
let dspan = DelimSpan::from_pair(open, close);

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ 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::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
15+
use rustc_span::{
16+
ErrorGuaranteed, Ident, Span, Symbol, freeze_metavar_spans, kw, sym, with_metavar_spans,
17+
};
1618

1719
use crate::hir::ModuleItems;
1820
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -1087,6 +1089,9 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
10871089
.map(DebuggerVisualizerFile::path_erased)
10881090
.collect();
10891091

1092+
// Freeze metavars since we do not expect any more expansion after this.
1093+
freeze_metavar_spans();
1094+
10901095
let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| {
10911096
let mut stable_hasher = StableHasher::new();
10921097
hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher);
@@ -1116,6 +1121,9 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
11161121
// the fly in the resolver, storing only their accumulated hash in `ResolverGlobalCtxt`,
11171122
// and combining it with other hashes here.
11181123
resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
1124+
with_metavar_spans(|mspans| {
1125+
mspans.hash_stable(&mut hcx, &mut stable_hasher);
1126+
});
11191127
stable_hasher.finish()
11201128
});
11211129

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

+17-5
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ use std::str::FromStr;
8585
use std::{fmt, iter};
8686

8787
use md5::{Digest, Md5};
88-
use rustc_data_structures::fx::FxHashMap;
8988
use rustc_data_structures::stable_hasher::{Hash64, Hash128, HashStable, StableHasher};
9089
use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock, Lrc};
90+
use rustc_data_structures::unord::UnordMap;
9191
use sha1::Sha1;
9292
use sha2::Sha256;
9393

@@ -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: Lock<FxHashMap<Span, Span>>,
106+
metavar_spans: FreezeLock<UnordMap<Span, Span>>,
107107
hygiene_data: Lock<hygiene::HygieneData>,
108108

109109
/// The session's source map, if there is one. This field should only be
@@ -178,8 +178,20 @@ 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<R>(f: impl FnOnce(&mut FxHashMap<Span, Span>) -> R) -> R {
182-
with_session_globals(|session_globals| f(&mut session_globals.metavar_spans.lock()))
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()))
188+
}
189+
190+
#[inline]
191+
pub fn freeze_metavar_spans() {
192+
with_session_globals(|session_globals| {
193+
session_globals.metavar_spans.freeze();
194+
});
183195
}
184196

185197
// FIXME: We should use this enum or something like it to get rid of the
@@ -872,7 +884,7 @@ impl Span {
872884

873885
/// Check if you can select metavar spans for the given spans to get matching contexts.
874886
fn try_metavars(a: SpanData, b: SpanData, a_orig: Span, b_orig: Span) -> (SpanData, SpanData) {
875-
let get = |mspans: &FxHashMap<_, _>, s| mspans.get(&s).copied();
887+
let get = |mspans: &UnordMap<_, _>, s| mspans.get(&s).copied();
876888
match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) {
877889
(None, None) => {}
878890
(Some(meta_a), None) => {

0 commit comments

Comments
 (0)