@@ -18,6 +18,7 @@ use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
18
18
19
19
use rustc_data_structures:: fx:: { FxHashMap } ;
20
20
use rustc_data_structures:: sync:: { Lrc , Lock } ;
21
+ use rustc_data_structures:: thin_vec:: ThinVec ;
21
22
use std:: mem;
22
23
use std:: ptr;
23
24
use std:: collections:: hash_map:: Entry ;
@@ -195,19 +196,21 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
195
196
pub ( super ) fn start < ' lcx , F , R > (
196
197
& self ,
197
198
tcx : TyCtxt < ' _ , ' tcx , ' lcx > ,
199
+ diagnostics : Option < & Lock < ThinVec < Diagnostic > > > ,
198
200
compute : F )
199
- -> ( R , Vec < Diagnostic > )
201
+ -> R
200
202
where
201
203
F : for < ' b > FnOnce ( TyCtxt < ' b , ' tcx , ' lcx > ) -> R
202
204
{
203
205
// The TyCtxt stored in TLS has the same global interner lifetime
204
206
// as `tcx`, so we use `with_related_context` to relate the 'gcx lifetimes
205
207
// when accessing the ImplicitCtxt
206
- let r = tls:: with_related_context ( tcx, move |current_icx| {
208
+ tls:: with_related_context ( tcx, move |current_icx| {
207
209
// Update the ImplicitCtxt to point to our new query job
208
210
let new_icx = tls:: ImplicitCtxt {
209
211
tcx : tcx. global_tcx ( ) ,
210
212
query : Some ( self . job . clone ( ) ) ,
213
+ diagnostics,
211
214
layout_depth : current_icx. layout_depth ,
212
215
task_deps : current_icx. task_deps ,
213
216
} ;
@@ -216,13 +219,19 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
216
219
tls:: enter_context ( & new_icx, |_| {
217
220
compute ( tcx)
218
221
} )
219
- } ) ;
222
+ } )
223
+ }
220
224
221
- // Extract the diagnostic from the job
222
- let diagnostics = mem:: replace ( & mut * self . job . diagnostics . lock ( ) , Vec :: new ( ) ) ;
225
+ }
223
226
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 ( ) )
226
235
}
227
236
228
237
impl < ' a , ' tcx , Q : QueryDescription < ' tcx > > Drop for JobOwner < ' a , ' tcx , Q > {
@@ -402,20 +411,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
402
411
profq_msg ! ( self , ProfileQueriesMsg :: ProviderBegin ) ;
403
412
self . sess . profiler ( |p| p. start_activity ( Q :: CATEGORY ) ) ;
404
413
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
+ } )
408
419
} )
409
420
} ) ;
410
421
411
422
self . sess . profiler ( |p| p. end_activity ( Q :: CATEGORY ) ) ;
412
423
profq_msg ! ( self , ProfileQueriesMsg :: ProviderEnd ) ;
413
- let ( ( result, dep_node_index) , diagnostics) = res;
414
424
415
425
self . dep_graph . read_index ( dep_node_index) ;
416
426
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
+ }
419
431
420
432
job. complete ( & result, dep_node_index) ;
421
433
@@ -487,7 +499,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
487
499
// The diagnostics for this query have already been
488
500
// promoted to the current session during
489
501
// try_mark_green(), so we can ignore them here.
490
- let ( result, _ ) = job. start ( self , |tcx| {
502
+ let result = job. start ( self , None , |tcx| {
491
503
// The dep-graph for this computation is already in
492
504
// place
493
505
tcx. dep_graph . with_ignore ( || {
@@ -566,32 +578,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
566
578
profq_msg ! ( self , ProfileQueriesMsg :: ProviderBegin ) ;
567
579
self . sess . profiler ( |p| p. start_activity ( Q :: CATEGORY ) ) ;
568
580
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
+ } )
581
595
} ) ;
582
596
583
597
self . sess . profiler ( |p| p. end_activity ( Q :: CATEGORY ) ) ;
584
598
profq_msg ! ( self , ProfileQueriesMsg :: ProviderEnd ) ;
585
599
586
- let ( ( result, dep_node_index) , diagnostics) = res;
587
-
588
600
if unlikely ! ( self . sess. opts. debugging_opts. query_dep_graph) {
589
601
self . dep_graph . mark_loaded_from_cache ( dep_node_index, false ) ;
590
602
}
591
603
592
604
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
+ }
595
609
}
596
610
597
611
job. complete ( & result, dep_node_index) ;
0 commit comments