@@ -74,6 +74,7 @@ use std::cmp::Ordering;
74
74
use std:: fmt;
75
75
use std:: hash:: { Hash , Hasher } ;
76
76
use std:: iter;
77
+ use std:: marker:: PhantomData ;
77
78
use std:: mem;
78
79
use std:: ops:: { Bound , Deref } ;
79
80
@@ -519,6 +520,23 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> {
519
520
key : KEY ,
520
521
}
521
522
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
+
522
540
impl < ' tcx > TyCtxt < ' tcx > {
523
541
pub fn feed_unit_query ( self ) -> TyCtxtFeed < ' tcx , ( ) > {
524
542
TyCtxtFeed { tcx : self , key : ( ) }
@@ -544,6 +562,23 @@ impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
544
562
pub fn key ( & self ) -> KEY {
545
563
self . key
546
564
}
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
+ }
547
582
}
548
583
549
584
impl < ' tcx > TyCtxtFeed < ' tcx , LocalDefId > {
0 commit comments