Skip to content

Move the query system to a dedicated crate #70162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Mar 28, 2020
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8c1c90b
Make QueryConfig argument a type.
cjgillot Mar 8, 2020
f74fd03
Make QueryAccessor argument a type.
cjgillot Mar 8, 2020
57c3177
Make QueryDescription parameter a type.
cjgillot Mar 8, 2020
c4a451e
Make QueryCache generic on the context.
cjgillot Mar 11, 2020
ee9781c
Make QueryContext a subtrait of DepContext.
cjgillot Mar 18, 2020
2a52436
Generalise QueryJobId.
cjgillot Mar 18, 2020
a51ad88
Decouple from DepKind.
cjgillot Mar 18, 2020
232364a
Generalise QueryLatch.
cjgillot Mar 18, 2020
63087b6
Parametrise by try_collect_active_jobs.
cjgillot Mar 19, 2020
42f0db5
Move HashStable bound to the trait definition.
cjgillot Mar 19, 2020
decfd70
Generalise try_get_cached.
cjgillot Mar 19, 2020
4ac4ccd
Generalise JobOwner::try_start.
cjgillot Mar 19, 2020
27e8a95
Generalise Query starting.
cjgillot Mar 19, 2020
6184a71
Make get_query into an extension trait.
cjgillot Mar 19, 2020
5b8dac3
Move query system to librustc_query_system.
cjgillot Mar 19, 2020
8e873c3
Make librustc_query_system compile.
cjgillot Mar 19, 2020
dca0344
Make librustc compile.
cjgillot Mar 19, 2020
301ad11
Rustfmt.
cjgillot Mar 26, 2020
d305b2c
Unify key types in get_lookup.
cjgillot Mar 24, 2020
228ca8e
Access QueryStateShard directly.
cjgillot Mar 24, 2020
b6033fc
Retire DepGraphSafe and HashStableContext.
cjgillot Mar 24, 2020
0e8b59a
Prune dependencies.
cjgillot Mar 24, 2020
fa06cfd
Move generics on QueryCache.
cjgillot Mar 24, 2020
5dfed41
Simplify generics on try_start.
cjgillot Mar 24, 2020
fce0d37
Add comment.
cjgillot Mar 24, 2020
d224e21
Rename read_query_job -> current_query_job and simplify it.
cjgillot Mar 25, 2020
260cfab
Don't allow access to the Session.
cjgillot Mar 25, 2020
4faf701
Remove the QueryGetter trait.
cjgillot Mar 27, 2020
db5be1f
Move QueryContext to the parent module.
cjgillot Mar 27, 2020
222d010
Cleanups.
cjgillot Mar 27, 2020
2d7bbda
Implement HashStable directly.
cjgillot Mar 27, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -4042,12 +4042,12 @@ version = "0.0.0"
dependencies = [
"log",
"parking_lot 0.9.0",
"rustc_ast",
"rustc-rayon-core",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_span",
"serialize",
"smallvec 1.0.0",
]
41 changes: 18 additions & 23 deletions src/librustc/dep_graph/mod.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@ use rustc_errors::Diagnostic;
use rustc_hir::def_id::DefId;

mod dep_node;
mod safe;

pub(crate) use rustc_query_system::dep_graph::DepNodeParams;
pub use rustc_query_system::dep_graph::{
@@ -17,8 +16,6 @@ pub use rustc_query_system::dep_graph::{
};

pub use dep_node::{label_strs, DepConstructor, DepKind, DepNode, DepNodeExt};
pub use safe::AssertDepGraphSafe;
pub use safe::DepGraphSafe;

pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepKind>;
pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps<DepKind>;
@@ -27,6 +24,8 @@ pub type PreviousDepGraph = rustc_query_system::dep_graph::PreviousDepGraph<DepK
pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph<DepKind>;

impl rustc_query_system::dep_graph::DepKind for DepKind {
const NULL: Self = DepKind::Null;

fn is_eval_always(&self) -> bool {
DepKind::is_eval_always(self)
}
@@ -82,6 +81,10 @@ impl rustc_query_system::dep_graph::DepKind for DepKind {
op(icx.task_deps)
})
}

