@@ -12,9 +12,9 @@ pub use sealed::IntoQueryParam;
1212
1313use crate :: dep_graph:: { DepKind , DepNodeIndex , SerializedDepNodeIndex } ;
1414use crate :: ich:: StableHashingContext ;
15- use crate :: queries:: { ExternProviders , Providers , QueryArenas , QueryVTables } ;
15+ use crate :: queries:: { ExternProviders , Providers , QueryArenas , QueryVTables , TaggedQueryKey } ;
1616use crate :: query:: on_disk_cache:: OnDiskCache ;
17- use crate :: query:: stack:: { QueryStackDeferred , QueryStackFrame , QueryStackFrameExtra } ;
17+ use crate :: query:: stack:: QueryStackFrame ;
1818use crate :: query:: { QueryCache , QueryInfo , QueryJob } ;
1919use crate :: ty:: TyCtxt ;
2020
@@ -60,19 +60,10 @@ pub enum CycleErrorHandling {
6060}
6161
6262#[ derive( Clone , Debug ) ]
63- pub struct CycleError < I = QueryStackFrameExtra > {
63+ pub struct CycleError < ' tcx > {
6464 /// The query and related span that uses the cycle.
65- pub usage : Option < ( Span , QueryStackFrame < I > ) > ,
66- pub cycle : Vec < QueryInfo < I > > ,
67- }
68-
69- impl < ' tcx > CycleError < QueryStackDeferred < ' tcx > > {
70- pub fn lift ( & self ) -> CycleError < QueryStackFrameExtra > {
71- CycleError {
72- usage : self . usage . as_ref ( ) . map ( |( span, frame) | ( * span, frame. lift ( ) ) ) ,
73- cycle : self . cycle . iter ( ) . map ( |info| info. lift ( ) ) . collect ( ) ,
74- }
75- }
65+ pub usage : Option < ( Span , QueryStackFrame < ' tcx > ) > ,
66+ pub cycle : Vec < QueryInfo < ' tcx > > ,
7667}
7768
7869#[ derive( Debug ) ]
@@ -139,16 +130,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
139130 pub value_from_cycle_error : fn (
140131 tcx : TyCtxt < ' tcx > ,
141132 key : C :: Key ,
142- cycle_error : CycleError ,
133+ cycle_error : CycleError < ' tcx > ,
143134 guar : ErrorGuaranteed ,
144135 ) -> C :: Value ,
145136 pub format_value : fn ( & C :: Value ) -> String ,
146137
147- /// Formats a human-readable description of this query and its key, as
148- /// specified by the `desc` query modifier.
149- ///
150- /// Used when reporting query cycle errors and similar problems.
151- pub description_fn : fn ( TyCtxt < ' tcx > , C :: Key ) -> String ,
138+ pub create_tagged_key : fn ( C :: Key ) -> TaggedQueryKey < ' tcx > ,
152139
153140 /// Function pointer that is called by the query methods on [`TyCtxt`] and
154141 /// friends[^1], after they have checked the in-memory cache and found no
@@ -523,6 +510,69 @@ macro_rules! define_callbacks {
523510 }
524511 ) *
525512
513+ /// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a number.
514+ #[ allow( non_camel_case_types) ]
515+ #[ derive( Clone , Debug ) ]
516+ pub enum TaggedQueryKey <' tcx> {
517+ $(
518+ $name( $name:: Key <' tcx>) ,
519+ ) *
520+ }
521+
522+ impl <' tcx> TaggedQueryKey <' tcx> {
523+ /// Formats a human-readable description of this query and its key, as
524+ /// specified by the `desc` query modifier.
525+ ///
526+ /// Used when reporting query cycle errors and similar problems.
527+ pub fn description( & self , tcx: TyCtxt <' tcx>) -> String {
528+ let ( name, description) = ty:: print:: with_no_queries!( match self {
529+ $(
530+ TaggedQueryKey :: $name( key) => ( stringify!( $name) , _description_fns:: $name( tcx, * key) ) ,
531+ ) *
532+ } ) ;
533+ if tcx. sess. verbose_internals( ) {
534+ format!( "{description} [{name:?}]" )
535+ } else {
536+ description
537+ }
538+ }
539+
540+ /// Returns the default span for this query if `span` is a dummy span.
541+ pub fn default_span( & self , tcx: TyCtxt <' tcx>, span: Span ) -> Span {
542+ if !span. is_dummy( ) {
543+ return span
544+ }
545+ if let TaggedQueryKey :: def_span( ..) = self {
546+ // The `def_span` query is used to calculate `default_span`,
547+ // so exit to avoid infinite recursion.
548+ return DUMMY_SP
549+ }
550+ match self {
551+ $(
552+ TaggedQueryKey :: $name( key) => crate :: query:: QueryKey :: default_span( key, tcx) ,
553+ ) *
554+ }
555+ }
556+
557+ pub fn def_kind( & self , tcx: TyCtxt <' tcx>) -> Option <DefKind > {
558+ // This is used to reduce code generation as it
559+ // can be reused for queries with the same key type.
560+ fn inner<' tcx>( key: & impl crate :: query:: QueryKey , tcx: TyCtxt <' tcx>) -> Option <DefKind > {
561+ key. key_as_def_id( ) . and_then( |def_id| def_id. as_local( ) ) . map( |def_id| tcx. def_kind( def_id) )
562+ }
563+
564+ if let TaggedQueryKey :: def_kind( ..) = self {
565+ // Try to avoid infinite recursion.
566+ return None
567+ }
568+ match self {
569+ $(
570+ TaggedQueryKey :: $name( key) => inner( key, tcx) ,
571+ ) *
572+ }
573+ }
574+ }
575+
526576 /// Holds a `QueryVTable` for each query.
527577 pub struct QueryVTables <' tcx> {
528578 $(
0 commit comments