@@ -3,23 +3,23 @@ use std::mem;
33
44use rustc_data_structures:: hash_table:: { Entry , HashTable } ;
55use rustc_data_structures:: stack:: ensure_sufficient_stack;
6+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
67use rustc_data_structures:: { outline, sharded, sync} ;
78use rustc_errors:: { Diag , FatalError , StashKey } ;
89use rustc_middle:: dep_graph:: { DepGraphData , DepNodeKey , SerializedDepNodeIndex } ;
910use rustc_middle:: query:: plumbing:: QueryVTable ;
1011use rustc_middle:: query:: {
1112 ActiveKeyStatus , CycleError , CycleErrorHandling , EnsureMode , QueryCache , QueryJob , QueryJobId ,
12- QueryLatch , QueryMode , QueryStackDeferred , QueryStackFrame , QueryState ,
13+ QueryKey , QueryLatch , QueryMode , QueryState ,
1314} ;
1415use rustc_middle:: ty:: TyCtxt ;
1516use rustc_middle:: verify_ich:: incremental_verify_ich;
1617use rustc_span:: { DUMMY_SP , Span } ;
1718
19+ use crate :: collect_active_jobs_from_all_queries;
1820use crate :: dep_graph:: { DepNode , DepNodeIndex } ;
1921use crate :: job:: { QueryJobInfo , QueryJobMap , find_cycle_in_stack, report_cycle} ;
20- use crate :: plumbing:: {
21- collect_active_jobs_from_all_queries, current_query_job, next_job_id, start_query,
22- } ;
22+ use crate :: plumbing:: { current_query_job, next_job_id, start_query} ;
2323
2424#[ inline]
2525fn equivalent_key < K : Eq , V > ( k : & K ) -> impl Fn ( & ( K , V ) ) -> bool + ' _ {
@@ -43,18 +43,25 @@ pub(crate) fn all_inactive<'tcx, K>(state: &QueryState<'tcx, K>) -> bool {
4343
4444/// Internal plumbing for collecting the set of active jobs for this query.
4545///
46- /// Should only be called from `gather_active_jobs`.
47- pub ( crate ) fn gather_active_jobs_inner < ' tcx , K : Copy > (
48- state : & QueryState < ' tcx , K > ,
46+ /// Should only be called from `collect_active_jobs_from_all_queries`.
47+ ///
48+ /// (We arbitrarily use the word "gather" when collecting the jobs for
49+ /// each individual query, so that we have distinct function names to
50+ /// grep for.)
51+ pub ( crate ) fn gather_active_jobs < ' tcx , C > (
52+ query : & ' tcx QueryVTable < ' tcx , C > ,
4953 tcx : TyCtxt < ' tcx > ,
50- make_frame : fn ( TyCtxt < ' tcx > , K ) -> QueryStackFrame < QueryStackDeferred < ' tcx > > ,
5154 require_complete : bool ,
5255 job_map_out : & mut QueryJobMap < ' tcx > , // Out-param; job info is gathered into this map
53- ) -> Option < ( ) > {
56+ ) -> Option < ( ) >
57+ where
58+ C : QueryCache < Key : QueryKey + DynSend + DynSync > ,
59+ QueryVTable < ' tcx , C > : DynSync ,
60+ {
5461 let mut active = Vec :: new ( ) ;
5562
5663 // Helper to gather active jobs from a single shard.
57- let mut gather_shard_jobs = |shard : & HashTable < ( K , ActiveKeyStatus < ' tcx > ) > | {
64+ let mut gather_shard_jobs = |shard : & HashTable < ( C :: Key , ActiveKeyStatus < ' tcx > ) > | {
5865 for ( k, v) in shard. iter ( ) {
5966 if let ActiveKeyStatus :: Started ( ref job) = * v {
6067 active. push ( ( * k, job. clone ( ) ) ) ;
@@ -64,22 +71,33 @@ pub(crate) fn gather_active_jobs_inner<'tcx, K: Copy>(
6471
6572 // Lock shards and gather jobs from each shard.
6673 if require_complete {
67- for shard in state. active . lock_shards ( ) {
74+ for shard in query . state . active . lock_shards ( ) {
6875 gather_shard_jobs ( & shard) ;
6976 }
7077 } else {
7178 // We use try_lock_shards here since we are called from the
7279 // deadlock handler, and this shouldn't be locked.
73- for shard in state. active . try_lock_shards ( ) {
74- let shard = shard?;
75- gather_shard_jobs ( & shard) ;
80+ for shard in query. state . active . try_lock_shards ( ) {
81+ // This can be called during unwinding, and the function has a `try_`-prefix, so
82+ // don't `unwrap()` here, just manually check for `None` and do best-effort error
83+ // reporting.
84+ match shard {
85+ None => {
86+ tracing:: warn!(
87+ "Failed to collect active jobs for query with name `{}`!" ,
88+ query. name
89+ ) ;
90+ return None ;
91+ }
92+ Some ( shard) => gather_shard_jobs ( & shard) ,
93+ }
7694 }
7795 }
7896
7997 // Call `make_frame` while we're not holding a `state.active` lock as `make_frame` may call
8098 // queries leading to a deadlock.
8199 for ( key, job) in active {
82- let frame = make_frame ( tcx, key) ;
100+ let frame = crate :: plumbing :: create_deferred_query_stack_frame ( tcx, query , key) ;
83101 job_map_out. insert ( job. id , QueryJobInfo { frame, job } ) ;
84102 }
85103
0 commit comments