2
2
//! generate the actual methods on tcx which find and execute the provider,
3
3
//! manage the caches, and so forth.
4
4
5
- use super :: { queries, Query } ;
5
+ use super :: queries;
6
6
use rustc_middle:: dep_graph:: { DepKind , DepNode , DepNodeExt , DepNodeIndex , SerializedDepNodeIndex } ;
7
7
use rustc_middle:: ty:: query:: on_disk_cache;
8
8
use rustc_middle:: ty:: tls:: { self , ImplicitCtxt } ;
9
9
use rustc_middle:: ty:: { self , TyCtxt } ;
10
10
use rustc_query_system:: dep_graph:: HasDepContext ;
11
- use rustc_query_system:: query:: { CycleError , QueryJobId , QueryJobInfo } ;
12
- use rustc_query_system:: query:: { QueryContext , QueryDescription } ;
11
+ use rustc_query_system:: query:: { QueryContext , QueryDescription , QueryJobId , QueryMap } ;
13
12
14
- use rustc_data_structures:: fx:: FxHashMap ;
15
13
use rustc_data_structures:: sync:: Lock ;
16
14
use rustc_data_structures:: thin_vec:: ThinVec ;
17
- use rustc_errors:: { struct_span_err , Diagnostic , DiagnosticBuilder } ;
15
+ use rustc_errors:: Diagnostic ;
18
16
use rustc_serialize:: opaque;
19
17
use rustc_span:: def_id:: { DefId , LocalDefId } ;
20
- use rustc_span:: Span ;
21
18
22
19
#[ derive( Copy , Clone ) ]
23
20
pub struct QueryCtxt < ' tcx > {
@@ -45,15 +42,6 @@ impl HasDepContext for QueryCtxt<'tcx> {
45
42
}
46
43
47
44
impl QueryContext for QueryCtxt < ' tcx > {
48
- type Query = Query < ' tcx > ;
49
-
50
- fn incremental_verify_ich ( & self ) -> bool {
51
- self . sess . opts . debugging_opts . incremental_verify_ich
52
- }
53
- fn verbose ( & self ) -> bool {
54
- self . sess . verbose ( )
55
- }
56
-
57
45
fn def_path_str ( & self , def_id : DefId ) -> String {
58
46
self . tcx . def_path_str ( def_id)
59
47
}
@@ -62,11 +50,8 @@ impl QueryContext for QueryCtxt<'tcx> {
62
50
tls:: with_related_context ( * * self , |icx| icx. query )
63
51
}
64
52
65
- fn try_collect_active_jobs (
66
- & self ,
67
- ) -> Option < FxHashMap < QueryJobId < Self :: DepKind > , QueryJobInfo < Self :: DepKind , Self :: Query > > >
68
- {
69
- self . queries . try_collect_active_jobs ( )
53
+ fn try_collect_active_jobs ( & self ) -> Option < QueryMap < Self :: DepKind > > {
54
+ self . queries . try_collect_active_jobs ( * * self )
70
55
}
71
56
72
57
fn try_load_from_on_disk_cache ( & self , dep_node : & DepNode ) {
@@ -132,14 +117,6 @@ impl QueryContext for QueryCtxt<'tcx> {
132
117
( cb. force_from_dep_node ) ( * self , dep_node)
133
118
}
134
119
135
- fn has_errors_or_delayed_span_bugs ( & self ) -> bool {
136
- self . sess . has_errors_or_delayed_span_bugs ( )
137
- }
138
-
139
- fn diagnostic ( & self ) -> & rustc_errors:: Handler {
140
- self . sess . diagnostic ( )
141
- }
142
-
143
120
// Interactions with on_disk_cache
144
121
fn load_diagnostics ( & self , prev_dep_node_index : SerializedDepNodeIndex ) -> Vec < Diagnostic > {
145
122
self . on_disk_cache
@@ -196,54 +173,6 @@ impl QueryContext for QueryCtxt<'tcx> {
196
173
}
197
174
198
175
impl < ' tcx > QueryCtxt < ' tcx > {
199
- #[ inline( never) ]
200
- #[ cold]
201
- pub ( super ) fn report_cycle (
202
- self ,
203
- CycleError { usage, cycle : stack } : CycleError < Query < ' tcx > > ,
204
- ) -> DiagnosticBuilder < ' tcx > {
205
- assert ! ( !stack. is_empty( ) ) ;
206
-
207
- let fix_span = |span : Span , query : & Query < ' tcx > | {
208
- self . sess . source_map ( ) . guess_head_span ( query. default_span ( * self , span) )
209
- } ;
210
-
211
- // Disable naming impls with types in this path, since that
212
- // sometimes cycles itself, leading to extra cycle errors.
213
- // (And cycle errors around impls tend to occur during the
214
- // collect/coherence phases anyhow.)
215
- ty:: print:: with_forced_impl_filename_line ( || {
216
- let span = fix_span ( stack[ 1 % stack. len ( ) ] . span , & stack[ 0 ] . query ) ;
217
- let mut err = struct_span_err ! (
218
- self . sess,
219
- span,
220
- E0391 ,
221
- "cycle detected when {}" ,
222
- stack[ 0 ] . query. describe( self )
223
- ) ;
224
-
225
- for i in 1 ..stack. len ( ) {
226
- let query = & stack[ i] . query ;
227
- let span = fix_span ( stack[ ( i + 1 ) % stack. len ( ) ] . span , query) ;
228
- err. span_note ( span, & format ! ( "...which requires {}..." , query. describe( self ) ) ) ;
229
- }
230
-
231
- err. note ( & format ! (
232
- "...which again requires {}, completing the cycle" ,
233
- stack[ 0 ] . query. describe( self )
234
- ) ) ;
235
-
236
- if let Some ( ( span, query) ) = usage {
237
- err. span_note (
238
- fix_span ( span, & query) ,
239
- & format ! ( "cycle used when {}" , query. describe( self ) ) ,
240
- ) ;
241
- }
242
-
243
- err
244
- } )
245
- }
246
-
247
176
pub ( super ) fn encode_query_results (
248
177
self ,
249
178
encoder : & mut on_disk_cache:: CacheEncoder < ' a , ' tcx , opaque:: FileEncoder > ,
@@ -323,16 +252,16 @@ pub struct QueryStruct {
323
252
324
253
macro_rules! handle_cycle_error {
325
254
( [ ] [ $tcx: expr, $error: expr] ) => { {
326
- $tcx . report_cycle ( $ error) . emit( ) ;
255
+ $error. emit( ) ;
327
256
Value :: from_cycle_error( $tcx)
328
257
} } ;
329
258
( [ fatal_cycle $( $rest: tt) * ] [ $tcx: expr, $error: expr] ) => { {
330
- $tcx . report_cycle ( $ error) . emit( ) ;
259
+ $error. emit( ) ;
331
260
$tcx. sess. abort_if_errors( ) ;
332
261
unreachable!( )
333
262
} } ;
334
263
( [ cycle_delay_bug $( $rest: tt) * ] [ $tcx: expr, $error: expr] ) => { {
335
- $tcx . report_cycle ( $ error) . delay_as_bug( ) ;
264
+ $error. delay_as_bug( ) ;
336
265
Value :: from_cycle_error( $tcx)
337
266
} } ;
338
267
( [ $other: ident $( ( $( $other_args: tt) * ) ) * $( , $( $modifiers: tt) * ) * ] [ $( $args: tt) * ] ) => {
@@ -386,55 +315,40 @@ macro_rules! define_queries {
386
315
input: ( $( ( [ $( $modifiers) * ] [ $( $attr) * ] [ $name] ) ) * )
387
316
}
388
317
389
- #[ allow( nonstandard_style) ]
390
- #[ derive( Clone , Debug ) ]
391
- pub enum Query <$tcx> {
392
- $( $( #[ $attr] ) * $name( query_keys:: $name<$tcx>) ) ,*
393
- }
394
-
395
- impl <$tcx> Query <$tcx> {
396
- pub fn name( & self ) -> & ' static str {
397
- match * self {
398
- $( Query :: $name( _) => stringify!( $name) , ) *
399
- }
400
- }
318
+ mod make_query {
319
+ use super :: * ;
401
320
402
- pub ( crate ) fn describe( & self , tcx: QueryCtxt <$tcx>) -> String {
403
- let ( r, name) = match * self {
404
- $( Query :: $name( key) => {
405
- ( queries:: $name:: describe( tcx, key) , stringify!( $name) )
406
- } ) *
321
+ // Create an eponymous constructor for each query.
322
+ $( #[ allow( nonstandard_style) ] $( #[ $attr] ) *
323
+ pub fn $name<$tcx>( tcx: QueryCtxt <$tcx>, key: query_keys:: $name<$tcx>) -> QueryStackFrame {
324
+ let kind = dep_graph:: DepKind :: $name;
325
+ let name = stringify!( $name) ;
326
+ let description = ty:: print:: with_forced_impl_filename_line(
327
+ // Force filename-line mode to avoid invoking `type_of` query.
328
+ || queries:: $name:: describe( tcx, key)
329
+ ) ;
330
+ let description = if tcx. sess. verbose( ) {
331
+ format!( "{} [{}]" , description, name)
332
+ } else {
333
+ description
407
334
} ;
408
- if tcx. sess. verbose( ) {
409
- format!( "{} [{}]" , r, name)
335
+ let span = if kind == dep_graph:: DepKind :: def_span {
336
+ // The `def_span` query is used to calculate `default_span`,
337
+ // so exit to avoid infinite recursion.
338
+ None
410
339
} else {
411
- r
412
- }
413
- }
414
-
415
- // FIXME(eddyb) Get more valid `Span`s on queries.
416
- pub fn default_span( & self , tcx: TyCtxt <$tcx>, span: Span ) -> Span {
417
- if !span. is_dummy( ) {
418
- return span;
419
- }
420
- // The `def_span` query is used to calculate `default_span`,
421
- // so exit to avoid infinite recursion.
422
- if let Query :: def_span( ..) = * self {
423
- return span
424
- }
425
- match * self {
426
- $( Query :: $name( key) => key. default_span( tcx) , ) *
427
- }
428
- }
429
- }
340
+ Some ( key. default_span( * tcx) )
341
+ } ;
342
+ let hash = || {
343
+ let mut hcx = tcx. create_stable_hashing_context( ) ;
344
+ let mut hasher = StableHasher :: new( ) ;
345
+ std:: mem:: discriminant( & kind) . hash_stable( & mut hcx, & mut hasher) ;
346
+ key. hash_stable( & mut hcx, & mut hasher) ;
347
+ hasher. finish:: <u64 >( )
348
+ } ;
430
349
431
- impl <' a, $tcx> HashStable <StableHashingContext <' a>> for Query <$tcx> {
432
- fn hash_stable( & self , hcx: & mut StableHashingContext <' a>, hasher: & mut StableHasher ) {
433
- mem:: discriminant( self ) . hash_stable( hcx, hasher) ;
434
- match * self {
435
- $( Query :: $name( key) => key. hash_stable( hcx, hasher) , ) *
436
- }
437
- }
350
+ QueryStackFrame :: new( name, description, span, hash)
351
+ } ) *
438
352
}
439
353
440
354
#[ allow( nonstandard_style) ]
@@ -461,7 +375,9 @@ macro_rules! define_queries {
461
375
type Cache = query_storage:: $name<$tcx>;
462
376
463
377
#[ inline( always) ]
464
- fn query_state<' a>( tcx: QueryCtxt <$tcx>) -> & ' a QueryState <crate :: dep_graph:: DepKind , Query <$tcx>, Self :: Key > {
378
+ fn query_state<' a>( tcx: QueryCtxt <$tcx>) -> & ' a QueryState <crate :: dep_graph:: DepKind , Self :: Key >
379
+ where QueryCtxt <$tcx>: ' a
380
+ {
465
381
& tcx. queries. $name
466
382
}
467
383
@@ -493,7 +409,7 @@ macro_rules! define_queries {
493
409
494
410
fn handle_cycle_error(
495
411
tcx: QueryCtxt <' tcx>,
496
- error: CycleError < Query < ' tcx>>
412
+ mut error: DiagnosticBuilder < ' _> ,
497
413
) -> Self :: Value {
498
414
handle_cycle_error!( [ $( $modifiers) * ] [ tcx, error] )
499
415
}
@@ -596,7 +512,6 @@ macro_rules! define_queries_struct {
596
512
597
513
$( $( #[ $attr] ) * $name: QueryState <
598
514
crate :: dep_graph:: DepKind ,
599
- Query <$tcx>,
600
515
query_keys:: $name<$tcx>,
601
516
>, ) *
602
517
}
@@ -614,14 +529,17 @@ macro_rules! define_queries_struct {
614
529
}
615
530
616
531
pub ( crate ) fn try_collect_active_jobs(
617
- & self
618
- ) -> Option <FxHashMap <QueryJobId <crate :: dep_graph:: DepKind >, QueryJobInfo <crate :: dep_graph:: DepKind , Query <$tcx>>>> {
619
- let mut jobs = FxHashMap :: default ( ) ;
532
+ & $tcx self ,
533
+ tcx: TyCtxt <$tcx>,
534
+ ) -> Option <QueryMap <crate :: dep_graph:: DepKind >> {
535
+ let tcx = QueryCtxt { tcx, queries: self } ;
536
+ let mut jobs = QueryMap :: default ( ) ;
620
537
621
538
$(
622
539
self . $name. try_collect_active_jobs(
623
- <queries:: $name<' tcx> as QueryAccessors <QueryCtxt <' tcx>>>:: DEP_KIND ,
624
- Query :: $name,
540
+ tcx,
541
+ dep_graph:: DepKind :: $name,
542
+ make_query:: $name,
625
543
& mut jobs,
626
544
) ?;
627
545
) *
@@ -666,38 +584,8 @@ macro_rules! define_queries_struct {
666
584
handler: & Handler ,
667
585
num_frames: Option <usize >,
668
586
) -> usize {
669
- let query_map = self . try_collect_active_jobs( ) ;
670
-
671
- let mut current_query = query;
672
- let mut i = 0 ;
673
-
674
- while let Some ( query) = current_query {
675
- if Some ( i) == num_frames {
676
- break ;
677
- }
678
- let query_info = if let Some ( info) = query_map. as_ref( ) . and_then( |map| map. get( & query) )
679
- {
680
- info
681
- } else {
682
- break ;
683
- } ;
684
- let mut diag = Diagnostic :: new(
685
- Level :: FailureNote ,
686
- & format!(
687
- "#{} [{}] {}" ,
688
- i,
689
- query_info. info. query. name( ) ,
690
- query_info. info. query. describe( QueryCtxt { tcx, queries: self } )
691
- ) ,
692
- ) ;
693
- diag. span = tcx. sess. source_map( ) . guess_head_span( query_info. info. span) . into( ) ;
694
- handler. force_print_diagnostic( diag) ;
695
-
696
- current_query = query_info. job. parent;
697
- i += 1 ;
698
- }
699
-
700
- i
587
+ let qcx = QueryCtxt { tcx, queries: self } ;
588
+ rustc_query_system:: query:: print_query_stack( qcx, query, handler, num_frames)
701
589
}
702
590
703
591
$( $( #[ $attr] ) *
0 commit comments