@@ -41,7 +41,7 @@ use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
4141use rustc_index:: IndexVec ;
4242use rustc_macros:: { HashStable , TyDecodable , TyEncodable } ;
4343use rustc_query_system:: cache:: WithDepNode ;
44- use rustc_query_system:: dep_graph:: DepNodeIndex ;
44+ use rustc_query_system:: dep_graph:: { DepNodeIndex , TaskDepsRef } ;
4545use rustc_query_system:: ich:: StableHashingContext ;
4646use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder } ;
4747use rustc_session:: config:: CrateType ;
@@ -1955,27 +1955,42 @@ impl<'tcx> TyCtxt<'tcx> {
19551955 def_kind : DefKind ,
19561956 ) -> TyCtxtFeed < ' tcx , LocalDefId > {
19571957 let data = def_kind. def_path_data ( name) ;
1958- // The following call has the side effect of modifying the tables inside `definitions`.
1959- // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1960- // decode the on-disk cache.
1961- //
1962- // Any LocalDefId which is used within queries, either as key or result, either:
1963- // - has been created before the construction of the TyCtxt;
1964- // - has been created by this call to `create_def`.
1965- // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1966- // comp. engine itself.
1967- //
1968- // This call also writes to the value of the `source_span` query.
1969- // This is fine because:
1970- // - that query is `eval_always` so we won't miss its result changing;
1971- // - this write will have happened before that query is called.
1972- let def_id = self . untracked . definitions . write ( ) . create_def ( parent, data) ;
1973-
1974- // This function modifies `self.definitions` using a side-effect.
1975- // We need to ensure that these side effects are re-run by the incr. comp. engine.
1976- // Depending on the forever-red node will tell the graph that the calling query
1977- // needs to be re-evaluated.
1978- self . dep_graph . read_index ( DepNodeIndex :: FOREVER_RED_NODE ) ;
1958+
1959+ let def_id = tls:: with_context ( |icx| {
1960+ match icx. task_deps {
1961+ // Always gets rerun anyway, so nothing to replay
1962+ TaskDepsRef :: EvalAlways |
1963+ // Top-level queries like the resolver get rerun every time anyway
1964+ TaskDepsRef :: Ignore => {
1965+ // The following call has the side effect of modifying the tables inside `definitions`.
1966+ // These very tables are relied on by the incr. comp. engine to decode DepNodes and to
1967+ // decode the on-disk cache.
1968+ //
1969+ // Any LocalDefId which is used within queries, either as key or result, either:
1970+ // - has been created before the construction of the TyCtxt;
1971+ // - has been created by this call to `create_def`.
1972+ // As a consequence, this LocalDefId is always re-created before it is needed by the incr.
1973+ // comp. engine itself.
1974+ //
1975+ // This call also writes to the value of the `source_span` query.
1976+ // This is fine because:
1977+ // - that query is `eval_always` so we won't miss its result changing;
1978+ // - this write will have happened before that query is called.
1979+ self . untracked . definitions . write ( ) . create_def ( parent, data, None )
1980+ }
1981+ TaskDepsRef :: Forbid => bug ! (
1982+ "cannot create definition {parent:?} {data:?} without being able to register task dependencies"
1983+ ) ,
1984+ TaskDepsRef :: Allow ( deps) => {
1985+ let idx = deps. lock ( ) . next_def_id_idx ( ) ;
1986+ self . create_def_raw ( ( parent, data, idx) )
1987+ }
1988+ TaskDepsRef :: Replay { created_def_ids } => {
1989+ let idx = created_def_ids. fetch_add ( 1 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
1990+ self . create_def_raw ( ( parent, data, idx) )
1991+ }
1992+ }
1993+ } ) ;
19791994
19801995 let feed = TyCtxtFeed { tcx : self , key : def_id } ;
19811996 feed. def_kind ( def_kind) ;
0 commit comments