From 67012158a379dbf58318346e87a631e7eb310bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 26 Feb 2020 00:26:38 +0100 Subject: [PATCH 1/4] Move `analysis` to the query macro --- src/librustc/dep_graph/dep_node.rs | 2 -- src/librustc/query/mod.rs | 5 +++++ src/librustc/ty/query/config.rs | 9 +-------- src/librustc/ty/query/mod.rs | 7 +------ src/librustc/ty/query/plumbing.rs | 14 -------------- 5 files changed, 7 insertions(+), 30 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index eb7e2871bfcd8..05088dc419339 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -360,8 +360,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [anon] TraitSelect, [] CompileCodegenUnit(Symbol), - - [eval_always] Analysis(CrateNum), ]); pub trait RecoverKey<'tcx>: Sized { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index b7f4f432838be..daf89cab8af6d 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -60,6 +60,11 @@ rustc_queries! { cache_on_disk_if { key.is_local() } } + query analysis(key: CrateNum) -> Result<(), ErrorReported> { + eval_always + desc { "running analysis passes on this crate" } + } + /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its /// associated generics. query generics_of(key: DefId) -> &'tcx ty::Generics { diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index e0e1ca374d9ae..178c2362def6e 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -2,11 +2,10 @@ use crate::dep_graph::SerializedDepNodeIndex; use crate::dep_graph::{DepKind, DepNode}; use crate::ty::query::caches::QueryCache; use crate::ty::query::plumbing::CycleError; -use crate::ty::query::queries; use crate::ty::query::{Query, QueryState}; use crate::ty::TyCtxt; use rustc_data_structures::profiling::ProfileCategory; -use rustc_hir::def_id::{CrateNum, DefId}; +use rustc_hir::def_id::DefId; use crate::ich::StableHashingContext; use rustc_data_structures::fingerprint::Fingerprint; @@ -87,9 +86,3 @@ where bug!("QueryDescription::load_from_disk() called for an unsupported query.") } } - -impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> { - fn describe(_tcx: TyCtxt<'_>, _: CrateNum) -> Cow<'static, str> { - "running analysis passes on this crate".into() - } -} diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 8614fd5cdca9a..f49c64a7b87a7 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -104,9 +104,4 @@ pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. -rustc_query_append! { [define_queries!][ <'tcx> - Other { - /// Runs analysis passes on the crate. - [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>, - }, -]} +rustc_query_append! { [define_queries!][<'tcx>] } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c94909549df22..1769a925ec301 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1246,20 +1246,6 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { DepKind::CompileCodegenUnit => { bug!("force_from_dep_node: encountered {:?}", dep_node) } - - DepKind::Analysis => { - let def_id = if let Some(def_id) = dep_node.extract_def_id(tcx) { - def_id - } else { - // Return from the whole function. - return false - }; - tcx.force_query::>( - def_id.krate, - DUMMY_SP, - *dep_node - ); - } ); true From cbce21767b757b209c4d4df6792995fecf02c7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 26 Feb 2020 02:20:33 +0100 Subject: [PATCH 2/4] Remove the need for `no_force` --- src/librustc/dep_graph/dep_node.rs | 42 ++++++------ src/librustc/dep_graph/mod.rs | 3 +- src/librustc/query/mod.rs | 2 +- src/librustc/ty/query/mod.rs | 105 ++++++++++++++++++++++++++++- src/librustc/ty/query/plumbing.rs | 92 +------------------------ src/librustc_macros/src/query.rs | 57 ++++++---------- 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 05088dc419339..bcb270ff0a64e 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; -} - -impl RecoverKey<'tcx> for CrateNum { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx).map(|id| id.krate) - } -} - -impl RecoverKey<'tcx> for DefId { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - dep_node.extract_def_id(tcx) - } -} - -impl RecoverKey<'tcx> for DefIndex { - fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option { - 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; } 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 { + 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 { + 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 { + 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 { + 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 eb377d20f5963..1fbd90743f402 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 daf89cab8af6d..c8155005480ff 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 f49c64a7b87a7..8adb828fbebc4 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 1769a925ec301..acf67f52dceaa 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 + 'tcx>( + pub(super) fn force_query + '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 97b800decc59b..c23095968fb3e 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::>( 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 _ => (), } From f4450772ede7bc064d1727430acdb1b2dc851742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 26 Feb 2020 02:39:18 +0100 Subject: [PATCH 3/4] Remove the `no_force` query attribute --- src/librustc/query/mod.rs | 38 -------------------------------- src/librustc_macros/src/query.rs | 16 -------------- 2 files changed, 54 deletions(-) diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index c8155005480ff..11e9acf3a3912 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -200,7 +200,6 @@ rustc_queries! { // queries). Making it anonymous avoids hashing the result, which // may save a bit of time. anon - no_force desc { "erasing regions from `{:?}`", ty } } @@ -209,7 +208,6 @@ rustc_queries! { } query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> { - no_force desc { "generating chalk-style clauses for environment" } } @@ -252,7 +250,6 @@ rustc_queries! { /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates(key: (DefId, DefId)) -> ty::GenericPredicates<'tcx> { - no_force desc { |tcx| "computing the bounds for type parameter `{}`", { let id = tcx.hir().as_local_hir_id(key.1).unwrap(); tcx.hir().ty_param_name(id) @@ -508,7 +505,6 @@ rustc_queries! { /// form to be used outside of const eval. query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalRawResult<'tcx> { - no_force desc { |tcx| "const-evaluating `{}`", tcx.def_path_str(key.value.instance.def.def_id()) @@ -525,7 +521,6 @@ rustc_queries! { /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalResult<'tcx> { - no_force desc { |tcx| "const-evaluating + checking `{}`", tcx.def_path_str(key.value.instance.def.def_id()) @@ -540,7 +535,6 @@ rustc_queries! { query const_field( key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)> ) -> ConstValue<'tcx> { - no_force desc { "extract field of const" } } @@ -549,19 +543,16 @@ rustc_queries! { query destructure_const( key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>> ) -> mir::DestructuredConst<'tcx> { - no_force desc { "destructure constant" } } query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { - no_force desc { "get a &core::panic::Location referring to a span" } } query lit_to_const( key: LitToConstInput<'tcx> ) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { - no_force desc { "converting literal to const" } } } @@ -592,7 +583,6 @@ rustc_queries! { query region_scope_tree(_: DefId) -> &'tcx region::ScopeTree {} query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::BodyAndCache<'tcx> { - no_force desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) } } @@ -600,7 +590,6 @@ rustc_queries! { /// given instance from the local crate. In particular, it will also /// look up the correct symbol name of instances from upstream crates. query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName { - no_force desc { "computing the symbol for `{}`", key } cache_on_disk_if { true } } @@ -647,7 +636,6 @@ rustc_queries! { Other { query vtable_methods(key: ty::PolyTraitRef<'tcx>) -> &'tcx [Option<(DefId, SubstsRef<'tcx>)>] { - no_force desc { |tcx| "finding all methods for trait {}", tcx.def_path_str(key.def_id()) } } } @@ -656,7 +644,6 @@ rustc_queries! { query codegen_fulfill_obligation( key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) ) -> Option> { - no_force cache_on_disk_if { true } desc { |tcx| "checking if `{}` fulfills its obligations", @@ -688,22 +675,18 @@ rustc_queries! { /// Trait selection queries. These are best used by invoking `ty.is_copy_modulo_regions()`, /// `ty.is_copy()`, etc, since that will prune the environment where possible. query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` is `Copy`", env.value } } /// Query backing `TyS::is_sized`. query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` is `Sized`", env.value } } /// Query backing `TyS::is_freeze`. query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` is freeze", env.value } } /// Query backing `TyS::needs_drop`. query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - no_force desc { "computing whether `{}` needs drop", env.value } } @@ -717,7 +700,6 @@ rustc_queries! { query layout_raw( env: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Result<&'tcx ty::layout::LayoutDetails, ty::layout::LayoutError<'tcx>> { - no_force desc { "computing layout of `{}`", env.value } } } @@ -773,7 +755,6 @@ rustc_queries! { TypeChecking { query specializes(_: (DefId, DefId)) -> bool { - no_force desc { "computing whether impls specialize one another" } } query in_scope_traits_map(_: DefIndex) @@ -858,7 +839,6 @@ rustc_queries! { /// (like `Clone::clone` for example). query upstream_drop_glue_for(substs: SubstsRef<'tcx>) -> Option { desc { "available upstream drop-glue for `{:?}`", substs } - no_force } } @@ -903,7 +883,6 @@ rustc_queries! { TypeChecking { query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [DefId] { - no_force desc { "looking up implementations of a trait in a crate" } } query all_trait_implementations(_: CrateNum) @@ -1070,7 +1049,6 @@ rustc_queries! { } query is_codegened_item(_: DefId) -> bool {} query codegen_unit(_: Symbol) -> Arc> { - no_force desc { "codegen_unit" } } query backend_optimization_level(_: CrateNum) -> OptLevel { @@ -1093,7 +1071,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1101,7 +1078,6 @@ rustc_queries! { query normalize_ty_after_erasing_regions( goal: ParamEnvAnd<'tcx, Ty<'tcx>> ) -> Ty<'tcx> { - no_force desc { "normalizing `{:?}`", goal } } @@ -1111,7 +1087,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec>>>, NoSolution, > { - no_force desc { "computing implied outlives bounds for `{:?}`", goal } } @@ -1122,7 +1097,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution, > { - no_force desc { "computing dropck types for `{:?}`", goal } } @@ -1131,7 +1105,6 @@ rustc_queries! { query evaluate_obligation( goal: CanonicalPredicateGoal<'tcx> ) -> Result { - no_force desc { "evaluating trait selection obligation `{}`", goal.value.value } } @@ -1142,7 +1115,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal } } @@ -1153,7 +1125,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_eq` `{:?}`", goal } } @@ -1164,7 +1135,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_subtype` `{:?}`", goal } } @@ -1175,7 +1145,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, NoSolution, > { - no_force desc { "evaluating `type_op_prove_predicate` `{:?}`", goal } } @@ -1186,7 +1155,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1197,7 +1165,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1208,7 +1175,6 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } @@ -1219,12 +1185,10 @@ rustc_queries! { &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>, NoSolution, > { - no_force desc { "normalizing `{:?}`", goal } } query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { - no_force desc { |tcx| "testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0) @@ -1234,7 +1198,6 @@ rustc_queries! { query method_autoderef_steps( goal: CanonicalTyGoal<'tcx> ) -> MethodAutoderefStepsResult<'tcx> { - no_force desc { "computing autoderef types for `{:?}`", goal } } } @@ -1248,7 +1211,6 @@ rustc_queries! { // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning. query instance_def_size_estimate(def: ty::InstanceDef<'tcx>) -> usize { - no_force desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) } } diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index c23095968fb3e..56b7be2f7e2d5 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -51,9 +51,6 @@ enum QueryModifier { /// Don't hash the result, instead just mark a query red if it runs NoHash, - /// Don't force the query - NoForce, - /// Generate a dep node based on the dependencies of the query Anon, @@ -118,8 +115,6 @@ impl Parse for QueryModifier { Ok(QueryModifier::CycleDelayBug) } else if modifier == "no_hash" { Ok(QueryModifier::NoHash) - } else if modifier == "no_force" { - Ok(QueryModifier::NoForce) } else if modifier == "anon" { Ok(QueryModifier::Anon) } else if modifier == "eval_always" { @@ -222,9 +217,6 @@ struct QueryModifiers { /// Don't hash the result, instead just mark a query red if it runs no_hash: bool, - /// Don't force the query - no_force: bool, - /// Generate a dep node based on the dependencies of the query anon: bool, @@ -241,7 +233,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut fatal_cycle = false; let mut cycle_delay_bug = false; let mut no_hash = false; - let mut no_force = false; let mut anon = false; let mut eval_always = false; for modifier in query.modifiers.0.drain(..) { @@ -288,12 +279,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } no_hash = true; } - QueryModifier::NoForce => { - if no_force { - panic!("duplicate modifier `no_force` for query `{}`", query.name); - } - no_force = true; - } QueryModifier::Anon => { if anon { panic!("duplicate modifier `anon` for query `{}`", query.name); @@ -316,7 +301,6 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { fatal_cycle, cycle_delay_bug, no_hash, - no_force, anon, eval_always, } From 2f120095b59320d8c0adc3ad8f9294560bdf5c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 9 Mar 2020 14:50:09 +0100 Subject: [PATCH 4/4] Add a comment to `recover`. --- src/librustc/dep_graph/dep_node.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index bcb270ff0a64e..156f412e0902e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -377,6 +377,12 @@ pub(crate) trait DepNodeParams<'tcx>: fmt::Debug + Sized { format!("{:?}", self) } + /// 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`. + /// 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: TyCtxt<'tcx>, dep_node: &DepNode) -> Option; }