fn can_reconstruct_query_key(&self) -> bool {
DepKind::can_reconstruct_query_key(self)
}
}

impl<'tcx> DepContext for TyCtxt<'tcx> {
@@ -92,6 +95,10 @@ impl<'tcx> DepContext for TyCtxt<'tcx> {
TyCtxt::create_stable_hashing_context(*self)
}

fn debug_dep_tasks(&self) -> bool {
self.sess.opts.debugging_opts.dep_tasks
}

fn try_force_from_dep_node(&self, dep_node: &DepNode) -> bool {
// FIXME: This match is just a workaround for incremental bugs and should
// be removed. https://github.com/rust-lang/rust/issues/62649 is one such
@@ -160,6 +167,14 @@ impl<'tcx> DepContext for TyCtxt<'tcx> {
self.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics)
}

fn store_diagnostics_for_anon_node(
&self,
dep_node_index: DepNodeIndex,
diagnostics: ThinVec<Diagnostic>,
) {
self.queries.on_disk_cache.store_diagnostics_for_anon_node(dep_node_index, diagnostics)
}

fn profiler(&self) -> &SelfProfilerRef {
&self.prof
}
@@ -169,23 +184,3 @@ fn def_id_corresponds_to_hir_dep_node(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
def_id.index == hir_id.owner.local_def_index
}

impl rustc_query_system::HashStableContext for StableHashingContext<'_> {
fn debug_dep_tasks(&self) -> bool {
self.sess().opts.debugging_opts.dep_tasks
}
}

impl rustc_query_system::HashStableContextProvider<StableHashingContext<'tcx>> for TyCtxt<'tcx> {
fn get_stable_hashing_context(&self) -> StableHashingContext<'tcx> {
self.create_stable_hashing_context()
}
}

impl rustc_query_system::HashStableContextProvider<StableHashingContext<'a>>
for StableHashingContext<'a>
{
fn get_stable_hashing_context(&self) -> Self {
self.clone()
}
}
9 changes: 0 additions & 9 deletions src/librustc/dep_graph/safe.rs

This file was deleted.

2 changes: 0 additions & 2 deletions src/librustc/ich/hcx.rs
Original file line number Diff line number Diff line change
@@ -194,8 +194,6 @@ impl<'a> StableHashingContextProvider<'a> for StableHashingContext<'a> {
}
}

impl<'a> crate::dep_graph::DepGraphSafe for StableHashingContext<'a> {}

impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId {
fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
panic!("Node IDs should not appear in incremental state");
4 changes: 2 additions & 2 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
@@ -1603,7 +1603,7 @@ nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};

use crate::dep_graph::TaskDeps;
use crate::dep_graph::{DepKind, TaskDeps};
use crate::ty::query;
use rustc_data_structures::sync::{self, Lock};
use rustc_data_structures::thin_vec::ThinVec;
@@ -1630,7 +1630,7 @@ pub mod tls {

/// The current query job, if any. This is updated by `JobOwner::start` in
/// `ty::query::plumbing` when executing a query.
pub query: Option<query::QueryJobId>,
pub query: Option<query::QueryJobId<DepKind>>,

/// Where to store diagnostics for the current query job, if any.
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
82 changes: 0 additions & 82 deletions src/librustc/ty/query/config.rs

This file was deleted.

566 changes: 3 additions & 563 deletions src/librustc/ty/query/job.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/librustc/ty/query/keys.rs
Original file line number Diff line number Diff line change
@@ -4,10 +4,10 @@ use crate::infer::canonical::Canonical;
use crate::mir;
use crate::traits;
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::query::caches::DefaultCacheSelector;
use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::{self, Ty, TyCtxt};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc_query_system::query::DefaultCacheSelector;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};

