diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index bd89b8cfe7c..0d58ac7ae49 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -88,6 +88,12 @@ pub struct DepKindStruct { /// their inputs have not changed since the last compiler invocation. The result is still /// cached within one compiler invocation. pub(super) is_eval_always: bool, + + /// Whether the query key can be recovered from the hashed fingerprint. + /// See [DepNodeParams] trait for the behaviour of each key type. + // FIXME: Make this a simple boolean once DepNodeParams::can_reconstruct_query_key + // can be made a specialized associated const. + can_reconstruct_query_key: fn() -> bool, } impl std::ops::Deref for DepKind { @@ -97,6 +103,19 @@ impl std::ops::Deref for DepKind { } } +impl DepKind { + #[inline(always)] + pub fn can_reconstruct_query_key(&self) -> bool { + // Only fetch the DepKindStruct once. + let data: &DepKindStruct = &**self; + if data.is_anon { + return false; + } + + (data.can_reconstruct_query_key)() + } +} + // erase!() just makes tokens go away. It's used to specify which macro argument // is repeated (i.e., which sub-expression of the macro we are in) but don't need // to actually use any of the arguments. @@ -133,20 +152,41 @@ macro_rules! contains_eval_always_attr { #[allow(non_upper_case_globals)] pub mod dep_kind { use super::*; + use crate::ty::query::query_keys; // We use this for most things when incr. comp. is turned off. - pub const Null: DepKindStruct = - DepKindStruct { has_params: false, is_anon: false, is_eval_always: false }; + pub const Null: DepKindStruct = DepKindStruct { + has_params: false, + is_anon: false, + is_eval_always: false, + + can_reconstruct_query_key: || true, + }; // Represents metadata from an extern crate. - pub const CrateMetadata: DepKindStruct = - DepKindStruct { has_params: true, is_anon: false, is_eval_always: true }; + pub const CrateMetadata: DepKindStruct = DepKindStruct { + has_params: true, + is_anon: false, + is_eval_always: true, - pub const TraitSelect: DepKindStruct = - DepKindStruct { has_params: false, is_anon: true, is_eval_always: false }; + can_reconstruct_query_key: || true, + }; - pub const CompileCodegenUnit: DepKindStruct = - DepKindStruct { has_params: true, is_anon: false, is_eval_always: false }; + pub const TraitSelect: DepKindStruct = DepKindStruct { + has_params: false, + is_anon: true, + is_eval_always: false, + + can_reconstruct_query_key: || false, + }; + + pub const CompileCodegenUnit: DepKindStruct = DepKindStruct { + has_params: true, + is_anon: false, + is_eval_always: false, + + can_reconstruct_query_key: || false, + }; macro_rules! define_query_dep_kinds { ($( @@ -158,10 +198,18 @@ pub mod dep_kind { const is_anon: bool = contains_anon_attr!($($attrs)*); const is_eval_always: bool = contains_eval_always_attr!($($attrs)*); + #[inline(always)] + fn can_reconstruct_query_key() -> bool { + !is_anon && + as DepNodeParams>> + ::can_reconstruct_query_key() + } + DepKindStruct { has_params, is_anon, is_eval_always, + can_reconstruct_query_key, } };)* ); @@ -186,29 +234,6 @@ macro_rules! define_dep_nodes { $($variant),* } - impl DepKind { - #[allow(unreachable_code)] - pub fn can_reconstruct_query_key<$tcx>(&self) -> bool { - if self.is_anon { - return false; - } - - match *self { - $( - DepKind :: $variant => { - // tuple args - $({ - return <$tuple_arg_ty as DepNodeParams>> - ::can_reconstruct_query_key(); - })* - - true - } - )* - } - } - } - pub struct DepConstructor; #[allow(non_camel_case_types)] diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 546c3877e4d..d4cbbfa86ae 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -26,6 +26,11 @@ pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph< impl rustc_query_system::dep_graph::DepKind for DepKind { const NULL: Self = DepKind::Null; + #[inline(always)] + fn can_reconstruct_query_key(&self) -> bool { + DepKind::can_reconstruct_query_key(self) + } + #[inline(always)] fn is_eval_always(&self) -> bool { self.is_eval_always @@ -83,10 +88,6 @@ impl rustc_query_system::dep_graph::DepKind for DepKind { op(icx.task_deps) }) } - - fn can_reconstruct_query_key(&self) -> bool { - DepKind::can_reconstruct_query_key(self) - } } impl<'tcx> DepContext for TyCtxt<'tcx> {