1
Fork 0

Make sure to record deps from cached task in new solver on first run

This commit is contained in:
Michael Goulet 2024-12-03 22:47:08 +00:00
parent 3f089971ff
commit 988f28d442
4 changed files with 22 additions and 10 deletions

View file

@ -302,7 +302,11 @@ impl<D: Deps> DepGraph<D> {
OP: FnOnce() -> R, OP: FnOnce() -> R,
{ {
match self.data() { match self.data() {
Some(data) => data.with_anon_task(cx, dep_kind, op), Some(data) => {
let (result, index) = data.with_anon_task_inner(cx, dep_kind, op);
self.read_index(index);
(result, index)
}
None => (op(), self.next_virtual_depnode_index()), None => (op(), self.next_virtual_depnode_index()),
} }
} }
@ -397,7 +401,16 @@ impl<D: Deps> DepGraphData<D> {
/// Executes something within an "anonymous" task, that is, a task the /// Executes something within an "anonymous" task, that is, a task the
/// `DepNode` of which is determined by the list of inputs it read from. /// `DepNode` of which is determined by the list of inputs it read from.
pub(crate) fn with_anon_task<Tcx: DepContext<Deps = D>, OP, R>( ///
/// NOTE: this does not actually count as a read of the DepNode here.
/// Using the result of this task without reading the DepNode will result
/// in untracked dependencies which may lead to ICEs as nodes are
/// incorrectly marked green.
///
/// FIXME: This could perhaps return a `WithDepNode` to ensure that the
/// user of this function actually performs the read; we'll have to see
/// how to make that work with `anon` in `execute_job_incr`, though.
pub(crate) fn with_anon_task_inner<Tcx: DepContext<Deps = D>, OP, R>(
&self, &self,
cx: Tcx, cx: Tcx,
dep_kind: DepKind, dep_kind: DepKind,

View file

@ -520,9 +520,11 @@ where
let (result, dep_node_index) = let (result, dep_node_index) =
qcx.start_query(job_id, query.depth_limit(), Some(&diagnostics), || { qcx.start_query(job_id, query.depth_limit(), Some(&diagnostics), || {
if query.anon() { if query.anon() {
return dep_graph_data.with_anon_task(*qcx.dep_context(), query.dep_kind(), || { return dep_graph_data.with_anon_task_inner(
query.compute(qcx, key) *qcx.dep_context(),
}); query.dep_kind(),
|| query.compute(qcx, key),
);
} }
// `to_dep_node` is expensive for some `DepKind`s. // `to_dep_node` is expensive for some `DepKind`s.

View file

@ -1400,10 +1400,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
where where
OP: FnOnce(&mut Self) -> R, OP: FnOnce(&mut Self) -> R,
{ {
let (result, dep_node) = self.tcx().dep_graph.with_anon_task(self.tcx(), dep_kinds::TraitSelect, || op(self))
self.tcx().dep_graph.with_anon_task(self.tcx(), dep_kinds::TraitSelect, || op(self));
self.tcx().dep_graph.read_index(dep_node);
(result, dep_node)
} }
/// filter_impls filters candidates that have a positive impl for a negative /// filter_impls filters candidates that have a positive impl for a negative

View file

@ -511,7 +511,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
// This is for global caching, so we properly track query dependencies. // This is for global caching, so we properly track query dependencies.
// Everything that affects the `result` should be performed within this // Everything that affects the `result` should be performed within this
// `with_anon_task` closure. If computing this goal depends on something // `with_cached_task` closure. If computing this goal depends on something
// not tracked by the cache key and from outside of this anon task, it // not tracked by the cache key and from outside of this anon task, it
// must not be added to the global cache. Notably, this is the case for // must not be added to the global cache. Notably, this is the case for
// trait solver cycles participants. // trait solver cycles participants.