-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Use dataflow to propagate Qualif
s during const-qualification
#63860
Conversation
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
24cf5ff
to
de55d91
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
☔ The latest upstream changes (presumably #63580) made this pull request unmergeable. Please resolve the merge conflicts. |
999dc59
to
ff0d211
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
ff0d211
to
c970931
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
c970931
to
2e8921a
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
44e4bf3
to
6ab8410
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
6ab8410
to
4dd29eb
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
eebfcce
to
1ddae0b
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
71c1209
to
8fd7189
Compare
Add a `Place::is_indirect` method to determine whether a `Place` contains a `Deref` projection Working on rust-lang#63860 requires tracking some property about each local. This requires differentiating `Place`s like `x` and `x.field[index]` from ones like `*x` and `*x.field`, since the first two will always access the same region of memory as `x` while the latter two may access any region of memory. This functionality is duplicated in various places across the compiler. This PR adds a helper method to `Place` which determines whether that `Place` has a `Deref` projection at any point and changes some existing code to use the new method. I've not converted `qualify_consts.rs` to use the new method, since it's not a trivial conversion and it will get replaced anyway by rust-lang#63860. There may be other potential uses besides the two I change in this PR. r? @oli-obk
Add a `Place::is_indirect` method to determine whether a `Place` contains a `Deref` projection Working on rust-lang#63860 requires tracking some property about each local. This requires differentiating `Place`s like `x` and `x.field[index]` from ones like `*x` and `*x.field`, since the first two will always access the same region of memory as `x` while the latter two may access any region of memory. This functionality is duplicated in various places across the compiler. This PR adds a helper method to `Place` which determines whether that `Place` has a `Deref` projection at any point and changes some existing code to use the new method. I've not converted `qualify_consts.rs` to use the new method, since it's not a trivial conversion and it will get replaced anyway by rust-lang#63860. There may be other potential uses besides the two I change in this PR. r? @oli-obk
…oli-obk Refactor the `MirPass for QualifyAndPromoteConstants` This is an accumulation of drive-by commits while working on `Vec::new` as a stable `const fn`. The PR is probably easiest read commit-by-commit. r? @oli-obk cc @eddyb @ecstatic-morse -- your two PRs #63812 and #63860 respectively will conflict with this a tiny bit but it should be trivial to reintegrate your changes atop of this.
☔ The latest upstream changes (presumably #63994) made this pull request unmergeable. Please resolve the merge conflicts. |
To do dataflow-based qualification, we need to pass a reference to the dataflow state directly to the `Qualif::in_*` methods. As such, we move the `PerQualif<BitSet<Local>>` that holds the qualification state for each local to `Checker` itself and use a macro (`get_qualif`) to extract the correct `BitSet` when querying the qualifications for each local.
8fd7189
to
d94a901
Compare
☔ The latest upstream changes (presumably #63420) made this pull request unmergeable. Please resolve the merge conflicts. |
This PR has been subsumed by #64470. |
… r=eddyb,oli-obk Implement dataflow-based const validation This PR adds a separate, dataflow-enabled pass that checks the bodies of `const`s, `static`s and `const fn`s for [const safety](https://github.com/rust-rfcs/const-eval/blob/master/const.md). This is based on my work in #63860, which tried to integrate into the existing pass in [`qualify_consts.rs`](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/transform/qualify_consts.rs). However, the resulting pass was even more unwieldy than the original. Unlike its predecessor, this PR is designed to be combined with #63812 to replace the existing pass completely. The new checker lives in [`librustc_mir/transform/check_consts`](https://github.com/ecstatic-morse/rust/tree/split-promotion-and-validation/src/librustc_mir/transform/check_consts). [`qualifs.rs`](https://github.com/ecstatic-morse/rust/blob/split-promotion-and-validation/src/librustc_mir/transform/check_consts/qualifs.rs) contains small modifications to the existing `Qualif` trait and its implementors, but is mostly unchanged except for the removal of `IsNotPromotable` and `IsNotImplicitlyPromotable`, which are only necessary for promotion. [`resolver.rs`](https://github.com/ecstatic-morse/rust/blob/split-promotion-and-validation/src/librustc_mir/transform/check_consts/resolver.rs) contains the dataflow analysis used to propagate qualifs between locals. Finally, [`validation.rs`](https://github.com/ecstatic-morse/rust/blob/split-promotion-and-validation/src/librustc_mir/transform/check_consts/validation.rs) contains a refactored version of the existing [`Visitor`](https://github.com/rust-lang/rust/blob/ca3766e2e58f462a20922e42c821a37eaf0e13db/src/librustc_mir/transform/qualify_consts.rs#L1024) in `qualfy_consts.rs`. All errors have been associated with a `struct` to make [comparison with the existing pass](https://github.com/ecstatic-morse/rust/blob/1c19f2d540ca0a964900449d79a5d5181b43146d/src/librustc_mir/transform/qualify_consts.rs#L1006) simple. The existing validation logic in [`qualify_consts`](https://github.com/rust-lang/rust/blob/master/src/librustc_mir/transform/qualify_consts.rs) has been modified to allow it to run in parallel with the new validator. If [`use_new_validator`](https://github.com/rust-lang/rust/pull/64470/files#diff-c2552a106550d05b69d5e07612f0f812R950) is not set, the old validation will be responsible for actually generating the errors, but those errors can be compared with the ones from the new validator.
Edit: See #64470 for the most recent implementation of dataflow-based const qualification.
In order to support arbitrary control-flow in consts (#49146, #52000, etc.), we need to extend the analysis that ensures const-safety to be flow-sensitive. Although a generic framework for bit-vector dataflow analysis already exists in
rustc
, dataflow-based const qualification requires copying dataflow state between locals, which cannot be expressed as agen/kill
set (at least directly, see #62547).This PR introduces a more generic dataflow implementation which allows a consumer to define arbitrary transfer functions. This analysis is not as generic as possible: it still requires that the domain of the analysis be a bitset, while analyses like const-propagation require a more complex lattice. In a later PR, the existing bit-vector framework could be folded into this one via an adapter, since they currently share a lot of code.
One reason progress in this area has been so slow is that the current
qualify_consts
pass is doing many things at once. The sameVisitor
is responsible for:Qualif
s between locals.NeedsDrop
).The goal of this PR is to separate the first task from the latter two while preserving the existing behavior of the const-checker (@eddyb is working to separate promotion in #63812). To accomplish this, we implement a dataflow analysis pass that propagates
Qualif
s between consts. This analysis is run to fixpoint before the const checker validates the MIR statement-by-statement.However, promotion adds another layer of complexity. Because the const-checker is used to identify candidates for promotion, this pass must run even on non-const functions. Since promotion is viable only for temporary variables that are assigned to exactly once, there is no need to run the full dataflow-based qualif propagator (you can read @eddyb's notes in #63812 for more info). Instead, we abstract over the new
FlowSensitiveResolver
and aTempOnlyResolver
(not yet implemented) that is equivalent to the old qualif propagator with theQualifResolver
trait. Even when #63812 lands and theIsNotPromotable
qualif is handled elsewhere, we will still need this abstraction to calculate the state ofHasMutInterior
andNeedsDrop
for temps in non-const functions.r? @eddyb
Disclaimer:
Large parts of this PR may change before being merged, and fixing small style issues may not be the best use of reviewer time. However, comments on the high-level approach and the modifications to the
Qualif
trait, especially the naming ofwould be greatly appreciated.in_any_const_safe_value_of
,