18 changes: 7 additions & 11 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
@@ -61,31 +61,27 @@ use std::sync::Arc;

#[macro_use]
mod plumbing;
pub(crate) use self::plumbing::CycleError;
use self::plumbing::*;
pub(crate) use rustc_query_system::query::CycleError;
use rustc_query_system::query::*;

mod stats;
pub use self::stats::print_stats;

#[cfg(parallel_compiler)]
mod job;
#[cfg(parallel_compiler)]
pub use self::job::handle_deadlock;
use self::job::QueryJobInfo;
pub use self::job::{QueryInfo, QueryJob, QueryJobId};
pub use rustc_query_system::query::{QueryInfo, QueryJob, QueryJobId};

mod keys;
use self::keys::Key;

mod values;
use self::values::Value;

mod caches;
use self::caches::CacheSelector;

mod config;
use self::config::QueryAccessors;
pub use self::config::QueryConfig;
pub(crate) use self::config::QueryDescription;
use rustc_query_system::query::QueryAccessors;
pub use rustc_query_system::query::QueryConfig;
pub(crate) use rustc_query_system::query::QueryDescription;

mod on_disk_cache;
pub use self::on_disk_cache::OnDiskCache;
3 changes: 2 additions & 1 deletion src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
@@ -994,7 +994,8 @@ fn encode_query_results<'a, 'tcx, Q, E>(
query_result_index: &mut EncodedQueryResultIndex,
) -> Result<(), E::Error>
where
Q: super::config::QueryDescription<'tcx, Value: Encodable>,
Q: super::QueryDescription<TyCtxt<'tcx>>,
Q::Value: Encodable,
E: 'a + TyEncoder,
{
let _timer = tcx
732 changes: 48 additions & 684 deletions src/librustc/ty/query/plumbing.rs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/librustc/ty/query/profiling_support.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::ty::context::TyCtxt;
use crate::ty::query::caches::QueryCache;
use crate::ty::query::plumbing::QueryState;
use measureme::{StringComponent, StringId};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfiler;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData;
use rustc_query_system::query::QueryCache;
use rustc_query_system::query::QueryState;
use std::fmt::Debug;
use std::io::Write;

@@ -160,7 +160,7 @@ where
pub(super) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
tcx: TyCtxt<'tcx>,
query_name: &'static str,
query_state: &QueryState<'tcx, C>,
query_state: &QueryState<TyCtxt<'tcx>, C>,
string_cache: &mut QueryKeyStringCache,
) where
C: QueryCache,
14 changes: 9 additions & 5 deletions src/librustc/ty/query/stats.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::ty::query::caches::QueryCache;
use crate::ty::query::config::QueryAccessors;
use crate::ty::query::plumbing::QueryState;
use crate::ty::query::queries;
use crate::ty::TyCtxt;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_query_system::query::QueryCache;
use rustc_query_system::query::QueryState;
use rustc_query_system::query::{QueryAccessors, QueryContext};

use std::any::type_name;
use std::mem;
@@ -38,7 +38,10 @@ struct QueryStats {
local_def_id_keys: Option<usize>,
}

