@@ -39,7 +39,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
3939use rustc_data_structures:: sharded:: { IntoPointer , ShardedHashMap } ;
4040use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
4141use rustc_data_structures:: steal:: Steal ;
42- use rustc_data_structures:: sync:: { self , FreezeReadGuard , Lock , WorkerLocal } ;
42+ use rustc_data_structures:: sync:: { self , FreezeReadGuard , Lock , Lrc , WorkerLocal } ;
4343#[ cfg( parallel_compiler) ]
4444use rustc_data_structures:: sync:: { DynSend , DynSync } ;
4545use rustc_data_structures:: unord:: UnordSet ;
@@ -60,7 +60,7 @@ use rustc_session::config::CrateType;
6060use rustc_session:: cstore:: { CrateStoreDyn , Untracked } ;
6161use rustc_session:: lint:: Lint ;
6262use rustc_session:: { Limit , MetadataKind , Session } ;
63- use rustc_span:: def_id:: { DefPathHash , StableCrateId } ;
63+ use rustc_span:: def_id:: { DefPathHash , StableCrateId , CRATE_DEF_ID } ;
6464use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
6565use rustc_span:: { Span , DUMMY_SP } ;
6666use rustc_target:: abi:: { FieldIdx , Layout , LayoutS , TargetDataLayout , VariantIdx } ;
@@ -74,6 +74,7 @@ use std::cmp::Ordering;
7474use std:: fmt;
7575use std:: hash:: { Hash , Hasher } ;
7676use std:: iter;
77+ use std:: marker:: PhantomData ;
7778use std:: mem;
7879use std:: ops:: { Bound , Deref } ;
7980
@@ -498,14 +499,55 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> {
498499 key : KEY ,
499500}
500501
502+ /// Never return a `Feed` from a query. Only queries that create a `DefId` are
503+ /// allowed to feed queries for that `DefId`.
504+ impl < KEY : Copy , CTX > !HashStable < CTX > for TyCtxtFeed < ' _ , KEY > { }
505+
506+ /// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
507+ /// Use this to pass around when you have a `TyCtxt` elsewhere.
508+ /// Just an optimization to save space and not store hundreds of
509+ /// `TyCtxtFeed` in the resolver.
510+ #[ derive( Copy , Clone ) ]
511+ pub struct Feed < ' tcx , KEY : Copy > {
512+ _tcx : PhantomData < TyCtxt < ' tcx > > ,
513+ // Do not allow direct access, as downstream code must not mutate this field.
514+ key : KEY ,
515+ }
516+
517+ /// Never return a `Feed` from a query. Only queries that create a `DefId` are
518+ /// allowed to feed queries for that `DefId`.
519+ impl < KEY : Copy , CTX > !HashStable < CTX > for Feed < ' _ , KEY > { }
520+
521+ impl < T : fmt:: Debug + Copy > fmt:: Debug for Feed < ' _ , T > {
522+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
523+ self . key . fmt ( f)
524+ }
525+ }
526+
527+ /// Some workarounds to use cases that cannot use `create_def`.
528+ /// Do not add new ways to create `TyCtxtFeed` without consulting
529+ /// with T-compiler and making an analysis about why your addition
530+ /// does not cause incremental compilation issues.
501531impl < ' tcx > TyCtxt < ' tcx > {
532+ /// Can only be fed before queries are run, and is thus exempt from any
533+ /// incremental issues. Do not use except for the initial query feeding.
502534 pub fn feed_unit_query ( self ) -> TyCtxtFeed < ' tcx , ( ) > {
535+ self . dep_graph . assert_ignored ( ) ;
503536 TyCtxtFeed { tcx : self , key : ( ) }
504537 }
538+
539+ /// Can only be fed before queries are run, and is thus exempt from any
540+ /// incremental issues. Do not use except for the initial query feeding.
505541 pub fn feed_local_crate ( self ) -> TyCtxtFeed < ' tcx , CrateNum > {
542+ self . dep_graph . assert_ignored ( ) ;
506543 TyCtxtFeed { tcx : self , key : LOCAL_CRATE }
507544 }
508- pub fn feed_local_def_id ( self , key : LocalDefId ) -> TyCtxtFeed < ' tcx , LocalDefId > {
545+
546+ /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
547+ /// some queries for it. It will panic if used twice.
548+ pub fn create_local_crate_def_id ( self , span : Span ) -> TyCtxtFeed < ' tcx , LocalDefId > {
549+ let key = self . untracked ( ) . source_span . push ( span) ;
550+ assert_eq ! ( key, CRATE_DEF_ID ) ;
509551 TyCtxtFeed { tcx : self , key }
510552 }
511553
@@ -523,6 +565,23 @@ impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
523565 pub fn key ( & self ) -> KEY {
524566 self . key
525567 }
568+
569+ #[ inline( always) ]
570+ pub fn downgrade ( self ) -> Feed < ' tcx , KEY > {
571+ Feed { _tcx : PhantomData , key : self . key }
572+ }
573+ }
574+
575+ impl < ' tcx , KEY : Copy > Feed < ' tcx , KEY > {
576+ #[ inline( always) ]
577+ pub fn key ( & self ) -> KEY {
578+ self . key
579+ }
580+
581+ #[ inline( always) ]
582+ pub fn upgrade ( self , tcx : TyCtxt < ' tcx > ) -> TyCtxtFeed < ' tcx , KEY > {
583+ TyCtxtFeed { tcx, key : self . key }
584+ }
526585}
527586
528587impl < ' tcx > TyCtxtFeed < ' tcx , LocalDefId > {
@@ -1067,7 +1126,7 @@ impl<'tcx> TyCtxt<'tcx> {
10671126 // needs to be re-evaluated.
10681127 self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
10691128
1070- let feed = self . feed_local_def_id ( def_id) ;
1129+ let feed = TyCtxtFeed { tcx : self , key : def_id } ;
10711130 feed. def_kind ( def_kind) ;
10721131 // Unique types created for closures participate in type privacy checking.
10731132 // They have visibilities inherited from the module they are defined in.
@@ -2304,6 +2363,10 @@ impl<'tcx> TyCtxt<'tcx> {
23042363 self . resolutions ( ( ) ) . module_children . get ( & def_id) . map_or ( & [ ] , |v| & v[ ..] )
23052364 }
23062365
2366+ pub fn resolver_for_lowering ( self ) -> & ' tcx Steal < ( ty:: ResolverAstLowering , Lrc < ast:: Crate > ) > {
2367+ self . resolver_for_lowering_raw ( ( ) ) . 0
2368+ }
2369+
23072370 /// Given an `impl_id`, return the trait it implements.
23082371 /// Return `None` if this is an inherent impl.
23092372 pub fn impl_trait_ref (
0 commit comments