From 7948340989227b2f0883db82387b8e39349a75cf Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 16:35:15 -0500 Subject: [PATCH 1/8] Work on cache --- compiler/rustc_middle/src/query/mod.rs | 21 ++++- compiler/rustc_query_system/src/lib.rs | 1 + .../rustc_query_system/src/query/caches.rs | 89 +++++++++++++++++++ compiler/rustc_query_system/src/query/mod.rs | 2 +- .../rustc_query_system/src/query/plumbing.rs | 4 +- 5 files changed, 113 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0860520ef9df..86141ed36e14 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -23,6 +23,7 @@ rustc_queries! { query hir_crate(key: ()) -> &'tcx Crate<'tcx> { eval_always no_hash + storage(CellCacheSelector<'tcx>) desc { "get the crate HIR" } } @@ -31,6 +32,7 @@ rustc_queries! { query index_hir(_: ()) -> &'tcx crate::hir::IndexedHir<'tcx> { eval_always no_hash + storage(CellCacheSelector<'tcx>) desc { "index HIR" } } @@ -116,6 +118,7 @@ rustc_queries! { query analysis(key: ()) -> Result<(), ErrorReported> { eval_always + storage(CellCacheSelector<'tcx>) desc { "running analysis passes on this crate" } } @@ -701,6 +704,7 @@ rustc_queries! { } query typeck_item_bodies(_: ()) -> () { + storage(CellCacheSelector<'tcx>) desc { "type-checking all item bodies" } } @@ -770,6 +774,7 @@ rustc_queries! { query crate_inherent_impls_overlap_check(_: ()) -> () { eval_always + storage(CellCacheSelector<'tcx>) desc { "check for overlap between inherent impls defined in this crate" } } @@ -863,10 +868,12 @@ rustc_queries! { /// Performs part of the privacy check and computes "access levels". query privacy_access_levels(_: ()) -> &'tcx AccessLevels { eval_always + storage(CellCacheSelector<'tcx>) desc { "privacy access levels" } } query check_private_in_public(_: ()) -> () { eval_always + storage(CellCacheSelector<'tcx>) desc { "checking for private elements in public interfaces" } } @@ -981,6 +988,7 @@ rustc_queries! { /// /// [`LOCAL_CRATE`]: rustc_hir::def_id::LOCAL_CRATE query all_local_trait_impls(_: ()) -> &'tcx BTreeMap> { + storage(CellCacheSelector<'tcx>) desc { "local trait impls" } } @@ -1229,12 +1237,15 @@ rustc_queries! { /// Identifies the entry-point (e.g., the `main` function) for a given /// crate, returning `None` if there is no entry point (such as for library crates). query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> { + storage(CellCacheSelector<'tcx>) desc { "looking up the entry function of a crate" } } query plugin_registrar_fn(_: ()) -> Option { + storage(CellCacheSelector<'tcx>) desc { "looking up the plugin registrar for a crate" } } query proc_macro_decls_static(_: ()) -> Option { + storage(CellCacheSelector<'tcx>) desc { "looking up the derive registrar for a crate" } } query crate_disambiguator(_: CrateNum) -> CrateDisambiguator { @@ -1412,6 +1423,7 @@ rustc_queries! { } query postorder_cnums(_: ()) -> &'tcx [CrateNum] { eval_always + storage(CellCacheSelector<'tcx>) desc { "generating a postorder list of CrateNums" } } /// Returns whether or not the crate with CrateNum 'cnum' @@ -1431,6 +1443,7 @@ rustc_queries! { } query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] { eval_always + storage(CellCacheSelector<'tcx>) desc { "looking up all possibly unused extern crates" } } query names_imported_by_glob_use(def_id: LocalDefId) @@ -1446,6 +1459,7 @@ rustc_queries! { } query all_crate_nums(_: ()) -> &'tcx [CrateNum] { eval_always + storage(CellCacheSelector<'tcx>) desc { "fetching all foreign CrateNum instances" } } @@ -1453,6 +1467,7 @@ rustc_queries! { /// (i.e., including those from subcrates). This is used only for /// error reporting. query all_traits(_: ()) -> &'tcx [DefId] { + storage(CellCacheSelector<'tcx>) desc { "fetching all foreign and local traits" } } @@ -1468,6 +1483,7 @@ rustc_queries! { query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) { eval_always + storage(CellCacheSelector<'tcx>) desc { "collect_and_partition_mono_items" } } query is_codegened_item(def_id: DefId) -> bool { @@ -1477,7 +1493,8 @@ rustc_queries! { /// All items participating in code generation together with items inlined into them. query codegened_and_inlined_items(_: ()) -> &'tcx DefIdSet { eval_always - desc { "codegened_and_inlined_items" } + storage(CellCacheSelector<'tcx>) + desc { "codegened_and_inlined_items" } } query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> { @@ -1491,6 +1508,7 @@ rustc_queries! { } } query backend_optimization_level(_: ()) -> OptLevel { + storage(CellCacheSelector<'tcx>) desc { "optimization level used by backend" } } @@ -1672,6 +1690,7 @@ rustc_queries! { query features_query(_: ()) -> &'tcx rustc_feature::Features { eval_always + storage(CellCacheSelector<'tcx>) desc { "looking up enabled feature gates" } } diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 0d4fb34265c5..27632fb9de20 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -1,4 +1,5 @@ #![feature(bool_to_option)] +#![feature(const_panic)] #![feature(core_intrinsics)] #![feature(hash_raw_entry)] #![feature(iter_zip)] diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 011c2ceebb71..5bf69ebcfe95 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -8,6 +8,7 @@ use rustc_data_structures::sync::WorkerLocal; use std::default::Default; use std::fmt::Debug; use std::hash::Hash; +use std::cell::Cell; use std::marker::PhantomData; pub trait CacheSelector { @@ -221,3 +222,91 @@ where } } } + +pub struct CellCacheSelector<'tcx>(PhantomData<&'tcx ()>); + +impl<'tcx, K: Eq + Hash, V: Clone> CacheSelector for CellCacheSelector<'tcx> { + type Cache = CellCache; +} + +pub struct CellCache(PhantomData<(K, V)>); + +impl Default for CellCache { + fn default() -> Self { + CellCache(PhantomData) + } +} + +impl CellCache { + const KEY_IS_ZST: () = { + if std::mem::size_of::() != 0 { + panic!("Key must be a ZST"); + } + }; +} + +impl QueryStorage for CellCache { + type Value = V; + type Stored = V; + + #[inline] + fn store_nocache(&self, value: Self::Value) -> Self::Stored { + // We have no dedicated storage + value + } +} + +impl QueryCache for CellCache +where + K: Eq + Hash + Copy + Clone + Debug, + V: Copy + Clone + Debug, +{ + type Key = K; + type Sharded = Cell>; + + #[inline(always)] + fn lookup<'s, R, OnHit>( + &self, + state: &'s QueryCacheStore, + _key: &K, + on_hit: OnHit, + ) -> Result + where + OnHit: FnOnce(&V, DepNodeIndex) -> R, + { + let _ = Self::KEY_IS_ZST; + + let lock = state.shards.get_shard_by_index(0).lock(); + if let Some((_key, val, dep_node)) = lock.get() { + Ok(on_hit(&val, dep_node)) + } else { + Err(QueryLookup { + key_hash: 0, + shard: 0 + }) + } + } + + #[inline] + fn complete( + &self, + lock_sharded_storage: &mut Self::Sharded, + key: K, + value: V, + index: DepNodeIndex, + ) -> Self::Stored { + lock_sharded_storage.set(Some((key, value, index))); + value + } + + fn iter( + &self, + shards: &Sharded, + f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex), + ) { + let lock = shards.get_shard_by_index(0).lock(); + if let Some((key, val, dep_node)) = lock.get() { + f(&key, &val, dep_node); + } + } +} diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 927e8117f05e..b5f8d6fdde15 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -8,7 +8,7 @@ pub use self::job::{print_query_stack, QueryInfo, QueryJob, QueryJobId, QueryJob mod caches; pub use self::caches::{ - ArenaCacheSelector, CacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, + ArenaCacheSelector, CacheSelector, CellCacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, }; mod config; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index c1f9fa39e98c..b62011c91bea 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -31,7 +31,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; pub struct QueryCacheStore { cache: C, - shards: Sharded, + pub(super) shards: Sharded, #[cfg(debug_assertions)] pub cache_hits: AtomicUsize, } @@ -50,7 +50,7 @@ impl Default for QueryCacheStore { /// Values used when checking a query cache which can be reused on a cache-miss to execute the query. pub struct QueryLookup { pub(super) key_hash: u64, - shard: usize, + pub(super) shard: usize, } // We compute the key's hash once and then use it for both the From a277c2010d1e7a5c84c344d4cc6fc512a95a03b6 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:03:22 -0500 Subject: [PATCH 2/8] Rename and remove Cell --- compiler/rustc_middle/src/query/mod.rs | 20 +---------- .../rustc_query_system/src/query/caches.rs | 33 +++++++++---------- compiler/rustc_query_system/src/query/mod.rs | 2 +- 3 files changed, 18 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 86141ed36e14..faa67235ada5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -23,7 +23,6 @@ rustc_queries! { query hir_crate(key: ()) -> &'tcx Crate<'tcx> { eval_always no_hash - storage(CellCacheSelector<'tcx>) desc { "get the crate HIR" } } @@ -32,7 +31,6 @@ rustc_queries! { query index_hir(_: ()) -> &'tcx crate::hir::IndexedHir<'tcx> { eval_always no_hash - storage(CellCacheSelector<'tcx>) desc { "index HIR" } } @@ -118,7 +116,6 @@ rustc_queries! { query analysis(key: ()) -> Result<(), ErrorReported> { eval_always - storage(CellCacheSelector<'tcx>) desc { "running analysis passes on this crate" } } @@ -704,7 +701,6 @@ rustc_queries! { } query typeck_item_bodies(_: ()) -> () { - storage(CellCacheSelector<'tcx>) desc { "type-checking all item bodies" } } @@ -774,7 +770,6 @@ rustc_queries! { query crate_inherent_impls_overlap_check(_: ()) -> () { eval_always - storage(CellCacheSelector<'tcx>) desc { "check for overlap between inherent impls defined in this crate" } } @@ -868,12 +863,10 @@ rustc_queries! { /// Performs part of the privacy check and computes "access levels". query privacy_access_levels(_: ()) -> &'tcx AccessLevels { eval_always - storage(CellCacheSelector<'tcx>) desc { "privacy access levels" } } query check_private_in_public(_: ()) -> () { eval_always - storage(CellCacheSelector<'tcx>) desc { "checking for private elements in public interfaces" } } @@ -988,7 +981,6 @@ rustc_queries! { /// /// [`LOCAL_CRATE`]: rustc_hir::def_id::LOCAL_CRATE query all_local_trait_impls(_: ()) -> &'tcx BTreeMap> { - storage(CellCacheSelector<'tcx>) desc { "local trait impls" } } @@ -1237,15 +1229,12 @@ rustc_queries! { /// Identifies the entry-point (e.g., the `main` function) for a given /// crate, returning `None` if there is no entry point (such as for library crates). query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> { - storage(CellCacheSelector<'tcx>) desc { "looking up the entry function of a crate" } } query plugin_registrar_fn(_: ()) -> Option { - storage(CellCacheSelector<'tcx>) desc { "looking up the plugin registrar for a crate" } } query proc_macro_decls_static(_: ()) -> Option { - storage(CellCacheSelector<'tcx>) desc { "looking up the derive registrar for a crate" } } query crate_disambiguator(_: CrateNum) -> CrateDisambiguator { @@ -1423,7 +1412,6 @@ rustc_queries! { } query postorder_cnums(_: ()) -> &'tcx [CrateNum] { eval_always - storage(CellCacheSelector<'tcx>) desc { "generating a postorder list of CrateNums" } } /// Returns whether or not the crate with CrateNum 'cnum' @@ -1443,7 +1431,6 @@ rustc_queries! { } query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] { eval_always - storage(CellCacheSelector<'tcx>) desc { "looking up all possibly unused extern crates" } } query names_imported_by_glob_use(def_id: LocalDefId) @@ -1459,7 +1446,6 @@ rustc_queries! { } query all_crate_nums(_: ()) -> &'tcx [CrateNum] { eval_always - storage(CellCacheSelector<'tcx>) desc { "fetching all foreign CrateNum instances" } } @@ -1467,7 +1453,6 @@ rustc_queries! { /// (i.e., including those from subcrates). This is used only for /// error reporting. query all_traits(_: ()) -> &'tcx [DefId] { - storage(CellCacheSelector<'tcx>) desc { "fetching all foreign and local traits" } } @@ -1483,7 +1468,6 @@ rustc_queries! { query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) { eval_always - storage(CellCacheSelector<'tcx>) desc { "collect_and_partition_mono_items" } } query is_codegened_item(def_id: DefId) -> bool { @@ -1493,7 +1477,6 @@ rustc_queries! { /// All items participating in code generation together with items inlined into them. query codegened_and_inlined_items(_: ()) -> &'tcx DefIdSet { eval_always - storage(CellCacheSelector<'tcx>) desc { "codegened_and_inlined_items" } } @@ -1508,7 +1491,6 @@ rustc_queries! { } } query backend_optimization_level(_: ()) -> OptLevel { - storage(CellCacheSelector<'tcx>) desc { "optimization level used by backend" } } @@ -1689,8 +1671,8 @@ rustc_queries! { } query features_query(_: ()) -> &'tcx rustc_feature::Features { + storage(SingletonCacheSelector<'tcx>) eval_always - storage(CellCacheSelector<'tcx>) desc { "looking up enabled feature gates" } } diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 5bf69ebcfe95..a03f6f1612e1 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -8,7 +8,6 @@ use rustc_data_structures::sync::WorkerLocal; use std::default::Default; use std::fmt::Debug; use std::hash::Hash; -use std::cell::Cell; use std::marker::PhantomData; pub trait CacheSelector { @@ -223,21 +222,21 @@ where } } -pub struct CellCacheSelector<'tcx>(PhantomData<&'tcx ()>); +pub struct SingletonCacheSelector<'tcx>(PhantomData<&'tcx ()>); -impl<'tcx, K: Eq + Hash, V: Clone> CacheSelector for CellCacheSelector<'tcx> { - type Cache = CellCache; +impl<'tcx, K: Eq + Hash, V: Clone> CacheSelector for SingletonCacheSelector<'tcx> { + type Cache = SingletonCache; } -pub struct CellCache(PhantomData<(K, V)>); +pub struct SingletonCache(PhantomData<(K, V)>); -impl Default for CellCache { +impl Default for SingletonCache { fn default() -> Self { - CellCache(PhantomData) + SingletonCache(PhantomData) } } -impl CellCache { +impl SingletonCache { const KEY_IS_ZST: () = { if std::mem::size_of::() != 0 { panic!("Key must be a ZST"); @@ -245,7 +244,7 @@ impl CellCache { }; } -impl QueryStorage for CellCache { +impl QueryStorage for SingletonCache { type Value = V; type Stored = V; @@ -256,13 +255,13 @@ impl QueryStorage for CellCache { } } -impl QueryCache for CellCache +impl QueryCache for SingletonCache where K: Eq + Hash + Copy + Clone + Debug, - V: Copy + Clone + Debug, + V: Clone + Debug, { type Key = K; - type Sharded = Cell>; + type Sharded = Option<(K, V, DepNodeIndex)>; #[inline(always)] fn lookup<'s, R, OnHit>( @@ -277,8 +276,8 @@ where let _ = Self::KEY_IS_ZST; let lock = state.shards.get_shard_by_index(0).lock(); - if let Some((_key, val, dep_node)) = lock.get() { - Ok(on_hit(&val, dep_node)) + if let Some((_key, val, dep_node)) = &*lock { + Ok(on_hit(&val, *dep_node)) } else { Err(QueryLookup { key_hash: 0, @@ -295,7 +294,7 @@ where value: V, index: DepNodeIndex, ) -> Self::Stored { - lock_sharded_storage.set(Some((key, value, index))); + *lock_sharded_storage = Some((key, value.clone(), index)); value } @@ -305,8 +304,8 @@ where f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex), ) { let lock = shards.get_shard_by_index(0).lock(); - if let Some((key, val, dep_node)) = lock.get() { - f(&key, &val, dep_node); + if let Some((key, val, dep_node)) = &*lock { + f(&key, &val, *dep_node); } } } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index b5f8d6fdde15..51922e5ff070 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -8,7 +8,7 @@ pub use self::job::{print_query_stack, QueryInfo, QueryJob, QueryJobId, QueryJob mod caches; pub use self::caches::{ - ArenaCacheSelector, CacheSelector, CellCacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, + ArenaCacheSelector, CacheSelector, SingletonCacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, }; mod config; From a03cf1b502484a1edb443436c9fbf48df0b7664f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:06:47 -0500 Subject: [PATCH 3/8] Avoid ambiguity by always using parens for query modifiers Otherwise, we can get an ambiguity error (with multiple comma-separated modifiers) because the parents can either be parsed as the 'arg', or part of the undifferentiated 'other arguments' --- compiler/rustc_macros/src/query.rs | 10 +++++----- compiler/rustc_middle/src/ty/query/mod.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 18 +++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 291e7ef045e4..6b664a662833 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -455,7 +455,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { // Pass on the fatal_cycle modifier if modifiers.fatal_cycle { - attributes.push(quote! { fatal_cycle }); + attributes.push(quote! { fatal_cycle() }); }; // Pass on the storage modifier if let Some(ref ty) = modifiers.storage { @@ -463,19 +463,19 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { }; // Pass on the cycle_delay_bug modifier if modifiers.cycle_delay_bug { - attributes.push(quote! { cycle_delay_bug }); + attributes.push(quote! { cycle_delay_bug() }); }; // Pass on the no_hash modifier if modifiers.no_hash { - attributes.push(quote! { no_hash }); + attributes.push(quote! { no_hash() }); }; // Pass on the anon modifier if modifiers.anon { - attributes.push(quote! { anon }); + attributes.push(quote! { anon() }); }; // Pass on the eval_always modifier if modifiers.eval_always { - attributes.push(quote! { eval_always }); + attributes.push(quote! { eval_always() }); }; let attribute_stream = quote! {#(#attributes),*}; diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 297110ee3ecf..0aa2cd3d23ec 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -116,7 +116,7 @@ macro_rules! query_storage { ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { <$ty as CacheSelector<$K, $V>>::Cache }; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*][$($args:tt)*]) => { query_storage!([$($($modifiers)*)*][$($args)*]) }; } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index b4191c135b4f..4044ae0e355f 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -219,16 +219,16 @@ macro_rules! handle_cycle_error { $error.emit(); Value::from_cycle_error($tcx) }}; - ([fatal_cycle $($rest:tt)*][$tcx:expr, $error:expr]) => {{ + ([fatal_cycle() $($rest:tt)*][$tcx:expr, $error:expr]) => {{ $error.emit(); $tcx.sess.abort_if_errors(); unreachable!() }}; - ([cycle_delay_bug $($rest:tt)*][$tcx:expr, $error:expr]) => {{ + ([cycle_delay_bug() $($rest:tt)*][$tcx:expr, $error:expr]) => {{ $error.delay_as_bug(); Value::from_cycle_error($tcx) }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*][$($args:tt)*]) => { handle_cycle_error!([$($($modifiers)*)*][$($args)*]) }; } @@ -237,10 +237,10 @@ macro_rules! is_anon { ([]) => {{ false }}; - ([anon $($rest:tt)*]) => {{ + ([anon() $($rest:tt)*]) => {{ true }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { + ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*]) => { is_anon!([$($($modifiers)*)*]) }; } @@ -249,10 +249,10 @@ macro_rules! is_eval_always { ([]) => {{ false }}; - ([eval_always $($rest:tt)*]) => {{ + ([eval_always() $($rest:tt)*]) => {{ true }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { + ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*]) => { is_eval_always!([$($($modifiers)*)*]) }; } @@ -261,10 +261,10 @@ macro_rules! hash_result { ([][$hcx:expr, $result:expr]) => {{ dep_graph::hash_result($hcx, &$result) }}; - ([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{ + ([no_hash() $($rest:tt)*][$hcx:expr, $result:expr]) => {{ None }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*][$($args:tt)*]) => { hash_result!([$($($modifiers)*)*][$($args)*]) }; } From 0bed2b882db136cda706eeb8cd08527e8a2a3a82 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:09:13 -0500 Subject: [PATCH 4/8] Remove lifetime parameter --- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_query_system/src/query/caches.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index faa67235ada5..f029bf59d1c5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1671,7 +1671,7 @@ rustc_queries! { } query features_query(_: ()) -> &'tcx rustc_feature::Features { - storage(SingletonCacheSelector<'tcx>) + storage(SingletonCacheSelector) eval_always desc { "looking up enabled feature gates" } } diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index a03f6f1612e1..57ef0ac843b3 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -222,9 +222,9 @@ where } } -pub struct SingletonCacheSelector<'tcx>(PhantomData<&'tcx ()>); +pub struct SingletonCacheSelector; -impl<'tcx, K: Eq + Hash, V: Clone> CacheSelector for SingletonCacheSelector<'tcx> { +impl CacheSelector for SingletonCacheSelector { type Cache = SingletonCache; } From 86edc29150db89f2da8328ecac57e374fda28f8d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:18:46 -0500 Subject: [PATCH 5/8] Revert "Avoid ambiguity by always using parens for query modifiers" This reverts commit a03cf1b502484a1edb443436c9fbf48df0b7664f. --- compiler/rustc_macros/src/query.rs | 10 +++++----- compiler/rustc_middle/src/ty/query/mod.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 18 +++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 6b664a662833..291e7ef045e4 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -455,7 +455,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { // Pass on the fatal_cycle modifier if modifiers.fatal_cycle { - attributes.push(quote! { fatal_cycle() }); + attributes.push(quote! { fatal_cycle }); }; // Pass on the storage modifier if let Some(ref ty) = modifiers.storage { @@ -463,19 +463,19 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { }; // Pass on the cycle_delay_bug modifier if modifiers.cycle_delay_bug { - attributes.push(quote! { cycle_delay_bug() }); + attributes.push(quote! { cycle_delay_bug }); }; // Pass on the no_hash modifier if modifiers.no_hash { - attributes.push(quote! { no_hash() }); + attributes.push(quote! { no_hash }); }; // Pass on the anon modifier if modifiers.anon { - attributes.push(quote! { anon() }); + attributes.push(quote! { anon }); }; // Pass on the eval_always modifier if modifiers.eval_always { - attributes.push(quote! { eval_always() }); + attributes.push(quote! { eval_always }); }; let attribute_stream = quote! {#(#attributes),*}; diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 0aa2cd3d23ec..297110ee3ecf 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -116,7 +116,7 @@ macro_rules! query_storage { ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { <$ty as CacheSelector<$K, $V>>::Cache }; - ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { query_storage!([$($($modifiers)*)*][$($args)*]) }; } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 4044ae0e355f..b4191c135b4f 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -219,16 +219,16 @@ macro_rules! handle_cycle_error { $error.emit(); Value::from_cycle_error($tcx) }}; - ([fatal_cycle() $($rest:tt)*][$tcx:expr, $error:expr]) => {{ + ([fatal_cycle $($rest:tt)*][$tcx:expr, $error:expr]) => {{ $error.emit(); $tcx.sess.abort_if_errors(); unreachable!() }}; - ([cycle_delay_bug() $($rest:tt)*][$tcx:expr, $error:expr]) => {{ + ([cycle_delay_bug $($rest:tt)*][$tcx:expr, $error:expr]) => {{ $error.delay_as_bug(); Value::from_cycle_error($tcx) }}; - ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { handle_cycle_error!([$($($modifiers)*)*][$($args)*]) }; } @@ -237,10 +237,10 @@ macro_rules! is_anon { ([]) => {{ false }}; - ([anon() $($rest:tt)*]) => {{ + ([anon $($rest:tt)*]) => {{ true }}; - ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { is_anon!([$($($modifiers)*)*]) }; } @@ -249,10 +249,10 @@ macro_rules! is_eval_always { ([]) => {{ false }}; - ([eval_always() $($rest:tt)*]) => {{ + ([eval_always $($rest:tt)*]) => {{ true }}; - ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { is_eval_always!([$($($modifiers)*)*]) }; } @@ -261,10 +261,10 @@ macro_rules! hash_result { ([][$hcx:expr, $result:expr]) => {{ dep_graph::hash_result($hcx, &$result) }}; - ([no_hash() $($rest:tt)*][$hcx:expr, $result:expr]) => {{ + ([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{ None }}; - ([$other:ident ($($other_args:tt)*) $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { hash_result!([$($($modifiers)*)*][$($args)*]) }; } From e056cb8b37bd6094b7059f1a4143f0e86f9aceca Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:20:54 -0500 Subject: [PATCH 6/8] Use question mark to avoid ambiguity --- compiler/rustc_middle/src/ty/query/mod.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/query/mod.rs b/compiler/rustc_middle/src/ty/query/mod.rs index 297110ee3ecf..2301c890697d 100644 --- a/compiler/rustc_middle/src/ty/query/mod.rs +++ b/compiler/rustc_middle/src/ty/query/mod.rs @@ -116,7 +116,7 @@ macro_rules! query_storage { ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => { <$ty as CacheSelector<$K, $V>>::Cache }; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)?][$($args:tt)*]) => { query_storage!([$($($modifiers)*)*][$($args)*]) }; } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index b4191c135b4f..20faf6356044 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -228,7 +228,7 @@ macro_rules! handle_cycle_error { $error.delay_as_bug(); Value::from_cycle_error($tcx) }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)?][$($args:tt)*]) => { handle_cycle_error!([$($($modifiers)*)*][$($args)*]) }; } @@ -240,7 +240,7 @@ macro_rules! is_anon { ([anon $($rest:tt)*]) => {{ true }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)?]) => { is_anon!([$($($modifiers)*)*]) }; } @@ -252,7 +252,7 @@ macro_rules! is_eval_always { ([eval_always $($rest:tt)*]) => {{ true }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)?]) => { is_eval_always!([$($($modifiers)*)*]) }; } @@ -264,7 +264,7 @@ macro_rules! hash_result { ([no_hash $($rest:tt)*][$hcx:expr, $result:expr]) => {{ None }}; - ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => { + ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)?][$($args:tt)*]) => { hash_result!([$($($modifiers)*)*][$($args)*]) }; } From 6ad3389dfaa8b0d6f2dd07c662ac43923e2d1674 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:24:34 -0500 Subject: [PATCH 7/8] Use SingletonCacheSelector where possible --- compiler/rustc_middle/src/query/mod.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f029bf59d1c5..b8795c1d6dbe 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -21,6 +21,7 @@ rustc_queries! { /// To avoid this fate, do not call `tcx.hir().krate()`; instead, /// prefer wrappers like `tcx.visit_all_items_in_krate()`. query hir_crate(key: ()) -> &'tcx Crate<'tcx> { + storage(SingletonCacheSelector) eval_always no_hash desc { "get the crate HIR" } @@ -29,6 +30,7 @@ rustc_queries! { /// The indexed HIR. This can be conveniently accessed by `tcx.hir()`. /// Avoid calling this query directly. query index_hir(_: ()) -> &'tcx crate::hir::IndexedHir<'tcx> { + storage(SingletonCacheSelector) eval_always no_hash desc { "index HIR" } @@ -115,6 +117,7 @@ rustc_queries! { } query analysis(key: ()) -> Result<(), ErrorReported> { + storage(SingletonCacheSelector) eval_always desc { "running analysis passes on this crate" } } @@ -701,6 +704,7 @@ rustc_queries! { } query typeck_item_bodies(_: ()) -> () { + storage(SingletonCacheSelector) desc { "type-checking all item bodies" } } @@ -769,6 +773,7 @@ rustc_queries! { /// Not meant to be used directly outside of coherence. query crate_inherent_impls_overlap_check(_: ()) -> () { + storage(SingletonCacheSelector) eval_always desc { "check for overlap between inherent impls defined in this crate" } } @@ -862,10 +867,12 @@ rustc_queries! { /// Performs part of the privacy check and computes "access levels". query privacy_access_levels(_: ()) -> &'tcx AccessLevels { + storage(SingletonCacheSelector) eval_always desc { "privacy access levels" } } query check_private_in_public(_: ()) -> () { + storage(SingletonCacheSelector) eval_always desc { "checking for private elements in public interfaces" } } @@ -981,6 +988,7 @@ rustc_queries! { /// /// [`LOCAL_CRATE`]: rustc_hir::def_id::LOCAL_CRATE query all_local_trait_impls(_: ()) -> &'tcx BTreeMap> { + storage(SingletonCacheSelector) desc { "local trait impls" } } @@ -1084,6 +1092,7 @@ rustc_queries! { } query dependency_formats(_: ()) -> Lrc { + storage(SingletonCacheSelector) desc { "get the linkage format of all dependencies" } } @@ -1229,12 +1238,15 @@ rustc_queries! { /// Identifies the entry-point (e.g., the `main` function) for a given /// crate, returning `None` if there is no entry point (such as for library crates). query entry_fn(_: ()) -> Option<(DefId, EntryFnType)> { + storage(SingletonCacheSelector) desc { "looking up the entry function of a crate" } } query plugin_registrar_fn(_: ()) -> Option { + storage(SingletonCacheSelector) desc { "looking up the plugin registrar for a crate" } } query proc_macro_decls_static(_: ()) -> Option { + storage(SingletonCacheSelector) desc { "looking up the derive registrar for a crate" } } query crate_disambiguator(_: CrateNum) -> CrateDisambiguator { @@ -1411,6 +1423,7 @@ rustc_queries! { desc { "looking at the source for a crate" } } query postorder_cnums(_: ()) -> &'tcx [CrateNum] { + storage(SingletonCacheSelector) eval_always desc { "generating a postorder list of CrateNums" } } @@ -1430,6 +1443,7 @@ rustc_queries! { desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) } } query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] { + storage(SingletonCacheSelector) eval_always desc { "looking up all possibly unused extern crates" } } @@ -1445,6 +1459,7 @@ rustc_queries! { desc { "calculating the stability index for the local crate" } } query all_crate_nums(_: ()) -> &'tcx [CrateNum] { + storage(SingletonCacheSelector) eval_always desc { "fetching all foreign CrateNum instances" } } @@ -1453,6 +1468,7 @@ rustc_queries! { /// (i.e., including those from subcrates). This is used only for /// error reporting. query all_traits(_: ()) -> &'tcx [DefId] { + storage(SingletonCacheSelector) desc { "fetching all foreign and local traits" } } @@ -1467,6 +1483,7 @@ rustc_queries! { } query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) { + storage(SingletonCacheSelector) eval_always desc { "collect_and_partition_mono_items" } } @@ -1476,6 +1493,7 @@ rustc_queries! { /// All items participating in code generation together with items inlined into them. query codegened_and_inlined_items(_: ()) -> &'tcx DefIdSet { + storage(SingletonCacheSelector) eval_always desc { "codegened_and_inlined_items" } } @@ -1491,10 +1509,12 @@ rustc_queries! { } } query backend_optimization_level(_: ()) -> OptLevel { + storage(SingletonCacheSelector) desc { "optimization level used by backend" } } query output_filenames(_: ()) -> Arc { + storage(SingletonCacheSelector) eval_always desc { "output_filenames" } } From 75ee1ed37b49ed0956e0bae04a9effc9cb2523b3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 7 Jun 2021 17:25:02 -0500 Subject: [PATCH 8/8] Run fmt --- compiler/rustc_query_system/src/query/caches.rs | 5 +---- compiler/rustc_query_system/src/query/mod.rs | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 57ef0ac843b3..84104747f391 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -279,10 +279,7 @@ where if let Some((_key, val, dep_node)) = &*lock { Ok(on_hit(&val, *dep_node)) } else { - Err(QueryLookup { - key_hash: 0, - shard: 0 - }) + Err(QueryLookup { key_hash: 0, shard: 0 }) } } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 51922e5ff070..8542f09ce9ee 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -8,7 +8,8 @@ pub use self::job::{print_query_stack, QueryInfo, QueryJob, QueryJobId, QueryJob mod caches; pub use self::caches::{ - ArenaCacheSelector, CacheSelector, SingletonCacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, + ArenaCacheSelector, CacheSelector, DefaultCacheSelector, QueryCache, QueryStorage, + SingletonCacheSelector, }; mod config;