]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_middle/src/dep_graph/dep_node.rs
Auto merge of #105893 - Ayush1325:remote-test-server-improve, r=Mark-Simulacrum
[rust.git] / compiler / rustc_middle / src / dep_graph / dep_node.rs
index eded3b3eedc6c49a1869950ebc1048a1824edf83..865bb70afb506172c5976fc73f8e504246a9b210 100644 (file)
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_hir::definitions::DefPathHash;
-use rustc_hir::{HirId, ItemLocalId};
+use rustc_hir::{HirId, ItemLocalId, OwnerId};
 use rustc_query_system::dep_graph::FingerprintStyle;
 use rustc_span::symbol::Symbol;
 use std::hash::Hash;
 
 pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
 
-/// This struct stores metadata about each DepKind.
-///
-/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value
-/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual
-/// jump table instead of large matches.
-pub struct DepKindStruct<'tcx> {
-    /// Anonymous queries cannot be replayed from one compiler invocation to the next.
-    /// When their result is needed, it is recomputed. They are useful for fine-grained
-    /// dependency tracking, and caching within one compiler invocation.
-    pub is_anon: bool,
-
-    /// Eval-always queries do not track their dependencies, and are always recomputed, even if
-    /// their inputs have not changed since the last compiler invocation. The result is still
-    /// cached within one compiler invocation.
-    pub 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.
-    pub fingerprint_style: FingerprintStyle,
-
-    /// The red/green evaluation system will try to mark a specific DepNode in the
-    /// dependency graph as green by recursively trying to mark the dependencies of
-    /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode`
-    /// where we don't know if it is red or green and we therefore actually have
-    /// to recompute its value in order to find out. Since the only piece of
-    /// information that we have at that point is the `DepNode` we are trying to
-    /// re-evaluate, we need some way to re-run a query from just that. This is what
-    /// `force_from_dep_node()` implements.
-    ///
-    /// In the general case, a `DepNode` consists of a `DepKind` and an opaque
-    /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
-    /// is usually constructed by computing a stable hash of the query-key that the
-    /// `DepNode` corresponds to. Consequently, it is not in general possible to go
-    /// back from hash to query-key (since hash functions are not reversible). For
-    /// this reason `force_from_dep_node()` is expected to fail from time to time
-    /// because we just cannot find out, from the `DepNode` alone, what the
-    /// corresponding query-key is and therefore cannot re-run the query.
-    ///
-    /// The system deals with this case letting `try_mark_green` fail which forces
-    /// the root query to be re-evaluated.
-    ///
-    /// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
-    /// Fortunately, we can use some contextual information that will allow us to
-    /// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
-    /// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
-    /// valid `DefPathHash`. Since we also always build a huge table that maps every
-    /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
-    /// everything we need to re-run the query.
-    ///
-    /// Take the `mir_promoted` query as an example. Like many other queries, it
-    /// just has a single parameter: the `DefId` of the item it will compute the
-    /// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
-    /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
-    /// is actually a `DefPathHash`, and can therefore just look up the corresponding
-    /// `DefId` in `tcx.def_path_hash_to_def_id`.
-    pub force_from_dep_node: Option<fn(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool>,
-
-    /// Invoke a query to put the on-disk cached value in memory.
-    pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'tcx>, DepNode)>,
-}
-
-impl DepKind {
-    #[inline(always)]
-    pub fn fingerprint_style(self, tcx: TyCtxt<'_>) -> FingerprintStyle {
-        // Only fetch the DepKindStruct once.
-        let data = tcx.query_kind(self);
-        if data.is_anon {
-            return FingerprintStyle::Opaque;
-        }
-        data.fingerprint_style
-    }
-}
-
 macro_rules! define_dep_nodes {
     (
      $($(#[$attr:meta])*
@@ -159,7 +86,7 @@ pub enum DepKind {
             $( $( #[$attr] )* $variant),*
         }
 
-        fn dep_kind_from_label_string(label: &str) -> Result<DepKind, ()> {
+        pub(super) fn dep_kind_from_label_string(label: &str) -> Result<DepKind, ()> {
             match label {
                 $(stringify!($variant) => Ok(DepKind::$variant),)*
                 _ => Err(()),
@@ -214,11 +141,6 @@ pub(crate) fn make_compile_mono_item<'tcx>(
 static_assert_size!(DepNode, 24);
 
 pub trait DepNodeExt: Sized {
-    /// Construct a DepNode from the given DepKind and DefPathHash. This
-    /// method will assert that the given DepKind actually requires a
-    /// single DefId/DefPathHash parameter.
-    fn from_def_path_hash(tcx: TyCtxt<'_>, def_path_hash: DefPathHash, kind: DepKind) -> Self;
-
     /// Extracts the DefId corresponding to this DepNode. This will work
     /// if two conditions are met:
     ///
@@ -243,14 +165,6 @@ fn from_label_string(
 }
 
 impl DepNodeExt for DepNode {
-    /// Construct a DepNode from the given DepKind and DefPathHash. This
-    /// method will assert that the given DepKind actually requires a
-    /// single DefId/DefPathHash parameter.
-    fn from_def_path_hash(tcx: TyCtxt<'_>, def_path_hash: DefPathHash, kind: DepKind) -> DepNode {
-        debug_assert!(kind.fingerprint_style(tcx) == FingerprintStyle::DefPathHash);
-        DepNode { kind, hash: def_path_hash.0.into() }
-    }
-
     /// Extracts the DefId corresponding to this DepNode. This will work
     /// if two conditions are met:
     ///
@@ -261,8 +175,8 @@ fn from_def_path_hash(tcx: TyCtxt<'_>, def_path_hash: DefPathHash, kind: DepKind
     /// DepNode. Condition (2) might not be fulfilled if a DepNode
     /// refers to something from the previous compilation session that
     /// has been removed.
-    fn extract_def_id<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<DefId> {
-        if self.kind.fingerprint_style(tcx) == FingerprintStyle::DefPathHash {
+    fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
+        if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
             Some(tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()), &mut || {
                 panic!("Failed to extract DefId: {:?} {}", self.kind, self.hash)
             }))
@@ -279,7 +193,7 @@ fn from_label_string(
     ) -> Result<DepNode, ()> {
         let kind = dep_kind_from_label_string(label)?;
 
-        match kind.fingerprint_style(tcx) {
+        match tcx.fingerprint_style(kind) {
             FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()),
             FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)),
             FingerprintStyle::DefPathHash => {
@@ -355,6 +269,28 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
     }
 }
 
+impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for OwnerId {
+    #[inline(always)]
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::DefPathHash
+    }
+
+    #[inline(always)]
+    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+        self.to_def_id().to_fingerprint(tcx)
+    }
+
+    #[inline(always)]
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+        self.to_def_id().to_debug_str(tcx)
+    }
+
+    #[inline(always)]
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
+    }
+}
+
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum {
     #[inline(always)]
     fn fingerprint_style() -> FingerprintStyle {
@@ -433,10 +369,10 @@ fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
 
     #[inline(always)]
     fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        if dep_node.kind.fingerprint_style(tcx) == FingerprintStyle::HirId {
+        if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
             let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value();
             let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash);
-            let owner = tcx
+            let def_id = tcx
                 .def_path_hash_to_def_id(def_path_hash, &mut || {
                     panic!("Failed to extract HirId: {:?} {}", dep_node.kind, dep_node.hash)
                 })
@@ -444,7 +380,7 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
             let local_id = local_id
                 .try_into()
                 .unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id));
-            Some(HirId { owner, local_id: ItemLocalId::from_u32(local_id) })
+            Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
         } else {
             None
         }