From 6f78eed1c75bf6e42a2e7db125111bad155893b9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 2 Oct 2021 12:06:42 -0400 Subject: [PATCH] Query the fingerprint style during key reconstruction Keys can be reconstructed from fingerprints that are not DefPathHash, but then we cannot extract a DefId from them. --- .../rustc_middle/src/dep_graph/dep_node.rs | 72 ++++++++++--------- compiler/rustc_middle/src/dep_graph/mod.rs | 4 +- compiler/rustc_query_impl/src/plumbing.rs | 7 +- .../src/dep_graph/dep_node.rs | 12 ++-- .../rustc_query_system/src/dep_graph/mod.rs | 23 +++++- .../rustc_query_system/src/query/plumbing.rs | 4 +- 6 files changed, 74 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 07d42902be5..23d475a5953 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -63,6 +63,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::definitions::DefPathHash; use rustc_hir::HirId; +use rustc_query_system::dep_graph::FingerprintStyle; use rustc_span::symbol::Symbol; use std::hash::Hash; @@ -89,9 +90,9 @@ pub struct DepKindStruct { /// 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 + // FIXME: Make this a simple boolean once DepNodeParams::fingerprint_style // can be made a specialized associated const. - can_reconstruct_query_key: fn() -> bool, + fingerprint_style: fn() -> FingerprintStyle, } impl std::ops::Deref for DepKind { @@ -103,14 +104,14 @@ impl std::ops::Deref for DepKind { impl DepKind { #[inline(always)] - pub fn can_reconstruct_query_key(&self) -> bool { + pub fn fingerprint_style(&self) -> FingerprintStyle { // Only fetch the DepKindStruct once. let data: &DepKindStruct = &**self; if data.is_anon { - return false; + return FingerprintStyle::Opaque; } - (data.can_reconstruct_query_key)() + (data.fingerprint_style)() } } @@ -151,6 +152,7 @@ macro_rules! contains_eval_always_attr { pub mod dep_kind { use super::*; use crate::ty::query::query_keys; + use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. pub const Null: DepKindStruct = DepKindStruct { @@ -158,7 +160,7 @@ pub mod dep_kind { is_anon: false, is_eval_always: false, - can_reconstruct_query_key: || true, + fingerprint_style: || FingerprintStyle::Unit, }; pub const TraitSelect: DepKindStruct = DepKindStruct { @@ -166,7 +168,7 @@ pub mod dep_kind { is_anon: true, is_eval_always: false, - can_reconstruct_query_key: || true, + fingerprint_style: || FingerprintStyle::Unit, }; pub const CompileCodegenUnit: DepKindStruct = DepKindStruct { @@ -174,7 +176,7 @@ pub mod dep_kind { is_anon: false, is_eval_always: false, - can_reconstruct_query_key: || false, + fingerprint_style: || FingerprintStyle::Opaque, }; pub const CompileMonoItem: DepKindStruct = DepKindStruct { @@ -182,7 +184,7 @@ pub mod dep_kind { is_anon: false, is_eval_always: false, - can_reconstruct_query_key: || false, + fingerprint_style: || FingerprintStyle::Opaque, }; macro_rules! define_query_dep_kinds { @@ -196,16 +198,16 @@ pub mod dep_kind { const is_eval_always: bool = contains_eval_always_attr!($($attrs)*); #[inline(always)] - fn can_reconstruct_query_key() -> bool { + fn fingerprint_style() -> rustc_query_system::dep_graph::FingerprintStyle { as DepNodeParams>> - ::can_reconstruct_query_key() + ::fingerprint_style() } DepKindStruct { has_params, is_anon, is_eval_always, - can_reconstruct_query_key, + fingerprint_style, } };)* ); @@ -320,7 +322,7 @@ impl DepNodeExt for DepNode { /// method will assert that the given DepKind actually requires a /// single DefId/DefPathHash parameter. fn from_def_path_hash(def_path_hash: DefPathHash, kind: DepKind) -> DepNode { - debug_assert!(kind.can_reconstruct_query_key() && kind.has_params); + debug_assert!(kind.fingerprint_style() == FingerprintStyle::DefPathHash); DepNode { kind, hash: def_path_hash.0.into() } } @@ -335,7 +337,7 @@ impl DepNodeExt for DepNode { /// refers to something from the previous compilation session that /// has been removed. fn extract_def_id(&self, tcx: TyCtxt<'tcx>) -> Option { - if self.kind.can_reconstruct_query_key() { + if self.kind.fingerprint_style() == FingerprintStyle::DefPathHash { Some( tcx.on_disk_cache .as_ref()? @@ -350,14 +352,16 @@ impl DepNodeExt for DepNode { fn from_label_string(label: &str, def_path_hash: DefPathHash) -> Result { let kind = dep_kind_from_label_string(label)?; - if !kind.can_reconstruct_query_key() { - return Err(()); - } - - if kind.has_params { - Ok(DepNode::from_def_path_hash(def_path_hash, kind)) - } else { - Ok(DepNode::new_no_params(kind)) + match kind.fingerprint_style() { + FingerprintStyle::Opaque => Err(()), + FingerprintStyle::Unit => { + if !kind.has_params { + Ok(DepNode::new_no_params(kind)) + } else { + Err(()) + } + } + FingerprintStyle::DefPathHash => Ok(DepNode::from_def_path_hash(def_path_hash, kind)), } } @@ -369,8 +373,8 @@ impl DepNodeExt for DepNode { impl<'tcx> DepNodeParams> for () { #[inline(always)] - fn can_reconstruct_query_key() -> bool { - true + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Unit } fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint { @@ -384,8 +388,8 @@ impl<'tcx> DepNodeParams> for () { impl<'tcx> DepNodeParams> for DefId { #[inline(always)] - fn can_reconstruct_query_key() -> bool { - true + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { @@ -403,8 +407,8 @@ impl<'tcx> DepNodeParams> for DefId { impl<'tcx> DepNodeParams> for LocalDefId { #[inline(always)] - fn can_reconstruct_query_key() -> bool { - true + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { @@ -422,8 +426,8 @@ impl<'tcx> DepNodeParams> for LocalDefId { impl<'tcx> DepNodeParams> for CrateNum { #[inline(always)] - fn can_reconstruct_query_key() -> bool { - true + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::DefPathHash } fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { @@ -442,8 +446,8 @@ impl<'tcx> DepNodeParams> for CrateNum { impl<'tcx> DepNodeParams> for (DefId, DefId) { #[inline(always)] - fn can_reconstruct_query_key() -> bool { - false + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Opaque } // We actually would not need to specialize the implementation of this @@ -467,8 +471,8 @@ impl<'tcx> DepNodeParams> for (DefId, DefId) { impl<'tcx> DepNodeParams> for HirId { #[inline(always)] - fn can_reconstruct_query_key() -> bool { - false + fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Opaque } // We actually would not need to specialize the implementation of this diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 70895f7b98e..cda99639074 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -25,8 +25,8 @@ 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) + fn fingerprint_style(&self) -> rustc_query_system::dep_graph::FingerprintStyle { + DepKind::fingerprint_style(self) } #[inline(always)] diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index b71a1722036..4d1e39db0ed 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -428,6 +428,7 @@ macro_rules! define_queries { use rustc_middle::ty::query::query_keys; use rustc_query_system::dep_graph::DepNodeParams; use rustc_query_system::query::{force_query, QueryDescription}; + use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. pub const Null: QueryStruct = QueryStruct { @@ -454,9 +455,9 @@ macro_rules! define_queries { const is_anon: bool = is_anon!([$($modifiers)*]); #[inline(always)] - fn can_reconstruct_query_key() -> bool { + fn fingerprint_style() -> FingerprintStyle { as DepNodeParams>> - ::can_reconstruct_query_key() + ::fingerprint_style() } fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option> { @@ -472,7 +473,7 @@ macro_rules! define_queries { return } - if !can_reconstruct_query_key() { + if !fingerprint_style().reconstructible() { return } diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index dd500015374..8602219a7f3 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -42,7 +42,7 @@ //! `DefId` it was computed from. In other cases, too much information gets //! lost during fingerprint computation. -use super::{DepContext, DepKind}; +use super::{DepContext, DepKind, FingerprintStyle}; use crate::ich::StableHashingContext; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; @@ -75,7 +75,7 @@ impl DepNode { #[cfg(debug_assertions)] { - if !kind.can_reconstruct_query_key() + if !kind.fingerprint_style().reconstructible() && (tcx.sess().opts.debugging_opts.incremental_info || tcx.sess().opts.debugging_opts.query_dep_graph) { @@ -94,7 +94,7 @@ impl fmt::Debug for DepNode { } pub trait DepNodeParams: fmt::Debug + Sized { - fn can_reconstruct_query_key() -> bool; + fn fingerprint_style() -> FingerprintStyle; /// This method turns the parameters of a DepNodeConstructor into an opaque /// Fingerprint to be used in DepNode. @@ -111,7 +111,7 @@ pub trait DepNodeParams: fmt::Debug + Sized { /// This method tries to recover the query key from the given `DepNode`, /// something which is needed when forcing `DepNode`s during red-green /// evaluation. The query system will only call this method if - /// `can_reconstruct_query_key()` is `true`. + /// `fingerprint_style()` is not `FingerprintStyle::Opaque`. /// It is always valid to return `None` here, in which case incremental /// compilation will treat the query as having changed instead of forcing it. fn recover(tcx: Ctxt, dep_node: &DepNode) -> Option; @@ -122,8 +122,8 @@ where T: for<'a> HashStable> + fmt::Debug, { #[inline] - default fn can_reconstruct_query_key() -> bool { - false + default fn fingerprint_style() -> FingerprintStyle { + FingerprintStyle::Opaque } default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint { diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 2afef210254..dcda5728334 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -50,6 +50,27 @@ impl HasDepContext for T { } } +/// Describes the contents of the fingerprint generated by a given query. +#[derive(PartialEq, Eq, Copy, Clone)] +pub enum FingerprintStyle { + /// The fingerprint is actually a DefPathHash. + DefPathHash, + /// Query key was `()` or equivalent, so fingerprint is just zero. + Unit, + /// Some opaque hash. + Opaque, +} + +impl FingerprintStyle { + #[inline] + pub fn reconstructible(self) -> bool { + match self { + FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true, + FingerprintStyle::Opaque => false, + } + } +} + /// Describe the different families of dependency nodes. pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable + 'static { const NULL: Self; @@ -73,5 +94,5 @@ pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable where OP: for<'a> FnOnce(Option<&'a Lock>>); - fn can_reconstruct_query_key(&self) -> bool; + fn fingerprint_style(&self) -> FingerprintStyle; } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 3534c324295..75184cd6f51 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -540,7 +540,7 @@ where // We always expect to find a cached result for things that // can be forced from `DepNode`. debug_assert!( - !dep_node.kind.can_reconstruct_query_key() || result.is_some(), + !dep_node.kind.fingerprint_style().reconstructible() || result.is_some(), "missing on-disk cache entry for {:?}", dep_node ); @@ -778,7 +778,7 @@ where return false; } - if !>::can_reconstruct_query_key() { + if !>::fingerprint_style().reconstructible() { return false; }