33//! manage the caches, and so forth.
44
55use std:: num:: NonZero ;
6+ use std:: sync:: Arc ;
67
78use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
9+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
810use rustc_data_structures:: unord:: UnordMap ;
911use rustc_hashes:: Hash64 ;
1012use rustc_index:: Idx ;
@@ -24,8 +26,8 @@ use rustc_middle::ty::{self, TyCtxt};
2426use rustc_query_system:: dep_graph:: { DepNodeParams , HasDepContext } ;
2527use rustc_query_system:: ich:: StableHashingContext ;
2628use 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,
2931} ;
3032use rustc_query_system:: { QueryOverflow , QueryOverflowNote } ;
3133use rustc_serialize:: { Decodable , Encodable } ;
@@ -65,7 +67,9 @@ impl<'tcx> HasDepContext for QueryCtxt<'tcx> {
6567 }
6668}
6769
68- impl QueryContext for QueryCtxt < ' _ > {
70+ impl < ' tcx > QueryContext for QueryCtxt < ' tcx > {
71+ type QueryInfo = QueryStackDeferred < ' tcx > ;
72+
6973 #[ inline]
7074 fn next_job_id ( self ) -> QueryJobId {
7175 QueryJobId (
@@ -82,19 +86,26 @@ impl QueryContext for QueryCtxt<'_> {
8286 /// Returns a query map representing active query jobs.
8387 /// It returns an incomplete map as an error if it fails
8488 /// 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 > > > {
8690 let mut jobs = QueryMap :: default ( ) ;
8791 let mut complete = true ;
8892
8993 for collect in super :: TRY_COLLECT_ACTIVE_JOBS . iter ( ) {
9094 if collect ( self . tcx , & mut jobs) . is_none ( ) {
9195 complete = false ;
92- }
96+ }
9397 }
9498
9599 if complete { Ok ( jobs) } else { Err ( jobs) }
96100 }
97101
102+ fn lift_query_info (
103+ self ,
104+ info : & QueryStackDeferred < ' tcx > ,
105+ ) -> rustc_query_system:: query:: QueryStackFrameExtra {
106+ info. extract ( )
107+ }
108+
98109 // Interactions with on_disk_cache
99110 fn load_side_effect (
100111 self ,
@@ -159,7 +170,10 @@ impl QueryContext for QueryCtxt<'_> {
159170
160171 self . sess . dcx ( ) . emit_fatal ( QueryOverflow {
161172 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+ } ,
163177 suggested_limit,
164178 crate_name : self . crate_name ( LOCAL_CRATE ) ,
165179 } ) ;
@@ -298,39 +312,45 @@ macro_rules! should_ever_cache_on_disk {
298312
299313pub ( crate ) fn create_query_frame <
300314 ' tcx ,
301- K : Copy + Key + for < ' a > HashStable < StableHashingContext < ' a > > ,
315+ K : Copy + DynSend + DynSync + Key + for < ' a > HashStable < StableHashingContext < ' a > > + ' tcx ,
302316> (
303317 tcx : TyCtxt < ' tcx > ,
304318 do_describe : fn ( TyCtxt < ' tcx > , K ) -> String ,
305319 key : K ,
306320 kind : DepKind ,
307321 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 > > {
327323 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)
333352 } ;
353+
334354 let hash = || {
335355 tcx. with_stable_hashing_context ( |mut hcx| {
336356 let mut hasher = StableHasher :: new ( ) ;
@@ -341,7 +361,11 @@ pub(crate) fn create_query_frame<
341361 } ;
342362 let def_id_for_ty_in_cycle = key. def_id_for_ty_in_cycle ( ) ;
343363
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)
345369}
346370
347371pub ( crate ) fn encode_query_results < ' a , ' tcx , Q > (
@@ -688,7 +712,10 @@ macro_rules! define_queries {
688712 }
689713 }
690714
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 <( ) > {
692719 let make_query = |tcx, key| {
693720 let kind = rustc_middle:: dep_graph:: dep_kinds:: $name;
694721 let name = stringify!( $name) ;
@@ -768,7 +795,9 @@ macro_rules! define_queries {
768795
769796 // These arrays are used for iteration and can't be indexed by `DepKind`.
770797
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+ ] =
772801 & [ $( query_impl:: $name:: try_collect_active_jobs) ,* ] ;
773802
774803 const ALLOC_SELF_PROFILE_QUERY_STRINGS : & [
0 commit comments