@@ -41,7 +41,7 @@ use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
41
41
use rustc_index:: IndexVec ;
42
42
use rustc_macros:: { HashStable , TyDecodable , TyEncodable } ;
43
43
use rustc_query_system:: cache:: WithDepNode ;
44
- use rustc_query_system:: dep_graph:: DepNodeIndex ;
44
+ use rustc_query_system:: dep_graph:: { DepNodeIndex , TaskDepsRef } ;
45
45
use rustc_query_system:: ich:: StableHashingContext ;
46
46
use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder } ;
47
47
use rustc_session:: config:: CrateType ;
@@ -1955,27 +1955,42 @@ impl<'tcx> TyCtxt<'tcx> {
1955
1955
def_kind : DefKind ,
1956
1956
) -> TyCtxtFeed < ' tcx , LocalDefId > {
1957
1957
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
+ } ) ;
1979
1994
1980
1995
let feed = TyCtxtFeed { tcx : self , key : def_id } ;
1981
1996
feed. def_kind ( def_kind) ;
0 commit comments