@@ -53,6 +53,7 @@ use rustc_hir::{
53
53
use rustc_index:: vec:: { Idx , IndexVec } ;
54
54
use rustc_macros:: HashStable ;
55
55
use rustc_middle:: mir:: FakeReadCause ;
56
+ use rustc_query_system:: dep_graph:: DepNodeIndex ;
56
57
use rustc_query_system:: ich:: StableHashingContext ;
57
58
use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder } ;
58
59
use rustc_session:: config:: { CrateType , OutputFilenames } ;
@@ -1009,6 +1010,14 @@ pub struct FreeRegionInfo {
1009
1010
pub is_impl_item : bool ,
1010
1011
}
1011
1012
1013
+ #[ derive( Copy , Clone ) ]
1014
+ pub struct TyCtxtFeed < ' tcx > {
1015
+ pub tcx : TyCtxt < ' tcx > ,
1016
+ pub def_id : LocalDefId ,
1017
+ /// This struct should only be created by `create_def`.
1018
+ _priv : ( ) ,
1019
+ }
1020
+
1012
1021
/// The central data structure of the compiler. It stores references
1013
1022
/// to the various **arenas** and also houses the results of the
1014
1023
/// various **compiler queries** that have been performed. See the
@@ -1471,12 +1480,15 @@ impl<'tcx> TyCtxt<'tcx> {
1471
1480
}
1472
1481
1473
1482
/// Create a new definition within the incr. comp. engine.
1474
- pub fn create_def ( self , parent : LocalDefId , data : hir:: definitions:: DefPathData ) -> LocalDefId {
1483
+ pub fn create_def (
1484
+ self ,
1485
+ parent : LocalDefId ,
1486
+ data : hir:: definitions:: DefPathData ,
1487
+ ) -> TyCtxtFeed < ' tcx > {
1475
1488
// This function modifies `self.definitions` using a side-effect.
1476
1489
// We need to ensure that these side effects are re-run by the incr. comp. engine.
1477
1490
// Depending on the forever-red node will tell the graph that the calling query
1478
1491
// needs to be re-evaluated.
1479
- use rustc_query_system:: dep_graph:: DepNodeIndex ;
1480
1492
self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1481
1493
1482
1494
// The following call has the side effect of modifying the tables inside `definitions`.
@@ -1493,23 +1505,38 @@ impl<'tcx> TyCtxt<'tcx> {
1493
1505
// This is fine because:
1494
1506
// - those queries are `eval_always` so we won't miss their result changing;
1495
1507
// - this write will have happened before these queries are called.
1496
- self . definitions . write ( ) . create_def ( parent, data)
1508
+ let def_id = self . definitions . write ( ) . create_def ( parent, data) ;
1509
+
1510
+ TyCtxtFeed { tcx : self , def_id, _priv : ( ) }
1497
1511
}
1498
1512
1499
1513
pub fn iter_local_def_id ( self ) -> impl Iterator < Item = LocalDefId > + ' tcx {
1500
- // Create a dependency to the crate to be sure we re-execute this when the amount of
1514
+ // Create a dependency to the red node to be sure we re-execute this when the amount of
1501
1515
// definitions change.
1502
- self . ensure ( ) . hir_crate ( ( ) ) ;
1503
- // Leak a read lock once we start iterating on definitions, to prevent adding new ones
1504
- // while iterating. If some query needs to add definitions, it should be `ensure`d above.
1505
- let definitions = self . definitions . leak ( ) ;
1506
- definitions. iter_local_def_id ( )
1516
+ self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1517
+
1518
+ let definitions = & self . definitions ;
1519
+ std:: iter:: from_generator ( || {
1520
+ let mut i = 0 ;
1521
+
1522
+ // Recompute the number of definitions each time, because our caller may be creating
1523
+ // new ones.
1524
+ while i < { definitions. read ( ) . num_definitions ( ) } {
1525
+ let local_def_index = rustc_span:: def_id:: DefIndex :: from_usize ( i) ;
1526
+ yield LocalDefId { local_def_index } ;
1527
+ i += 1 ;
1528
+ }
1529
+
1530
+ // Leak a read lock once we finish iterating on definitions, to prevent adding new ones.
1531
+ definitions. leak ( ) ;
1532
+ } )
1507
1533
}
1508
1534
1509
1535
pub fn def_path_table ( self ) -> & ' tcx rustc_hir:: definitions:: DefPathTable {
1510
1536
// Create a dependency to the crate to be sure we re-execute this when the amount of
1511
1537
// definitions change.
1512
- self . ensure ( ) . hir_crate ( ( ) ) ;
1538
+ self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1539
+
1513
1540
// Leak a read lock once we start iterating on definitions, to prevent adding new ones
1514
1541
// while iterating. If some query needs to add definitions, it should be `ensure`d above.
1515
1542
let definitions = self . definitions . leak ( ) ;
0 commit comments