@@ -3,13 +3,14 @@ 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 } ;
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;
@@ -44,17 +45,20 @@ pub(crate) fn all_inactive<'tcx, K>(state: &QueryState<'tcx, K>) -> bool {
4445/// Internal plumbing for collecting the set of active jobs for this query.
4546///
4647/// Should only be called from `gather_active_jobs`.
47- pub ( crate ) fn gather_active_jobs_inner < ' tcx , K : Copy > (
48- state : & QueryState < ' tcx , K > ,
48+ pub ( crate ) fn gather_active_jobs_inner < ' tcx , C > (
49+ query : & ' tcx QueryVTable < ' tcx , C > ,
4950 tcx : TyCtxt < ' tcx > ,
50- make_frame : fn ( TyCtxt < ' tcx > , K ) -> QueryStackFrame < QueryStackDeferred < ' tcx > > ,
5151 require_complete : bool ,
5252 job_map_out : & mut QueryJobMap < ' tcx > , // Out-param; job info is gathered into this map
53- ) -> Option < ( ) > {
53+ ) -> Option < ( ) >
54+ where
55+ C : QueryCache < Key : QueryKey + DynSend + DynSync > ,
56+ QueryVTable < ' tcx , C > : DynSync ,
57+ {
5458 let mut active = Vec :: new ( ) ;
5559
5660 // Helper to gather active jobs from a single shard.
57- let mut gather_shard_jobs = |shard : & HashTable < ( K , ActiveKeyStatus < ' tcx > ) > | {
61+ let mut gather_shard_jobs = |shard : & HashTable < ( C :: Key , ActiveKeyStatus < ' tcx > ) > | {
5862 for ( k, v) in shard. iter ( ) {
5963 if let ActiveKeyStatus :: Started ( ref job) = * v {
6064 active. push ( ( * k, job. clone ( ) ) ) ;
@@ -64,22 +68,33 @@ pub(crate) fn gather_active_jobs_inner<'tcx, K: Copy>(
6468
6569 // Lock shards and gather jobs from each shard.
6670 if require_complete {
67- for shard in state. active . lock_shards ( ) {
71+ for shard in query . state . active . lock_shards ( ) {
6872 gather_shard_jobs ( & shard) ;
6973 }
7074 } else {
7175 // We use try_lock_shards here since we are called from the
7276 // 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) ;
77+ for shard in query. state . active . try_lock_shards ( ) {
78+ // This can be called during unwinding, and the function has a `try_`-prefix, so
79+ // don't `unwrap()` here, just manually check for `None` and do best-effort error
80+ // reporting.
81+ match shard {
82+ None => {
83+ tracing:: warn!(
84+ "Failed to collect active jobs for query with name `{}`!" ,
85+ query. name
86+ ) ;
87+ return None ;
88+ }
89+ Some ( shard) => gather_shard_jobs ( & shard) ,
90+ }
7691 }
7792 }
7893
7994 // Call `make_frame` while we're not holding a `state.active` lock as `make_frame` may call
8095 // queries leading to a deadlock.
8196 for ( key, job) in active {
82- let frame = make_frame ( tcx, key) ;
97+ let frame = crate :: plumbing :: create_deferred_query_stack_frame ( tcx, query , key) ;
8398 job_map_out. insert ( job. id , QueryJobInfo { frame, job } ) ;
8499 }
85100
0 commit comments