Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Unfortunately this is nowhere near a minimal example, but it was a tricky one to figure out how to reliably reproduce. Here are the steps: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --This also happens with current nightly too: And here's the error from nightly: Unfortunately it's hard to say which version of Rust introduced this error since tracks the latest stable version of Rust. One possible way to narrow this down is that not all changes to the code seem to provoke the ICE. For example, if you checkout , do and then checkout and build that too, then it works fine. So I wonder if there is something about that is provoking the problem.
has an MSRV of 1.77 so I couldn't easily check how old this ICE is or bisect, but it happens on 1.77 as well. Finally, an incr-comp ICE with a repro <3
A repro with no external deps: to panics
rustc 1.80.0-nightly ( 2024-05-01) still crashes
duplicate of ?

Discussion:
} #[inline(always)] <del> pub fn local_def_path_hash_to_def_id( &self, hash: DefPathHash, err_msg: &dyn std::fmt::Debug, ) -> LocalDefId { </del> <ins> /// Returns `None` if the `DefPathHash` does not correspond to a `LocalDefId` /// in the current compilation session. This can legitimately happen if the /// `DefPathHash` is from a `DefId` in an upstream crate or, during incr. comp., /// if the `DefPathHash` is from a previous compilation session and /// the def-path does not exist anymore. pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> { </ins> debug_assert!(hash.stable_crate_id() == self.table.stable_crate_id); <del> #[cold] #[inline(never)] fn err(err_msg: &dyn std::fmt::Debug) -> ! { panic!("{err_msg:?}") } </del> self.table .def_path_hash_to_index .get(&hash.local_hash()) .map(|local_def_index| LocalDefId { local_def_index }) <del> .unwrap_or_else(|| err(err_msg)) </del> } pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {

/// has been removed. fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> { if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash { <del> Some(tcx.def_path_hash_to_def_id( DefPathHash(self.hash.into()), &("Failed to extract DefId", self.kind, self.hash), )) </del> <ins> tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into())) </ins> } else { None }

if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId { let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split(); let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash); <del> let def_id = tcx .def_path_hash_to_def_id( def_path_hash, &("Failed to extract HirId", dep_node.kind, dep_node.hash), ) .expect_local(); </del> <ins> let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local(); </ins> let local_id = local_id .as_u64() .try_into()

// If we get to this point, then all of the query inputs were green, // which means that the definition with this hash is guaranteed to // still exist in the current compilation session. <del> self.tcx.def_path_hash_to_def_id( def_path_hash, &("Failed to convert DefPathHash", def_path_hash), ) </del> <ins> match self.tcx.def_path_hash_to_def_id(def_path_hash) { Some(r) => r, None => panic!("Failed to convert DefPathHash {def_path_hash:?}"), } </ins> } fn decode_attr_id(&mut self) -> rustc_span::AttrId {

/// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation /// session, if it still exists. This is used during incremental compilation to /// turn a deserialized `DefPathHash` into its current `DefId`. <del> pub fn def_path_hash_to_def_id( self, hash: DefPathHash, err_msg: &dyn std::fmt::Debug, ) -> DefId { </del> <ins> pub fn def_path_hash_to_def_id(self, hash: DefPathHash) -> Option<DefId> { </ins> debug!("def_path_hash_to_def_id({:?})", hash); let stable_crate_id = hash.stable_crate_id();

// If this is a DefPathHash from the local crate, we can look up the // DefId in the tcx's `Definitions`. if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) { <del> self.untracked .definitions .read() .local_def_path_hash_to_def_id(hash, err_msg) .to_def_id() </del> <ins> Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id()) </ins> } else { <del> self.def_path_hash_to_def_id_extern(hash, stable_crate_id) </del> <ins> Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id)) </ins> } }

} /// Try to force a dep node to execute and see if it's green. <ins> /// /// Returns true if the query has actually been forced. It is valid that a query /// fails to be forced, e.g. when the query key cannot be reconstructed from the /// dep-node or when the query kind outright does not support it. </ins> #[inline] #[instrument(skip(self, frame), level = "debug")] fn try_force_from_dep_node(self, dep_node: DepNode, frame: Option<&MarkFrame<'_>>) -> bool { let cb = self.dep_kind_info(dep_node.kind); if let Some(f) = cb.force_from_dep_node { <del> if let Err(value) = panic::catch_unwind(panic::AssertUnwindSafe(|| { f(self, dep_node); })) { if !value.is::<rustc_errors::FatalErrorMarker>() { print_markframe_trace(self.dep_graph(), frame); </del> <ins> match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node))) { Err(value) => { if !value.is::<rustc_errors::FatalErrorMarker>() { print_markframe_trace(self.dep_graph(), frame); } panic::resume_unwind(value) </ins> } <del> panic::resume_unwind(value) </del> <ins> Ok(query_has_been_forced) => query_has_been_forced, </ins> } <del> true </del> } else { false }

<ins> // If it is impossible to find query arguments just from the hash // compiler should treat the node as red // In this test prior to fixing compiler was having problems figuring out // drop impl for T inside of m //@ revisions:cfail1 cfail2 //@ compile-flags: --crate-type=lib //@ build-pass pub trait P { type A; } struct S; impl P for S { type A = C; } struct T<D: P>(D::A, Z<D>); struct Z<D: P>(D::A, String); impl<D: P> T<D> { pub fn i() -> Self { loop {} } } enum C { #[cfg(cfail1)] Up(()), #[cfg(cfail2)] Lorry(()), } pub fn m() { T::<S>::i(); } </ins>