diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 82b0e50b50c48..3d5e7dd0af121 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -142,9 +142,6 @@ macro_rules! define_dep_nodes { } } - // FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties - // of queries - #[inline(always)] pub fn is_anon(&self) -> bool { match *self { $( @@ -163,7 +160,6 @@ macro_rules! define_dep_nodes { } #[allow(unreachable_code)] - #[inline(always)] pub fn has_params(&self) -> bool { match *self { $( diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 13d93f173e845..6ad4ecb3e980c 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -1,5 +1,5 @@ use crate::dep_graph::SerializedDepNodeIndex; -use crate::dep_graph::DepNode; +use crate::dep_graph::{DepKind, DepNode}; use crate::hir::def_id::{CrateNum, DefId}; use crate::ty::TyCtxt; use crate::ty::query::queries; @@ -28,6 +28,9 @@ pub trait QueryConfig<'tcx> { } pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { + const ANON: bool; + const EVAL_ALWAYS: bool; + fn query(key: Self::Key) -> Query<'tcx>; // Don't use this method to access query results, instead use the methods on TyCtxt @@ -35,6 +38,8 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode; + fn dep_kind() -> DepKind; + // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index e595b52876f4c..e788628bc58e2 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -101,6 +101,6 @@ pub use self::on_disk_cache::OnDiskCache; rustc_query_append! { [define_queries!][ <'tcx> Other { /// Runs analysis passes on the crate. - [] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>, + [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>, }, ]} diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 7d5f984c1b6f2..553c701c3aaa0 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -376,15 +376,13 @@ impl<'tcx> TyCtxt<'tcx> { return self.force_query_with_job::(key, job, null_dep_node).0; } - let dep_node = Q::to_dep_node(self, &key); - - if dep_node.kind.is_anon() { + if Q::ANON { profq_msg!(self, ProfileQueriesMsg::ProviderBegin); self.sess.profiler(|p| p.start_query(Q::NAME)); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { - tcx.dep_graph.with_anon_task(dep_node.kind, || { + tcx.dep_graph.with_anon_task(Q::dep_kind(), || { Q::compute(tcx.global_tcx(), key) }) }) @@ -405,7 +403,9 @@ impl<'tcx> TyCtxt<'tcx> { return result; } - if !dep_node.kind.is_eval_always() { + let dep_node = Q::to_dep_node(self, &key); + + if !Q::EVAL_ALWAYS { // The diagnostics for this query will be // promoted to the current session during // try_mark_green(), so we can ignore them here. @@ -546,7 +546,7 @@ impl<'tcx> TyCtxt<'tcx> { let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { - if dep_node.kind.is_eval_always() { + if Q::EVAL_ALWAYS { tcx.dep_graph.with_eval_always_task(dep_node, tcx, key, @@ -569,8 +569,8 @@ impl<'tcx> TyCtxt<'tcx> { self.dep_graph.mark_loaded_from_cache(dep_node_index, false); } - if dep_node.kind != crate::dep_graph::DepKind::Null { - if unlikely!(!diagnostics.is_empty()) { + if unlikely!(!diagnostics.is_empty()) { + if dep_node.kind != crate::dep_graph::DepKind::Null { self.queries.on_disk_cache .store_diagnostics(dep_node_index, diagnostics); } @@ -589,15 +589,16 @@ impl<'tcx> TyCtxt<'tcx> { /// /// Note: The optimization is only available during incr. comp. pub(super) fn ensure_query>(self, key: Q::Key) -> () { - let dep_node = Q::to_dep_node(self, &key); - - if dep_node.kind.is_eval_always() { + if Q::EVAL_ALWAYS { let _ = self.get_query::(DUMMY_SP, key); return; } // Ensuring an anonymous query makes no sense - assert!(!dep_node.kind.is_anon()); + assert!(!Q::ANON); + + let dep_node = Q::to_dep_node(self, &key); + if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() { // A None return from `try_mark_green_and_read` means that this is either // a new dep node or that the dep node has already been marked red. @@ -653,6 +654,30 @@ macro_rules! handle_cycle_error { }; } +macro_rules! is_anon { + ([]) => {{ + false + }}; + ([anon$(, $modifiers:ident)*]) => {{ + true + }}; + ([$other:ident$(, $modifiers:ident)*]) => { + is_anon!([$($modifiers),*]) + }; +} + +macro_rules! is_eval_always { + ([]) => {{ + false + }}; + ([eval_always$(, $modifiers:ident)*]) => {{ + true + }}; + ([$other:ident$(, $modifiers:ident)*]) => { + is_eval_always!([$($modifiers),*]) + }; +} + macro_rules! hash_result { ([][$hcx:expr, $result:expr]) => {{ dep_graph::hash_result($hcx, &$result) @@ -933,6 +958,9 @@ macro_rules! define_queries_inner { } impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> { + const ANON: bool = is_anon!([$($modifiers)*]); + const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]); + #[inline(always)] fn query(key: Self::Key) -> Query<'tcx> { Query::$name(key) @@ -951,6 +979,11 @@ macro_rules! define_queries_inner { DepNode::new(tcx, $node(*key)) } + #[inline(always)] + fn dep_kind() -> dep_graph::DepKind { + dep_graph::DepKind::$node + } + #[inline] fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { __query_compute::$name(move || { diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 0474d2a2e3b3a..2cf364b562766 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -423,20 +423,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { if modifiers.no_hash { attributes.push(quote! { no_hash }); }; - - let mut attribute_stream = quote! {}; - - for e in attributes.into_iter().intersperse(quote! {,}) { - attribute_stream.extend(e); - } - - // Add the query to the group - group_stream.extend(quote! { - [#attribute_stream] fn #name: #name(#arg) #result, - }); - - let mut attributes = Vec::new(); - // Pass on the anon modifier if modifiers.anon { attributes.push(quote! { anon }); @@ -450,6 +436,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { for e in attributes.into_iter().intersperse(quote! {,}) { attribute_stream.extend(e); } + + // Add the query to the group + group_stream.extend(quote! { + [#attribute_stream] fn #name: #name(#arg) #result, + }); + // Create a dep node for the query dep_node_def_stream.extend(quote! { [#attribute_stream] #name(#arg),