@@ -59,7 +59,7 @@ use tracing::{debug, instrument};
5959
6060use crate :: arena:: Arena ;
6161use crate :: dep_graph:: dep_node:: make_metadata;
62- use crate :: dep_graph:: { DepGraph , DepKindVTable , DepNodeIndex } ;
62+ use crate :: dep_graph:: { DepGraph , DepKindVTable , DepNode , TaskDepsRef } ;
6363use crate :: ich:: StableHashingContext ;
6464use crate :: infer:: canonical:: { CanonicalParamEnvCache , CanonicalVarKind } ;
6565use crate :: lint:: emit_lint_base;
@@ -1428,6 +1428,34 @@ impl<'tcx> TyCtxt<'tcx> {
14281428 }
14291429}
14301430
1431+ #[ instrument( level = "trace" , skip( tcx) , ret) ]
1432+ fn create_def_raw_provider < ' tcx > (
1433+ tcx : TyCtxt < ' tcx > ,
1434+ ( parent, data, query, index) : ( LocalDefId , DefPathData , Option < DepNode > , usize ) ,
1435+ ) -> LocalDefId {
1436+ // `query` and `index` are guaranteed to change for each successive call to
1437+ // `create_def_raw`, but in a predictable manner.
1438+ let _ = ( query, index) ;
1439+
1440+ // This query is `eval_always`, so we can access untracked data.
1441+ let mut disambiguator_state = tcx. untracked_disambiguator_state . lock ( ) ;
1442+
1443+ // The following call has the side effect of modifying the tables inside `definitions`.
1444+ // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1445+ // decode the on-disk cache.
1446+ //
1447+ // Any LocalDefId which is used within queries, either as key or result, either:
1448+ // - has been created before the construction of the TyCtxt;
1449+ // - has been created by this call to `create_def`.
1450+ // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1451+ // comp. engine itself.
1452+ tcx. untracked . definitions . write ( ) . create_def (
1453+ parent,
1454+ data,
1455+ disambiguator_state. get_or_create ( parent) ,
1456+ )
1457+ }
1458+
14311459impl < ' tcx > TyCtxtAt < ' tcx > {
14321460 /// Create a new definition within the incr. comp. engine.
14331461 pub fn create_def (
@@ -1437,9 +1465,7 @@ impl<'tcx> TyCtxtAt<'tcx> {
14371465 def_kind : DefKind ,
14381466 override_def_path_data : Option < DefPathData > ,
14391467 ) -> TyCtxtFeed < ' tcx , LocalDefId > {
1440- let feed =
1441- self . tcx . create_def ( parent, name, def_kind, override_def_path_data) ;
1442-
1468+ let feed = self . tcx . create_def ( parent, name, def_kind, override_def_path_data) ;
14431469 feed. def_span ( self . span ) ;
14441470 feed
14451471 }
@@ -1455,28 +1481,36 @@ impl<'tcx> TyCtxt<'tcx> {
14551481 override_def_path_data : Option < DefPathData > ,
14561482 ) -> TyCtxtFeed < ' tcx , LocalDefId > {
14571483 let data = override_def_path_data. unwrap_or_else ( || def_kind. def_path_data ( name) ) ;
1458- let mut disambiguators = self . untracked_disambiguator_state . lock ( ) ;
1459- let disambiguator = disambiguators. get_or_create ( parent) ;
1460-
1461- // The following call has the side effect of modifying the tables inside `definitions`.
1462- // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1463- // decode the on-disk cache.
1464- //
1465- // Any LocalDefId which is used within queries, either as key or result, either:
1466- // - has been created before the construction of the TyCtxt;
1467- // - has been created by this call to `create_def`.
1468- // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1469- // comp. engine itself.
1470- let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data, disambiguator) ;
1471-
1472- // This function modifies `self.definitions` using a side-effect.
1473- // We need to ensure that these side effects are re-run by the incr. comp. engine.
1474- // Depending on the forever-red node will tell the graph that the calling query
1475- // needs to be re-evaluated.
1476- self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1484+
1485+ // `create_def_raw` is a query, so it can be replayed by the dep-graph engine. However, we
1486+ // may invoke it multiple times with the same `(parent, data)` pair, and we expect to
1487+ // create *different* defintions from them. In order to make this compatible with the
1488+ // general model of queries, we add additional information which must change at each call.
1489+ let ( dep_node, query_local_index) = ty:: tls:: with_context ( |icx| match icx. task_deps {
1490+ // If we are inside a query, we can only use local information, and no global
1491+ // mutable state. The current query's name and the number of calls to `create_def`
1492+ // are local to the current query, so are ok to use.
1493+ TaskDepsRef :: Allow ( deps) => {
1494+ let opt_dep_node_and_index = deps. lock ( ) . next_query_local_index ( ) ;
1495+ if let Some ( ( dep_node, index) ) = opt_dep_node_and_index {
1496+ ( Some ( dep_node) , index)
1497+ } else {
1498+ // No idea how to support this for now...
1499+ bug ! ( "trying to create a definition from an anonymous query" )
1500+ }
1501+ }
1502+ // If we are not tracking dependencies, we can use global mutable state,
1503+ // so we use the total number of definitions as a proxy.
1504+ TaskDepsRef :: EvalAlways | TaskDepsRef :: Forbid | TaskDepsRef :: Ignore => {
1505+ let global_count = self . untracked . definitions . read ( ) . def_index_count ( ) ;
1506+ ( None , global_count)
1507+ }
1508+ } ) ;
1509+ let def_id = self . create_def_raw ( ( parent, data, dep_node, query_local_index) ) ;
14771510
14781511 let feed = TyCtxtFeed { tcx : self , key : def_id } ;
14791512 feed. def_kind ( def_kind) ;
1513+
14801514 // Unique types created for closures participate in type privacy checking.
14811515 // They have visibilities inherited from the module they are defined in.
14821516 // Visibilities for opaque types are meaningless, but still provided
@@ -2914,4 +2948,5 @@ pub fn provide(providers: &mut Providers) {
29142948 tcx. lang_items ( ) . panic_impl ( ) . is_some_and ( |did| did. is_local ( ) )
29152949 } ;
29162950 providers. source_span = |tcx, def_id| tcx. untracked . source_span . get ( def_id) . unwrap_or ( DUMMY_SP ) ;
2951+ providers. create_def_raw = create_def_raw_provider;
29172952}
0 commit comments