@@ -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
@@ -519,6 +520,23 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> {
519520 key : KEY ,
520521}
521522
523+ /// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
524+ /// Use this to pass around when you have a `TyCtxt` elsewhere.
525+ /// Just an optimization to save space and not store hundreds of
526+ /// `TyCtxtFeed` in the resolver.
527+ #[ derive( Copy , Clone ) ]
528+ pub struct Feed < ' tcx , KEY : Copy > {
529+ _tcx : PhantomData < TyCtxt < ' tcx > > ,
530+ // Do not allow direct access, as downstream code must not mutate this field.
531+ key : KEY ,
532+ }
533+
534+ impl < T : fmt:: Debug + Copy > fmt:: Debug for Feed < ' _ , T > {
535+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
536+ self . key . fmt ( f)
537+ }
538+ }
539+
522540impl < ' tcx > TyCtxt < ' tcx > {
523541 pub fn feed_unit_query ( self ) -> TyCtxtFeed < ' tcx , ( ) > {
524542 TyCtxtFeed { tcx : self , key : ( ) }
@@ -544,6 +562,23 @@ impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
544562 pub fn key ( & self ) -> KEY {
545563 self . key
546564 }
565+
566+ #[ inline( always) ]
567+ pub fn downgrade ( self ) -> Feed < ' tcx , KEY > {
568+ Feed { _tcx : PhantomData , key : self . key }
569+ }
570+ }
571+
572+ impl < ' tcx , KEY : Copy > Feed < ' tcx , KEY > {
573+ #[ inline( always) ]
574+ pub fn key ( & self ) -> KEY {
575+ self . key
576+ }
577+
578+ #[ inline( always) ]
579+ pub fn upgrade ( self , tcx : TyCtxt < ' tcx > ) -> TyCtxtFeed < ' tcx , KEY > {
580+ TyCtxtFeed { tcx, key : self . key }
581+ }
547582}
548583
549584impl < ' tcx > TyCtxtFeed < ' tcx , LocalDefId > {
0 commit comments