about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2020-02-26 02:20:33 +0100
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2020-03-09 14:50:40 +0100
commitcbce21767b757b209c4d4df6792995fecf02c7fa (patch)
tree9bc05490c45c20b7fd9f5ccfb45294fca070f641 /src
parent67012158a379dbf58318346e87a631e7eb310bd5 (diff)
downloadrust-cbce21767b757b209c4d4df6792995fecf02c7fa.tar.gz
rust-cbce21767b757b209c4d4df6792995fecf02c7fa.zip
Remove the need for `no_force`
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs42
-rw-r--r--src/librustc/dep_graph/mod.rs3
-rw-r--r--src/librustc/query/mod.rs2
-rw-r--r--src/librustc/ty/query/mod.rs105
-rw-r--r--src/librustc/ty/query/plumbing.rs92
-rw-r--r--src/librustc_macros/src/query.rs57
6 files changed, 148 insertions, 153 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 05088dc4193..bcb270ff0a6 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -362,29 +362,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] CompileCodegenUnit(Symbol),
 ]);
 
-pub trait RecoverKey<'tcx>: Sized {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
-}
-
-impl RecoverKey<'tcx> for CrateNum {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        dep_node.extract_def_id(tcx).map(|id| id.krate)
-    }
-}
-
-impl RecoverKey<'tcx> for DefId {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        dep_node.extract_def_id(tcx)
-    }
-}
-
-impl RecoverKey<'tcx> for DefIndex {
-    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
-        dep_node.extract_def_id(tcx).map(|id| id.index)
-    }
-}
-
-trait DepNodeParams<'tcx>: fmt::Debug {
+pub(crate) trait DepNodeParams<'tcx>: fmt::Debug + Sized {
     const CAN_RECONSTRUCT_QUERY_KEY: bool;
 
     /// This method turns the parameters of a DepNodeConstructor into an opaque
@@ -398,6 +376,8 @@ trait DepNodeParams<'tcx>: fmt::Debug {
     fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
         format!("{:?}", self)
     }
+
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
 }
 
 impl<'tcx, T> DepNodeParams<'tcx> for T
@@ -418,6 +398,10 @@ where
     default fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
         format!("{:?}", *self)
     }
+
+    default fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
+        None
+    }
 }
 
 impl<'tcx> DepNodeParams<'tcx> for DefId {
@@ -430,6 +414,10 @@ impl<'tcx> DepNodeParams<'tcx> for DefId {
     fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         tcx.def_path_str(*self)
     }
+
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        dep_node.extract_def_id(tcx)
+    }
 }
 
 impl<'tcx> DepNodeParams<'tcx> for DefIndex {
@@ -442,6 +430,10 @@ impl<'tcx> DepNodeParams<'tcx> for DefIndex {
     fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         tcx.def_path_str(DefId::local(*self))
     }
+
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        dep_node.extract_def_id(tcx).map(|id| id.index)
+    }
 }
 
 impl<'tcx> DepNodeParams<'tcx> for CrateNum {
@@ -455,6 +447,10 @@ impl<'tcx> DepNodeParams<'tcx> for CrateNum {
     fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         tcx.crate_name(*self).to_string()
     }
+
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+        dep_node.extract_def_id(tcx).map(|id| id.krate)
+    }
 }
 
 impl<'tcx> DepNodeParams<'tcx> for (DefId, DefId) {
diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs
index eb377d20f59..1fbd90743f4 100644
--- a/src/librustc/dep_graph/mod.rs
+++ b/src/librustc/dep_graph/mod.rs
@@ -6,7 +6,8 @@ mod query;
 mod safe;
 mod serialized;
 
-pub use self::dep_node::{label_strs, DepConstructor, DepKind, DepNode, RecoverKey, WorkProductId};
+pub(crate) use self::dep_node::DepNodeParams;
+pub use self::dep_node::{label_strs, DepConstructor, DepKind, DepNode, WorkProductId};
 pub use self::graph::WorkProductFileKind;
 pub use self::graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct};
 pub use self::prev::PreviousDepGraph;
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index daf89cab8af..c8155005480 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -1,4 +1,4 @@
-use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex};
+use crate::dep_graph::SerializedDepNodeIndex;
 use crate::mir;
 use crate::mir::interpret::{GlobalId, LitToConstInput};
 use crate::traits;
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index f49c64a7b87..8adb828fbeb 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -1,4 +1,4 @@
-use crate::dep_graph::{self, DepConstructor, DepNode};
+use crate::dep_graph::{self, DepConstructor, DepNode, DepNodeParams};
 use crate::hir::exports::Export;
 use crate::infer::canonical::{self, Canonical};
 use crate::lint::LintLevelMap;
@@ -60,8 +60,8 @@ use std::sync::Arc;
 
 #[macro_use]
 mod plumbing;
