@@ -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
@@ -524,6 +511,69 @@ macro_rules! define_callbacks {
524511 }
525512 ) *
526513
514+ /// Identifies a query by kind and key. This is in contrast to `QueryId` which is just a number.
515+ #[ allow( non_camel_case_types) ]
516+ #[ derive( Clone , Debug ) ]
517+ pub enum TaggedQueryKey <' tcx> {
518+ $(
519+ $name( $name:: Key <' tcx>) ,
520+ ) *
521+ }
522+
523+ impl <' tcx> TaggedQueryKey <' tcx> {
524+ /// Formats a human-readable description of this query and its key, as
525+ /// specified by the `desc` query modifier.
526+ ///
527+ /// Used when reporting query cycle errors and similar problems.
528+ pub fn description( & self , tcx: TyCtxt <' tcx>) -> String {
529+ let ( name, description) = ty:: print:: with_no_queries!( match self {
530+ $(
531+ TaggedQueryKey :: $name( key) => ( stringify!( $name) , _description_fns:: $name( tcx, * key) ) ,
532+ ) *
533+ } ) ;
534+ if tcx. sess. verbose_internals( ) {
535+ format!( "{description} [{name:?}]" )
536+ } else {
537+ description
538+ }
539+ }
540+
541+ /// Returns the default span for this query if `span` is a dummy span.
542+ pub fn default_span( & self , tcx: TyCtxt <' tcx>, span: Span ) -> Span {
543+ if !span. is_dummy( ) {
544+ return span
545+ }
546+ if let TaggedQueryKey :: def_span( ..) = self {
547+ // The `def_span` query is used to calculate `default_span`,
548+ // so exit to avoid infinite recursion.
549+ return DUMMY_SP
550+ }
551+ match self {
552+ $(
553+ TaggedQueryKey :: $name( key) => crate :: query:: QueryKey :: default_span( key, tcx) ,
554+ ) *
555+ }
556+ }
557+
558+ pub fn def_kind( & self , tcx: TyCtxt <' tcx>) -> Option <DefKind > {
559+ // This is used to reduce code generation as it
560+ // can be reused for queries with the same key type.
561+ fn inner<' tcx>( key: & impl crate :: query:: QueryKey , tcx: TyCtxt <' tcx>) -> Option <DefKind > {
562+ key. key_as_def_id( ) . and_then( |def_id| def_id. as_local( ) ) . map( |def_id| tcx. def_kind( def_id) )
563+ }
564+
565+ if let TaggedQueryKey :: def_kind( ..) = self {
566+ // Try to avoid infinite recursion.
567+ return None
568+ }
569+ match self {
570+ $(
571+ TaggedQueryKey :: $name( key) => inner( key, tcx) ,
572+ ) *
573+ }
574+ }
575+ }
576+
527577 /// Holds a `QueryVTable` for each query.
528578 pub struct QueryVTables <' tcx> {
529579 $(
0 commit comments