Skip to content

Commit 6afc9dc

Browse files
committed
Store disambiguators for each DepNode in CurrentDepNode.
1 parent bc333db commit 6afc9dc

File tree

7 files changed

+53
-67
lines changed

7 files changed

+53
-67
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
pub mod tls;
66

77
use crate::arena::Arena;
8-
use crate::dep_graph::{CurrentDepNode, DepGraph, DepKindStruct, DepNode};
8+
use crate::dep_graph::{CurrentDepNode, DepGraph, DepKindStruct};
99
use crate::infer::canonical::CanonicalVarInfo;
1010
use crate::lint::struct_lint_level;
1111
use crate::metadata::ModChild;
@@ -902,40 +902,28 @@ impl<'tcx> TyCtxt<'tcx> {
902902
}
903903
}
904904

905-
const ENSURE_FAKE_DEP_NODE_SYNC: () = if std::mem::size_of::<rustc_span::hygiene::FakeDepNode>()
906-
!= std::mem::size_of::<DepNode>()
907-
{
908-
panic!(
909-
"rustc_span::hygiene::FakeDepNode has come out of sync with DepNode and should be updated."
910-
)
911-
};
912-
913905
impl<'tcx> TyCtxt<'tcx> {
914906
#[instrument(level = "trace", skip(self), ret)]
915907
pub fn create_expansion(self, expn_data: ExpnData) -> LocalExpnId {
916-
let current_node = tls::with_related_context(self, |icx| icx.current_node);
917-
let CurrentDepNode::Regular(DepNode { kind, hash }) = current_node else {
908+
let current_node = tls::with_related_context(self, |icx| icx.current_node.clone());
909+
let CurrentDepNode::Regular { dep_node, expn_disambiguators } = current_node else {
918910
bug!("creating an expansion outside of a query")
919911
};
920-
let _ = ENSURE_FAKE_DEP_NODE_SYNC;
921-
let fake_dep_node = rustc_span::hygiene::FakeDepNode { kind: kind as _, hash };
922912
self.with_stable_hashing_context(|ctx| {
923-
LocalExpnId::create_untracked_expansion(expn_data, fake_dep_node, ctx)
913+
LocalExpnId::create_untracked_expansion(expn_data, dep_node, ctx, &expn_disambiguators)
924914
})
925915
}
926916

927917
/// Fill an empty expansion. This method must not be used outside of the resolver.
928918
#[inline]
929919
#[instrument(level = "trace", skip(self))]
930920
pub fn finalize_expansion(self, expn_id: LocalExpnId, expn_data: ExpnData) {
931-
let current_node = tls::with_related_context(self, |icx| icx.current_node);
932-
let CurrentDepNode::Regular(DepNode { kind, hash }) = current_node else {
921+
let current_node = tls::with_related_context(self, |icx| icx.current_node.clone());
922+
let CurrentDepNode::Regular { dep_node, expn_disambiguators } = current_node else {
933923
bug!("creating an expansion outside of a query")
934924
};
935-
let _ = ENSURE_FAKE_DEP_NODE_SYNC;
936-
let fake_dep_node = rustc_span::hygiene::FakeDepNode { kind: kind as _, hash };
937925
self.with_stable_hashing_context(|ctx| {
938-
expn_id.set_untracked_expn_data(expn_data, fake_dep_node, ctx)
926+
expn_id.set_untracked_expn_data(expn_data, dep_node, ctx, &expn_disambiguators)
939927
});
940928
}
941929

compiler/rustc_middle/src/ty/context/tls.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub struct ImplicitCtxt<'a, 'tcx> {
3131
/// Used to prevent queries from calling too deeply.
3232
pub query_depth: usize,
3333

34-
/// The DepNode of the query being executed. This is updated by the dep-graph. Thisis used to
34+
/// The DepNode of the query being executed. This is updated by the dep-graph. This is used to
3535
/// know which query created an expansion.
3636
pub current_node: CurrentDepNode,
3737

@@ -46,7 +46,7 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
4646
let current_node = if tcx.dep_graph.is_fully_enabled() {
4747
CurrentDepNode::Untracked
4848
} else {
49-
CurrentDepNode::Regular(DepNode::NULL)
49+
CurrentDepNode::regular(DepNode::NULL)
5050
};
5151
ImplicitCtxt {
5252
tcx,

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl QueryContext for QueryCtxt<'_> {
142142
query: Some(token),
143143
diagnostics,
144144
query_depth: current_icx.query_depth + depth_limit as usize,
145-
current_node: current_icx.current_node,
145+
current_node: current_icx.current_node.clone(),
146146
task_deps: current_icx.task_deps,
147147
};
148148

compiler/rustc_query_system/src/dep_graph/graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl<K: DepKind> DepGraphData<K> {
355355
);
356356

357357
let with_deps =
358-
|task_deps| K::with_deps(CurrentDepNode::Regular(key), task_deps, || task(cx, arg));
358+
|task_deps| K::with_deps(CurrentDepNode::regular(key), task_deps, || task(cx, arg));
359359
let (result, edges) = if cx.dep_context().is_eval_always(key.kind) {
360360
(with_deps(TaskDepsRef::EvalAlways), smallvec![])
361361
} else {

compiler/rustc_query_system/src/dep_graph/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
1414

1515
use crate::ich::StableHashingContext;
1616
use rustc_data_structures::profiling::SelfProfilerRef;
17+
use rustc_data_structures::stable_hasher::Hash64;
18+
use rustc_data_structures::sync::{Lock, Lrc};
19+
use rustc_data_structures::unhash::UnhashMap;
1720
use rustc_serialize::{opaque::FileEncoder, Encodable};
1821
use rustc_session::Session;
1922

@@ -137,13 +140,27 @@ impl FingerprintStyle {
137140
}
138141
}
139142

140-
#[derive(Copy, Clone, Hash)]
143+
#[derive(Clone)]
141144
pub enum CurrentDepNode<K> {
142-
Regular(DepNode<K>),
145+
Regular {
146+
dep_node: DepNode<K>,
147+
/// Disambiguation map for expansions created while executing
148+
/// the query with this `DepNode`.
149+
expn_disambiguators: Lrc<Lock<UnhashMap<Hash64, u32>>>,
150+
},
143151
Anonymous,
144152
Untracked,
145153
}
146154

155+
impl<K> CurrentDepNode<K> {
156+
pub fn regular(dep_node: DepNode<K>) -> CurrentDepNode<K> {
157+
CurrentDepNode::Regular {
158+
dep_node,
159+
expn_disambiguators: Lrc::new(Lock::new(UnhashMap::default())),
160+
}
161+
}
162+
}
163+
147164
/// Describe the different families of dependency nodes.
148165
pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder> + 'static {
149166
/// DepKind to use when incr. comp. is turned off.

compiler/rustc_query_system/src/query/plumbing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ where
632632
// The dep-graph for this computation is already in-place, but any side effect due to this
633633
// query needs to know our DepNode.
634634
let result =
635-
Qcx::DepKind::with_deps(CurrentDepNode::Regular(*dep_node), TaskDepsRef::Ignore, || {
635+
Qcx::DepKind::with_deps(CurrentDepNode::regular(*dep_node), TaskDepsRef::Ignore, || {
636636
query.compute(qcx, *key)
637637
});
638638

compiler/rustc_span/src/hygiene.rs

Lines changed: 22 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::with_session_globals;
3030
use crate::{HashStableContext, Span, DUMMY_SP};
3131

3232
use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
33-
use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
33+
use rustc_data_structures::fingerprint::Fingerprint;
3434
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
3535
use rustc_data_structures::stable_hasher::HashingControls;
3636
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
@@ -195,11 +195,12 @@ impl LocalExpnId {
195195
#[instrument(level = "trace", skip(ctx), ret)]
196196
pub fn create_untracked_expansion(
197197
mut expn_data: ExpnData,
198-
dep_node: FakeDepNode,
198+
hash_extra: impl Hash + Copy + fmt::Debug,
199199
ctx: impl HashStableContext,
200+
disambiguation_map: &Lock<UnhashMap<Hash64, u32>>,
200201
) -> LocalExpnId {
201202
debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE);
202-
let expn_hash = update_disambiguator(&mut expn_data, dep_node, ctx);
203+
let expn_hash = update_disambiguator(&mut expn_data, hash_extra, ctx, disambiguation_map);
203204
HygieneData::with(|data| {
204205
let expn_id = data.local_expn_data.push(Some(expn_data));
205206
let _eid = data.local_expn_hashes.push(expn_hash);
@@ -218,11 +219,12 @@ impl LocalExpnId {
218219
pub fn set_untracked_expn_data(
219220
self,
220221
mut expn_data: ExpnData,
221-
dep_node: FakeDepNode,
222+
hash_extra: impl Hash + Copy + fmt::Debug,
222223
ctx: impl HashStableContext,
224+
disambiguation_map: &Lock<UnhashMap<Hash64, u32>>,
223225
) {
224226
debug_assert_eq!(expn_data.parent.krate, LOCAL_CRATE);
225-
let expn_hash = update_disambiguator(&mut expn_data, dep_node, ctx);
227+
let expn_hash = update_disambiguator(&mut expn_data, hash_extra, ctx, disambiguation_map);
226228
HygieneData::with(|data| {
227229
let old_expn_data = &mut data.local_expn_data[self];
228230
assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID");
@@ -349,14 +351,6 @@ impl ExpnId {
349351
}
350352
}
351353

352-
/// This struct is meant to be a surrogate for the actual `DepNode` in rustc_middle.
353-
/// Both types should be kept in sync.
354-
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
355-
pub struct FakeDepNode {
356-
pub kind: u16,
357-
pub hash: PackedFingerprint,
358-
}
359-
360354
#[derive(Debug)]
361355
pub struct HygieneData {
362356
/// Each expansion should have an associated expansion data, but sometimes there's a delay
@@ -371,12 +365,6 @@ pub struct HygieneData {
371365
expn_hash_to_expn_id: UnhashMap<ExpnHash, ExpnId>,
372366
syntax_context_data: Vec<SyntaxContextData>,
373367
syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>,
374-
/// Maps the `local_hash` of an `ExpnData` to the next disambiguator value.
375-
/// This is used by `update_disambiguator` to keep track of which `ExpnData`s
376-
/// would have collisions without a disambiguator.
377-
/// The keys of this map are always computed with `ExpnData.disambiguator`
378-
/// set to 0.
379-
expn_data_disambiguators: FxHashMap<FakeDepNode, FxHashMap<Hash64, u32>>,
380368
}
381369

382370
impl HygieneData {
@@ -405,7 +393,6 @@ impl HygieneData {
405393
dollar_crate_name: kw::DollarCrate,
406394
}],
407395
syntax_context_map: FxHashMap::default(),
408-
expn_data_disambiguators: FxHashMap::default(),
409396
}
410397
}
411398

@@ -1049,10 +1036,10 @@ impl ExpnData {
10491036
}
10501037

10511038
#[inline]
1052-
fn hash_expn(&self, dep_node: FakeDepNode, ctx: &mut impl HashStableContext) -> Hash64 {
1039+
fn hash_expn(&self, hash_extra: impl Hash, ctx: &mut impl HashStableContext) -> Hash64 {
10531040
let mut hasher = StableHasher::new();
10541041
self.hash_stable(ctx, &mut hasher);
1055-
dep_node.hash(&mut hasher);
1042+
hash_extra.hash(&mut hasher);
10561043
hasher.finish()
10571044
}
10581045
}
@@ -1478,44 +1465,38 @@ impl<D: Decoder> Decodable<D> for SyntaxContext {
14781465
#[instrument(level = "trace", skip(ctx), ret)]
14791466
fn update_disambiguator(
14801467
expn_data: &mut ExpnData,
1481-
dep_node: FakeDepNode,
1468+
hash_extra: impl Hash + Copy + fmt::Debug,
14821469
mut ctx: impl HashStableContext,
1470+
disambiguation_map: &Lock<UnhashMap<Hash64, u32>>,
14831471
) -> ExpnHash {
14841472
// This disambiguator should not have been set yet.
14851473
assert_eq!(expn_data.disambiguator, 0, "Already set disambiguator for ExpnData: {expn_data:?}");
14861474
assert_default_hashing_controls(&ctx, "ExpnData (disambiguator)");
1487-
let mut expn_hash = expn_data.hash_expn(dep_node, &mut ctx);
1475+
let mut expn_hash = expn_data.hash_expn(hash_extra, &mut ctx);
14881476
debug!(?expn_hash);
14891477

1490-
let disambiguator = HygieneData::with(|data| {
1478+
let disambiguator = {
14911479
// If this is the first ExpnData with a given hash, then keep our
14921480
// disambiguator at 0 (the default u32 value)
1493-
let disambig = data
1494-
.expn_data_disambiguators
1495-
.entry(dep_node)
1496-
.or_default()
1497-
.entry(expn_hash)
1498-
.or_default();
1481+
let mut disambiguation_map = disambiguation_map.lock();
1482+
let disambig = disambiguation_map.entry(expn_hash).or_default();
14991483
let disambiguator = *disambig;
15001484
*disambig += 1;
15011485
disambiguator
1502-
});
1486+
};
15031487

15041488
if disambiguator != 0 {
15051489
debug!("Set disambiguator for expn_data={:?} expn_hash={:?}", expn_data, expn_hash);
15061490

15071491
expn_data.disambiguator = disambiguator;
1508-
expn_hash = expn_data.hash_expn(dep_node, &mut ctx);
1492+
expn_hash = expn_data.hash_expn(hash_extra, &mut ctx);
15091493

15101494
// Verify that the new disambiguator makes the hash unique
1511-
#[cfg(debug_assertions)]
1512-
HygieneData::with(|data| {
1513-
assert_eq!(
1514-
data.expn_data_disambiguators[&dep_node].get(&expn_hash),
1515-
None,
1516-
"Hash collision after disambiguator update!",
1517-
);
1518-
});
1495+
debug_assert_eq!(
1496+
disambiguation_map.lock().get(&expn_hash),
1497+
None,
1498+
"Hash collision after disambiguator update!",
1499+
);
15191500
}
15201501

15211502
ExpnHash::new(ctx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), expn_hash)

0 commit comments

Comments
 (0)