From 8a2ad75a60b599cab49b57000660b884e8fb27dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 14 Feb 2020 18:29:20 +0100 Subject: [PATCH] Add a `storage` query modifier to override the query cache --- src/librustc/dep_graph/dep_node.rs | 12 ++++----- src/librustc/ty/query/plumbing.rs | 40 +++++++++++++++++++----------- src/librustc_macros/src/query.rs | 21 ++++++++++++++++ 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 29b94986a5f..963f45b3f17 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -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 @@ macro_rules! define_dep_nodes { match *self { $( DepKind :: $variant => { - if contains_anon_attr!($($attr),*) { + if contains_anon_attr!($($attrs)*) { return false; } @@ -152,7 +152,7 @@ macro_rules! define_dep_nodes { pub fn is_anon(&self) -> bool { match *self { $( - DepKind :: $variant => { contains_anon_attr!($($attr),*) } + DepKind :: $variant => { contains_anon_attr!($($attrs)*) } )* } } @@ -160,7 +160,7 @@ macro_rules! define_dep_nodes { pub fn is_eval_always(&self) -> bool { match *self { $( - DepKind :: $variant => { contains_eval_always_attr!($($attr), *) } + DepKind :: $variant => { contains_eval_always_attr!($($attrs)*) } )* } } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 3eaf4e36f39..13132739f89 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -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 @@ macro_rules! define_queries_inner { 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> { diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 294cdb7643f..6362f3c2c49 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -33,6 +33,9 @@ enum QueryModifier { /// The description of the query. Desc(Option, Punctuated), + /// 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 @@ impl Parse for QueryModifier { 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, Punctuated)>, + /// Use this type for the in-memory cache. + storage: Option, + /// 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 });