-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
NLL: need to decide match guard static control-flow semantics #47295
Comments
It seems that the reason we accept this program is because of a very narrow exception in the CFG generation that specifically targets "all constant" arms: rust/src/librustc/cfg/construct.rs Lines 498 to 526 in 619ced0
|
The "all constant" rule seems very wrong. First, the "all the constants are the same" condition is no longer "rejected by match v {
(1, 2) => (),
(1, 2) => (), // OK, only a warning
_ => (),
} Second, it was never (since 1.0) rejected in presence of fn main() {
let x = Box::new(1);
let v = (1, 2);
match v {
(1, 2) if rand(x) => (),
(1, 2) if rand(x) => (), // May consume `x` twice
_ => (),
}
}
fn rand<T>(_: T) -> bool { false /* or true */} |
@petrochenkov I'm not a big fan of the rule, but then it may be we need to keep some variant of it for backwards compatibility. Still, that's a pretty interesting example -- is there a bug filed for that? Maybe we can use it as justification to simplify the code and remove this silly rule. It looks to have been put in place just to satisfy a particular run-pass test, and hopefully isn't relied upon much in crater (have to test). |
Maybe we should whip up a branch just for cratering purposes that removes that relevant code from the CFG. |
@nikomatsakis Nice! I say that @petrochenkov 's example lets us file this under "we can issue breaking changes to fix soundness holes", because that certainly is a soundness hole, right? |
@pnkfelix seems like it |
The main question is how much real-world code relies on this. It's hard to imagine there being much. |
An old fix for moves-in-guards had a hack for adjacent all-const match arms. The hack was explained in a comment, which you can see here: https://github.com/rust-lang/rust/pull/22580/files#diff-402a0fa4b3c6755c5650027c6d4cf1efR497 But hack was incomplete (and thus unsound), as pointed out here: rust-lang#47295 (comment) Plus, it is likely to be at least tricky to reimplement this hack in the new NLL borrowck. So rather than try to preserve the hack, we want to try to just remove it outright. (At least to see the results of a crater run.) [breaking-change] This is a breaking-change, but our hope is that no one is actually relying on such an extreme special case. (We hypothesize the hack was originally added to accommodate a file in our own test suite, not code in the wild.)
…komatsakis Remove adjacent all-const match arm hack. An old fix for moves-in-guards had a hack for adjacent all-const match arms. The hack was explained in a comment, which you can see here: https://github.com/rust-lang/rust/pull/22580/files#diff-402a0fa4b3c6755c5650027c6d4cf1efR497 But hack was incomplete (and thus unsound), as pointed out here: #47295 (comment) Plus, it is likely to be at least tricky to reimplement this hack in the new NLL borrowck. So rather than try to preserve the hack, we want to try to just remove it outright. (At least to see the results of a crater run.) [breaking-change] This is a breaking-change, but our hope is that no one is actually relying on such an extreme special case. (We hypothesize the hack was originally added to accommodate a file in our own test suite, not code in the wild.)
This issue seems to be solved? |
Here is a test that already exists in the
run-pass
suite:The above is accepted under AST-borrowck. Unfortunately, it is rejected by MIR-borrowck:
So here's the issue: We were hoping, in MIR-borrowck, to apply a pretty conservative semantics to model the control-flow of match arms, to maximize freedom in choosing future
match
-desugaring strategies.But clearly we already allow moves in
match
guards in a way that we cannot just use the current naive "every guard might be executed regardless of its associated pattern" ... at least, not without marking it as a breaking-change to the language.It might not be that hard to encode some amount of intelligence into the control-flow, in terms of modelling pattern disjointness in the arms. But its not what we're currently doing, so we need to figure out if doing that is a blocker for deploying MIR-borrowck (and thus NLL).
The text was updated successfully, but these errors were encountered: