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,7 +86,9 @@ 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 (
90+ self ,
91+ ) -> Result < QueryMap < QueryStackDeferred < ' tcx > > , QueryMap < QueryStackDeferred < ' tcx > > > {
8692 let mut jobs = QueryMap :: default ( ) ;
8793 let mut complete = true ;
8894
@@ -95,6 +101,13 @@ impl QueryContext for QueryCtxt<'_> {
95101 if complete { Ok ( jobs) } else { Err ( jobs) }
96102 }
97103
104+ fn lift_query_info (
105+ self ,
106+ info : & QueryStackDeferred < ' tcx > ,
107+ ) -> rustc_query_system:: query:: QueryStackFrameExtra {
108+ info. extract ( )
109+ }
110+
98111 // Interactions with on_disk_cache
99112 fn load_side_effect (
100113 self ,
@@ -159,7 +172,10 @@ impl QueryContext for QueryCtxt<'_> {
159172
160173 self . sess . dcx ( ) . emit_fatal ( QueryOverflow {
161174 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+ } ,
163179 suggested_limit,
164180 crate_name : self . crate_name ( LOCAL_CRATE ) ,
165181 } ) ;
@@ -298,39 +314,45 @@ macro_rules! should_ever_cache_on_disk {
298314
299315pub ( crate ) fn create_query_frame <
300316 ' tcx ,
301- K : Copy + Key + for < ' a > HashStable < StableHashingContext < ' a > > ,
317+ K : Copy + DynSend + DynSync + Key + for < ' a > HashStable < StableHashingContext < ' a > > + ' tcx ,
302318> (
303319 tcx : TyCtxt < ' tcx > ,
304320 do_describe : fn ( TyCtxt < ' tcx > , K ) -> String ,
305321 key : K ,
306322 kind : DepKind ,
307323 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 > > {
327325 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)
333354 } ;
355+
334356 let hash = || {
335357 tcx. with_stable_hashing_context ( |mut hcx| {
336358 let mut hasher = StableHasher :: new ( ) ;
@@ -341,7 +363,11 @@ pub(crate) fn create_query_frame<
341363 } ;
342364 let def_id_for_ty_in_cycle = key. def_id_for_ty_in_cycle ( ) ;
343365
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)
345371}
346372
347373pub ( crate ) fn encode_query_results < ' a , ' tcx , Q > (
@@ -688,7 +714,10 @@ macro_rules! define_queries {
688714 }
689715 }
690716
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 <( ) > {
692721 let make_query = |tcx, key| {
693722 let kind = rustc_middle:: dep_graph:: dep_kinds:: $name;
694723 let name = stringify!( $name) ;
@@ -768,7 +797,9 @@ macro_rules! define_queries {
768797
769798 // These arrays are used for iteration and can't be indexed by `DepKind`.
770799
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+ ] =
772803 & [ $( query_impl:: $name:: try_collect_active_jobs) ,* ] ;
773804
774805 const ALLOC_SELF_PROFILE_QUERY_STRINGS : & [
0 commit comments