Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6f8f71c

Browse files
committedSep 6, 2023
Make create_def a side effect instead of marking the entire query as always red
1 parent d6e884d commit 6f8f71c

File tree

7 files changed

+59
-35
lines changed

7 files changed

+59
-35
lines changed
 

‎compiler/rustc_interface/src/callbacks.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
3030
fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {
3131
tls::with_context_opt(|icx| {
3232
if let Some(icx) = icx {
33-
if let Some(diagnostics) = icx.diagnostics {
34-
let mut diagnostics = diagnostics.lock();
35-
diagnostics.extend(Some(diagnostic.clone()));
36-
std::mem::drop(diagnostics);
33+
if let Some(side_effects) = icx.side_effects {
34+
let mut side_effects = side_effects.lock();
35+
side_effects.diagnostics.push(diagnostic.clone());
36+
std::mem::drop(side_effects);
3737
}
3838

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

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

+10-5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use rustc_index::IndexVec;
5555
use rustc_macros::HashStable;
5656
use rustc_query_system::dep_graph::DepNodeIndex;
5757
use rustc_query_system::ich::StableHashingContext;
58+
use rustc_query_system::query::DefIdInfo;
5859
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
5960
use rustc_session::config::CrateType;
6061
use rustc_session::cstore::{CrateStoreDyn, Untracked};
@@ -918,11 +919,15 @@ impl<'tcx> TyCtxtAt<'tcx> {
918919
parent: LocalDefId,
919920
data: hir::definitions::DefPathData,
920921
) -> TyCtxtFeed<'tcx, LocalDefId> {
921-
// This function modifies `self.definitions` using a side-effect.
922-
// We need to ensure that these side effects are re-run by the incr. comp. engine.
923-
// Depending on the forever-red node will tell the graph that the calling query
924-
// needs to be re-evaluated.
925-
self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
922+
tls::with_context_opt(|icx| {
923+
if let Some(icx) = icx {
924+
if let Some(side_effects) = icx.side_effects {
925+
let mut side_effects = side_effects.lock();
926+
side_effects.definitions.push(DefIdInfo { parent, data, span: self.span });
927+
std::mem::drop(side_effects);
928+
}
929+
}
930+
});
926931

927932
// The following call has the side effect of modifying the tables inside `definitions`.
928933
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to

‎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

+18-6
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
use rustc_index::Idx;
1211
use rustc_middle::dep_graph::{
1312
self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex,
@@ -20,16 +19,15 @@ use rustc_middle::ty::{self, print::with_no_queries, TyCtxt};
2019
use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
2120
use rustc_query_system::ich::StableHashingContext;
2221
use rustc_query_system::query::{
23-
force_query, QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects,
24-
QueryStackFrame,
22+
force_query, DefIdInfo, QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap,
23+
QuerySideEffects, QueryStackFrame,
2524
};
2625
use rustc_query_system::{LayoutOfDepth, QueryOverflow};
2726
use rustc_serialize::Decodable;
2827
use rustc_serialize::Encodable;
2928
use rustc_session::Limit;
3029
use rustc_span::def_id::LOCAL_CRATE;
3130
use std::num::NonZeroU64;
32-
use thin_vec::ThinVec;
3331

3432
#[derive(Copy, Clone)]
3533
pub struct QueryCtxt<'tcx> {
@@ -125,7 +123,7 @@ impl QueryContext for QueryCtxt<'_> {
125123
self,
126124
token: QueryJobId,
127125
depth_limit: bool,
128-
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
126+
side_effects: Option<&Lock<QuerySideEffects>>,
129127
compute: impl FnOnce() -> R,
130128
) -> R {
131129
// The `TyCtxt` stored in TLS has the same global interner lifetime
@@ -140,7 +138,7 @@ impl QueryContext for QueryCtxt<'_> {
140138
let new_icx = ImplicitCtxt {
141139
tcx: self.tcx,
142140
query: Some(token),
143-
diagnostics,
141+
side_effects,
144142
query_depth: current_icx.query_depth + depth_limit as usize,
145143
task_deps: current_icx.task_deps,
146144
};
@@ -172,6 +170,20 @@ impl QueryContext for QueryCtxt<'_> {
172170
crate_name: self.crate_name(LOCAL_CRATE),
173171
});
174172
}
173+
174+
#[tracing::instrument(level = "trace", skip(self))]
175+
fn apply_side_effects(self, side_effects: QuerySideEffects) {
176+
let handle = self.sess.diagnostic();
177+
let QuerySideEffects { diagnostics, definitions } = side_effects;
178+
179+
for mut diagnostic in diagnostics {
180+
handle.emit_diagnostic(&mut diagnostic);
181+
}
182+
183+
for DefIdInfo { parent, data, span: _ } in definitions {
184+
self.tcx.untracked().definitions.write().create_def(parent, data);
185+
}
186+
}
175187
}
176188

177189
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
@@ -936,11 +936,7 @@ impl<K: DepKind> DepGraphData<K> {
936936
// Promote the previous diagnostics to the current session.
937937
qcx.store_side_effects(dep_node_index, side_effects.clone());
938938

939-
let handle = qcx.dep_context().sess().diagnostic();
940-
941-
for mut diagnostic in side_effects.diagnostics {
942-
handle.emit_diagnostic(&mut diagnostic);
943-
}
939+
qcx.apply_side_effects(side_effects);
944940
}
945941
}
946942
}

