@@ -18,6 +18,7 @@ use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
1818
1919use rustc_data_structures:: fx:: { FxHashMap } ;
2020use rustc_data_structures:: sync:: { Lrc , Lock } ;
21+ use rustc_data_structures:: thin_vec:: ThinVec ;
2122use std:: mem;
2223use std:: ptr;
2324use std:: collections:: hash_map:: Entry ;
@@ -195,19 +196,21 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
195196 pub ( super ) fn start < ' lcx , F , R > (
196197 & self ,
197198 tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
199+ diagnostics : Option < & Lock < ThinVec < Diagnostic > > > ,
198200 compute : F )
199- -> ( R , Vec < Diagnostic > )
201+ -> R
200202 where
201203 F : for < ' b > FnOnce ( TyCtxt < ' b , ' tcx , ' lcx > ) -> R
202204 {
203205 // The TyCtxt stored in TLS has the same global interner lifetime
204206 // as `tcx`, so we use `with_related_context` to relate the 'gcx lifetimes
205207 // when accessing the ImplicitCtxt
206- let r = tls:: with_related_context ( tcx, move |current_icx| {
208+ tls:: with_related_context ( tcx, move |current_icx| {
207209 // Update the ImplicitCtxt to point to our new query job
208210 let new_icx = tls:: ImplicitCtxt {
209211 tcx : tcx. global_tcx ( ) ,
210212 query : Some ( self . job . clone ( ) ) ,
213+ diagnostics,
211214 layout_depth : current_icx. layout_depth ,
212215 task_deps : current_icx. task_deps ,
213216 } ;
@@ -216,13 +219,19 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
216219 tls:: enter_context ( & new_icx, |_| {
217220 compute ( tcx)
218221 } )
219- } ) ;
222+ } )
223+ }
220224
221- // Extract the diagnostic from the job
222- let diagnostics = mem:: replace ( & mut * self . job . diagnostics . lock ( ) , Vec :: new ( ) ) ;
225+ }
223226
224- ( r, diagnostics)
225- }
227+ #[ inline( always) ]
228+ fn with_diagnostics < F , R > ( f : F ) -> ( R , ThinVec < Diagnostic > )
229+ where
230+ F : FnOnce ( Option < & Lock < ThinVec < Diagnostic > > > ) -> R
231+ {
232+ let diagnostics = Lock :: new ( ThinVec :: new ( ) ) ;
233+ let result = f ( Some ( & diagnostics) ) ;
234+ ( result, diagnostics. into_inner ( ) )
226235}
227236
228237impl < ' a , ' tcx , Q : QueryDescription < ' tcx > > Drop for JobOwner < ' a , ' tcx , Q > {
@@ -402,20 +411,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
402411 profq_msg ! ( self , ProfileQueriesMsg :: ProviderBegin ) ;
403412 self . sess . profiler ( |p| p. start_activity ( Q :: CATEGORY ) ) ;
404413
405- let res = job. start ( self , |tcx| {
406- tcx. dep_graph . with_anon_task ( dep_node. kind , || {
407- Q :: compute ( tcx. global_tcx ( ) , key)
414+ let ( ( result, dep_node_index) , diagnostics) = with_diagnostics ( |diagnostics| {
415+ job. start ( self , diagnostics, |tcx| {
416+ tcx. dep_graph . with_anon_task ( dep_node. kind , || {
417+ Q :: compute ( tcx. global_tcx ( ) , key)
418+ } )
408419 } )
409420 } ) ;
410421
411422 self . sess . profiler ( |p| p. end_activity ( Q :: CATEGORY ) ) ;
412423 profq_msg ! ( self , ProfileQueriesMsg :: ProviderEnd ) ;
413- let ( ( result, dep_node_index) , diagnostics) = res;
414424
415425 self . dep_graph . read_index ( dep_node_index) ;
416426
417- self . queries . on_disk_cache
418- . store_diagnostics_for_anon_node ( dep_node_index, diagnostics) ;
427+ if unlikely ! ( !diagnostics. is_empty( ) ) {
428+ self . queries . on_disk_cache
429+ . store_diagnostics_for_anon_node ( dep_node_index, diagnostics) ;
430+ }
419431
420432 job. complete ( & result, dep_node_index) ;
421433
@@ -487,7 +499,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
487499 // The diagnostics for this query have already been
488500 // promoted to the current session during
489501 // try_mark_green(), so we can ignore them here.
490- let ( result, _ ) = job. start ( self , |tcx| {
502+ let result = job. start ( self , None , |tcx| {
491503 // The dep-graph for this computation is already in
492504 // place
493505 tcx. dep_graph . with_ignore ( || {
@@ -566,32 +578,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
566578 profq_msg ! ( self , ProfileQueriesMsg :: ProviderBegin ) ;
567579 self . sess . profiler ( |p| p. start_activity ( Q :: CATEGORY ) ) ;
568580
569- let res = job. start ( self , |tcx| {
570- if dep_node. kind . is_eval_always ( ) {
571- tcx. dep_graph . with_eval_always_task ( dep_node,
572- tcx,
573- key,
574- Q :: compute)
575- } else {
576- tcx. dep_graph . with_task ( dep_node,
577- tcx,
578- key,
579- Q :: compute)
580- }
581+ let ( ( result, dep_node_index) , diagnostics) = with_diagnostics ( |diagnostics| {
582+ job. start ( self , diagnostics, |tcx| {
583+ if dep_node. kind . is_eval_always ( ) {
584+ tcx. dep_graph . with_eval_always_task ( dep_node,
585+ tcx,
586+ key,
587+ Q :: compute)
588+ } else {
589+ tcx. dep_graph . with_task ( dep_node,
590+ tcx,
591+ key,
592+ Q :: compute)
593+ }
594+ } )
581595 } ) ;
582596
583597 self . sess . profiler ( |p| p. end_activity ( Q :: CATEGORY ) ) ;
584598 profq_msg ! ( self , ProfileQueriesMsg :: ProviderEnd ) ;
585599
586- let ( ( result, dep_node_index) , diagnostics) = res;
587-
588600 if unlikely ! ( self . sess. opts. debugging_opts. query_dep_graph) {
589601 self . dep_graph . mark_loaded_from_cache ( dep_node_index, false ) ;
590602 }
591603
592604 if dep_node. kind != :: dep_graph:: DepKind :: Null {
593- self . queries . on_disk_cache
594- . store_diagnostics ( dep_node_index, diagnostics) ;
605+ if unlikely ! ( !diagnostics. is_empty( ) ) {
606+ self . queries . on_disk_cache
607+ . store_diagnostics ( dep_node_index, diagnostics) ;
608+ }
595609 }
596610
597611 job. complete ( & result, dep_node_index) ;
0 commit comments