Skip to content

Commit 1d96de2

Browse files
committed
Auto merge of #126409 - pacak:incr-uplorry, r=michaelwoerister
Trying to address an incremental compilation issues This pull request contains two independent changes, one makes it so when `try_force_from_dep_node` fails to recover a query - it marks the node as "red" instead of "green" and the second one makes Debug impl for `DepNode` less panicky if it encounters something from the previous compilation that doesn't map to anything in the current one. I'm not 100% confident that this is the correct approach, but so far I managed to find a bunch of comments suggesting that some things are allowed to fail in a certain way and changes I made are allowing for those things to fail this way and it fixes all the small reproducers I managed to find. Compilation panic this pull request avoids is caused by an automatically generated code on an associated type and it is not happening if something else marks it as outdated first (or close like that, but scenario is quite obscure). Fixes #107226 Fixes #125367
2 parents 1208edd + 12f8d12 commit 1d96de2

File tree

6 files changed

+66
-43
lines changed

6 files changed

+66
-43
lines changed

compiler/rustc_hir/src/definitions.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -377,22 +377,17 @@ impl Definitions {
377377
}
378378

379379
#[inline(always)]
380-
pub fn local_def_path_hash_to_def_id(
381-
&self,
382-
hash: DefPathHash,
383-
err_msg: &dyn std::fmt::Debug,
384-
) -> LocalDefId {
380+
/// Returns `None` if the `DefPathHash` does not correspond to a `LocalDefId`
381+
/// in the current compilation session. This can legitimately happen if the
382+
/// `DefPathHash` is from a `DefId` in an upstream crate or, during incr. comp.,
383+
/// if the `DefPathHash` is from a previous compilation session and
384+
/// the def-path does not exist anymore.
385+
pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> {
385386
debug_assert!(hash.stable_crate_id() == self.table.stable_crate_id);
386-
#[cold]
387-
#[inline(never)]
388-
fn err(err_msg: &dyn std::fmt::Debug) -> ! {
389-
panic!("{err_msg:?}")
390-
}
391387
self.table
392388
.def_path_hash_to_index
393389
.get(&hash.local_hash())
394390
.map(|local_def_index| LocalDefId { local_def_index })
395-
.unwrap_or_else(|| err(err_msg))
396391
}
397392

398393
pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {

compiler/rustc_middle/src/dep_graph/dep_node.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,7 @@ impl DepNodeExt for DepNode {
194194
/// has been removed.
195195
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
196196
if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
197-
Some(tcx.def_path_hash_to_def_id(
198-
DefPathHash(self.hash.into()),
199-
&("Failed to extract DefId", self.kind, self.hash),
200-
))
197+
tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()))
201198
} else {
202199
None
203200
}
@@ -390,12 +387,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
390387
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
391388
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
392389
let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
393-
let def_id = tcx
394-
.def_path_hash_to_def_id(
395-
def_path_hash,
396-
&("Failed to extract HirId", dep_node.kind, dep_node.hash),
397-
)
398-
.expect_local();
390+
let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
399391
let local_id = local_id
400392
.as_u64()
401393
.try_into()

compiler/rustc_middle/src/query/on_disk_cache.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -733,10 +733,10 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
733733
// If we get to this point, then all of the query inputs were green,
734734
// which means that the definition with this hash is guaranteed to
735735
// still exist in the current compilation session.
736-
self.tcx.def_path_hash_to_def_id(
737-
def_path_hash,
738-
&("Failed to convert DefPathHash", def_path_hash),
739-
)
736+
match self.tcx.def_path_hash_to_def_id(def_path_hash) {
737+
Some(r) => r,
738+
None => panic!("Failed to convert DefPathHash {def_path_hash:?}"),
739+
}
740740
}
741741

742742
fn decode_attr_id(&mut self) -> rustc_span::AttrId {

compiler/rustc_middle/src/ty/context.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -1677,25 +1677,17 @@ impl<'tcx> TyCtxt<'tcx> {
16771677
/// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
16781678
/// session, if it still exists. This is used during incremental compilation to
16791679
/// turn a deserialized `DefPathHash` into its current `DefId`.
1680-
pub fn def_path_hash_to_def_id(
1681-
self,
1682-
hash: DefPathHash,
1683-
err_msg: &dyn std::fmt::Debug,
1684-
) -> DefId {
1680+
pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> {
16851681
debug!("def_path_hash_to_def_id({:?})", hash);
16861682

16871683
let stable_crate_id = hash.stable_crate_id();
16881684

16891685
// If this is a DefPathHash from the local crate, we can look up the
16901686
// DefId in the tcx's `Definitions`.
16911687
if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
1692-
self.untracked
1693-
.definitions
1694-
.read()
1695-
.local_def_path_hash_to_def_id(hash, err_msg)
1696-
.to_def_id()
1688+
Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
16971689
} else {
1698-
self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
1690+
Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
16991691
}
17001692
}
17011693

compiler/rustc_query_system/src/dep_graph/mod.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,24 @@ pub trait DepContext: Copy {
5151
}
5252

5353
/// Try to force a dep node to execute and see if it's green.
54+
///
55+
/// Returns true if the query has actually been forced. It is valid that a query
56+
/// fails to be forced, e.g. when the query key cannot be reconstructed from the
57+
/// dep-node or when the query kind outright does not support it.
5458
#[inline]
5559
#[instrument(skip(self, frame), level = "debug")]
5660
fn try_force_from_dep_node(self, dep_node: DepNode, frame: Option<&MarkFrame<'_>>) -> bool {
5761
let cb = self.dep_kind_info(dep_node.kind);
5862
if let Some(f) = cb.force_from_dep_node {
59-
if let Err(value) = panic::catch_unwind(panic::AssertUnwindSafe(|| {
60-
f(self, dep_node);
61-
})) {
62-
if !value.is::<rustc_errors::FatalErrorMarker>() {
63-
print_markframe_trace(self.dep_graph(), frame);
63+
match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node))) {
64+
Err(value) => {
65+
if !value.is::<rustc_errors::FatalErrorMarker>() {
66+
print_markframe_trace(self.dep_graph(), frame);
67+
}
68+
panic::resume_unwind(value)
6469
}
65-
panic::resume_unwind(value)
70+
Ok(query_has_been_forced) => query_has_been_forced,
6671
}
67-
true
6872
} else {
6973
false
7074
}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// If it is impossible to find query arguments just from the hash
2+
// compiler should treat the node as red
3+
4+
// In this test prior to fixing compiler was having problems figuring out
5+
// drop impl for T inside of m
6+
7+
//@ revisions:cfail1 cfail2
8+
//@ compile-flags: --crate-type=lib
9+
//@ build-pass
10+
11+
pub trait P {
12+
type A;
13+
}
14+
15+
struct S;
16+
17+
impl P for S {
18+
type A = C;
19+
}
20+
21+
struct T<D: P>(D::A, Z<D>);
22+
23+
struct Z<D: P>(D::A, String);
24+
25+
impl<D: P> T<D> {
26+
pub fn i() -> Self {
27+
loop {}
28+
}
29+
}
30+
31+
enum C {
32+
#[cfg(cfail1)]
33+
Up(()),
34+
#[cfg(cfail2)]
35+
Lorry(()),
36+
}
37+
38+
pub fn m() {
39+
T::<S>::i();
40+
}

0 commit comments

Comments
 (0)