fn stats<'tcx, C: QueryCache>(name: &'static str, map: &QueryState<'tcx, C>) -> QueryStats {
fn stats<CTX: QueryContext, C: QueryCache>(
name: &'static str,
map: &QueryState<CTX, C>,
) -> QueryStats {
let mut stats = QueryStats {
name,
#[cfg(debug_assertions)]
@@ -124,7 +127,8 @@ macro_rules! print_stats {

$($(
queries.push(stats::<
<queries::$name<'_> as QueryAccessors<'_>>::Cache,
TyCtxt<'_>,
<queries::$name<'_> as QueryAccessors<TyCtxt<'_>>>::Cache,
>(
stringify!($name),
&tcx.queries.$name,
3 changes: 0 additions & 3 deletions src/librustc_codegen_llvm/context.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@ use crate::type_::Type;
use crate::value::Value;

use rustc::bug;
use rustc::dep_graph::DepGraphSafe;
use rustc::mir::mono::CodegenUnit;
use rustc::ty::layout::{
HasParamEnv, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx,
@@ -90,8 +89,6 @@ pub struct CodegenCx<'ll, 'tcx> {
local_gen_sym_counter: Cell<usize>,
}

impl<'ll, 'tcx> DepGraphSafe for CodegenCx<'ll, 'tcx> {}

pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
let reloc_model_arg = match sess.opts.cg.relocation_model {
Some(ref s) => &s[..],
7 changes: 4 additions & 3 deletions src/librustc_macros/src/query.rs
Original file line number Diff line number Diff line change
@@ -380,7 +380,7 @@ fn add_query_description_impl(
quote! {
#[allow(unused_variables)]
fn describe(
#tcx: TyCtxt<'_>,
#tcx: TyCtxt<'tcx>,
#key: #arg,
) -> Cow<'static, str> {
format!(#desc).into()
@@ -393,7 +393,7 @@ fn add_query_description_impl(
let desc = desc.unwrap_or(quote! {});

impls.extend(quote! {
impl<'tcx> QueryDescription<'tcx> for queries::#name<'tcx> {
impl<'tcx> QueryDescription<TyCtxt<'tcx>> for queries::#name<'tcx> {
#desc
#cache
}
@@ -489,7 +489,8 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
::rustc::dep_graph::DepKind::#name => {
if <#arg as DepNodeParams<TyCtxt<'_>>>::CAN_RECONSTRUCT_QUERY_KEY {
if let Some(key) = <#arg as DepNodeParams<TyCtxt<'_>>>::recover($tcx, $dep_node) {
$tcx.force_query::<crate::ty::query::queries::#name<'_>>(
force_query::<crate::ty::query::queries::#name<'_>, _>(
$tcx,
key,
DUMMY_SP,
*$dep_node
2 changes: 1 addition & 1 deletion src/librustc_metadata/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ macro_rules! provide {
$(fn $name<$lt: $lt, T: IntoArgs>(
$tcx: TyCtxt<$lt>,
def_id_arg: T,
) -> <ty::queries::$name<$lt> as QueryConfig<$lt>>::Value {
) -> <ty::queries::$name<$lt> as QueryConfig<TyCtxt<$lt>>>::Value {
let _prof_timer =
$tcx.prof.generic_activity("metadata_decode_entry");

4 changes: 2 additions & 2 deletions src/librustc_query_system/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,12 +11,12 @@ doctest = false

[dependencies]
log = { version = "0.4", features = ["release_max_level_info", "std"] }
rustc_ast = { path = "../librustc_ast" }
rustc-rayon-core = "0.3.0"
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
rustc_hir = { path = "../librustc_hir" }
rustc_index = { path = "../librustc_index" }
rustc_macros = { path = "../librustc_macros" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc_span = { path = "../librustc_span" }
parking_lot = "0.9"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
9 changes: 7 additions & 2 deletions src/librustc_query_system/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -46,7 +46,6 @@ use super::{DepContext, DepKind};

use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable_Generic;

use std::fmt;
use std::hash::Hash;
@@ -127,7 +126,6 @@ where
/// the need to be mapped or unmapped. (This ensures we can serialize
/// them even in the absence of a tcx.)
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
#[derive(HashStable_Generic)]
pub struct WorkProductId {
hash: Fingerprint,
}
@@ -144,3 +142,10 @@ impl WorkProductId {
WorkProductId { hash: fingerprint }
}
}

impl<HCX> HashStable<HCX> for WorkProductId {
#[inline]
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
self.hash.hash_stable(hcx, hasher)
}
}
48 changes: 17 additions & 31 deletions src/librustc_query_system/dep_graph/graph.rs
Original file line number Diff line number Diff line change
@@ -20,10 +20,8 @@ use std::sync::atomic::Ordering::Relaxed;
use super::debug::EdgeFilter;
use super::prev::PreviousDepGraph;
use super::query::DepGraphQuery;
use super::safe::DepGraphSafe;
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
use super::{DepContext, DepKind, DepNode, WorkProductId};
use crate::{HashStableContext, HashStableContextProvider};

#[derive(Clone)]
pub struct DepGraph<K: DepKind> {
@@ -191,18 +189,14 @@ impl<K: DepKind> DepGraph<K> {
/// `arg` parameter.
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html
pub fn with_task<H, C, A, R>(
pub fn with_task<Ctxt: DepContext<DepKind = K>, A, R>(
&self,
key: DepNode<K>,
cx: C,
cx: Ctxt,
arg: A,
task: fn(C, A) -> R,
hash_result: impl FnOnce(&mut H, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex)
where
C: DepGraphSafe + HashStableContextProvider<H>,
H: HashStableContext,
{
task: fn(Ctxt, A) -> R,
hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex) {
self.with_task_impl(
key,
cx,
@@ -223,26 +217,22 @@ impl<K: DepKind> DepGraph<K> {
)
}

fn with_task_impl<H, C, A, R>(
fn with_task_impl<Ctxt: DepContext<DepKind = K>, A, R>(
&self,
key: DepNode<K>,
cx: C,
cx: Ctxt,
arg: A,
no_tcx: bool,
task: fn(C, A) -> R,
task: fn(Ctxt, A) -> R,
create_task: fn(DepNode<K>) -> Option<TaskDeps<K>>,
finish_task_and_alloc_depnode: fn(
&CurrentDepGraph<K>,
DepNode<K>,
Fingerprint,
Option<TaskDeps<K>>,
) -> DepNodeIndex,
hash_result: impl FnOnce(&mut H, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex)
where
C: DepGraphSafe + HashStableContextProvider<H>,
H: HashStableContext,
{
hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex) {
if let Some(ref data) = self.data {
let task_deps = create_task(key).map(Lock::new);

@@ -251,7 +241,7 @@ impl<K: DepKind> DepGraph<K> {
// anyway so that
// - we make sure that the infrastructure works and
// - we can get an idea of the runtime cost.
let mut hcx = cx.get_stable_hashing_context();
let mut hcx = cx.create_stable_hashing_context();

let result = if no_tcx {
task(cx, arg)
@@ -268,7 +258,7 @@ impl<K: DepKind> DepGraph<K> {
task_deps.map(|lock| lock.into_inner()),
);

let print_status = cfg!(debug_assertions) && hcx.debug_dep_tasks();
let print_status = cfg!(debug_assertions) && cx.debug_dep_tasks();

// Determine the color of the new DepNode.
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
@@ -335,18 +325,14 @@ impl<K: DepKind> DepGraph<K> {

/// Executes something within an "eval-always" task which is a task
/// that runs whenever anything changes.
pub fn with_eval_always_task<H, C, A, R>(
pub fn with_eval_always_task<Ctxt: DepContext<DepKind = K>, A, R>(
&self,
key: DepNode<K>,
cx: C,
cx: Ctxt,
arg: A,
task: fn(C, A) -> R,
hash_result: impl FnOnce(&mut H, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex)
where
C: DepGraphSafe + HashStableContextProvider<H>,
H: HashStableContext,
{
task: fn(Ctxt, A) -> R,
hash_result: impl FnOnce(&mut Ctxt::StableHashingContext, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex) {
self.with_task_impl(
key,
cx,
18 changes: 14 additions & 4 deletions src/librustc_query_system/dep_graph/mod.rs
Original file line number Diff line number Diff line change
@@ -3,16 +3,13 @@ mod dep_node;
mod graph;
mod prev;
mod query;
mod safe;
mod serialized;

pub use dep_node::{DepNode, DepNodeParams, WorkProductId};
pub use graph::WorkProductFileKind;
pub use graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct};
pub use prev::PreviousDepGraph;
pub use query::DepGraphQuery;
pub use safe::AssertDepGraphSafe;
pub use safe::DepGraphSafe;
pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};

use rustc_data_structures::profiling::SelfProfilerRef;
@@ -25,11 +22,13 @@ use std::hash::Hash;

pub trait DepContext: Copy {
type DepKind: self::DepKind;
type StableHashingContext: crate::HashStableContext;
type StableHashingContext;

/// Create a hashing context for hashing new results.
fn create_stable_hashing_context(&self) -> Self::StableHashingContext;

fn debug_dep_tasks(&self) -> bool;

/// Try to force a dep node to execute and see if it's green.
fn try_force_from_dep_node(&self, dep_node: &DepNode<Self::DepKind>) -> bool;

@@ -48,12 +47,21 @@ pub trait DepContext: Copy {
/// Register diagnostics for the given node, for use in next session.
fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<Diagnostic>);

/// Register diagnostics for the given node, for use in next session.
fn store_diagnostics_for_anon_node(
&self,
dep_node_index: DepNodeIndex,
diagnostics: ThinVec<Diagnostic>,
);

/// Access the profiler.
fn profiler(&self) -> &SelfProfilerRef;
}

/// Describe the different families of dependency nodes.
pub trait DepKind: Copy + fmt::Debug + Eq + Ord + Hash {
const NULL: Self;

/// Return whether this kind always require evaluation.
fn is_eval_always(&self) -> bool;

@@ -72,4 +80,6 @@ pub trait DepKind: Copy + fmt::Debug + Eq + Ord + Hash {
fn read_deps<OP>(op: OP) -> ()
where
OP: for<'a> FnOnce(Option<&'a Lock<TaskDeps<Self>>>) -> ();

fn can_reconstruct_query_key(&self) -> bool;
}
51 changes: 0 additions & 51 deletions src/librustc_query_system/dep_graph/safe.rs

This file was deleted.

27 changes: 6 additions & 21 deletions src/librustc_query_system/lib.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
#![feature(bool_to_option)]
#![feature(const_fn)]
#![feature(const_if_match)]
#![feature(const_panic)]
#![feature(core_intrinsics)]
#![feature(hash_raw_entry)]
#![feature(specialization)]
#![feature(stmt_expr_attributes)]
#![feature(vec_remove_item)]

#[macro_use]
extern crate log;
#[macro_use]
extern crate rustc_data_structures;

pub mod dep_graph;

pub trait HashStableContext {
fn debug_dep_tasks(&self) -> bool;
}

/// Something that can provide a stable hashing context.
pub trait HashStableContextProvider<Ctxt> {
fn get_stable_hashing_context(&self) -> Ctxt;
}

impl<Ctxt, T: HashStableContextProvider<Ctxt>> HashStableContextProvider<Ctxt> for &T {
fn get_stable_hashing_context(&self) -> Ctxt {
(**self).get_stable_hashing_context()
}
}

impl<Ctxt, T: HashStableContextProvider<Ctxt>> HashStableContextProvider<Ctxt> for &mut T {
fn get_stable_hashing_context(&self) -> Ctxt {
(**self).get_stable_hashing_context()
}
}
pub mod query;
3 changes: 3 additions & 0 deletions src/librustc_query_system/query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
For more information about how the query system works, see the [rustc dev guide].

[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html
Original file line number Diff line number Diff line change
@@ -1,45 +1,41 @@
use crate::dep_graph::DepNodeIndex;
use crate::ty::query::plumbing::{QueryLookup, QueryState, QueryStateShard};
use crate::ty::TyCtxt;
use crate::query::plumbing::{QueryLookup, QueryState};
use crate::query::QueryContext;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sharded::Sharded;
use std::default::Default;
use std::hash::Hash;
use std::marker::PhantomData;

pub(crate) trait CacheSelector<K, V> {
pub trait CacheSelector<K: Hash, V> {
type Cache: QueryCache<Key = K, Value = V>;
}

pub(crate) trait QueryCache: Default {
type Key;
pub trait QueryCache: Default {
type Key: Hash;
type Value;
type Sharded: Default;

/// Checks if the query is already computed and in the cache.
/// It returns the shard index and a lock guard to the shard,
/// which will be used if the query is not in the cache and we need
/// to compute it.
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
fn lookup<CTX: QueryContext, R, OnHit, OnMiss>(
&self,
state: &'tcx QueryState<'tcx, Self>,
get_cache: GetCache,
state: &QueryState<CTX, Self>,
key: Self::Key,
// `on_hit` can be called while holding a lock to the query state shard.
on_hit: OnHit,
on_miss: OnMiss,
) -> R
where
GetCache: for<'a> Fn(
&'a mut QueryStateShard<'tcx, Self::Key, Self::Sharded>,
) -> &'a mut Self::Sharded,
OnHit: FnOnce(&Self::Value, DepNodeIndex) -> R,
OnMiss: FnOnce(Self::Key, QueryLookup<'tcx, Self::Key, Self::Sharded>) -> R;
OnMiss: FnOnce(Self::Key, QueryLookup<'_, CTX, Self::Key, Self::Sharded>) -> R;

fn complete(
fn complete<CTX: QueryContext>(
&self,
tcx: TyCtxt<'tcx>,
tcx: CTX,
lock_sharded_storage: &mut Self::Sharded,
key: Self::Key,
value: Self::Value,
@@ -76,32 +72,29 @@ impl<K: Eq + Hash, V: Clone> QueryCache for DefaultCache<K, V> {
type Sharded = FxHashMap<K, (V, DepNodeIndex)>;

#[inline(always)]
fn lookup<'tcx, R, GetCache, OnHit, OnMiss>(
fn lookup<CTX: QueryContext, R, OnHit, OnMiss>(
&self,
state: &'tcx QueryState<'tcx, Self>,
get_cache: GetCache,
state: &QueryState<CTX, Self>,
key: K,
on_hit: OnHit,
on_miss: OnMiss,
) -> R
where
GetCache:
for<'a> Fn(&'a mut QueryStateShard<'tcx, K, Self::Sharded>) -> &'a mut Self::Sharded,
OnHit: FnOnce(&V, DepNodeIndex) -> R,
OnMiss: FnOnce(K, QueryLookup<'tcx, K, Self::Sharded>) -> R,
OnMiss: FnOnce(K, QueryLookup<'_, CTX, K, Self::Sharded>) -> R,
{
let mut lookup = state.get_lookup(&key);
let lock = &mut *lookup.lock;

let result = get_cache(lock).raw_entry().from_key_hashed_nocheck(lookup.key_hash, &key);
let result = lock.cache.raw_entry().from_key_hashed_nocheck(lookup.key_hash, &key);

if let Some((_, value)) = result { on_hit(&value.0, value.1) } else { on_miss(key, lookup) }
}

#[inline]
fn complete(
fn complete<CTX: QueryContext>(
&self,
_: TyCtxt<'tcx>,
_: CTX,
lock_sharded_storage: &mut Self::Sharded,
key: K,
value: V,
82 changes: 82 additions & 0 deletions src/librustc_query_system/query/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Query configuration and description traits.
use crate::dep_graph::DepNode;
use crate::dep_graph::SerializedDepNodeIndex;
use crate::query::caches::QueryCache;
use crate::query::plumbing::CycleError;
use crate::query::{QueryContext, QueryState};
use rustc_data_structures::profiling::ProfileCategory;
use rustc_span::def_id::DefId;

use rustc_data_structures::fingerprint::Fingerprint;
use std::borrow::Cow;
use std::fmt::Debug;
use std::hash::Hash;

// The parameter `CTX` is required in librustc: implementations may need to access the `'tcx`
// lifetime in `CTX = TyCtxt<'tcx>`.
pub trait QueryConfig<CTX> {
const NAME: &'static str;
const CATEGORY: ProfileCategory;

type Key: Eq + Hash + Clone + Debug;
type Value: Clone;
}

pub trait QueryAccessors<CTX: QueryContext>: QueryConfig<CTX> {
const ANON: bool;
const EVAL_ALWAYS: bool;
const DEP_KIND: CTX::DepKind;

type Cache: QueryCache<Key = Self::Key, Value = Self::Value>;

// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_state<'a>(tcx: CTX) -> &'a QueryState<CTX, Self::Cache>;

fn to_dep_node(tcx: CTX, key: &Self::Key) -> DepNode<CTX::DepKind>;

// Don't use this method to compute query results, instead use the methods on TyCtxt
fn compute(tcx: CTX, key: Self::Key) -> Self::Value;

fn hash_result(
hcx: &mut CTX::StableHashingContext,
result: &Self::Value,
) -> Option<Fingerprint>;

fn handle_cycle_error(tcx: CTX, error: CycleError<CTX::Query>) -> Self::Value;
}

pub trait QueryDescription<CTX: QueryContext>: QueryAccessors<CTX> {
fn describe(tcx: CTX, key: Self::Key) -> Cow<'static, str>;

#[inline]
fn cache_on_disk(_: CTX, _: Self::Key, _: Option<&Self::Value>) -> bool {
false
}

fn try_load_from_disk(_: CTX, _: SerializedDepNodeIndex) -> Option<Self::Value> {
panic!("QueryDescription::load_from_disk() called for an unsupported query.")
}
}

impl<CTX: QueryContext, M> QueryDescription<CTX> for M
where
M: QueryAccessors<CTX, Key = DefId>,
{
default fn describe(tcx: CTX, def_id: DefId) -> Cow<'static, str> {
if !tcx.verbose() {
format!("processing `{}`", tcx.def_path_str(def_id)).into()
} else {
let name = ::std::any::type_name::<M>();
format!("processing {:?} with query `{}`", def_id, name).into()
}
}

default fn cache_on_disk(_: CTX, _: Self::Key, _: Option<&Self::Value>) -> bool {
false
}

default fn try_load_from_disk(_: CTX, _: SerializedDepNodeIndex) -> Option<Self::Value> {
panic!("QueryDescription::load_from_disk() called for an unsupported query.")
}
}
564 changes: 564 additions & 0 deletions src/librustc_query_system/query/job.rs

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions src/librustc_query_system/query/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
mod plumbing;
pub use self::plumbing::*;

mod job;
#[cfg(parallel_compiler)]
pub use self::job::deadlock;
pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo};

mod caches;
pub use self::caches::{CacheSelector, DefaultCacheSelector, QueryCache};

mod config;
pub use self::config::{QueryAccessors, QueryConfig, QueryDescription};

use crate::dep_graph::{DepContext, DepGraph};

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::HashStable;
use rustc_data_structures::sync::Lock;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::Diagnostic;
use rustc_span::def_id::DefId;

pub trait QueryContext: DepContext {
type Query: Clone + HashStable<Self::StableHashingContext>;

fn incremental_verify_ich(&self) -> bool;
fn verbose(&self) -> bool;

/// Get string representation from DefPath.
fn def_path_str(&self, def_id: DefId) -> String;

/// Access the DepGraph.
fn dep_graph(&self) -> &DepGraph<Self::DepKind>;

/// Get the query information from the TLS context.
fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>>;

fn try_collect_active_jobs(
&self,
) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self>>>;

/// Executes a job by changing the `ImplicitCtxt` to point to the
/// new query job while it executes. It returns the diagnostics
/// captured during execution and the actual result.
fn start_query<R>(
&self,
token: QueryJobId<Self::DepKind>,
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
compute: impl FnOnce(Self) -> R,
) -> R;
}
693 changes: 693 additions & 0 deletions src/librustc_query_system/query/plumbing.rs

Large diffs are not rendered by default.