Add a `storage` query modifier to override the query cache
This commit is contained in:
parent
e2a8589e01
commit
8a2ad75a60
|
@ -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)*) }
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 @@ 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<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 });
|
||||
|
|
Loading…
Reference in New Issue