@@ -32,7 +32,9 @@ use rustc_data_structures::sync::{
3232use rustc_errors:: { Applicability , Diag , DiagCtxtHandle , Diagnostic , MultiSpan } ;
3333use rustc_hir:: def:: DefKind ;
3434use rustc_hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE , LocalDefId , StableCrateIdMap } ;
35- use rustc_hir:: definitions:: { DefPathData , Definitions , PerParentDisambiguatorState } ;
35+ use rustc_hir:: definitions:: {
36+ DefPathData , Definitions , DisambiguatedDefPathData , PerParentDisambiguatorState ,
37+ } ;
3638use rustc_hir:: intravisit:: VisitorExt ;
3739use rustc_hir:: lang_items:: LangItem ;
3840use rustc_hir:: limit:: Limit ;
@@ -52,7 +54,7 @@ use tracing::{debug, instrument};
5254
5355use crate :: arena:: Arena ;
5456use crate :: dep_graph:: dep_node:: make_metadata;
55- use crate :: dep_graph:: { DepGraph , DepKindVTable , DepNodeIndex } ;
57+ use crate :: dep_graph:: { DepGraph , DepKindVTable , TaskDepsRef } ;
5658use crate :: ich:: StableHashingContext ;
5759use crate :: infer:: canonical:: { CanonicalParamEnvCache , CanonicalVarKind } ;
5860use crate :: lint:: emit_lint_base;
@@ -1320,6 +1322,23 @@ impl<'tcx> TyCtxt<'tcx> {
13201322 }
13211323}
13221324
1325+ #[ instrument( level = "trace" , skip( tcx) , ret) ]
1326+ fn create_def_raw_provider < ' tcx > (
1327+ tcx : TyCtxt < ' tcx > ,
1328+ ( parent, data) : ( LocalDefId , DisambiguatedDefPathData ) ,
1329+ ) -> LocalDefId {
1330+ // The following call has the side effect of modifying the tables inside `definitions`.
1331+ // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1332+ // decode the on-disk cache.
1333+ //
1334+ // Any LocalDefId which is used within queries, either as key or result, either:
1335+ // - has been created before the construction of the TyCtxt;
1336+ // - has been created by this call to `create_def`.
1337+ // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1338+ // comp. engine itself.
1339+ tcx. untracked . definitions . write ( ) . create_def ( parent, data)
1340+ }
1341+
13231342impl < ' tcx > TyCtxtAt < ' tcx > {
13241343 /// Create a new definition within the incr. comp. engine.
13251344 pub fn create_def (
@@ -1349,25 +1368,29 @@ impl<'tcx> TyCtxt<'tcx> {
13491368 disambiguator : & mut PerParentDisambiguatorState ,
13501369 ) -> TyCtxtFeed < ' tcx , LocalDefId > {
13511370 let data = override_def_path_data. unwrap_or_else ( || def_kind. def_path_data ( name) ) ;
1352- // The following call has the side effect of modifying the tables inside `definitions`.
1353- // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1354- // decode the on-disk cache.
1355- //
1356- // Any LocalDefId which is used within queries, either as key or result, either:
1357- // - has been created before the construction of the TyCtxt;
1358- // - has been created by this call to `create_def`.
1359- // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1360- // comp. engine itself.
1361- let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data, disambiguator) ;
1362-
1363- // This function modifies `self.definitions` using a side-effect.
1364- // We need to ensure that these side effects are re-run by the incr. comp. engine.
1365- // Depending on the forever-red node will tell the graph that the calling query
1366- // needs to be re-evaluated.
1367- self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1371+
1372+ // Find the next free disambiguator for this key.
1373+ let data = disambiguator. disambiguate ( parent, data) ;
1374+
1375+ let def_id = ty:: tls:: with_context ( |icx| match icx. task_deps {
1376+ // `create_def_raw` is a query, so it can be replayed by the dep-graph engine.
1377+ // However, we may invoke it multiple times with the same `(parent, data)` pair,
1378+ // and we expect to create *different* definitions from them.
1379+ //
1380+ // In order to make this compatible with the general model of queries, we add
1381+ // additional information which must change at each call.
1382+ TaskDepsRef :: Allow ( ..) => self . create_def_raw ( ( parent, data) ) ,
1383+
1384+ // If we are not tracking dependencies, we can use global mutable state.
1385+ // This is only an optimization to avoid the cost of registering the dep-node.
1386+ TaskDepsRef :: EvalAlways | TaskDepsRef :: Forbid | TaskDepsRef :: Ignore => {
1387+ self . untracked . definitions . write ( ) . create_def ( parent, data)
1388+ }
1389+ } ) ;
13681390
13691391 let feed = TyCtxtFeed { tcx : self , key : def_id } ;
13701392 feed. def_kind ( def_kind) ;
1393+
13711394 // Unique types created for closures participate in type privacy checking.
13721395 // They have visibilities inherited from the module they are defined in.
13731396 // Visibilities for opaque types are meaningless, but still provided
@@ -2801,4 +2824,5 @@ pub fn provide(providers: &mut Providers) {
28012824 tcx. lang_items ( ) . panic_impl ( ) . is_some_and ( |did| did. is_local ( ) )
28022825 } ;
28032826 providers. source_span = |tcx, def_id| tcx. untracked . source_span . get ( def_id) . unwrap_or ( DUMMY_SP ) ;
2827+ providers. create_def_raw = create_def_raw_provider;
28042828}
0 commit comments