Remove QueryContext.

`rustc_query_system` has been reduced so much that it's no longer
needed. This avoids a lot of indirection and abstraction.
This commit is contained in:
Nicholas Nethercote
2026-02-11 19:06:33 +11:00
parent a33907a7a5
commit 32e6a1a0ab
13 changed files with 75 additions and 127 deletions
-1
View File
@@ -4500,7 +4500,6 @@ dependencies = [
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
@@ -45,7 +45,7 @@
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::bug;
use rustc_middle::dep_graph::{
DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter, dep_kinds,
DepGraphQuery, DepKind, DepNode, DepNodeFilter, EdgeFilter, dep_kinds,
};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
@@ -27,7 +27,7 @@
Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, find_attr,
intravisit,
};
use rustc_middle::dep_graph::{DepNode, DepNodeExt, dep_kind_from_label, label_strs};
use rustc_middle::dep_graph::{DepNode, dep_kind_from_label, label_strs};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_span::{Span, Symbol};
+2 -3
View File
@@ -13,9 +13,8 @@
use rustc_errors::{DiagInner, TRACK_DIAGNOSTIC};
use rustc_middle::dep_graph::dep_node::default_dep_kind_debug;
use rustc_middle::dep_graph::{DepContext, DepKind, DepNode, DepNodeExt, TaskDepsRef};
use rustc_middle::dep_graph::{DepContext, DepKind, DepNode, TaskDepsRef};
use rustc_middle::ty::tls;
use rustc_query_impl::QueryCtxt;
fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
tls::with_context_opt(|icx| {
@@ -41,7 +40,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
fn track_diagnostic<R>(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
tls::with_context_opt(|icx| {
if let Some(icx) = icx {
icx.tcx.dep_graph.record_diagnostic(QueryCtxt::new(icx.tcx), &diagnostic);
icx.tcx.dep_graph.record_diagnostic(icx.tcx, &diagnostic);
// Diagnostics are tracked, we can ignore the dependency.
let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() };
@@ -434,19 +434,7 @@ pub(crate) fn make_metadata(tcx: TyCtxt<'_>) -> DepNode {
DepNode::construct(tcx, dep_kinds::Metadata, &())
}
pub trait DepNodeExt: Sized {
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId>;
fn from_label_string(
tcx: TyCtxt<'_>,
label: &str,
def_path_hash: DefPathHash,
) -> Result<Self, ()>;
fn has_label_string(label: &str) -> bool;
}
impl DepNodeExt for DepNode {
impl DepNode {
/// Extracts the DefId corresponding to this DepNode. This will work
/// if two conditions are met:
///
@@ -457,7 +445,7 @@ impl DepNodeExt for DepNode {
/// DepNode. Condition (2) might not be fulfilled if a DepNode
/// refers to something from the previous compilation session that
/// has been removed.
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()))
} else {
@@ -465,8 +453,7 @@ fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
}
}
/// Used in testing
fn from_label_string(
pub fn from_label_string(
tcx: TyCtxt<'_>,
label: &str,
def_path_hash: DefPathHash,
@@ -482,8 +469,7 @@ fn from_label_string(
}
}
/// Used in testing
fn has_label_string(label: &str) -> bool {
pub fn has_label_string(label: &str) -> bool {
dep_kind_from_label_string(label).is_ok()
}
}
@@ -3,7 +3,7 @@
use rustc_hir::definitions::DefPathHash;
use rustc_hir::{HirId, ItemLocalId, OwnerId};
use crate::dep_graph::{DepContext, DepNode, DepNodeExt, DepNodeKey, FingerprintStyle};
use crate::dep_graph::{DepContext, DepNode, DepNodeKey, FingerprintStyle};
use crate::ty::TyCtxt;
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for () {
+58 -43
View File
@@ -27,7 +27,7 @@
use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
use super::{DepContext, DepKind, DepNode, Deps, HasDepContext, WorkProductId};
use crate::dep_graph::edges::EdgesVec;
use crate::query::QueryContext;
use crate::ty::TyCtxt;
use crate::verify_ich::incremental_verify_ich;
pub struct DepGraph<D: Deps> {
@@ -525,16 +525,12 @@ pub fn read_index(&self, dep_node_index: DepNodeIndex) {
/// This encodes a diagnostic by creating a node with an unique index and associating
/// `diagnostic` with it, for use in the next session.
#[inline]
pub fn record_diagnostic<'tcx, Qcx: QueryContext<'tcx>>(
&self,
qcx: Qcx,
diagnostic: &DiagInner,
) {
pub fn record_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) {
if let Some(ref data) = self.data {
D::read_deps(|task_deps| match task_deps {
TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return,
TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => {
self.read_index(data.encode_diagnostic(qcx, diagnostic));
self.read_index(data.encode_diagnostic(tcx, diagnostic));
}
})
}
@@ -542,13 +538,13 @@ pub fn record_diagnostic<'tcx, Qcx: QueryContext<'tcx>>(
/// This forces a diagnostic node green by running its side effect. `prev_index` would
/// refer to a node created used `encode_diagnostic` in the previous session.
#[inline]
pub fn force_diagnostic_node<'tcx, Qcx: QueryContext<'tcx>>(
pub fn force_diagnostic_node<'tcx>(
&self,
qcx: Qcx,
tcx: TyCtxt<'tcx>,
prev_index: SerializedDepNodeIndex,
) {
if let Some(ref data) = self.data {
data.force_diagnostic_node(qcx, prev_index);
data.force_diagnostic_node(tcx, prev_index);
}
}
@@ -688,11 +684,7 @@ pub fn mark_debug_loaded_from_disk(&self, dep_node: DepNode) {
/// This encodes a diagnostic by creating a node with an unique index and associating
/// `diagnostic` with it, for use in the next session.
#[inline]
fn encode_diagnostic<'tcx, Qcx: QueryContext<'tcx>>(
&self,
qcx: Qcx,
diagnostic: &DiagInner,
) -> DepNodeIndex {
fn encode_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) -> DepNodeIndex {
// Use `send_new` so we get an unique index, even though the dep node is not.
let dep_node_index = self.current.encoder.send_new(
DepNode {
@@ -705,24 +697,20 @@ fn encode_diagnostic<'tcx, Qcx: QueryContext<'tcx>>(
std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(),
);
let side_effect = QuerySideEffect::Diagnostic(diagnostic.clone());
qcx.store_side_effect(dep_node_index, side_effect);
tcx.store_side_effect(dep_node_index, side_effect);
dep_node_index
}
/// This forces a diagnostic node green by running its side effect. `prev_index` would
/// refer to a node created used `encode_diagnostic` in the previous session.
#[inline]
fn force_diagnostic_node<'tcx, Qcx: QueryContext<'tcx>>(
&self,
qcx: Qcx,
prev_index: SerializedDepNodeIndex,
) {
fn force_diagnostic_node<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) {
D::with_deps(TaskDepsRef::Ignore, || {
let side_effect = qcx.load_side_effect(prev_index).unwrap();
let side_effect = tcx.load_side_effect(prev_index).unwrap();
match &side_effect {
QuerySideEffect::Diagnostic(diagnostic) => {
qcx.dep_context().sess().dcx().emit_diagnostic(diagnostic.clone());
tcx.dcx().emit_diagnostic(diagnostic.clone());
}
}
@@ -741,7 +729,7 @@ fn force_diagnostic_node<'tcx, Qcx: QueryContext<'tcx>>(
true,
);
// This will just overwrite the same value for concurrent calls.
qcx.store_side_effect(dep_node_index, side_effect);
tcx.store_side_effect(dep_node_index, side_effect);
})
}
@@ -867,12 +855,12 @@ fn node_color(&self, dep_node: &DepNode) -> DepNodeColor {
DepNodeColor::Unknown
}
pub fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
pub fn try_mark_green<'tcx>(
&self,
qcx: Qcx,
tcx: TyCtxt<'tcx>,
dep_node: &DepNode,
) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
self.data().and_then(|data| data.try_mark_green(qcx, dep_node))
self.data().and_then(|data| data.try_mark_green(tcx, dep_node))
}
}
@@ -882,12 +870,12 @@ impl<D: Deps> DepGraphData<D> {
/// A node will have an index, when it's already been marked green, or when we can mark it
/// green. This function will mark the current task as a reader of the specified node, when
/// a node index can be found for that node.
pub fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
pub fn try_mark_green<'tcx>(
&self,
qcx: Qcx,
tcx: TyCtxt<'tcx>,
dep_node: &DepNode,
) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
debug_assert!(!qcx.dep_context().is_eval_always(dep_node.kind));
debug_assert!(!tcx.is_eval_always(dep_node.kind));
// Return None if the dep node didn't exist in the previous session
let prev_index = self.previous.node_to_index_opt(dep_node)?;
@@ -902,16 +890,16 @@ pub fn try_mark_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
// in the previous compilation session too, so we can try to
// mark it as green by recursively marking all of its
// dependencies green.
self.try_mark_previous_green(qcx, prev_index, None)
self.try_mark_previous_green(tcx, prev_index, None)
.map(|dep_node_index| (prev_index, dep_node_index))
}
}
}
#[instrument(skip(self, qcx, parent_dep_node_index, frame), level = "debug")]
fn try_mark_parent_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
#[instrument(skip(self, tcx, parent_dep_node_index, frame), level = "debug")]
fn try_mark_parent_green<'tcx>(
&self,
qcx: Qcx,
tcx: TyCtxt<'tcx>,
parent_dep_node_index: SerializedDepNodeIndex,
frame: &MarkFrame<'_>,
) -> Option<()> {
@@ -944,13 +932,13 @@ fn try_mark_parent_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
// We don't know the state of this dependency. If it isn't
// an eval_always node, let's try to mark it green recursively.
if !qcx.dep_context().is_eval_always(dep_dep_node.kind) {
if !tcx.is_eval_always(dep_dep_node.kind) {
debug!(
"state of dependency {:?} ({}) is unknown, trying to mark it green",
dep_dep_node, dep_dep_node.hash,
);
let node_index = self.try_mark_previous_green(qcx, parent_dep_node_index, Some(frame));
let node_index = self.try_mark_previous_green(tcx, parent_dep_node_index, Some(frame));
if node_index.is_some() {
debug!("managed to MARK dependency {dep_dep_node:?} as green");
@@ -960,7 +948,7 @@ fn try_mark_parent_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
// We failed to mark it green, so we try to force the query.
debug!("trying to force dependency {dep_dep_node:?}");
if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) {
if !tcx.dep_context().try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) {
// The DepNode could not be forced.
debug!("dependency {dep_dep_node:?} could not be forced");
return None;
@@ -978,7 +966,7 @@ fn try_mark_parent_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
DepNodeColor::Unknown => {}
}
if let None = qcx.dep_context().sess().dcx().has_errors_or_delayed_bugs() {
if let None = tcx.dcx().has_errors_or_delayed_bugs() {
panic!("try_mark_previous_green() - Forcing the DepNode should have set its color")
}
@@ -997,10 +985,10 @@ fn try_mark_parent_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
}
/// Try to mark a dep-node which existed in the previous compilation session as green.
#[instrument(skip(self, qcx, prev_dep_node_index, frame), level = "debug")]
fn try_mark_previous_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
#[instrument(skip(self, tcx, prev_dep_node_index, frame), level = "debug")]
fn try_mark_previous_green<'tcx>(
&self,
qcx: Qcx,
tcx: TyCtxt<'tcx>,
prev_dep_node_index: SerializedDepNodeIndex,
frame: Option<&MarkFrame<'_>>,
) -> Option<DepNodeIndex> {
@@ -1008,14 +996,14 @@ fn try_mark_previous_green<'tcx, Qcx: QueryContext<'tcx, Deps = D>>(
// We never try to mark eval_always nodes as green
debug_assert!(
!qcx.dep_context()
!tcx.dep_context()
.is_eval_always(self.previous.index_to_node(prev_dep_node_index).kind)
);
let prev_deps = self.previous.edge_targets_from(prev_dep_node_index);
for dep_dep_node_index in prev_deps {
self.try_mark_parent_green(qcx, dep_dep_node_index, &frame)?;
self.try_mark_parent_green(tcx, dep_dep_node_index, &frame)?;
}
// If we got here without hitting a `return` that means that all
@@ -1508,3 +1496,30 @@ fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepN
See <https://github.com/rust-lang/rust/pull/91919>."
)
}
impl<'tcx> TyCtxt<'tcx> {
/// Return whether this kind always require evaluation.
#[inline(always)]
fn is_eval_always(self, kind: DepKind) -> bool {
self.dep_kind_vtable(kind).is_eval_always
}
// Interactions with on_disk_cache
fn load_side_effect(
self,
prev_dep_node_index: SerializedDepNodeIndex,
) -> Option<QuerySideEffect> {
self.query_system
.on_disk_cache
.as_ref()
.and_then(|c| c.load_side_effect(self, prev_dep_node_index))
}
#[inline(never)]
#[cold]
fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
if let Some(c) = self.query_system.on_disk_cache.as_ref() {
c.store_side_effect(dep_node_index, side_effect)
}
}
}
+2 -2
View File
@@ -7,8 +7,7 @@
use tracing::instrument;
pub use self::dep_node::{
DepKind, DepNode, DepNodeExt, DepNodeKey, WorkProductId, dep_kind_from_label, dep_kinds,
label_strs,
DepKind, DepNode, DepNodeKey, WorkProductId, dep_kind_from_label, dep_kinds, label_strs,
};
pub use self::graph::{
DepGraphData, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result,
@@ -52,6 +51,7 @@ fn fingerprint_style(self, kind: DepKind) -> FingerprintStyle {
#[inline(always)]
/// Return whether this kind always require evaluation.
// FIXME: remove this in favour of the version on `TyCtxt`.
fn is_eval_always(self, kind: DepKind) -> bool {
self.dep_kind_vtable(kind).is_eval_always
}
-18
View File
@@ -1,6 +1,4 @@
use rustc_data_structures::jobserver::Proxy;
use rustc_hir::def_id::LocalDefId;
use rustc_query_system::query::QuerySideEffect;
pub use self::caches::{
DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache,
@@ -12,7 +10,6 @@
TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk,
};
pub use self::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra};
use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
pub use crate::queries::Providers;
use crate::ty::TyCtxt;
@@ -36,18 +33,3 @@ pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> Str
format!("module `{}`", tcx.def_path_str(def_id))
}
}
pub trait QueryContext<'tcx>: HasDepContext {
/// Gets a jobserver reference which is used to release then acquire
/// a token while waiting on a query.
fn jobserver_proxy(&self) -> &Proxy;
/// Load a side effect associated to the node in the previous session.
fn load_side_effect(
self,
prev_dep_node_index: SerializedDepNodeIndex,
) -> Option<QuerySideEffect>;
/// Register a side effect for the given node, for use in next session.
fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect);
}
-1
View File
@@ -14,7 +14,6 @@ rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
@@ -4,7 +4,7 @@
use rustc_middle::ty::TyCtxt;
use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner};
use crate::{QueryCtxt, QueryDispatcherUnerased, QueryFlags};
use crate::{QueryDispatcherUnerased, QueryFlags};
/// [`DepKindVTable`] constructors for special dep kinds that aren't queries.
#[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")]
@@ -45,7 +45,7 @@ pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> {
is_eval_always: false,
fingerprint_style: FingerprintStyle::Unit,
force_from_dep_node: Some(|tcx, _, prev_index| {
tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index);
tcx.dep_graph.force_diagnostic_node(tcx, prev_index);
true
}),
try_load_from_on_disk_cache: None,
+2 -2
View File
@@ -495,7 +495,7 @@ fn try_load_from_disk_and_cache_in_memory<'tcx, C: QueryCache, const FLAGS: Quer
// Note this function can be called concurrently from the same query
// We must ensure that this is handled correctly.
let (prev_dep_node_index, dep_node_index) = dep_graph_data.try_mark_green(qcx, dep_node)?;
let (prev_dep_node_index, dep_node_index) = dep_graph_data.try_mark_green(qcx.tcx, dep_node)?;
debug_assert!(dep_graph_data.is_index_green(prev_dep_node_index));
@@ -602,7 +602,7 @@ fn ensure_must_run<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
let dep_node = query.construct_dep_node(qcx.tcx, key);
let dep_graph = &qcx.tcx.dep_graph;
let serialized_dep_node_index = match dep_graph.try_mark_green(qcx, &dep_node) {
let serialized_dep_node_index = match dep_graph.try_mark_green(qcx.tcx, &dep_node) {
None => {
// A None return from `try_mark_green` means that this is either
// a new dep node or that the dep node has already been marked red.
+2 -34
View File
@@ -4,7 +4,6 @@
use std::num::NonZero;
use rustc_data_structures::jobserver::Proxy;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::unord::UnordMap;
@@ -24,14 +23,12 @@
};
use rustc_middle::query::plumbing::QueryVTable;
use rustc_middle::query::{
Key, QueryCache, QueryContext, QueryJobId, QueryStackDeferred, QueryStackFrame,
QueryStackFrameExtra,
Key, QueryCache, QueryJobId, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra,
};
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::print::with_reduced_queries;
use rustc_middle::ty::tls::{self, ImplicitCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_query_system::query::QuerySideEffect;
use rustc_serialize::{Decodable, Encodable};
use rustc_span::def_id::LOCAL_CRATE;
@@ -40,8 +37,6 @@
use crate::job::{QueryJobMap, find_dep_kind_root};
use crate::{QueryDispatcherUnerased, QueryFlags, SemiDynamicQueryDispatcher};
/// Implements [`QueryContext`] for use by [`rustc_query_system`], since that
/// crate does not have direct access to [`TyCtxt`].
#[derive(Copy, Clone)]
pub struct QueryCtxt<'tcx> {
pub tcx: TyCtxt<'tcx>,
@@ -156,35 +151,8 @@ fn dep_context(&self) -> &Self::DepContext {
}
}
impl<'tcx> QueryContext<'tcx> for QueryCtxt<'tcx> {
#[inline]
fn jobserver_proxy(&self) -> &Proxy {
&self.tcx.jobserver_proxy
}
// Interactions with on_disk_cache
fn load_side_effect(
self,
prev_dep_node_index: SerializedDepNodeIndex,
) -> Option<QuerySideEffect> {
self.tcx
.query_system
.on_disk_cache
.as_ref()
.and_then(|c| c.load_side_effect(self.tcx, prev_dep_node_index))
}
#[inline(never)]
#[cold]
fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
if let Some(c) = self.tcx.query_system.on_disk_cache.as_ref() {
c.store_side_effect(dep_node_index, side_effect)
}
}
}
pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool {
tcx.dep_graph.try_mark_green(QueryCtxt::new(tcx), dep_node).is_some()
tcx.dep_graph.try_mark_green(tcx, dep_node).is_some()
}
pub(super) fn encode_all_query_results<'tcx>(