about summary refs log tree commit diff
path: root/compiler/rustc_query_impl
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-03-25 18:09:05 +0100
committerGitHub <noreply@github.com>2025-03-25 18:09:05 +0100
commit43297ffc22ae4c053dc9904cd8a2cb0fde1198a9 (patch)
treee4c64433e9f14c4f5ca4141e6a018dbd343c9b63 /compiler/rustc_query_impl
parent81e227583af709b43865b3069ba9e05dd595cff3 (diff)
parent34244c1477e4b485c51872fc3c6d846b4a3c6ffa (diff)
downloadrust-43297ffc22ae4c053dc9904cd8a2cb0fde1198a9.tar.gz
rust-43297ffc22ae4c053dc9904cd8a2cb0fde1198a9.zip
Rollup merge of #138581 - Zoxc:abort-handler-if-locked, r=SparrowLii
Abort in deadlock handler if we fail to get a query map

Resolving query cycles requires the complete active query map, or it may miss query cycles. We did not check that the map is completely constructed before. If there is some error collecting the map, something has gone wrong already. This adds a check to abort/panic if we fail to construct the complete map.

This can help differentiate errors from the `deadlock detected` case if constructing query map has errors in practice.

An `Option` is not used for `collect_active_jobs` as the panic handler can still make use of a partial map.
Diffstat (limited to 'compiler/rustc_query_impl')
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs24
1 files changed, 18 insertions, 6 deletions
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 6fc7f023cf0..55281cd5ac7 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -79,14 +79,20 @@ impl QueryContext for QueryCtxt<'_> {
         tls::with_related_context(self.tcx, |icx| icx.query)
     }
 
-    fn collect_active_jobs(self) -> QueryMap {
+    /// Returns a query map representing active query jobs.
+    /// It returns an incomplete map as an error if it fails
+    /// to take locks.
+    fn collect_active_jobs(self) -> Result<QueryMap, QueryMap> {
         let mut jobs = QueryMap::default();
+        let mut complete = true;
 
         for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
-            collect(self.tcx, &mut jobs);
+            if collect(self.tcx, &mut jobs).is_none() {
+                complete = false;
+            }
         }
 
-        jobs
+        if complete { Ok(jobs) } else { Err(jobs) }
     }
 
     // Interactions with on_disk_cache
@@ -139,7 +145,12 @@ impl QueryContext for QueryCtxt<'_> {
     }
 
     fn depth_limit_error(self, job: QueryJobId) {
-        let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
+        // FIXME: `collect_active_jobs` expects no locks to be held, which doesn't hold for this call.
+        let query_map = match self.collect_active_jobs() {
+            Ok(query_map) => query_map,
+            Err(query_map) => query_map,
+        };
+        let (info, depth) = job.find_dep_kind_root(query_map);
 
         let suggested_limit = match self.recursion_limit() {
             Limit(0) => Limit(2),
@@ -677,7 +688,7 @@ macro_rules! define_queries {
                 }
             }
 
-            pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
+            pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) -> Option<()> {
                 let make_query = |tcx, key| {
                     let kind = rustc_middle::dep_graph::dep_kinds::$name;
                     let name = stringify!($name);
@@ -697,6 +708,7 @@ macro_rules! define_queries {
                         stringify!($name)
                     );
                 }
+                res
             }
 
             pub(crate) fn alloc_self_profile_query_strings<'tcx>(
@@ -756,7 +768,7 @@ macro_rules! define_queries {
 
         // These arrays are used for iteration and can't be indexed by `DepKind`.
 
-        const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] =
+        const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap) -> Option<()>] =
             &[$(query_impl::$name::try_collect_active_jobs),*];
 
         const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[