+pub use self::plumbing::CycleError;
 use self::plumbing::*;
-pub use self::plumbing::{force_from_dep_node, CycleError};
 
 mod stats;
 pub use self::stats::print_stats;
@@ -105,3 +105,104 @@ pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder
 // as they will raise an fatal error on query cycles instead.
 
 rustc_query_append! { [define_queries!][<'tcx>] }
+
+/// 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_validated` 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`.
+///
+/// When you implement a new query, it will likely have a corresponding new
+/// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As
+/// a rule of thumb, if your query takes a `DefId` or `DefIndex` as sole parameter,
+/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
+/// add it to the "We don't have enough information to reconstruct..." group in
+/// the match below.
+pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool {
+    use crate::dep_graph::DepKind;
+
+    // We must avoid ever having to call `force_from_dep_node()` for a
+    // `DepNode::codegen_unit`:
+    // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
+    // would always end up having to evaluate the first caller of the
+    // `codegen_unit` query that *is* reconstructible. This might very well be
+    // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
+    // to re-trigger calling the `codegen_unit` query with the right key. At
+    // that point we would already have re-done all the work we are trying to
+    // avoid doing in the first place.
+    // The solution is simple: Just explicitly call the `codegen_unit` query for
+    // each CGU, right after partitioning. This way `try_mark_green` will always
+    // hit the cache instead of having to go through `force_from_dep_node`.
+    // This assertion makes sure, we actually keep applying the solution above.
+    debug_assert!(
+        dep_node.kind != DepKind::codegen_unit,
+        "calling force_from_dep_node() on DepKind::codegen_unit"
+    );
+
+    if !dep_node.kind.can_reconstruct_query_key() {
+        return false;
+    }
+
+    rustc_dep_node_force!([dep_node, tcx]
+        // These are inputs that are expected to be pre-allocated and that
+        // should therefore always be red or green already.
+        DepKind::AllLocalTraitImpls |
+        DepKind::CrateMetadata |
+        DepKind::HirBody |
+        DepKind::Hir |
+
+        // These are anonymous nodes.
+        DepKind::TraitSelect |
+
+        // We don't have enough information to reconstruct the query key of
+        // these.
+        DepKind::CompileCodegenUnit => {
+            bug!("force_from_dep_node: encountered {:?}", dep_node)
+        }
+    );
+
+    false
+}
+
+impl DepNode {
+    /// Check whether the query invocation corresponding to the given
+    /// DepNode is eligible for on-disk-caching. If so, this is method
+    /// will execute the query corresponding to the given DepNode.
+    /// Also, as a sanity check, it expects that the corresponding query
+    /// invocation has been marked as green already.
+    pub fn try_load_from_on_disk_cache<'tcx>(&self, tcx: TyCtxt<'tcx>) {
+        use crate::dep_graph::DepKind;
+
+        rustc_dep_node_try_load_from_on_disk_cache!(self, tcx)
+    }
+}
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 1769a925ec3..acf67f52dce 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -2,7 +2,7 @@
 //! generate the actual methods on tcx which find and execute the provider,
 //! manage the caches, and so forth.
 
-use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex};
+use crate::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex};
 use crate::ty::query::caches::QueryCache;
 use crate::ty::query::config::{QueryAccessors, QueryDescription};
 use crate::ty::query::job::{QueryInfo, QueryJob, QueryJobId, QueryShardJobId};
@@ -720,7 +720,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     #[allow(dead_code)]
-    fn force_query<Q: QueryDescription<'tcx> + 'tcx>(
+    pub(super) fn force_query<Q: QueryDescription<'tcx> + 'tcx>(
         self,
         key: Q::Key,
         span: Span,
@@ -1162,91 +1162,3 @@ macro_rules! define_provider_struct {
         }
     };
 }
