Auto merge of #122156 - Zoxc:side-effect-dep-node, r=oli-obk
Represent diagnostic side effects as dep nodes This changes diagnostic to be tracked as a special dep node (`SideEffect`) instead of having a list of side effects associated with each dep node. `SideEffect` is always red and when forced, it emits the diagnostic and marks itself green. Each emitted diagnostic generates a new `SideEffect` with an unique dep node index. Some implications of this: - Diagnostic may now be emitted more than once as they can be emitted once when the `SideEffect` gets marked green and again if the task it depends on needs to be re-executed due to another node being red. It relies on deduplicating of diagnostics to avoid that. - Anon tasks which emits diagnostics will no longer *incorrectly* be merged with other anon tasks. - Reusing a CGU will now emit diagnostics from the task generating it.
This commit is contained in:
commit
1aeb99d248
12 changed files with 185 additions and 206 deletions
|
@ -79,6 +79,7 @@ rustc_query_append!(define_dep_nodes![
|
|||
[] fn Null() -> (),
|
||||
/// We use this to create a forever-red node.
|
||||
[] fn Red() -> (),
|
||||
[] fn SideEffect() -> (),
|
||||
[] fn TraitSelect() -> (),
|
||||
[] fn CompileCodegenUnit() -> (),
|
||||
[] fn CompileMonoItem() -> (),
|
||||
|
|
|
@ -46,6 +46,7 @@ impl Deps for DepsType {
|
|||
|
||||
const DEP_KIND_NULL: DepKind = dep_kinds::Null;
|
||||
const DEP_KIND_RED: DepKind = dep_kinds::Red;
|
||||
const DEP_KIND_SIDE_EFFECT: DepKind = dep_kinds::SideEffect;
|
||||
const DEP_KIND_MAX: u16 = dep_node::DEP_KIND_VARIANTS - 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, Stab
|
|||
use rustc_hir::definitions::DefPathHash;
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_query_system::query::QuerySideEffects;
|
||||
use rustc_query_system::query::QuerySideEffect;
|
||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||
use rustc_session::Session;
|
||||
|
@ -55,9 +55,9 @@ pub struct OnDiskCache {
|
|||
// The complete cache data in serialized form.
|
||||
serialized_data: RwLock<Option<Mmap>>,
|
||||
|
||||
// Collects all `QuerySideEffects` created during the current compilation
|
||||
// Collects all `QuerySideEffect` created during the current compilation
|
||||
// session.
|
||||
current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffects>>,
|
||||
current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffect>>,
|
||||
|
||||
file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>,
|
||||
|
||||
|
@ -68,7 +68,7 @@ pub struct OnDiskCache {
|
|||
// `serialized_data`.
|
||||
query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
|
||||
|
||||
// A map from dep-node to the position of any associated `QuerySideEffects` in
|
||||
// A map from dep-node to the position of any associated `QuerySideEffect` in
|
||||
// `serialized_data`.
|
||||
prev_side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
|
||||
|
||||
|
@ -270,10 +270,10 @@ impl OnDiskCache {
|
|||
.current_side_effects
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(dep_node_index, side_effects)| {
|
||||
.map(|(dep_node_index, side_effect)| {
|
||||
let pos = AbsoluteBytePos::new(encoder.position());
|
||||
let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
|
||||
encoder.encode_tagged(dep_node_index, side_effects);
|
||||
encoder.encode_tagged(dep_node_index, side_effect);
|
||||
|
||||
(dep_node_index, pos)
|
||||
})
|
||||
|
@ -352,24 +352,23 @@ impl OnDiskCache {
|
|||
})
|
||||
}
|
||||
|
||||
/// Loads a `QuerySideEffects` created during the previous compilation session.
|
||||
pub fn load_side_effects(
|
||||
/// Loads a `QuerySideEffect` created during the previous compilation session.
|
||||
pub fn load_side_effect(
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
dep_node_index: SerializedDepNodeIndex,
|
||||
) -> QuerySideEffects {
|
||||
let side_effects: Option<QuerySideEffects> =
|
||||
) -> Option<QuerySideEffect> {
|
||||
let side_effect: Option<QuerySideEffect> =
|
||||
self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index);
|
||||
|
||||
side_effects.unwrap_or_default()
|
||||
side_effect
|
||||
}
|
||||
|
||||
/// Stores a `QuerySideEffects` emitted during the current compilation session.
|
||||
/// Anything stored like this will be available via `load_side_effects` in
|
||||
/// Stores a `QuerySideEffect` emitted during the current compilation session.
|
||||
/// Anything stored like this will be available via `load_side_effect` in
|
||||
/// the next compilation session.
|
||||
pub fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
|
||||
pub fn store_side_effect(&self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
|
||||
let mut current_side_effects = self.current_side_effects.borrow_mut();
|
||||
let prev = current_side_effects.insert(dep_node_index, side_effects);
|
||||
let prev = current_side_effects.insert(dep_node_index, side_effect);
|
||||
debug_assert!(prev.is_none());
|
||||
}
|
||||
|
||||
|
@ -395,21 +394,6 @@ impl OnDiskCache {
|
|||
opt_value
|
||||
}
|
||||
|
||||
/// Stores side effect emitted during computation of an anonymous query.
|
||||
/// Since many anonymous queries can share the same `DepNode`, we aggregate
|
||||
/// them -- as opposed to regular queries where we assume that there is a
|
||||
/// 1:1 relationship between query-key and `DepNode`.
|
||||
pub fn store_side_effects_for_anon_node(
|
||||
&self,
|
||||
dep_node_index: DepNodeIndex,
|
||||
side_effects: QuerySideEffects,
|
||||
) {
|
||||
let mut current_side_effects = self.current_side_effects.borrow_mut();
|
||||
|
||||
let x = current_side_effects.entry(dep_node_index).or_default();
|
||||
x.append(side_effects);
|
||||
}
|
||||
|
||||
fn load_indexed<'tcx, T>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use std::{mem, ptr};
|
||||
|
||||
use rustc_data_structures::sync::{self, Lock};
|
||||
use rustc_errors::DiagInner;
|
||||
use thin_vec::ThinVec;
|
||||
use rustc_data_structures::sync;
|
||||
|
||||
use super::{GlobalCtxt, TyCtxt};
|
||||
use crate::dep_graph::TaskDepsRef;
|
||||
|
@ -22,10 +20,6 @@ pub struct ImplicitCtxt<'a, 'tcx> {
|
|||
/// `ty::query::plumbing` when executing a query.
|
||||
pub query: Option<QueryJobId>,
|
||||
|
||||
/// 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.
|
||||
pub diagnostics: Option<&'a Lock<ThinVec<DiagInner>>>,
|
||||
|
||||
/// Used to prevent queries from calling too deeply.
|
||||
pub query_depth: usize,
|
||||
|
||||
|
@ -37,13 +31,7 @@ pub struct ImplicitCtxt<'a, 'tcx> {
|
|||
impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
|
||||
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
|
||||
let tcx = TyCtxt { gcx };
|
||||
ImplicitCtxt {
|
||||
tcx,
|
||||
query: None,
|
||||
diagnostics: None,
|
||||
query_depth: 0,
|
||||
task_deps: TaskDepsRef::Ignore,
|
||||
}
|
||||
ImplicitCtxt { tcx, query: None, query_depth: 0, task_deps: TaskDepsRef::Ignore }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue