@@ -60,7 +60,7 @@ use rustc_type_ir::{
6060use tracing:: { debug, instrument} ;
6161
6262use crate :: arena:: Arena ;
63- use crate :: dep_graph:: { DepGraph , DepKindStruct } ;
63+ use crate :: dep_graph:: { DepGraph , DepKindStruct , DepNode , TaskDepsRef } ;
6464use crate :: infer:: canonical:: { CanonicalParamEnvCache , CanonicalVarKind , CanonicalVarKinds } ;
6565use crate :: lint:: lint_level;
6666use crate :: metadata:: ModChild ;
@@ -1454,6 +1454,9 @@ pub struct GlobalCtxt<'tcx> {
14541454 pub ( crate ) hooks : crate :: hooks:: Providers ,
14551455
14561456 untracked : Untracked ,
1457+ /// This is shared untracked state for creating new definitions.
1458+ /// It should only be accessed by the `create_def_raw` query.
1459+ untracked_disambiguator_state : Lock < DisambiguatorState > ,
14571460
14581461 pub query_system : QuerySystem < ' tcx > ,
14591462 pub ( crate ) query_kinds : & ' tcx [ DepKindStruct < ' tcx > ] ,
@@ -1727,6 +1730,7 @@ impl<'tcx> TyCtxt<'tcx> {
17271730 lifetimes : common_lifetimes,
17281731 consts : common_consts,
17291732 untracked,
1733+ untracked_disambiguator_state : Lock :: new ( DisambiguatorState :: new ( ) ) ,
17301734 query_system,
17311735 query_kinds,
17321736 ty_rcache : Default :: default ( ) ,
@@ -2017,6 +2021,30 @@ impl<'tcx> TyCtxt<'tcx> {
20172021 }
20182022}
20192023
2024+ #[ instrument( level = "trace" , skip( tcx) , ret) ]
2025+ fn create_def_raw_provider < ' tcx > (
2026+ tcx : TyCtxt < ' tcx > ,
2027+ ( parent, data, query, index) : ( LocalDefId , DefPathData , Option < DepNode > , usize ) ,
2028+ ) -> LocalDefId {
2029+ // `query` and `index` are guaranteed to change for each successive call to
2030+ // `create_def_raw`, but in a predictable manner.
2031+ let _ = ( query, index) ;
2032+
2033+ // This query is `eval_always`, so we can access untracked data.
2034+ let mut disambiguator_state = tcx. untracked_disambiguator_state . lock ( ) ;
2035+
2036+ // The following call has the side effect of modifying the tables inside `definitions`.
2037+ // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
2038+ // decode the on-disk cache.
2039+ //
2040+ // Any LocalDefId which is used within queries, either as key or result, either:
2041+ // - has been created before the construction of the TyCtxt;
2042+ // - has been created by this call to `create_def`.
2043+ // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
2044+ // comp. engine itself.
2045+ tcx. untracked . definitions . write ( ) . create_def ( parent, data, & mut disambiguator_state)
2046+ }
2047+
20202048impl < ' tcx > TyCtxtAt < ' tcx > {
20212049 /// Create a new definition within the incr. comp. engine.
20222050 pub fn create_def (
@@ -2025,11 +2053,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
20252053 name : Option < Symbol > ,
20262054 def_kind : DefKind ,
20272055 override_def_path_data : Option < DefPathData > ,
2028- disambiguator : & mut DisambiguatorState ,
20292056 ) -> TyCtxtFeed < ' tcx , LocalDefId > {
2030- let feed =
2031- self . tcx . create_def ( parent, name, def_kind, override_def_path_data, disambiguator) ;
2032-
2057+ let feed = self . tcx . create_def ( parent, name, def_kind, override_def_path_data) ;
20332058 feed. def_span ( self . span ) ;
20342059 feed
20352060 }
@@ -2043,28 +2068,39 @@ impl<'tcx> TyCtxt<'tcx> {
20432068 name : Option < Symbol > ,
20442069 def_kind : DefKind ,
20452070 override_def_path_data : Option < DefPathData > ,
2046- disambiguator : & mut DisambiguatorState ,
20472071 ) -> TyCtxtFeed < ' tcx , LocalDefId > {
20482072 let data = override_def_path_data. unwrap_or_else ( || def_kind. def_path_data ( name) ) ;
2049- // The following call has the side effect of modifying the tables inside `definitions`.
2050- // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
2051- // decode the on-disk cache.
2052- //
2053- // Any LocalDefId which is used within queries, either as key or result, either:
2054- // - has been created before the construction of the TyCtxt;
2055- // - has been created by this call to `create_def`.
2056- // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
2057- // comp. engine itself.
2058- let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data, disambiguator) ;
2059-
2060- // This function modifies `self.definitions` using a side-effect.
2061- // We need to ensure that these side effects are re-run by the incr. comp. engine.
2062- // Depending on the forever-red node will tell the graph that the calling query
2063- // needs to be re-evaluated.
2064- self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
2073+
2074+ // `create_def_raw` is a query, so it can be replayed by the dep-graph engine. However, we
2075+ // may invoke it multiple times with the same `(parent, data)` pair, and we expect to
2076+ // create *different* defintions from them. In order to make this compatible with the
2077+ // general model of queries, we add additional information which must change at each call.
2078+ let ( dep_node, query_local_index) =
2079+ ty:: tls:: with_related_context ( self , |icx| match icx. task_deps {
2080+ // If we are inside a query, we can only use local information, and no global
2081+ // mutable state. The current query's name and the number of calls to `create_def`
2082+ // are local to the current query, so are ok to use.
2083+ TaskDepsRef :: Allow ( deps) => {
2084+ let opt_dep_node_and_index = deps. lock ( ) . next_query_local_index ( ) ;
2085+ if let Some ( ( dep_node, index) ) = opt_dep_node_and_index {
2086+ ( Some ( dep_node) , index)
2087+ } else {
2088+ // No idea how to support this for now...
2089+ bug ! ( "trying to create a definition from an anonymous query" )
2090+ }
2091+ }
2092+ // If we are not tracking dependencies, we can use global mutable state,
2093+ // so we use the total number of definitions as a proxy.
2094+ TaskDepsRef :: EvalAlways | TaskDepsRef :: Forbid | TaskDepsRef :: Ignore => {
2095+ let global_count = self . untracked . definitions . read ( ) . def_index_count ( ) ;
2096+ ( None , global_count)
2097+ }
2098+ } ) ;
2099+ let def_id = self . create_def_raw ( ( parent, data, dep_node, query_local_index) ) ;
20652100
20662101 let feed = TyCtxtFeed { tcx : self , key : def_id } ;
20672102 feed. def_kind ( def_kind) ;
2103+
20682104 // Unique types created for closures participate in type privacy checking.
20692105 // They have visibilities inherited from the module they are defined in.
20702106 // Visibilities for opaque types are meaningless, but still provided
@@ -3475,6 +3511,7 @@ pub fn provide(providers: &mut Providers) {
34753511 tcx. lang_items ( ) . panic_impl ( ) . is_some_and ( |did| did. is_local ( ) )
34763512 } ;
34773513 providers. source_span = |tcx, def_id| tcx. untracked . source_span . get ( def_id) . unwrap_or ( DUMMY_SP ) ;
3514+ providers. create_def_raw = create_def_raw_provider;
34783515}
34793516
34803517pub fn contains_name ( attrs : & [ Attribute ] , name : Symbol ) -> bool {
0 commit comments