-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Reorder mir_const_qualif
to make promotion in consts more consistent
#65883
Conversation
Computing `mir_const_qualif` requires running `QualifyAndPromoteConstants`, but no promotion was actually done until `mir_validated`. This required persisting a `BitSet` of promoted locals across queries, making it difficult to properly handle promotion in `const`s. This commit swaps the order of the two queries, and stores the result of `mir_const_qualif` (a single `u8`) in the result of `mir_validated`. `mir_const_qualif` now simply invokes `mir_validated` and extracts this result.
The old promotion logic ignores anything after a branch or loop in a `const`, so the new logic will often find new things to promote. Note that we can't actually do promotion in a `const` within a loop body using the current approach of removing `Drop` and `StorageDead`.
--> $DIR/issue-36163.rs:1:18 | ||
| | ||
LL | const A: isize = Foo::B as isize; | ||
| ^^^^^^^^^^^^^^^ | ||
= note: ...which again requires const checking `Foo::B::{{constant}}#0`, completing the cycle | ||
note: ...which requires computing qualifs for `Foo::B::{{constant}}#0`... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaking "qualifs" into diagnostics is ungreat. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if there was a way to silence unimportant queries–ones that are always invoked by another query–in the diagnostic output for cycles.
I think this complication is entirely unnecessary - we can simply move promotion to its own pass, using the new promotion validator, and disconnect the two systems. |
Sound good. I'll close this. |
Computing
mir_const_qualif
requires running most ofQualifyAndPromoteConstants
, but no promotion is actually done untilmir_validated
. This required persisting aBitSet
containing the promotable locals across queries and makes it difficult to properly handle promotion inconst
s, since the promotion context (Candidate
) for each local is gone. This PR swaps the order of the two queries, and stores the result ofmir_const_qualif
(a singleu8
) in the result ofmir_validated
.mir_const_qualif
now simply invokesmir_validated
and extracts this result.I don't think this should do any more work, but I'm new to the query system. At the very least, this saves us from having to keep a
BitSet
in the arena for eachconst
. It does, however, cause a small diagnostics regression for cyclical dependencies betweenconst
s, since there is an extra query in the cycle.After this PR is merged, promotion for every item (non-const
fn
,const
, etc.) will be done using a list ofCandidate
s. This makes it easier to fix places where promotion in aconst
acts differently than in regularfn
such as #65732, and will allow us to create promoted MIR fragments for aconst
which (I think) will be needed to implement #52000.I initially intended for this to resolve issue #65732, but I wasn't able to fix the
nll::type_check
errors that were caused by convertingMove
s of promotable array initializers toCopy
s within aconst
. The code that did this is commented out and aFIXME
was added to this effect. I think the best solution may be to start creating promoted MIR fragments, but others should weigh in.r? @eddyb