@@ -62,7 +62,7 @@ use rustc_session::config::CrateType;
6262use rustc_session:: cstore:: { CrateStoreDyn , Untracked } ;
6363use rustc_session:: lint:: Lint ;
6464use rustc_session:: { Limit , MetadataKind , Session } ;
65- use rustc_span:: def_id:: { DefPathHash , StableCrateId } ;
65+ use rustc_span:: def_id:: { DefPathHash , StableCrateId , CRATE_DEF_ID } ;
6666use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
6767use rustc_span:: { Span , DUMMY_SP } ;
6868use rustc_target:: abi:: { FieldIdx , Layout , LayoutS , TargetDataLayout , VariantIdx } ;
@@ -76,6 +76,7 @@ use std::cmp::Ordering;
7676use std:: fmt;
7777use std:: hash:: { Hash , Hasher } ;
7878use std:: iter;
79+ use std:: marker:: PhantomData ;
7980use std:: mem;
8081use std:: ops:: { Bound , Deref } ;
8182
@@ -522,14 +523,55 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> {
522523 key : KEY ,
523524}
524525
526+ /// Never return a `Feed` from a query. Only queries that create a `DefId` are
527+ /// allowed to feed queries for that `DefId`.
528+ impl < KEY : Copy , CTX > !HashStable < CTX > for TyCtxtFeed < ' _ , KEY > { }
529+
530+ /// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
531+ /// Use this to pass around when you have a `TyCtxt` elsewhere.
532+ /// Just an optimization to save space and not store hundreds of
533+ /// `TyCtxtFeed` in the resolver.
534+ #[ derive( Copy , Clone ) ]
535+ pub struct Feed < ' tcx , KEY : Copy > {
536+ _tcx : PhantomData < TyCtxt < ' tcx > > ,
537+ // Do not allow direct access, as downstream code must not mutate this field.
538+ key : KEY ,
539+ }
540+
541+ /// Never return a `Feed` from a query. Only queries that create a `DefId` are
542+ /// allowed to feed queries for that `DefId`.
543+ impl < KEY : Copy , CTX > !HashStable < CTX > for Feed < ' _ , KEY > { }
544+
545+ impl < T : fmt:: Debug + Copy > fmt:: Debug for Feed < ' _ , T > {
546+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
547+ self . key . fmt ( f)
548+ }
549+ }
550+
551+ /// Some workarounds to use cases that cannot use `create_def`.
552+ /// Do not add new ways to create `TyCtxtFeed` without consulting
553+ /// with T-compiler and making an analysis about why your addition
554+ /// does not cause incremental compilation issues.
525555impl < ' tcx > TyCtxt < ' tcx > {
556+ /// Can only be fed before queries are run, and is thus exempt from any
557+ /// incremental issues. Do not use except for the initial query feeding.
526558 pub fn feed_unit_query ( self ) -> TyCtxtFeed < ' tcx , ( ) > {
559+ self . dep_graph . assert_ignored ( ) ;
527560 TyCtxtFeed { tcx : self , key : ( ) }
528561 }
562+
563+ /// Can only be fed before queries are run, and is thus exempt from any
564+ /// incremental issues. Do not use except for the initial query feeding.
529565 pub fn feed_local_crate ( self ) -> TyCtxtFeed < ' tcx , CrateNum > {
566+ self . dep_graph . assert_ignored ( ) ;
530567 TyCtxtFeed { tcx : self , key : LOCAL_CRATE }
531568 }
532- pub fn feed_local_def_id ( self , key : LocalDefId ) -> TyCtxtFeed < ' tcx , LocalDefId > {
569+
570+ /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
571+ /// some queries for it. It will panic if used twice.
572+ pub fn create_local_crate_def_id ( self , span : Span ) -> TyCtxtFeed < ' tcx , LocalDefId > {
573+ let key = self . untracked ( ) . source_span . push ( span) ;
574+ assert_eq ! ( key, CRATE_DEF_ID ) ;
533575 TyCtxtFeed { tcx : self , key }
534576 }
535577
@@ -547,6 +589,23 @@ impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
547589 pub fn key ( & self ) -> KEY {
548590 self . key
549591 }
592+
593+ #[ inline( always) ]
594+ pub fn downgrade ( self ) -> Feed < ' tcx , KEY > {
595+ Feed { _tcx : PhantomData , key : self . key }
596+ }
597+ }
598+
599+ impl < ' tcx , KEY : Copy > Feed < ' tcx , KEY > {
600+ #[ inline( always) ]
601+ pub fn key ( & self ) -> KEY {
602+ self . key
603+ }
604+
605+ #[ inline( always) ]
606+ pub fn upgrade ( self , tcx : TyCtxt < ' tcx > ) -> TyCtxtFeed < ' tcx , KEY > {
607+ TyCtxtFeed { tcx, key : self . key }
608+ }
550609}
551610
552611impl < ' tcx > TyCtxtFeed < ' tcx , LocalDefId > {
@@ -1091,7 +1150,7 @@ impl<'tcx> TyCtxt<'tcx> {
10911150 // needs to be re-evaluated.
10921151 self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
10931152
1094- let feed = self . feed_local_def_id ( def_id) ;
1153+ let feed = TyCtxtFeed { tcx : self , key : def_id } ;
10951154 feed. def_kind ( def_kind) ;
10961155 // Unique types created for closures participate in type privacy checking.
10971156 // They have visibilities inherited from the module they are defined in.
0 commit comments