-
-/// 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_validated` 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`.
-///
-/// When you implement a new query, it will likely have a corresponding new
-/// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As
-/// a rule of thumb, if your query takes a `DefId` or `DefIndex` as sole parameter,
-/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
-/// add it to the "We don't have enough information to reconstruct..." group in
-/// the match below.
-pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
-    use crate::dep_graph::RecoverKey;
-
-    // We must avoid ever having to call `force_from_dep_node()` for a
-    // `DepNode::codegen_unit`:
-    // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
-    // would always end up having to evaluate the first caller of the
-    // `codegen_unit` query that *is* reconstructible. This might very well be
-    // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
-    // to re-trigger calling the `codegen_unit` query with the right key. At
-    // that point we would already have re-done all the work we are trying to
-    // avoid doing in the first place.
-    // The solution is simple: Just explicitly call the `codegen_unit` query for
-    // each CGU, right after partitioning. This way `try_mark_green` will always
-    // hit the cache instead of having to go through `force_from_dep_node`.
-    // This assertion makes sure, we actually keep applying the solution above.
-    debug_assert!(
-        dep_node.kind != DepKind::codegen_unit,
-        "calling force_from_dep_node() on DepKind::codegen_unit"
-    );
-
-    if !dep_node.kind.can_reconstruct_query_key() {
-        return false;
-    }
-
-    rustc_dep_node_force!([dep_node, tcx]
-        // These are inputs that are expected to be pre-allocated and that
-        // should therefore always be red or green already.
-        DepKind::AllLocalTraitImpls |
-        DepKind::CrateMetadata |
-        DepKind::HirBody |
-        DepKind::Hir |
-
-        // These are anonymous nodes.
-        DepKind::TraitSelect |
-
-        // We don't have enough information to reconstruct the query key of
-        // these.
-        DepKind::CompileCodegenUnit => {
-            bug!("force_from_dep_node: encountered {:?}", dep_node)
-        }
-    );
-
-    true
-}
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
index 97b800decc5..c23095968fb 100644
--- a/src/librustc_macros/src/query.rs
+++ b/src/librustc_macros/src/query.rs
@@ -425,7 +425,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
     let mut dep_node_def_stream = quote! {};
     let mut dep_node_force_stream = quote! {};
     let mut try_load_from_on_disk_cache_stream = quote! {};
-    let mut no_force_queries = Vec::new();
     let mut cached_queries = quote! {};
 
     for group in groups.0 {
@@ -444,19 +443,19 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 cached_queries.extend(quote! {
                     #name,
                 });
-            }
 
-            if modifiers.cache.is_some() && !modifiers.no_force {
                 try_load_from_on_disk_cache_stream.extend(quote! {
                     DepKind::#name => {
-                        debug_assert!(tcx.dep_graph
-                                         .node_color(self)
-                                         .map(|c| c.is_green())
-                                         .unwrap_or(false));
-
-                        let key = RecoverKey::recover(tcx, self).unwrap();
-                        if queries::#name::cache_on_disk(tcx, key, None) {
-                            let _ = tcx.#name(key);
+                        if <#arg as DepNodeParams>::CAN_RECONSTRUCT_QUERY_KEY {
+                            debug_assert!($tcx.dep_graph
+                                            .node_color($dep_node)
+                                            .map(|c| c.is_green())
+                                            .unwrap_or(false));
+
+                            let key = <#arg as DepNodeParams>::recover($tcx, $dep_node).unwrap();
+                            if queries::#name::cache_on_disk($tcx, key, None) {
+                                let _ = $tcx.#name(key);
+                            }
                         }
                     }
                 });
@@ -501,24 +500,21 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 [#attribute_stream] #name(#arg),
             });
 
-            if modifiers.no_force {
-                no_force_queries.push(name.clone());
-            } else {
-                // Add a match arm to force the query given the dep node
-                dep_node_force_stream.extend(quote! {
-                    DepKind::#name => {
-                        if let Some(key) = RecoverKey::recover($tcx, $dep_node) {
+            // Add a match arm to force the query given the dep node
+            dep_node_force_stream.extend(quote! {
+                DepKind::#name => {
+                    if <#arg as DepNodeParams>::CAN_RECONSTRUCT_QUERY_KEY {
+                        if let Some(key) = <#arg as DepNodeParams>::recover($tcx, $dep_node) {
                             $tcx.force_query::<crate::ty::query::queries::#name<'_>>(
                                 key,
                                 DUMMY_SP,
                                 *$dep_node
                             );
-                        } else {
-                            return false;
+                            return true;
                         }
                     }
-                });
-            }
+                }
+            });
 
             add_query_description_impl(&query, modifiers, &mut query_description_stream);
         }
@@ -528,12 +524,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
         });
     }
 
-    // Add an arm for the no force queries to panic when trying to force them
-    for query in no_force_queries {
-        dep_node_force_stream.extend(quote! {
-            DepKind::#query |
-        });
-    }
     dep_node_force_stream.extend(quote! {
         DepKind::Null => {
             bug!("Cannot force dep node: {:?}", $dep_node)
@@ -577,14 +567,9 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
 
         #query_description_stream
 
-        impl DepNode {
-            /// Check whether the query invocation corresponding to the given
-            /// DepNode is eligible for on-disk-caching. If so, this is method
-            /// will execute the query corresponding to the given DepNode.
-            /// Also, as a sanity check, it expects that the corresponding query
-            /// invocation has been marked as green already.
-            pub fn try_load_from_on_disk_cache(&self, tcx: TyCtxt<'_>) {
-                match self.kind {
+        macro_rules! rustc_dep_node_try_load_from_on_disk_cache {
+            ($dep_node:expr, $tcx:expr) => {
+                match $dep_node.kind {
                     #try_load_from_on_disk_cache_stream
                     _ => (),
                 }