9
9
// except according to those terms.
10
10
11
11
use dep_graph:: { DepConstructor , DepNode , DepNodeIndex } ;
12
+ use errors:: { Diagnostic , DiagnosticBuilder } ;
12
13
use hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
13
14
use hir:: def:: Def ;
14
15
use hir;
@@ -32,7 +33,7 @@ use util::common::{profq_msg, ProfileQueriesMsg};
32
33
33
34
use rustc_data_structures:: indexed_vec:: IndexVec ;
34
35
use rustc_data_structures:: fx:: FxHashMap ;
35
- use std:: cell:: { RefCell , RefMut } ;
36
+ use std:: cell:: { RefCell , RefMut , Cell } ;
36
37
use std:: fmt:: Debug ;
37
38
use std:: hash:: Hash ;
38
39
use std:: marker:: PhantomData ;
@@ -188,7 +189,18 @@ impl<'tcx> Value<'tcx> for ty::SymbolName {
188
189
189
190
struct QueryMap < D : QueryDescription > {
190
191
phantom : PhantomData < D > ,
191
- map : FxHashMap < D :: Key , ( D :: Value , DepNodeIndex ) > ,
192
+ map : FxHashMap < D :: Key , QueryValue < D :: Value > > ,
193
+ }
194
+
195
+ struct QueryValue < T > {
196
+ value : T ,
197
+ index : DepNodeIndex ,
198
+ diagnostics : Option < Box < QueryDiagnostics > > ,
199
+ }
200
+
201
+ struct QueryDiagnostics {
202
+ diagnostics : Vec < Diagnostic > ,
203
+ emitted_diagnostics : Cell < bool > ,
192
204
}
193
205
194
206
impl < M : QueryDescription > QueryMap < M > {
@@ -618,10 +630,20 @@ macro_rules! define_maps {
618
630
)
619
631
) ;
620
632
621
- if let Some ( & ( ref result, dep_node_index) ) = tcx. maps. $name. borrow( ) . map. get( & key) {
622
- tcx. dep_graph. read_index( dep_node_index) ;
633
+ if let Some ( value) = tcx. maps. $name. borrow( ) . map. get( & key) {
634
+ if let Some ( ref d) = value. diagnostics {
635
+ if !d. emitted_diagnostics. get( ) {
636
+ d. emitted_diagnostics. set( true ) ;
637
+ let handle = tcx. sess. diagnostic( ) ;
638
+ for diagnostic in d. diagnostics. iter( ) {
639
+ DiagnosticBuilder :: new_diagnostic( handle, diagnostic. clone( ) )
640
+ . emit( ) ;
641
+ }
642
+ }
643
+ }
623
644
profq_msg!( tcx, ProfileQueriesMsg :: CacheHit ) ;
624
- return Ok ( f( result) ) ;
645
+ tcx. dep_graph. read_index( value. index) ;
646
+ return Ok ( f( & value. value) ) ;
625
647
}
626
648
// else, we are going to run the provider:
627
649
profq_msg!( tcx, ProfileQueriesMsg :: ProviderBegin ) ;
@@ -633,36 +655,52 @@ macro_rules! define_maps {
633
655
span = key. default_span( tcx)
634
656
}
635
657
636
- let ( result , dep_node_index ) = tcx. cycle_check( span, Query :: $name( key) , || {
658
+ let res = tcx. cycle_check( span, Query :: $name( key) , || {
637
659
let dep_node = Self :: to_dep_node( tcx, & key) ;
638
660
639
- if dep_node. kind. is_anon( ) {
640
- tcx. dep_graph. with_anon_task( dep_node. kind, || {
641
- let provider = tcx. maps. providers[ key. map_crate( ) ] . $name;
642
- provider( tcx. global_tcx( ) , key)
643
- } )
644
- } else {
645
- fn run_provider<' a, ' tcx, ' lcx>( tcx: TyCtxt <' a, ' tcx, ' lcx>,
646
- key: $K)
647
- -> $V {
648
- let provider = tcx. maps. providers[ key. map_crate( ) ] . $name;
649
- provider( tcx. global_tcx( ) , key)
661
+ tcx. sess. diagnostic( ) . track_diagnostics( || {
662
+ if dep_node. kind. is_anon( ) {
663
+ tcx. dep_graph. with_anon_task( dep_node. kind, || {
664
+ let provider = tcx. maps. providers[ key. map_crate( ) ] . $name;
665
+ provider( tcx. global_tcx( ) , key)
666
+ } )
667
+ } else {
668
+ fn run_provider<' a, ' tcx, ' lcx>( tcx: TyCtxt <' a, ' tcx, ' lcx>,
669
+ key: $K)
670
+ -> $V {
671
+ let provider = tcx. maps. providers[ key. map_crate( ) ] . $name;
672
+ provider( tcx. global_tcx( ) , key)
673
+ }
674
+
675
+ tcx. dep_graph. with_task( dep_node, tcx, key, run_provider)
650
676
}
651
-
652
- tcx. dep_graph. with_task( dep_node, tcx, key, run_provider)
653
- }
677
+ } )
654
678
} ) ?;
655
679
profq_msg!( tcx, ProfileQueriesMsg :: ProviderEnd ) ;
680
+ let ( ( result, dep_node_index) , diagnostics) = res;
656
681
657
682
tcx. dep_graph. read_index( dep_node_index) ;
658
683
684
+ let value = QueryValue {
685
+ value: result,
686
+ index: dep_node_index,
687
+ diagnostics: if diagnostics. len( ) == 0 {
688
+ None
689
+ } else {
690
+ Some ( Box :: new( QueryDiagnostics {
691
+ diagnostics,
692
+ emitted_diagnostics: Cell :: new( true ) ,
693
+ } ) )
694
+ } ,
695
+ } ;
696
+
659
697
Ok ( f( & tcx. maps
660
698
. $name
661
699
. borrow_mut( )
662
700
. map
663
701
. entry( key)
664
- . or_insert( ( result , dep_node_index ) )
665
- . 0 ) )
702
+ . or_insert( value )
703
+ . value ) )
666
704
}
667
705
668
706
pub fn try_get( tcx: TyCtxt <' a, $tcx, ' lcx>, span: Span , key: $K)
0 commit comments