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,7 +86,9 @@ 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 (
90
+ self ,
91
+ ) -> Result < QueryMap < QueryStackDeferred < ' tcx > > , QueryMap < QueryStackDeferred < ' tcx > > > {
86
92
let mut jobs = QueryMap :: default ( ) ;
87
93
let mut complete = true ;
88
94
@@ -95,6 +101,13 @@ impl QueryContext for QueryCtxt<'_> {
95
101
if complete { Ok ( jobs) } else { Err ( jobs) }
96
102
}
97
103
104
+ fn lift_query_info (
105
+ self ,
106
+ info : & QueryStackDeferred < ' tcx > ,
107
+ ) -> rustc_query_system:: query:: QueryStackFrameExtra {
108
+ info. extract ( )
109
+ }
110
+
98
111
// Interactions with on_disk_cache
99
112
fn load_side_effect (
100
113
self ,
@@ -159,7 +172,10 @@ impl QueryContext for QueryCtxt<'_> {
159
172
160
173
self . sess . dcx ( ) . emit_fatal ( QueryOverflow {
161
174
span : info. job . span ,
162
- note : QueryOverflowNote { desc : info. query . description , depth } ,
175
+ note : QueryOverflowNote {
176
+ desc : self . lift_query_info ( & info. query . info ) . description ,
177
+ depth,
178
+ } ,
163
179
suggested_limit,
164
180
crate_name : self . crate_name ( LOCAL_CRATE ) ,
165
181
} ) ;
@@ -298,39 +314,45 @@ macro_rules! should_ever_cache_on_disk {
298
314
299
315
pub ( crate ) fn create_query_frame <
300
316
' tcx ,
301
- K : Copy + Key + for < ' a > HashStable < StableHashingContext < ' a > > ,
317
+ K : Copy + DynSend + DynSync + Key + for < ' a > HashStable < StableHashingContext < ' a > > + ' tcx ,
302
318
> (
303
319
tcx : TyCtxt < ' tcx > ,
304
320
do_describe : fn ( TyCtxt < ' tcx > , K ) -> String ,
305
321
key : K ,
306
322
kind : DepKind ,
307
323
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
- } ;
324
+ ) -> QueryStackFrame < QueryStackDeferred < ' tcx > > {
327
325
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) )
326
+
327
+ let extra = move || {
328
+ // If reduced queries are requested, we may be printing a query stack due
329
+ // to a panic. Avoid using `default_span` and `def_kind` in that case.
330
+ let reduce_queries = with_reduced_queries ( ) ;
331
+
332
+ // Avoid calling queries while formatting the description
333
+ let description = ty:: print:: with_no_queries!( do_describe( tcx, key) ) ;
334
+ let description = if tcx. sess . verbose_internals ( ) {
335
+ format ! ( "{description} [{name:?}]" )
336
+ } else {
337
+ description
338
+ } ;
339
+ let span = if kind == dep_graph:: dep_kinds:: def_span || reduce_queries {
340
+ // The `def_span` query is used to calculate `default_span`,
341
+ // so exit to avoid infinite recursion.
342
+ None
343
+ } else {
344
+ Some ( key. default_span ( tcx) )
345
+ } ;
346
+
347
+ let def_kind = if kind == dep_graph:: dep_kinds:: def_kind || reduce_queries {
348
+ // Try to avoid infinite recursion.
349
+ None
350
+ } else {
351
+ def_id. and_then ( |def_id| def_id. as_local ( ) ) . map ( |def_id| tcx. def_kind ( def_id) )
352
+ } ;
353
+ QueryStackFrameExtra :: new ( description, span, def_kind)
333
354
} ;
355
+
334
356
let hash = || {
335
357
tcx. with_stable_hashing_context ( |mut hcx| {
336
358
let mut hasher = StableHasher :: new ( ) ;
@@ -341,7 +363,11 @@ pub(crate) fn create_query_frame<
341
363
} ;
342
364
let def_id_for_ty_in_cycle = key. def_id_for_ty_in_cycle ( ) ;
343
365
344
- QueryStackFrame :: new ( description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash)
366
+ // SAFETY: None of the captures in `extra` have destructors that access 'tcx
367
+ // as they don't have destructors.
368
+ let info = unsafe { QueryStackDeferred :: new ( Arc :: new ( extra) ) } ;
369
+
370
+ QueryStackFrame :: new ( info, kind, hash, def_id, def_id_for_ty_in_cycle)
345
371
}
346
372
347
373
pub ( crate ) fn encode_query_results < ' a , ' tcx , Q > (
@@ -688,7 +714,10 @@ macro_rules! define_queries {
688
714
}
689
715
}
690
716
691
- pub ( crate ) fn try_collect_active_jobs<' tcx>( tcx: TyCtxt <' tcx>, qmap: & mut QueryMap ) -> Option <( ) > {
717
+ pub ( crate ) fn try_collect_active_jobs<' tcx>(
718
+ tcx: TyCtxt <' tcx>,
719
+ qmap: & mut QueryMap <QueryStackDeferred <' tcx>>,
720
+ ) -> Option <( ) > {
692
721
let make_query = |tcx, key| {
693
722
let kind = rustc_middle:: dep_graph:: dep_kinds:: $name;
694
723
let name = stringify!( $name) ;
@@ -768,7 +797,9 @@ macro_rules! define_queries {
768
797
769
798
// These arrays are used for iteration and can't be indexed by `DepKind`.
770
799
771
- const TRY_COLLECT_ACTIVE_JOBS : & [ for <' tcx> fn ( TyCtxt <' tcx>, & mut QueryMap ) -> Option <( ) >] =
800
+ const TRY_COLLECT_ACTIVE_JOBS : & [
801
+ for <' tcx> fn ( TyCtxt <' tcx>, & mut QueryMap <QueryStackDeferred <' tcx>>) -> Option <( ) >
802
+ ] =
772
803
& [ $( query_impl:: $name:: try_collect_active_jobs) ,* ] ;
773
804
774
805
const ALLOC_SELF_PROFILE_QUERY_STRINGS : & [
0 commit comments