about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-06-29 11:18:11 +0200
committerGitHub <noreply@github.com>2019-06-29 11:18:11 +0200
commit94a066e229e2f6f4efbde1ae3caa067b0aaa69a2 (patch)
tree7b2f3d69bb1e3aa27b562a1f44c35dce71ea8e5e
parenta4cf85e958f2a14c501821afba0754b5feba45df (diff)
parent11221d120f8f79ff8e6ad35256874f30a942908b (diff)
downloadrust-94a066e229e2f6f4efbde1ae3caa067b0aaa69a2.tar.gz
rust-94a066e229e2f6f4efbde1ae3caa067b0aaa69a2.zip
Rollup merge of #62104 - Zoxc:query-info, r=eddyb
Inform the query system about properties of queries at compile time
-rw-r--r--src/librustc/dep_graph/dep_node.rs4
-rw-r--r--src/librustc/ty/query/config.rs7
-rw-r--r--src/librustc/ty/query/mod.rs2
-rw-r--r--src/librustc/ty/query/plumbing.rs57
-rw-r--r--src/librustc_macros/src/query.rs20
-rw-r--r--src/libsyntax_pos/symbol.rs3
6 files changed, 61 insertions, 32 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 82b0e50b50c..3d5e7dd0af1 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 13d93f173e8..6ad4ecb3e98 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 e595b52876f..e788628bc58 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 7d5f984c1b6..553c701c3aa 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::<Q>(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<Q: QueryDescription<'tcx>>(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::<Q>(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 0474d2a2e3b..2cf364b5627 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),
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index bd9a9061b99..266bd2a04a2 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1132,6 +1132,7 @@ impl LocalInternedString {
         }
     }
 
+    #[inline]
     pub fn get(&self) -> &str {
         // This returns a valid string since we ensure that `self` outlives the interner
         // by creating the interner on a thread which outlives threads which can access it.
@@ -1145,6 +1146,7 @@ impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
 where
     str: std::convert::AsRef<U>
 {
+    #[inline]
     fn as_ref(&self) -> &U {
         self.string.as_ref()
     }
@@ -1185,6 +1187,7 @@ impl !Sync for LocalInternedString {}
 
 impl std::ops::Deref for LocalInternedString {
     type Target = str;
+    #[inline]
     fn deref(&self) -> &str { self.string }
 }