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 } ;
8- use rustc_data_structures:: sync:: Lock ;
9+ use rustc_data_structures:: sync:: { DynSend , DynSync , Lock } ;
910use rustc_data_structures:: unord:: UnordMap ;
1011use rustc_errors:: DiagInner ;
1112use rustc_hashes:: Hash64 ;
@@ -26,8 +27,8 @@ use rustc_middle::ty::{self, TyCtxt};
2627use rustc_query_system:: dep_graph:: { DepNodeParams , HasDepContext } ;
2728use rustc_query_system:: ich:: StableHashingContext ;
2829use rustc_query_system:: query:: {
29- QueryCache , QueryConfig , QueryContext , QueryJobId , QueryMap , QuerySideEffects , QueryStackFrame ,
30- force_query,
30+ QueryCache , QueryConfig , QueryContext , QueryJobId , QueryMap , QuerySideEffects ,
31+ QueryStackDeferred , QueryStackFrame , QueryStackFrameExtra , force_query,
3132} ;
3233use rustc_query_system:: { QueryOverflow , QueryOverflowNote } ;
3334use rustc_serialize:: { Decodable , Encodable } ;
@@ -68,7 +69,9 @@ impl<'tcx> HasDepContext for QueryCtxt<'tcx> {
6869 }
6970}
7071
71- impl QueryContext for QueryCtxt < ' _ > {
72+ impl < ' tcx > QueryContext for QueryCtxt < ' tcx > {
73+ type QueryInfo = QueryStackDeferred < ' tcx > ;
74+
7275 #[ inline]
7376 fn next_job_id ( self ) -> QueryJobId {
7477 QueryJobId (
@@ -84,7 +87,7 @@ impl QueryContext for QueryCtxt<'_> {
8487
8588 /// Returns a query map representing active query jobs and a bool being false
8689 /// if there was an error constructing the map.
87- fn collect_active_jobs ( self ) -> ( QueryMap , bool ) {
90+ fn collect_active_jobs ( self ) -> ( QueryMap < QueryStackDeferred < ' tcx > > , bool ) {
8891 let mut jobs = QueryMap :: default ( ) ;
8992 let mut complete = true ;
9093
@@ -95,6 +98,13 @@ impl QueryContext for QueryCtxt<'_> {
9598 ( jobs, complete)
9699 }
97100
101+ fn lift_query_info (
102+ self ,
103+ info : & QueryStackDeferred < ' tcx > ,
104+ ) -> rustc_query_system:: query:: QueryStackFrameExtra {
105+ info. extract ( )
106+ }
107+
98108 // Interactions with on_disk_cache
99109 fn load_side_effects ( self , prev_dep_node_index : SerializedDepNodeIndex ) -> QuerySideEffects {
100110 self . query_system
@@ -168,7 +178,10 @@ impl QueryContext for QueryCtxt<'_> {
168178
169179 self . sess . dcx ( ) . emit_fatal ( QueryOverflow {
170180 span : info. job . span ,
171- note : QueryOverflowNote { desc : info. query . description , depth } ,
181+ note : QueryOverflowNote {
182+ desc : self . lift_query_info ( & info. query . info ) . description ,
183+ depth,
184+ } ,
172185 suggested_limit,
173186 crate_name : self . crate_name ( LOCAL_CRATE ) ,
174187 } ) ;
@@ -307,39 +320,45 @@ macro_rules! should_ever_cache_on_disk {
307320
308321pub ( crate ) fn create_query_frame <
309322 ' tcx ,
310- K : Copy + Key + for < ' a > HashStable < StableHashingContext < ' a > > ,
323+ K : Copy + DynSend + DynSync + Key + for < ' a > HashStable < StableHashingContext < ' a > > + ' tcx ,
311324> (
312325 tcx : TyCtxt < ' tcx > ,
313326 do_describe : fn ( TyCtxt < ' tcx > , K ) -> String ,
314327 key : K ,
315328 kind : DepKind ,
316329 name : & ' static str ,
317- ) -> QueryStackFrame {
318- // If reduced queries are requested, we may be printing a query stack due
319- // to a panic. Avoid using `default_span` and `def_kind` in that case.
320- let reduce_queries = with_reduced_queries ( ) ;
321-
322- // Avoid calling queries while formatting the description
323- let description = ty:: print:: with_no_queries!( do_describe( tcx, key) ) ;
324- let description = if tcx. sess . verbose_internals ( ) {
325- format ! ( "{description} [{name:?}]" )
326- } else {
327- description
328- } ;
329- let span = if kind == dep_graph:: dep_kinds:: def_span || reduce_queries {
330- // The `def_span` query is used to calculate `default_span`,
331- // so exit to avoid infinite recursion.
332- None
333- } else {
334- Some ( key. default_span ( tcx) )
335- } ;
330+ ) -> QueryStackFrame < QueryStackDeferred < ' tcx > > {
336331 let def_id = key. key_as_def_id ( ) ;
337- let def_kind = if kind == dep_graph:: dep_kinds:: def_kind || reduce_queries {
338- // Try to avoid infinite recursion.
339- None
340- } else {
341- def_id. and_then ( |def_id| def_id. as_local ( ) ) . map ( |def_id| tcx. def_kind ( def_id) )
332+
333+ let extra = move || {
334+ // If reduced queries are requested, we may be printing a query stack due
335+ // to a panic. Avoid using `default_span` and `def_kind` in that case.
336+ let reduce_queries = with_reduced_queries ( ) ;
337+
338+ // Avoid calling queries while formatting the description
339+ let description = ty:: print:: with_no_queries!( do_describe( tcx, key) ) ;
340+ let description = if tcx. sess . verbose_internals ( ) {
341+ format ! ( "{description} [{name:?}]" )
342+ } else {
343+ description
344+ } ;
345+ let span = if kind == dep_graph:: dep_kinds:: def_span || reduce_queries {
346+ // The `def_span` query is used to calculate `default_span`,
347+ // so exit to avoid infinite recursion.
348+ None
349+ } else {
350+ Some ( key. default_span ( tcx) )
351+ } ;
352+
353+ let def_kind = if kind == dep_graph:: dep_kinds:: def_kind || reduce_queries {
354+ // Try to avoid infinite recursion.
355+ None
356+ } else {
357+ def_id. and_then ( |def_id| def_id. as_local ( ) ) . map ( |def_id| tcx. def_kind ( def_id) )
358+ } ;
359+ QueryStackFrameExtra :: new ( description, span, def_kind)
342360 } ;
361+
343362 let hash = || {
344363 tcx. with_stable_hashing_context ( |mut hcx| {
345364 let mut hasher = StableHasher :: new ( ) ;
@@ -350,7 +369,11 @@ pub(crate) fn create_query_frame<
350369 } ;
351370 let def_id_for_ty_in_cycle = key. def_id_for_ty_in_cycle ( ) ;
352371
353- QueryStackFrame :: new ( description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash)
372+ // SAFETY: None of the captures in `extra` have destructors that access 'tcx
373+ // as they don't have destructors.
374+ let info = unsafe { QueryStackDeferred :: new ( Arc :: new ( extra) ) } ;
375+
376+ QueryStackFrame :: new ( info, kind, hash, def_id, def_id_for_ty_in_cycle)
354377}
355378
356379pub ( crate ) fn encode_query_results < ' a , ' tcx , Q > (
@@ -697,7 +720,11 @@ macro_rules! define_queries {
697720 }
698721 }
699722
700- pub ( crate ) fn try_collect_active_jobs<' tcx>( tcx: TyCtxt <' tcx>, qmap: & mut QueryMap , complete: & mut bool ) {
723+ pub ( crate ) fn try_collect_active_jobs<' tcx>(
724+ tcx: TyCtxt <' tcx>,
725+ qmap: & mut QueryMap <QueryStackDeferred <' tcx>>,
726+ complete: & mut bool
727+ ) {
701728 let make_query = |tcx, key| {
702729 let kind = rustc_middle:: dep_graph:: dep_kinds:: $name;
703730 let name = stringify!( $name) ;
@@ -777,7 +804,9 @@ macro_rules! define_queries {
777804
778805 // These arrays are used for iteration and can't be indexed by `DepKind`.
779806
780- const TRY_COLLECT_ACTIVE_JOBS : & [ for <' tcx> fn ( TyCtxt <' tcx>, & mut QueryMap , & mut bool ) ] =
807+ const TRY_COLLECT_ACTIVE_JOBS : & [
808+ for <' tcx> fn ( TyCtxt <' tcx>, & mut QueryMap <QueryStackDeferred <' tcx>>, & mut bool )
809+ ] =
781810 & [ $( query_impl:: $name:: try_collect_active_jobs) ,* ] ;
782811
783812 const ALLOC_SELF_PROFILE_QUERY_STRINGS : & [
0 commit comments