‎compiler/rustc_query_system/src/query/mod.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_data_structures::stable_hasher::Hash64;
2020
use rustc_data_structures::sync::Lock;
2121
use rustc_errors::Diagnostic;
2222
use rustc_hir::def::DefKind;
23-
use rustc_span::def_id::DefId;
23+
use rustc_span::def_id::{DefId, LocalDefId};
2424
use rustc_span::Span;
2525
use thin_vec::ThinVec;
2626

@@ -85,18 +85,29 @@ pub struct QuerySideEffects {
8585
/// Stores any diagnostics emitted during query execution.
8686
/// These diagnostics will be re-emitted if we mark
8787
/// the query as green.
88-
pub(super) diagnostics: ThinVec<Diagnostic>,
88+
pub diagnostics: ThinVec<Diagnostic>,
89+
/// Stores any `DefId`s that were created during query execution.
90+
/// These `DefId`s will be re-created when we mark the query as green.
91+
pub definitions: ThinVec<DefIdInfo>,
92+
}
93+
94+
#[derive(Debug, Clone, Encodable, Decodable)]
95+
pub struct DefIdInfo {
96+
pub parent: LocalDefId,
97+
pub data: rustc_hir::definitions::DefPathData,
98+
pub span: Span,
8999
}
90100

91101
impl QuerySideEffects {
92102
#[inline]
93103
pub fn is_empty(&self) -> bool {
94-
let QuerySideEffects { diagnostics } = self;
95-
diagnostics.is_empty()
104+
let QuerySideEffects { diagnostics, definitions } = self;
105+
diagnostics.is_empty() && definitions.is_empty()
96106
}
97107
pub fn append(&mut self, other: QuerySideEffects) {
98-
let QuerySideEffects { diagnostics } = self;
108+
let QuerySideEffects { diagnostics, definitions } = self;
99109
diagnostics.extend(other.diagnostics);
110+
definitions.extend(other.definitions);
100111
}
101112
}
102113

@@ -114,6 +125,9 @@ pub trait QueryContext: HasDepContext {
114125
/// Register diagnostics for the given node, for use in next session.
115126
fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects);
116127

128+
/// Actually execute the side effects
129+
fn apply_side_effects(self, side_effects: QuerySideEffects);
130+
117131
/// Register diagnostics for the given node, for use in next session.
118132
fn store_side_effects_for_anon_node(
119133
self,
@@ -128,7 +142,7 @@ pub trait QueryContext: HasDepContext {
128142
self,
129143
token: QueryJobId,
130144
depth_limit: bool,
131-
diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
145+
side_effects: Option<&Lock<QuerySideEffects>>,
132146
compute: impl FnOnce() -> R,
133147
) -> R;
134148

‎compiler/rustc_query_system/src/query/plumbing.rs

+3-5
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

@@ -498,10 +497,10 @@ where
498497
}
499498

500499
let prof_timer = qcx.dep_context().profiler().query_provider();
501-
let diagnostics = Lock::new(ThinVec::new());
500+
let side_effects = Lock::new(QuerySideEffects::default());
502501

503502
let (result, dep_node_index) =
504-
qcx.start_query(job_id, query.depth_limit(), Some(&diagnostics), || {
503+
qcx.start_query(job_id, query.depth_limit(), Some(&side_effects), || {
505504
if query.anon() {
506505
return dep_graph_data.with_anon_task(*qcx.dep_context(), query.dep_kind(), || {
507506
query.compute(qcx, key)
@@ -523,8 +522,7 @@ where
523522

524523
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
525524

526-
let diagnostics = diagnostics.into_inner();
527-
let side_effects = QuerySideEffects { diagnostics };
525+
let side_effects = side_effects.into_inner();
528526

529527
if std::intrinsics::unlikely(!side_effects.is_empty()) {
530528
if query.anon() {

0 commit comments

Comments
 (0)
Failed to load comments.