1
Fork 0

Create QuerySideEffects and use it for diagnostics

This commit is contained in:
Aaron Hill 2021-07-23 16:40:26 -05:00
parent 5782f01a51
commit e6a5231238
No known key found for this signature in database
GPG key ID: B4087E510E98B164
5 changed files with 102 additions and 117 deletions

View file

@ -62,6 +62,31 @@ impl QueryStackFrame {
}
}
/// Tracks 'side effects' for a particular query.
/// This struct is saved to disk along with the query result,
/// and loaded from disk if we mark the query as green.
/// This allows us to 'replay' changes to global state
/// that would otherwise only occur if we actually
/// executed the query method.
#[derive(Debug, Clone, Default, Encodable, Decodable)]
pub struct QuerySideEffects {
/// Stores any diagnostics emitted during query execution.
/// These diagnostics will be re-emitted if we mark
/// the query as green.
pub diagnostics: ThinVec<Diagnostic>,
}
impl QuerySideEffects {
pub fn is_empty(&self) -> bool {
let QuerySideEffects { diagnostics } = self;
diagnostics.is_empty()
}
pub fn append(&mut self, other: QuerySideEffects) {
let QuerySideEffects { diagnostics } = self;
diagnostics.extend(other.diagnostics);
}
}
pub trait QueryContext: HasDepContext {
/// Get the query information from the TLS context.
fn current_query_job(&self) -> Option<QueryJobId<Self::DepKind>>;
@ -74,17 +99,17 @@ pub trait QueryContext: HasDepContext {
/// 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;
/// Load diagnostics associated to the node in the previous session.
fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec<Diagnostic>;
/// Load side effects associated to the node in the previous session.
fn load_side_effects(&self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects;
/// Register diagnostics for the given node, for use in next session.
fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<Diagnostic>);
fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects);
/// Register diagnostics for the given node, for use in next session.
fn store_diagnostics_for_anon_node(
fn store_side_effects_for_anon_node(
&self,
dep_node_index: DepNodeIndex,
diagnostics: ThinVec<Diagnostic>,
side_effects: QuerySideEffects,
);
/// Executes a job by changing the `ImplicitCtxt` to point to the

View file

@ -9,7 +9,7 @@ use crate::query::config::{QueryDescription, QueryVtable, QueryVtableExt};
use crate::query::job::{
report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId,
};
use crate::query::{QueryContext, QueryMap, QueryStackFrame};
use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHasher};
@ -479,8 +479,10 @@ where
dep_graph.read_index(dep_node_index);
if unlikely!(!diagnostics.is_empty()) {
tcx.store_diagnostics_for_anon_node(dep_node_index, diagnostics);
let side_effects = QuerySideEffects { diagnostics };
if unlikely!(!side_effects.is_empty()) {
tcx.store_side_effects_for_anon_node(dep_node_index, side_effects);
}
return job.complete(result, dep_node_index);
@ -677,8 +679,10 @@ where
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
if unlikely!(!diagnostics.is_empty()) && dep_node.kind != DepKind::NULL {
tcx.store_diagnostics(dep_node_index, diagnostics);
let side_effects = QuerySideEffects { diagnostics };
if unlikely!(!side_effects.is_empty()) && dep_node.kind != DepKind::NULL {
tcx.store_side_effects(dep_node_index, side_effects);
}
let result = job.complete(result, dep_node_index);