@@ -39,7 +39,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
39
39
use rustc_data_structures:: sharded:: { IntoPointer , ShardedHashMap } ;
40
40
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
41
41
use 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 } ;
43
43
#[ cfg( parallel_compiler) ]
44
44
use rustc_data_structures:: sync:: { DynSend , DynSync } ;
45
45
use rustc_data_structures:: unord:: UnordSet ;
@@ -60,7 +60,7 @@ use rustc_session::config::CrateType;
60
60
use rustc_session:: cstore:: { CrateStoreDyn , Untracked } ;
61
61
use rustc_session:: lint:: Lint ;
62
62
use rustc_session:: { Limit , MetadataKind , Session } ;
63
- use rustc_span:: def_id:: { DefPathHash , StableCrateId } ;
63
+ use rustc_span:: def_id:: { DefPathHash , StableCrateId , CRATE_DEF_ID } ;
64
64
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
65
65
use rustc_span:: { Span , DUMMY_SP } ;
66
66
use rustc_target:: abi:: { FieldIdx , Layout , LayoutS , TargetDataLayout , VariantIdx } ;
@@ -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
@@ -498,14 +499,55 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> {
498
499
key : KEY ,
499
500
}
500
501
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.
501
531
impl < ' 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.
502
534
pub fn feed_unit_query ( self ) -> TyCtxtFeed < ' tcx , ( ) > {
535
+ self . dep_graph . assert_ignored ( ) ;
503
536
TyCtxtFeed { tcx : self , key : ( ) }
504
537
}
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.
505
541
pub fn feed_local_crate ( self ) -> TyCtxtFeed < ' tcx , CrateNum > {
542
+ self . dep_graph . assert_ignored ( ) ;
506
543
TyCtxtFeed { tcx : self , key : LOCAL_CRATE }
507
544
}
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 ) ;
509
551
TyCtxtFeed { tcx : self , key }
510
552
}
511
553
@@ -523,6 +565,23 @@ impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
523
565
pub fn key ( & self ) -> KEY {
524
566
self . key
525
567
}
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
+ }
526
585
}
527
586
528
587
impl < ' tcx > TyCtxtFeed < ' tcx , LocalDefId > {
@@ -1067,7 +1126,7 @@ impl<'tcx> TyCtxt<'tcx> {
1067
1126
// needs to be re-evaluated.
1068
1127
self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1069
1128
1070
- let feed = self . feed_local_def_id ( def_id) ;
1129
+ let feed = TyCtxtFeed { tcx : self , key : def_id } ;
1071
1130
feed. def_kind ( def_kind) ;
1072
1131
// Unique types created for closures participate in type privacy checking.
1073
1132
// They have visibilities inherited from the module they are defined in.
@@ -2304,6 +2363,10 @@ impl<'tcx> TyCtxt<'tcx> {
2304
2363
self . resolutions ( ( ) ) . module_children . get ( & def_id) . map_or ( & [ ] , |v| & v[ ..] )
2305
2364
}
2306
2365
2366
+ pub fn resolver_for_lowering ( self ) -> & ' tcx Steal < ( ty:: ResolverAstLowering , Lrc < ast:: Crate > ) > {
2367
+ self . resolver_for_lowering_raw ( ( ) ) . 0
2368
+ }
2369
+
2307
2370
/// Given an `impl_id`, return the trait it implements.
2308
2371
/// Return `None` if this is an inherent impl.
2309
2372
pub fn impl_trait_ref (
0 commit comments