incr.comp.: Clarify compatibility of red/green evaluation and recovering from cycle errors · Issue #42633 · rust-lang/rust (original) (raw)
I originally planned to describe the differences between the current query system and the future version that supports red/green dependency tracking but while thinking about it, there's not too much of a difference when it comes to cycle errors:
- The in-memory caches of the query system will not change in the future.
- The try_mark_green step of red/green evaluation might
force
the evaluation of a query but that's no different from a regular query. - There's been talk about having to prevent the caching of intermediate results if those intermediate results arise from a query that turns out to be cyclic, because those intermediate results are "tainted". However, I don't see how one would get ahold of such an intermediate result (both in the current system and the future one) in the first place: If a query
A
starts a sub-queryB
andB
starts a sub-sub-queryC
, which would invokeA
again, then we would have to make sure that neither the results ofB
orC
are cached. But since we are still in the middle of computingB
andC
, we don't have any result to cache anyway.
The main difference I see between the current query system and the red/green one is dependency tracking (and there the current system behaves a bit strangely, actually): When a query is started, a new DepNode
is allocated and reads to that DepNode
are registered as they occur. E.g., we let's say we have the following "query trace":
Queries execute in the order of their label:
1 <------------+
| |
+-------+-------+ |
| | | |
v v v |
2 4 +-- 5 --+ |
| | | |
v v v |
3 6 7--+
The dependency graph would look exactly like that, cycle and all.
In the red/green system, a DepNode
would only be allocated after the successful evaluation of a query. Consequently, we would not end up with the dep-graph shown above. But we still want to record dependencies to those sub-queries because their result influenced what 1
evaluated to after recovering from the cycle. I propose to just merge all reads into the parent query when encountering a cycle error, effectively merging all reads into the root of the cycle. The dep-graph from above would then look like this:
1
|
+-------+-------+
| | |
v v v
2 4 6
|
v
3
There are no DepNodes
for 5
and 7
(they never completed) but we don't lose the information that 6
has been read, which is important, because the result of 6
might also have caused a trace without cycle.
I still think that recovering from cycle errors is dubious but at least the situation should not get worse with the new system.
Comments? @eddyb @nikomatsakis @rust-lang/compiler