Skip to content

Commit fc7e56d

Browse files
committed
Also store the DefPathHash as part of a DefId creation side effect, so we can reliably recreate the same DefId over and over again
Recreate `DefId`s when a cached query gets replayed
1 parent 2db556f commit fc7e56d

File tree

11 files changed

+65
-18
lines changed

11 files changed

+65
-18
lines changed

compiler/rustc_hir/src/definitions.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ impl DefPathTable {
6767
// being used.
6868
//
6969
// See the documentation for DefPathHash for more information.
70-
panic!(
70+
assert_eq!(
71+
def_path1, def_path2,
7172
"found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
7273
Compilation cannot continue."
7374
);
@@ -214,7 +215,7 @@ impl fmt::Display for DisambiguatedDefPathData {
214215
}
215216
}
216217

217-
#[derive(Clone, Debug, Encodable, Decodable)]
218+
#[derive(Clone, Debug, Encodable, Decodable, PartialEq)]
218219
pub struct DefPath {
219220
/// The path leading from the crate root to the item.
220221
pub data: Vec<DisambiguatedDefPathData>,
@@ -389,7 +390,7 @@ impl Definitions {
389390
parent: LocalDefId,
390391
data: DefPathData,
391392
disambiguator: u32,
392-
) -> LocalDefId {
393+
) -> (LocalDefId, DefPathHash) {
393394
// We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a
394395
// reference to `Definitions` and we're already holding a mutable reference.
395396
debug!(
@@ -411,7 +412,7 @@ impl Definitions {
411412
debug!("create_def: after disambiguation, key = {:?}", key);
412413

413414
// Create the definition.
414-
LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }
415+
(LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }, def_path_hash)
415416
}
416417

417418
#[inline(always)]

compiler/rustc_interface/src/callbacks.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ use std::fmt;
1414
use rustc_errors::{DiagInner, TRACK_DIAGNOSTIC};
1515
use rustc_middle::dep_graph::{DepNodeExt, TaskDepsRef};
1616
use rustc_middle::ty::tls;
17+
use rustc_middle::util::Providers;
1718
use rustc_query_impl::QueryCtxt;
1819
use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug;
1920
use rustc_query_system::dep_graph::{DepContext, DepKind, DepNode};
21+
use rustc_query_system::query::DefIdInfo;
2022

2123
fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
2224
tls::with_context_opt(|icx| {
@@ -113,3 +115,14 @@ pub fn setup_callbacks() {
113115
.swap(&(dep_node_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
114116
TRACK_DIAGNOSTIC.swap(&(track_diagnostic as _));
115117
}
118+
119+
pub fn provide(providers: &mut Providers) {
120+
providers.create_def_raw = |tcx, (parent, data, disambiguator)| {
121+
let (def_id, hash) =
122+
tcx.untracked().definitions.write().create_def(parent, data, disambiguator);
123+
124+
tcx.dep_graph
125+
.record_def(QueryCtxt::new(tcx), DefIdInfo { parent, data, hash, disambiguator });
126+
def_id
127+
}
128+
}

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
799799
rustc_lint::provide(providers);
800800
rustc_symbol_mangling::provide(providers);
801801
rustc_codegen_ssa::provide(providers);
802+
crate::callbacks::provide(providers);
802803
*providers
803804
});
804805

compiler/rustc_middle/src/dep_graph/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_data_structures::profiling::SelfProfilerRef;
22
use rustc_query_system::ich::StableHashingContext;
3+
use rustc_query_system::query::DefIdInfo;
34
use rustc_session::Session;
45

56
use crate::ty::{self, TyCtxt};
@@ -80,6 +81,11 @@ impl<'tcx> DepContext for TyCtxt<'tcx> {
8081
self.sess
8182
}
8283

84+
fn create_def(&self, &DefIdInfo { parent, data, disambiguator: index, hash }: &DefIdInfo) {
85+
let (_, h) = self.untracked().definitions.write().create_def(parent, data, index);
86+
assert_eq!(hash, h);
87+
}
88+
8389
#[inline]
8490
fn dep_kind_info(&self, dk: DepKind) -> &DepKindStruct<'tcx> {
8591
&self.query_kinds[dk.as_usize()]

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,4 @@ pub fn provide(providers: &mut Providers) {
239239
providers.in_scope_traits_map = |tcx, id| {
240240
tcx.hir_crate(()).owners[id.def_id].as_owner().map(|owner_info| &owner_info.trait_map)
241241
};
242-
providers.create_def_raw = |tcx, (parent, data, disambiguator)| {
243-
tcx.untracked().definitions.write().create_def(parent, data, disambiguator)
244-
}
245242
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,7 @@ rustc_queries! {
20592059
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
20602060
separate_provide_extern
20612061
feedable
2062+
cache_on_disk_if { def_id.is_local() }
20622063
}
20632064

20642065
query inhabited_predicate_adt(key: DefId) -> ty::inhabitedness::InhabitedPredicate<'tcx> {

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,7 @@ impl<'tcx> TyCtxtAt<'tcx> {
19901990

19911991
impl<'tcx> TyCtxt<'tcx> {
19921992
/// `tcx`-dependent operations performed for every created definition.
1993+
#[instrument(level = "trace", skip(self))]
19931994
pub fn create_def(
19941995
self,
19951996
parent: LocalDefId,
@@ -2009,13 +2010,7 @@ impl<'tcx> TyCtxt<'tcx> {
20092010
// The following call has the side effect of modifying the tables inside `definitions`.
20102011
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to
20112012
// decode the on-disk cache.
2012-
//
2013-
// Any LocalDefId which is used within queries, either as key or result, either:
2014-
// - has been created before the construction of the TyCtxt;
2015-
// - has been created by this call to `create_def`.
2016-
// As a consequence, this LocalDefId is always re-created before it is needed by the incr.
2017-
// comp. engine itself.
2018-
self.untracked.definitions.write().create_def(parent, data, disambiguator.next(parent, data))
2013+
self.untracked.definitions.write().create_def(parent, data, disambiguator.next(parent, data)).0
20192014
}
20202015
TaskDepsRef::Forbid => bug!(
20212016
"cannot create definition {parent:?} {data:?} without being able to register task dependencies"

compiler/rustc_query_system/src/dep_graph/graph.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex
2626
use super::{DepContext, DepKind, DepNode, Deps, HasDepContext, WorkProductId};
2727
use crate::dep_graph::edges::EdgesVec;
2828
use crate::ich::StableHashingContext;
29-
use crate::query::{QueryContext, QuerySideEffect};
29+
use crate::query::{DefIdInfo, QueryContext, QuerySideEffect};
3030

3131
#[derive(Clone)]
3232
pub struct DepGraph<D: Deps> {
@@ -260,6 +260,7 @@ impl<D: Deps> DepGraph<D> {
260260
}
261261

262262
#[inline(always)]
263+
/// A helper for `codegen_cranelift`.
263264
pub fn with_task<Ctxt: HasDepContext<Deps = D>, A: Debug, R>(
264265
&self,
265266
key: DepNode,
@@ -530,6 +531,18 @@ impl<D: Deps> DepGraph<D> {
530531
})
531532
}
532533
}
534+
535+
pub fn record_def<Qcx: QueryContext>(&self, qcx: Qcx, def: DefIdInfo) {
536+
if let Some(ref data) = self.data {
537+
D::read_deps(|task_deps| match task_deps {
538+
TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return,
539+
TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => {
540+
self.read_index(data.encode_side_effect(qcx, QuerySideEffect::Definition(def)));
541+
}
542+
})
543+
}
544+
}
545+
533546
/// This forces a diagnostic node green by running its side effect. `prev_index` would
534547
/// refer to a node created used [Self::record_diagnostic] in the previous session.
535548
#[inline]
@@ -667,7 +680,7 @@ impl<D: Deps> DepGraphData<D> {
667680
self.debug_loaded_from_disk.lock().insert(dep_node);
668681
}
669682

670-
/// This encodes a diagnostic by creating a node with an unique index and assoicating
683+
/// This encodes a diagnostic by creating a node with an unique index and associating
671684
/// `diagnostic` with it, for use in the next session.
672685
#[inline]
673686
fn encode_side_effect<Qcx: QueryContext>(
@@ -705,6 +718,9 @@ impl<D: Deps> DepGraphData<D> {
705718
QuerySideEffect::Diagnostic(diagnostic) => {
706719
qcx.dep_context().sess().dcx().emit_diagnostic(diagnostic.clone());
707720
}
721+
QuerySideEffect::Definition(def_id_info) => {
722+
qcx.dep_context().create_def(def_id_info)
723+
}
708724
}
709725

710726
// Use `send_and_color` as `promote_node_and_deps_to_current` expects all

compiler/rustc_query_system/src/dep_graph/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use tracing::instrument;
1919

2020
use self::graph::{MarkFrame, print_markframe_trace};
2121
use crate::ich::StableHashingContext;
22+
use crate::query::DefIdInfo;
2223

2324
pub trait DepContext: Copy {
2425
type Deps: Deps;
@@ -35,6 +36,8 @@ pub trait DepContext: Copy {
3536
/// Access the compiler session.
3637
fn sess(&self) -> &Session;
3738

39+
fn create_def(&self, def: &DefIdInfo);
40+
3841
fn dep_kind_info(&self, dep_node: DepKind) -> &DepKindStruct<Self>;
3942

4043
#[inline(always)]

compiler/rustc_query_system/src/query/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ use rustc_data_structures::sync::{DynSend, DynSync};
2121
use rustc_errors::DiagInner;
2222
use rustc_hashes::Hash64;
2323
use rustc_hir::def::DefKind;
24+
use rustc_hir::def_id::DefPathHash;
2425
use rustc_macros::{Decodable, Encodable};
2526
use rustc_span::Span;
26-
use rustc_span::def_id::DefId;
27+
use rustc_span::def_id::{DefId, LocalDefId};
2728

2829
pub use self::config::{HashResult, QueryConfig};
2930
use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
@@ -147,6 +148,19 @@ pub enum QuerySideEffect {
147148
/// the query as green, as that query will have the side
148149
/// effect dep node as a dependency.
149150
Diagnostic(DiagInner),
151+
152+
/// A `DefId` that was created during query execution.
153+
/// These `DefId`s will be re-created when we mark the query as green.
154+
Definition(DefIdInfo),
155+
}
156+
157+
#[derive(Debug, Clone, Encodable, Decodable, PartialEq)]
158+
pub struct DefIdInfo {
159+
pub parent: LocalDefId,
160+
pub data: rustc_hir::definitions::DefPathData,
161+
pub hash: DefPathHash,
162+
/// Disambiguator
163+
pub disambiguator: u32,
150164
}
151165

152166
pub trait QueryContext: HasDepContext {

compiler/rustc_query_system/src/query/plumbing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ where
525525
let dep_node =
526526
dep_node_opt.get_or_insert_with(|| query.construct_dep_node(*qcx.dep_context(), &key));
527527

528-
// The diagnostics for this query will be promoted to the current session during
528+
// The side_effects for this query will be promoted to the current session during
529529
// `try_mark_green()`, so we can ignore them here.
530530
if let Some(ret) = qcx.start_query(job_id, false, || {
531531
try_load_from_disk_and_cache_in_memory(query, dep_graph_data, qcx, &key, dep_node)

0 commit comments

Comments
 (0)