3
3
//! manage the caches, and so forth.
4
4
5
5
use std:: num:: NonZero ;
6
+ use std:: sync:: Arc ;
6
7
7
8
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
9
+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
8
10
use rustc_data_structures:: unord:: UnordMap ;
9
11
use rustc_hashes:: Hash64 ;
10
12
use rustc_index:: Idx ;
@@ -24,8 +26,8 @@ use rustc_middle::ty::{self, TyCtxt};
24
26
use rustc_query_system:: dep_graph:: { DepNodeParams , HasDepContext } ;
25
27
use rustc_query_system:: ich:: StableHashingContext ;
26
28
use rustc_query_system:: query:: {
27
- QueryCache , QueryConfig , QueryContext , QueryJobId , QueryMap , QuerySideEffect , QueryStackFrame ,
28
- force_query,
29
+ QueryCache , QueryConfig , QueryContext , QueryJobId , QueryMap , QuerySideEffect ,
30
+ QueryStackDeferred , QueryStackFrame , QueryStackFrameExtra , force_query,
29
31
} ;
30
32
use rustc_query_system:: { QueryOverflow , QueryOverflowNote } ;
31
33
use rustc_serialize:: { Decodable , Encodable } ;
@@ -65,7 +67,9 @@ impl<'tcx> HasDepContext for QueryCtxt<'tcx> {
65
67
}
66
68
}
67
69
68
- impl QueryContext for QueryCtxt < ' _ > {
70
+ impl < ' tcx > QueryContext for QueryCtxt < ' tcx > {
71
+ type QueryInfo = QueryStackDeferred < ' tcx > ;
72
+
69
73
#[ inline]
70
74
fn next_job_id ( self ) -> QueryJobId {
71
75
QueryJobId (
@@ -82,19 +86,26 @@ impl QueryContext for QueryCtxt<'_> {
82
86
/// Returns a query map representing active query jobs.
83
87
/// It returns an incomplete map as an error if it fails
84
88
/// to take locks.
85
- fn collect_active_jobs ( self ) -> Result < QueryMap , QueryMap > {
89
+ fn collect_active_jobs ( self ) -> Result < QueryMap < QueryStackDeferred < ' tcx > > , QueryMap < QueryStackDeferred < ' tcx > > > {
86
90
let mut jobs = QueryMap :: default ( ) ;
87
91
let mut complete = true ;
88
92
89
93
for collect in super :: TRY_COLLECT_ACTIVE_JOBS . iter ( ) {
90
94
if collect ( self . tcx , & mut jobs) . is_none ( ) {
91
95
complete = false ;
92
- }
96
+ }
93
97
}
94
98
95
99
if complete { Ok ( jobs) } else { Err ( jobs) }
96
100
}
97
101
102
+ fn lift_query_info (
103
+ self ,
104
+ info : & QueryStackDeferred < ' tcx > ,
105
+ ) -> rustc_query_system:: query:: QueryStackFrameExtra {
106
+ info. extract ( )
107
+ }
108
+
98
109
// Interactions with on_disk_cache
99
110
fn load_side_effect (
100
111
self ,
@@ -159,7 +170,10 @@ impl QueryContext for QueryCtxt<'_> {
159
170
160
171
self . sess . dcx ( ) . emit_fatal ( QueryOverflow {
161
172
span : info. job . span ,
162
- note : QueryOverflowNote { desc : info. query . description , depth } ,
173
+ note : QueryOverflowNote {
174
+ desc : self . lift_query_info ( & info. query . info ) . description ,
175
+ depth,
176
+ } ,
163
177
suggested_limit,
164
178
crate_name : self . crate_name ( LOCAL_CRATE ) ,
165
179
} ) ;
@@ -298,39 +312,45 @@ macro_rules! should_ever_cache_on_disk {
298
312
299
313
pub ( crate ) fn create_query_frame <
300
314
' tcx ,
301
- K : Copy + Key + for < ' a > HashStable < StableHashingContext < ' a > > ,
315
+ K : Copy + DynSend + DynSync + Key + for < ' a > HashStable < StableHashingContext < ' a > > + ' tcx ,
302
316
> (
303
317
tcx : TyCtxt < ' tcx > ,
304
318
do_describe : fn ( TyCtxt < ' tcx > , K ) -> String ,
305
319
key : K ,
306
320
kind : DepKind ,
307
321
name : & ' static str ,
308
- ) -> QueryStackFrame {
309
- // If reduced queries are requested, we may be printing a query stack due
310
- // to a panic. Avoid using `default_span` and `def_kind` in that case.
311
- let reduce_queries = with_reduced_queries ( ) ;
312
-
313
- // Avoid calling queries while formatting the description
314
- let description = ty:: print:: with_no_queries!( do_describe( tcx, key) ) ;
315
- let description = if tcx. sess . verbose_internals ( ) {
316
- format ! ( "{description} [{name:?}]" )
317
- } else {
318
- description
319
- } ;
320
- let span = if kind == dep_graph:: dep_kinds:: def_span || reduce_queries {
321
- // The `def_span` query is used to calculate `default_span`,
322
- // so exit to avoid infinite recursion.
323
- None
324
- } else {
325
- Some ( key. default_span ( tcx) )
326
- } ;
322
+ ) -> QueryStackFrame < QueryStackDeferred < ' tcx > > {
327
323
let def_id = key. key_as_def_id ( ) ;
328
- let def_kind = if kind == dep_graph:: dep_kinds:: def_kind || reduce_queries {
329
- // Try to avoid infinite recursion.
330
- None
331
- } else {
332
- def_id. and_then ( |def_id| def_id. as_local ( ) ) . map ( |def_id| tcx. def_kind ( def_id) )
324
+
325
+ let extra = move || {
326
+ // If reduced queries are requested, we may be printing a query stack due
327
+ // to a panic. Avoid using `default_span` and `def_kind` in that case.
328
+ let reduce_queries = with_reduced_queries ( ) ;
329
+
330
+ // Avoid calling queries while formatting the description
331
+ let description = ty:: print:: with_no_queries!( do_describe( tcx, key) ) ;
332
+ let description = if tcx. sess . verbose_internals ( ) {
333
+ format ! ( "{description} [{name:?}]" )
334
+ } else {
335
+ description
336
+ } ;
337
+ let span = if kind == dep_graph:: dep_kinds:: def_span || reduce_queries {
338
+ // The `def_span` query is used to calculate `default_span`,
339
+ // so exit to avoid infinite recursion.
340
+ None
341
+ } else {
342
+ Some ( key. default_span ( tcx) )
343
+ } ;
344
+
345
+ let def_kind = if kind == dep_graph:: dep_kinds:: def_kind || reduce_queries {
346
+ // Try to avoid infinite recursion.
347
+ None
348
+ } else {
349
+ def_id. and_then ( |def_id| def_id. as_local ( ) ) . map ( |def_id| tcx. def_kind ( def_id) )
350
+ } ;
351
+ QueryStackFrameExtra :: new ( description, span, def_kind)
333
352
} ;
353
+
334
354
let hash = || {
335
355
tcx. with_stable_hashing_context ( |mut hcx| {
336
356
let mut hasher = StableHasher :: new ( ) ;
@@ -341,7 +361,11 @@ pub(crate) fn create_query_frame<
341
361
} ;
342
362
let def_id_for_ty_in_cycle = key. def_id_for_ty_in_cycle ( ) ;
343
363
344
- QueryStackFrame :: new ( description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash)
364
+ // SAFETY: None of the captures in `extra` have destructors that access 'tcx
365
+ // as they don't have destructors.
366
+ let info = unsafe { QueryStackDeferred :: new ( Arc :: new ( extra) ) } ;
367
+
368
+ QueryStackFrame :: new ( info, kind, hash, def_id, def_id_for_ty_in_cycle)
345
369
}
346
370
347
371
pub ( crate ) fn encode_query_results < ' a , ' tcx , Q > (
@@ -688,7 +712,10 @@ macro_rules! define_queries {
688
712
}
689
713
}
690
714
691
- pub ( crate ) fn try_collect_active_jobs<' tcx>( tcx: TyCtxt <' tcx>, qmap: & mut QueryMap ) -> Option <( ) > {
715
+ pub ( crate ) fn try_collect_active_jobs<' tcx>(
716
+ tcx: TyCtxt <' tcx>,
717
+ qmap: & mut QueryMap <QueryStackDeferred <' tcx>>,
718
+ ) -> Option <( ) > {
692
719
let make_query = |tcx, key| {
693
720
let kind = rustc_middle:: dep_graph:: dep_kinds:: $name;
694
721
let name = stringify!( $name) ;
@@ -768,7 +795,9 @@ macro_rules! define_queries {
768
795
769
796
// These arrays are used for iteration and can't be indexed by `DepKind`.
770
797
771
- const TRY_COLLECT_ACTIVE_JOBS : & [ for <' tcx> fn ( TyCtxt <' tcx>, & mut QueryMap ) -> Option <( ) >] =
798
+ const TRY_COLLECT_ACTIVE_JOBS : & [
799
+ for <' tcx> fn ( TyCtxt <' tcx>, & mut QueryMap <QueryStackDeferred <' tcx>>) -> Option <( ) >
800
+ ] =
772
801
& [ $( query_impl:: $name:: try_collect_active_jobs) ,* ] ;
773
802
774
803
const ALLOC_SELF_PROFILE_QUERY_STRINGS : & [
0 commit comments