-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
incr.comp.: Clarify compatibility of red/green evaluation and recovering from cycle errors #42633
Comments
Yes, but on the way back up to |
@eddyb Oh, an |
@michaelwoerister The actual error is uninteresting, but |
Looking at the code again, no |
@michaelwoerister AFAIK we'd regress in a few places if we removed cycle recovery. I'd rather have it be enforced correct-by-default and have a warning that if you use |
Sorry I've been slow to weigh in on this thread. I've been thinking about cycles a lot. At this point, my opinion is that -- at least for now -- we should remove cycle recovery from the query system (that is, cycles should always be considered fatal to compilation -- they don't necessarily have to panic). Things that legitimately want to recover from cycles (which I think is basically just the trait system) should handle it themselves for now. We don't actually use cycle recovery that much right now, and I think all of the cases can make do with some form of hard error (after a bit of refactoring). We can survey them quite quickly.
Unless I missed something, those are all the uses of I was thinking of making trait selection into a query, but I've since thought better of it. I think it will be something "query-like" -- in particular, it will be a function that starts with just a Ultimately my view is that we should aim to keep the query system fairly simple, at least for now. Maybe eventually we will want to expand it into a full-on attribute grammar system that can handle all sorts of data propagation or whatever, but I think that the current setup -- where a query is basically just a memoized function call -- seems about right. |
As a side-note regarding inlining: With #43183, the trans-collector builds up a fairly accurate, global "call graph" between translation items. This could be useful for inlining too. It is post-monomorphization though, which is good for the quality of information it can provide, but which also means that it is a bit late in the pipeline. |
rustc: Start moving toward "try_get is a bug" for incremental This PR is an effort to burn down some of the work items on #42633. The basic change here was to leave the `try_get` function exposed but have it return a `DiagnosticBuilder` instead of a `CycleError`. This means that it should be a compiler bug to *not* handle the error as dropping a diagnostic should result in a complier panic. After that change it was then necessary to update the compiler's callsites of `try_get` to handle the error coming out. These were handled as: * The `sized_constraint` and `needs_drop_raw` checks take the diagnostic and defer it as a compiler bug. This was a new piece of functionality added to the error handling infrastructure, and the idea is that for both these checks a "real" compiler error should be emitted elsewhere, so it's only a bug if we don't actually emit the complier error elsewhere. * MIR inlining was updated to just ignore the diagnostic. This is being tracked by #43542 which sounded like it either already had some work underway or was planning to change regardless. * The final case, `item_path`, is still sort of up for debate. At the time of this writing this PR simply removes the invocations of `try_get` there, assuming that the query will always succeed. This turns out to be true for the test suite anyway! It sounds like, though, that this logic was intended to assist in "weird" situations like `RUST_LOG` where debug implementations can trigger at any time. This PR would therefore, however, break those implementations. I'm unfortunately sort of out of ideas on how to handle `item_path`, but other thoughts would be welcome! Closes #42633
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:
force
the evaluation of a query but that's no different from a regular 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 thatDepNode
are registered as they occur. E.g., we let's say we have the following "query trace":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 what1
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:There are no
DepNodes
for5
and7
(they never completed) but we don't lose the information that6
has been read, which is important, because the result of6
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
The text was updated successfully, but these errors were encountered: