4
4
5
5
pub mod tls;
6
6
7
+ use rustc_query_system:: query:: DefIdInfo ;
7
8
pub use rustc_type_ir:: lift:: Lift ;
8
9
9
10
use crate :: arena:: Arena ;
@@ -57,7 +58,7 @@ use rustc_hir::lang_items::LangItem;
57
58
use rustc_hir:: { HirId , Node , TraitCandidate } ;
58
59
use rustc_index:: IndexVec ;
59
60
use rustc_macros:: { HashStable , TyDecodable , TyEncodable } ;
60
- use rustc_query_system:: dep_graph:: DepNodeIndex ;
61
+ use rustc_query_system:: dep_graph:: { DepNodeIndex , TaskDepsRef } ;
61
62
use rustc_query_system:: ich:: StableHashingContext ;
62
63
use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder } ;
63
64
use rustc_session:: config:: CrateType ;
@@ -72,7 +73,7 @@ use rustc_target::spec::abi;
72
73
use rustc_type_ir:: TyKind :: * ;
73
74
use rustc_type_ir:: WithCachedTypeInfo ;
74
75
use rustc_type_ir:: { CollectAndApply , Interner , TypeFlags } ;
75
- use tracing:: { debug, instrument} ;
76
+ use tracing:: { debug, instrument, trace } ;
76
77
77
78
use std:: assert_matches:: assert_matches;
78
79
use std:: borrow:: Borrow ;
@@ -1332,34 +1333,71 @@ impl<'tcx> TyCtxtAt<'tcx> {
1332
1333
1333
1334
impl < ' tcx > TyCtxt < ' tcx > {
1334
1335
/// `tcx`-dependent operations performed for every created definition.
1336
+ #[ instrument( level = "trace" , skip( self ) ) ]
1335
1337
pub fn create_def (
1336
1338
self ,
1337
1339
parent : LocalDefId ,
1338
1340
name : Symbol ,
1339
1341
def_kind : DefKind ,
1340
1342
) -> TyCtxtFeed < ' tcx , LocalDefId > {
1341
1343
let data = def_kind. def_path_data ( name) ;
1342
- // The following call has the side effect of modifying the tables inside `definitions`.
1344
+ // The following create_def calls have the side effect of modifying the tables inside `definitions`.
1343
1345
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1344
1346
// decode the on-disk cache.
1345
1347
//
1346
1348
// Any LocalDefId which is used within queries, either as key or result, either:
1347
- // - has been created before the construction of the TyCtxt;
1349
+ // - has been created before the construction of the TyCtxt,
1350
+ // - has been created when marking a query as green (recreating definitions it created in the actual run),
1348
1351
// - has been created by this call to `create_def`.
1349
- // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1350
- // comp. engine itself.
1351
1352
//
1352
1353
// This call also writes to the value of `source_span` and `expn_that_defined` queries.
1353
1354
// This is fine because:
1354
1355
// - those queries are `eval_always` so we won't miss their result changing;
1355
1356
// - this write will have happened before these queries are called.
1356
- let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data) ;
1357
-
1358
- // This function modifies `self.definitions` using a side-effect.
1359
- // We need to ensure that these side effects are re-run by the incr. comp. engine.
1360
- // Depending on the forever-red node will tell the graph that the calling query
1361
- // needs to be re-evaluated.
1362
- self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1357
+ let def_id = tls:: with_context ( |icx| {
1358
+ match icx. task_deps {
1359
+ // Always gets rerun anyway, so nothing to replay
1360
+ TaskDepsRef :: EvalAlways => {
1361
+ let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data) . 0 ;
1362
+ trace ! ( ?def_id, "eval always" ) ;
1363
+ def_id
1364
+ }
1365
+ // Top-level queries like the resolver get rerun every time anyway
1366
+ TaskDepsRef :: Ignore => {
1367
+ let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data) . 0 ;
1368
+ trace ! ( ?def_id, "ignore" ) ;
1369
+ def_id
1370
+ }
1371
+ TaskDepsRef :: Forbid => bug ! (
1372
+ "cannot create definition {parent:?}, {name:?}, {def_kind:?} without being able to register task dependencies"
1373
+ ) ,
1374
+ TaskDepsRef :: Allow ( _) => {
1375
+ let ( def_id, hash) =
1376
+ self . untracked . definitions . write ( ) . create_def ( parent, data) ;
1377
+ trace ! ( ?def_id, "record side effects" ) ;
1378
+
1379
+ icx. side_effects . as_ref ( ) . unwrap ( ) . lock ( ) . definitions . push ( DefIdInfo {
1380
+ parent,
1381
+ data,
1382
+ hash,
1383
+ } ) ;
1384
+ def_id
1385
+ }
1386
+ TaskDepsRef :: Replay { prev_side_effects, created_def_ids } => {
1387
+ trace ! ( ?created_def_ids, "replay side effects" ) ;
1388
+ trace ! ( "num_defs : {}" , prev_side_effects. definitions. len( ) ) ;
1389
+ let index = created_def_ids. fetch_add ( 1 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
1390
+ let prev_info = & prev_side_effects. definitions [ index] ;
1391
+ let def_id = self . untracked . definitions . read ( ) . local_def_path_hash_to_def_id (
1392
+ prev_info. hash ,
1393
+ & "should have already recreated def id in try_mark_green" ,
1394
+ ) ;
1395
+ assert_eq ! ( prev_info. data, data) ;
1396
+ assert_eq ! ( prev_info. parent, parent) ;
1397
+ def_id
1398
+ }
1399
+ }
1400
+ } ) ;
1363
1401
1364
1402
let feed = TyCtxtFeed { tcx : self , key : def_id } ;
1365
1403
feed. def_kind ( def_kind) ;
0 commit comments