22//! generate the actual methods on tcx which find and execute the provider,
33//! manage the caches, and so forth.
44
5- use super :: { queries, Query } ;
5+ use super :: queries;
66use rustc_middle:: dep_graph:: { DepKind , DepNode , DepNodeExt , DepNodeIndex , SerializedDepNodeIndex } ;
77use rustc_middle:: ty:: query:: on_disk_cache;
88use rustc_middle:: ty:: tls:: { self , ImplicitCtxt } ;
99use rustc_middle:: ty:: { self , TyCtxt } ;
1010use 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 } ;
1312
14- use rustc_data_structures:: fx:: FxHashMap ;
1513use rustc_data_structures:: sync:: Lock ;
1614use rustc_data_structures:: thin_vec:: ThinVec ;
17- use rustc_errors:: { struct_span_err , Diagnostic , DiagnosticBuilder } ;
15+ use rustc_errors:: Diagnostic ;
1816use rustc_serialize:: opaque;
1917use rustc_span:: def_id:: { DefId , LocalDefId } ;
20- use rustc_span:: Span ;
2118
2219#[ derive( Copy , Clone ) ]
2320pub struct QueryCtxt < ' tcx > {
@@ -45,15 +42,6 @@ impl HasDepContext for QueryCtxt<'tcx> {
4542}
4643
4744impl 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-
5745 fn def_path_str ( & self , def_id : DefId ) -> String {
5846 self . tcx . def_path_str ( def_id)
5947 }
@@ -62,11 +50,8 @@ impl QueryContext for QueryCtxt<'tcx> {
6250 tls:: with_related_context ( * * self , |icx| icx. query )
6351 }
6452
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 )
7055 }
7156
7257 fn try_load_from_on_disk_cache ( & self , dep_node : & DepNode ) {
@@ -132,14 +117,6 @@ impl QueryContext for QueryCtxt<'tcx> {
132117 ( cb. force_from_dep_node ) ( * self , dep_node)
133118 }
134119
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-
143120 // Interactions with on_disk_cache
144121 fn load_diagnostics ( & self , prev_dep_node_index : SerializedDepNodeIndex ) -> Vec < Diagnostic > {
145122 self . on_disk_cache
@@ -196,54 +173,6 @@ impl QueryContext for QueryCtxt<'tcx> {
196173}
197174
198175impl < ' 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-
247176 pub ( super ) fn encode_query_results (
248177 self ,
249178 encoder : & mut on_disk_cache:: CacheEncoder < ' a , ' tcx , opaque:: FileEncoder > ,
@@ -323,16 +252,16 @@ pub struct QueryStruct {
323252
324253macro_rules! handle_cycle_error {
325254 ( [ ] [ $tcx: expr, $error: expr] ) => { {
326- $tcx . report_cycle ( $ error) . emit( ) ;
255+ $error. emit( ) ;
327256 Value :: from_cycle_error( $tcx)
328257 } } ;
329258 ( [ fatal_cycle $( $rest: tt) * ] [ $tcx: expr, $error: expr] ) => { {
330- $tcx . report_cycle ( $ error) . emit( ) ;
259+ $error. emit( ) ;
331260 $tcx. sess. abort_if_errors( ) ;
332261 unreachable!( )
333262 } } ;
334263 ( [ cycle_delay_bug $( $rest: tt) * ] [ $tcx: expr, $error: expr] ) => { {
335- $tcx . report_cycle ( $ error) . delay_as_bug( ) ;
264+ $error. delay_as_bug( ) ;
336265 Value :: from_cycle_error( $tcx)
337266 } } ;
338267 ( [ $other: ident $( ( $( $other_args: tt) * ) ) * $( , $( $modifiers: tt) * ) * ] [ $( $args: tt) * ] ) => {
@@ -386,55 +315,40 @@ macro_rules! define_queries {
386315 input: ( $( ( [ $( $modifiers) * ] [ $( $attr) * ] [ $name] ) ) * )
387316 }
388317
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 :: * ;
401320
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
407334 } ;
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
410339 } 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+ } ;
430349
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+ } ) *
438352 }
439353
440354 #[ allow( nonstandard_style) ]
@@ -461,7 +375,9 @@ macro_rules! define_queries {
461375 type Cache = query_storage:: $name<$tcx>;
462376
463377 #[ 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+ {
465381 & tcx. queries. $name
466382 }
467383
@@ -493,7 +409,7 @@ macro_rules! define_queries {
493409
494410 fn handle_cycle_error(
495411 tcx: QueryCtxt <' tcx>,
496- error: CycleError < Query < ' tcx>>
412+ mut error: DiagnosticBuilder < ' _> ,
497413 ) -> Self :: Value {
498414 handle_cycle_error!( [ $( $modifiers) * ] [ tcx, error] )
499415 }
@@ -596,7 +512,6 @@ macro_rules! define_queries_struct {
596512
597513 $( $( #[ $attr] ) * $name: QueryState <
598514 crate :: dep_graph:: DepKind ,
599- Query <$tcx>,
600515 query_keys:: $name<$tcx>,
601516 >, ) *
602517 }
@@ -614,14 +529,17 @@ macro_rules! define_queries_struct {
614529 }
615530
616531 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 ( ) ;
620537
621538 $(
622539 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,
625543 & mut jobs,
626544 ) ?;
627545 ) *
@@ -666,38 +584,8 @@ macro_rules! define_queries_struct {
666584 handler: & Handler ,
667585 num_frames: Option <usize >,
668586 ) -> 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)
701589 }
702590
703591 $( $( #[ $attr] ) *
0 commit comments