Skip to content

incr.comp.: Clarify compatibility of red/green evaluation and recovering from cycle errors #42633

Closed
@michaelwoerister

Description

@michaelwoerister

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-query B and B starts a sub-sub-query C, which would invoke A again, then we would have to make sure that neither the results of B or C are cached. But since we are still in the middle of computing B and C, 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-incr-compArea: Incremental compilationC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions