about summary refs log tree commit diff
path: root/compiler/rustc_query_impl
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-19 15:51:54 +0000
committerbors <bors@rust-lang.org>2025-03-19 15:51:54 +0000
commit1aeb99d248e1b0069110cb03c6f1dcc7b36fd7f3 (patch)
tree13c3b129ec79a46ed690c912ee0a63db0597eeb1 /compiler/rustc_query_impl
parenta7fc463dd8fbeca800d4b3efc501069502cffe64 (diff)
parentb43a29711e7ab50c1ee47a2d030273c83099b15e (diff)
downloadrust-1aeb99d248e1b0069110cb03c6f1dcc7b36fd7f3.tar.gz
rust-1aeb99d248e1b0069110cb03c6f1dcc7b36fd7f3.zip
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.
Diffstat (limited to 'compiler/rustc_query_impl')
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs54
1 files changed, 26 insertions, 28 deletions
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index fa31ef5eeb0..2b8457ace8e 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -5,9 +5,7 @@
 use std::num::NonZero;
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::Lock;
 use rustc_data_structures::unord::UnordMap;
-use rustc_errors::DiagInner;
 use rustc_hashes::Hash64;
 use rustc_index::Idx;
 use rustc_middle::bug;
@@ -26,14 +24,13 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_query_system::query::{
-    QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame,
+    QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect, QueryStackFrame,
     force_query,
 };
 use rustc_query_system::{QueryOverflow, QueryOverflowNote};
 use rustc_serialize::{Decodable, Encodable};
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
-use thin_vec::ThinVec;
 
 use crate::QueryConfigRestored;
 
@@ -93,43 +90,31 @@ impl QueryContext for QueryCtxt<'_> {
     }
 
     // Interactions with on_disk_cache
-    fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects {
+    fn load_side_effect(
+        self,
+        prev_dep_node_index: SerializedDepNodeIndex,
+    ) -> Option<QuerySideEffect> {
         self.query_system
             .on_disk_cache
             .as_ref()
-            .map(|c| c.load_side_effects(self.tcx, prev_dep_node_index))
-            .unwrap_or_default()
+            .and_then(|c| c.load_side_effect(self.tcx, prev_dep_node_index))
     }
 
     #[inline(never)]
     #[cold]
-    fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
+    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_effects(dep_node_index, side_effects)
-        }
-    }
-
-    #[inline(never)]
-    #[cold]
-    fn store_side_effects_for_anon_node(
-        self,
-        dep_node_index: DepNodeIndex,
-        side_effects: QuerySideEffects,
-    ) {
-        if let Some(c) = self.query_system.on_disk_cache.as_ref() {
-            c.store_side_effects_for_anon_node(dep_node_index, side_effects)
+            c.store_side_effect(dep_node_index, side_effect)
         }
     }
 
     /// Executes a job by changing the `ImplicitCtxt` to point to the
-    /// new query job while it executes. It returns the diagnostics
-    /// captured during execution and the actual result.
+    /// new query job while it executes.
     #[inline(always)]
     fn start_query<R>(
         self,
         token: QueryJobId,
         depth_limit: bool,
-        diagnostics: Option<&Lock<ThinVec<DiagInner>>>,
         compute: impl FnOnce() -> R,
     ) -> R {
         // The `TyCtxt` stored in TLS has the same global interner lifetime
@@ -144,7 +129,6 @@ impl QueryContext for QueryCtxt<'_> {
             let new_icx = ImplicitCtxt {
                 tcx: self.tcx,
                 query: Some(token),
-                diagnostics,
                 query_depth: current_icx.query_depth + depth_limit as usize,
                 task_deps: current_icx.task_deps,
             };
@@ -501,7 +485,7 @@ where
         is_anon,
         is_eval_always,
         fingerprint_style,
-        force_from_dep_node: Some(|tcx, dep_node| {
+        force_from_dep_node: Some(|tcx, dep_node, _| {
             force_from_dep_node(Q::config(tcx), tcx, dep_node)
         }),
         try_load_from_on_disk_cache: Some(|tcx, dep_node| {
@@ -803,7 +787,7 @@ macro_rules! define_queries {
                     is_anon: false,
                     is_eval_always: false,
                     fingerprint_style: FingerprintStyle::Unit,
-                    force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)),
+                    force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)),
                     try_load_from_on_disk_cache: None,
                     name: &"Null",
                 }
@@ -815,12 +799,26 @@ macro_rules! define_queries {
                     is_anon: false,
                     is_eval_always: false,
                     fingerprint_style: FingerprintStyle::Unit,
-                    force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)),
+                    force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)),
                     try_load_from_on_disk_cache: None,
                     name: &"Red",
                 }
             }
 
+            pub(crate) fn SideEffect<'tcx>() -> DepKindStruct<'tcx> {
+                DepKindStruct {
+                    is_anon: false,
+                    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);
+                        true
+                    }),
+                    try_load_from_on_disk_cache: None,
+                    name: &"SideEffect",
+                }
+            }
+
             pub(crate) fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
                 DepKindStruct {
                     is_anon: true,