]> git.lizzy.rs Git - rust.git/commitdiff
Add a `storage` query modifier to override the query cache
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Fri, 14 Feb 2020 17:29:20 +0000 (18:29 +0100)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Wed, 19 Feb 2020 15:03:19 +0000 (16:03 +0100)
src/librustc/dep_graph/dep_node.rs
src/librustc/ty/query/plumbing.rs
src/librustc_macros/src/query.rs

index 29b94986a5f3a00b6effa877341231b78011b645..963f45b3f17e935ea2922f123b5698f457b5f776 100644 (file)
@@ -99,17 +99,17 @@ macro_rules! is_eval_always_attr {
 }
 
 macro_rules! contains_anon_attr {
-    ($($attr:ident),*) => ({$(is_anon_attr!($attr) | )* false});
+    ($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_anon_attr!($attr) | )* false});
 }
 
 macro_rules! contains_eval_always_attr {
-    ($($attr:ident),*) => ({$(is_eval_always_attr!($attr) | )* false});
+    ($($attr:ident $(($($attr_args:tt)*))* ),*) => ({$(is_eval_always_attr!($attr) | )* false});
 }
 
 macro_rules! define_dep_nodes {
     (<$tcx:tt>
     $(
-        [$($attr:ident),* ]
+        [$($attrs:tt)*]
         $variant:ident $(( $tuple_arg_ty:ty $(,)? ))*
                        $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
       ,)*
@@ -126,7 +126,7 @@ pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
                 match *self {
                     $(
                         DepKind :: $variant => {
-                            if contains_anon_attr!($($attr),*) {
+                            if contains_anon_attr!($($attrs)*) {
                                 return false;
                             }
 
@@ -152,7 +152,7 @@ pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
             pub fn is_anon(&self) -> bool {
                 match *self {
                     $(
-                        DepKind :: $variant => { contains_anon_attr!($($attr),*) }
+                        DepKind :: $variant => { contains_anon_attr!($($attrs)*) }
                     )*
                 }
             }
@@ -160,7 +160,7 @@ pub fn is_anon(&self) -> bool {
             pub fn is_eval_always(&self) -> bool {
                 match *self {
                     $(
-                        DepKind :: $variant => { contains_eval_always_attr!($($attr), *) }
+                        DepKind :: $variant => { contains_eval_always_attr!($($attrs)*) }
                     )*
                 }
             }
index 3eaf4e36f3930975bf230982887122621bcb6229..13132739f89a3de127ffd113dda459296683af9e 100644 (file)
@@ -746,17 +746,17 @@ macro_rules! handle_cycle_error {
         $tcx.report_cycle($error).emit();
         Value::from_cycle_error($tcx)
     }};
-    ([fatal_cycle$(, $modifiers:ident)*][$tcx:expr, $error:expr]) => {{
+    ([fatal_cycle $($rest:tt)*][$tcx:expr, $error:expr]) => {{
         $tcx.report_cycle($error).emit();
         $tcx.sess.abort_if_errors();
         unreachable!()
     }};
-    ([cycle_delay_bug$(, $modifiers:ident)*][$tcx:expr, $error:expr]) => {{
+    ([cycle_delay_bug $($rest:tt)*][$tcx:expr, $error:expr]) => {{
         $tcx.report_cycle($error).delay_as_bug();
         Value::from_cycle_error($tcx)
     }};
-    ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
-        handle_cycle_error!([$($modifiers),*][$($args)*])
+    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
+        handle_cycle_error!([$($($modifiers)*)*][$($args)*])
     };
 }
 
@@ -764,11 +764,11 @@ macro_rules! is_anon {
     ([]) => {{
         false
     }};
-    ([anon$(, $modifiers:ident)*]) => {{
+    ([anon $($rest:tt)*]) => {{
         true
     }};
-    ([$other:ident$(, $modifiers:ident)*]) => {
-        is_anon!([$($modifiers),*])
+    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => {
+        is_anon!([$($($modifiers)*)*])
     };
 }
 
@@ -776,11 +776,23 @@ macro_rules! is_eval_always {
     ([]) => {{
         false
     }};
-    ([eval_always$(, $modifiers:ident)*]) => {{
+    ([eval_always $($rest:tt)*]) => {{
         true
     }};
-    ([$other:ident$(, $modifiers:ident)*]) => {
-        is_eval_always!([$($modifiers),*])
+    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => {
+        is_eval_always!([$($($modifiers)*)*])
+    };
+}
+
+macro_rules! query_storage {
+    ([][$K:ty, $V:ty]) => {
+        <<$K as Key>::CacheSelector as CacheSelector<$K, $V>>::Cache
+    };
+    ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
+        $ty
+    };
+    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
+        query_storage!([$($($modifiers)*)*][$($args)*])
     };
 }
 
@@ -788,11 +800,11 @@ macro_rules! hash_result {
     ([][$hcx:expr, $result:expr]) => {{
         dep_graph::hash_result($hcx, &$result)
     }};
-    ([no_hash$(, $modifiers:ident)*][$hcx:expr, $result:expr]) => {{
+    ([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{
         None
     }};
-    ([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
-        hash_result!([$($modifiers),*][$($args)*])
+    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
+        hash_result!([$($($modifiers)*)*][$($args)*])
     };
 }
 
@@ -1049,7 +1061,7 @@ impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
             const ANON: bool = is_anon!([$($modifiers)*]);
             const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
 
-            type Cache = <<$K as Key>::CacheSelector as CacheSelector<$K, $V>>::Cache;
+            type Cache = query_storage!([$($modifiers)*][$K, $V]);
 
             #[inline(always)]
             fn query(key: Self::Key) -> Query<'tcx> {
index 294cdb7643fc93ce10fce622efbbb64a5e72e311..6362f3c2c49f03929543ff72f9b204768ae75fcf 100644 (file)
@@ -33,6 +33,9 @@ enum QueryModifier {
     /// The description of the query.
     Desc(Option<Ident>, Punctuated<Expr, Token![,]>),
 
+    /// Use this type for the in-memory cache.
+    Storage(Type),
+
     /// Cache the query to disk if the `Expr` returns true.
     Cache(Option<(IdentOrWild, IdentOrWild)>, Block),
 
@@ -106,6 +109,9 @@ fn parse(input: ParseStream<'_>) -> Result<Self> {
             let id = args.parse()?;
             let block = input.parse()?;
             Ok(QueryModifier::LoadCached(tcx, id, block))
+        } else if modifier == "storage" {
+            let ty = input.parse()?;
+            Ok(QueryModifier::Storage(ty))
         } else if modifier == "fatal_cycle" {
             Ok(QueryModifier::FatalCycle)
         } else if modifier == "cycle_delay_bug" {
@@ -198,6 +204,9 @@ struct QueryModifiers {
     /// The description of the query.
     desc: Option<(Option<Ident>, Punctuated<Expr, Token![,]>)>,
 
+    /// Use this type for the in-memory cache.
+    storage: Option<Type>,
+
     /// Cache the query to disk if the `Block` returns true.
     cache: Option<(Option<(IdentOrWild, IdentOrWild)>, Block)>,
 
@@ -226,6 +235,7 @@ struct QueryModifiers {
 /// Process query modifiers into a struct, erroring on duplicates
 fn process_modifiers(query: &mut Query) -> QueryModifiers {
     let mut load_cached = None;
+    let mut storage = None;
     let mut cache = None;
     let mut desc = None;
     let mut fatal_cycle = false;
@@ -242,6 +252,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
                 }
                 load_cached = Some((tcx, id, block));
             }
+            QueryModifier::Storage(ty) => {
+                if storage.is_some() {
+                    panic!("duplicate modifier `storage` for query `{}`", query.name);
+                }
+                storage = Some(ty);
+            }
             QueryModifier::Cache(args, expr) => {
                 if cache.is_some() {
                     panic!("duplicate modifier `cache` for query `{}`", query.name);
@@ -294,6 +310,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
     }
     QueryModifiers {
         load_cached,
+        storage,
         cache,
         desc,
         fatal_cycle,
@@ -451,6 +468,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             if modifiers.fatal_cycle {
                 attributes.push(quote! { fatal_cycle });
             };
+            // Pass on the storage modifier
+            if let Some(ref ty) = modifiers.storage {
+                attributes.push(quote! { storage(#ty) });
+            };
             // Pass on the cycle_delay_bug modifier
             if modifiers.cycle_delay_bug {
                 attributes.push(quote! { cycle_delay_bug });