Skip to content

Commit cf6aab8

Browse files
committed
Generalize query side effect handling to make future additions easier
1 parent caa05bc commit cf6aab8

File tree

6 files changed

+28
-21
lines changed

6 files changed

+28
-21
lines changed

compiler/rustc_interface/src/callbacks.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
3232
fn track_diagnostic(diagnostic: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
3333
tls::with_context_opt(|icx| {
3434
if let Some(icx) = icx {
35-
if let Some(diagnostics) = icx.diagnostics {
36-
diagnostics.lock().extend(Some(diagnostic.clone()));
35+
if let Some(side_effects) = icx.side_effects {
36+
let mut side_effects = side_effects.lock();
37+
side_effects.diagnostics.push(diagnostic.clone());
38+
std::mem::drop(side_effects);
3739
}
3840

3941
// Diagnostics are tracked, we can ignore the dependency.

compiler/rustc_middle/src/ty/context/tls.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ use super::{GlobalCtxt, TyCtxt};
33
use crate::dep_graph::TaskDepsRef;
44
use crate::query::plumbing::QueryJobId;
55
use rustc_data_structures::sync::{self, Lock};
6-
use rustc_errors::Diagnostic;
6+
use rustc_query_system::query::QuerySideEffects;
77
#[cfg(not(parallel_compiler))]
88
use std::cell::Cell;
99
use std::mem;
1010
use std::ptr;
11-
use thin_vec::ThinVec;
1211

1312
/// This is the implicit state of rustc. It contains the current
1413
/// `TyCtxt` and query. It is updated when creating a local interner or
@@ -26,7 +25,7 @@ pub struct ImplicitCtxt<'a, 'tcx> {
2625

2726
/// Where to store diagnostics for the current query job, if any.
2827
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
29-
pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
28+
pub side_effects: Option<&'a Lock<QuerySideEffects>>,
3029

3130
/// Used to prevent queries from calling too deeply.
3231
pub query_depth: usize,
@@ -42,7 +41,7 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
4241
ImplicitCtxt {
4342
tcx,
4443
query: None,
45-
diagnostics: None,
44+
side_effects: None,
4645
query_depth: 0,
4746
task_deps: TaskDepsRef::Ignore,
4847
}

compiler/rustc_query_impl/src/plumbing.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::rustc_middle::ty::TyEncoder;
77
use crate::QueryConfigRestored;
88
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
99
use rustc_data_structures::sync::Lock;
10-
use rustc_errors::Diagnostic;
1110

1211
use rustc_index::Idx;
1312
use rustc_middle::dep_graph::dep_kinds;
@@ -31,7 +30,6 @@ use rustc_serialize::Encodable;
3130
use rustc_session::Limit;
3231
use rustc_span::def_id::LOCAL_CRATE;
3332
use std::num::NonZeroU64;
34-
use thin_vec::ThinVec;
3533

3634
#[derive(Copy, Clone)]
3735
pub struct QueryCtxt<'tcx> {
@@ -127,7 +125,7 @@ impl QueryContext for QueryCtxt<'_> {
127125
self,
128126
token: QueryJobId,
129127
depth_limit: bool,
130-
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
128+
side_effects: Option<&Lock<QuerySideEffects>>,
131129
compute: impl FnOnce() -> R,
132130
) -> R {
133131
// The `TyCtxt` stored in TLS has the same global interner lifetime
@@ -142,7 +140,7 @@ impl QueryContext for QueryCtxt<'_> {
142140
let new_icx = ImplicitCtxt {
143141
tcx: self.tcx,
144142
query: Some(token),
145-
diagnostics,
143+
side_effects,
146144
query_depth: current_icx.query_depth + depth_limit as usize,
147145
task_deps: current_icx.task_deps,
148146
};
@@ -174,6 +172,16 @@ impl QueryContext for QueryCtxt<'_> {
174172
crate_name: self.crate_name(LOCAL_CRATE),
175173
});
176174
}
175+
176+
#[tracing::instrument(level = "trace", skip(self))]
177+
fn apply_side_effects(self, side_effects: QuerySideEffects) {
178+
let dcx = self.dep_context().sess().dcx();
179+
let QuerySideEffects { diagnostics } = side_effects;
180+
181+
for diagnostic in diagnostics {
182+
dcx.emit_diagnostic(diagnostic);
183+
}
184+
}
177185
}
178186

179187
pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool {

compiler/rustc_query_system/src/dep_graph/graph.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -923,11 +923,7 @@ impl<D: Deps> DepGraphData<D> {
923923
// Promote the previous diagnostics to the current session.
924924
qcx.store_side_effects(dep_node_index, side_effects.clone());
925925

926-
let dcx = qcx.dep_context().sess().dcx();
927-
928-
for diagnostic in side_effects.diagnostics {
929-
dcx.emit_diagnostic(diagnostic);
930-
}
926+
qcx.apply_side_effects(side_effects);
931927
}
932928
}
933929
}

compiler/rustc_query_system/src/query/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub struct QuerySideEffects {
8989
/// Stores any diagnostics emitted during query execution.
9090
/// These diagnostics will be re-emitted if we mark
9191
/// the query as green.
92-
pub(super) diagnostics: ThinVec<Diagnostic>,
92+
pub diagnostics: ThinVec<Diagnostic>,
9393
}
9494

9595
impl QuerySideEffects {
@@ -121,6 +121,9 @@ pub trait QueryContext: HasDepContext {
121121
/// Register diagnostics for the given node, for use in next session.
122122
fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects);
123123

124+
/// Actually execute the side effects
125+
fn apply_side_effects(self, side_effects: QuerySideEffects);
126+
124127
/// Register diagnostics for the given node, for use in next session.
125128
fn store_side_effects_for_anon_node(
126129
self,
@@ -135,7 +138,7 @@ pub trait QueryContext: HasDepContext {
135138
self,
136139
token: QueryJobId,
137140
depth_limit: bool,
138-
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
141+
side_effects: Option<&Lock<QuerySideEffects>>,
139142
compute: impl FnOnce() -> R,
140143
) -> R;
141144

compiler/rustc_query_system/src/query/plumbing.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use std::collections::hash_map::Entry;
2626
use std::fmt::Debug;
2727
use std::hash::Hash;
2828
use std::mem;
29-
use thin_vec::ThinVec;
3029

3130
use super::QueryConfig;
3231

@@ -513,10 +512,10 @@ where
513512
}
514513

515514
let prof_timer = qcx.dep_context().profiler().query_provider();
516-
let diagnostics = Lock::new(ThinVec::new());
515+
let side_effects = Lock::new(QuerySideEffects::default());
517516

518517
let (result, dep_node_index) =
519-
qcx.start_query(job_id, query.depth_limit(), Some(&diagnostics), || {
518+
qcx.start_query(job_id, query.depth_limit(), Some(&side_effects), || {
520519
if query.anon() {
521520
return dep_graph_data.with_anon_task(*qcx.dep_context(), query.dep_kind(), || {
522521
query.compute(qcx, key)
@@ -538,7 +537,7 @@ where
538537

539538
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
540539

541-
let side_effects = QuerySideEffects { diagnostics: diagnostics.into_inner() };
540+
let side_effects = side_effects.into_inner();
542541

543542
if std::intrinsics::unlikely(side_effects.maybe_any()) {
544543
if query.anon() {

0 commit comments

Comments
 (0)