Skip to content

Commit

Permalink
Add a storage query modifier to override the query cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Feb 17, 2020
1 parent 9c25987 commit 325c82b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 20 deletions.
12 changes: 6 additions & 6 deletions src/librustc/dep_graph/dep_node.rs
Expand Up @@ -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),* })*
,)*
Expand All @@ -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;
}

Expand All @@ -152,15 +152,15 @@ 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)*) }
)*
}
}

pub fn is_eval_always(&self) -> bool {
match *self {
$(
DepKind :: $variant => { contains_eval_always_attr!($($attr), *) }
DepKind :: $variant => { contains_eval_always_attr!($($attrs)*) }
)*
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/query/mod.rs
Expand Up @@ -57,6 +57,7 @@ rustc_queries! {

/// Records the type of every item.
query type_of(key: DefId) -> Ty<'tcx> {
storage(caches::LocalDenseDefIdCache<Ty<'tcx>>)
cache_on_disk_if { key.is_local() }
}

Expand Down
40 changes: 26 additions & 14 deletions src/librustc/ty/query/plumbing.rs
Expand Up @@ -746,53 +746,65 @@ 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)*])
};
}

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)*)*])
};
}

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)*])
};
}

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)*])
};
}

Expand Down Expand Up @@ -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> {
Expand Down
21 changes: 21 additions & 0 deletions src/librustc_macros/src/query.rs
Expand Up @@ -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),

Expand Down Expand Up @@ -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" {
Expand Down Expand Up @@ -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)>,

Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -294,6 +310,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
}
QueryModifiers {
load_cached,
storage,
cache,
desc,
fatal_cycle,
Expand Down Expand Up @@ -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 });
Expand Down

0 comments on commit 325c82b

Please sign in to comment.