-
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
Pattern guard can consume value that is being matched #31287
Comments
triage: T-lang I-nominated I thought we fixed this :( |
@alexcrichton unfortunately no. I fixed a very similar issue involving multiple guards, but not this case. I did try to fix it, but it essentially requires SEME to work. This is because preventing this case introduces edges between successive patterns in the CFG and consequentially causes code like this:
to be rejected because the borrow in the first pattern overlaps the borrow in the second pattern. The reason why this has to be this way is because both move checking and borrow checking are done using the CFG, right now the CFG for a match "visits" all the arms in parallel, with pattern guards chaining into each other where appropriate. Improving it further requires chaining from the guard to the next pattern instead, but also requires indicating that the borrow in the pattern ends at both the "else" branch of the guard and the end of the block for the arm. In other words, we need regions with multiple exits aka SEME. |
Can't we just borrow the discriminant in all guards separately (cc @pnkfelix)? Actually, that might cause conflicts with This issue won't be really fixed with MIR if we are talking about bypassing-exhaustiveness rather than |
@arielb1 did you accidentally comment on the wrong issue? I'm not sure how discriminants and exhaustiveness come in here. |
triage: P-high |
I think this is one of those "fixed by moving region/borrowck to MIR" |
@pnkfelix Is this still on your radar? It's been assigned a while. |
@rust-lang/lang nominated for retriage. Still looks bad. Can we make progress now? |
As an update, still segfaults both on normal and MIR trans (example above) |
Moving to compiler team; we believe this is blocked on MIR borrowck. |
triage: P-medium |
After some discussion in @rust-lang/compiler, the consensus was that we should increase the priority of this issue. The preferred fix is still MIR borrowck. Assigning to @pnkfelix as he has been doing work in that direction. triage: P-high |
Discussed in the weekly NLL triage. |
A friend encountered this case which is not considered a hard error on the latest stable or nightly, but is a clear UAF (check the Miri interpreter): fn main() {
let x = String::from("sadsadsadsadsa");
let x = match 0 {
0 if { y(x) } => unreachable!(),
_ => x,
};
println!("Hello, world!");
}
fn y(p: String) -> bool {
false
} Relevant warning: warning[E0382]: use of moved value: `x`
--> src/main.rs:6:14
|
2 | let x = String::from("sadsadsadsadsa");
| - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
...
5 | 0 if { y(x) } => unreachable!(),
| - value moved here
6 | _ => x,
| ^ value used here after move
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future This only becomes a hard error caught by NLL if you explicitly add I'm not sure if this was intended to be considered a hard error now with NLL, but if not, I think it's worth revisiting. |
I think this was closed before we decided to not close fixed by NLL issues until they're hard errors. Reopening. |
I'm a bit surprised about |
I think the downgrade is performed here: rust/src/librustc_mir/borrow_check/mod.rs Lines 394 to 411 in 2f1bc91
And references these issues related to the downgrade #55492 #58776 For the explicit rust/src/librustc/ty/context.rs Lines 1555 to 1583 in fe5f42c
Can't seem to find the relevant discussion for the decision here though. |
@landaire Yeah but shouldn't Rust 2018 turn on the NLL borrowck in its full mode? |
it wasn't. |
and also wrote:
See also #58781. In particular is mention there of making full NLL mode the default for the 2018 edition on its own (vs doing that for all editions en masse). p.s. the default is |
…ewjasper Make `#![feature(bind_by_move_pattern_guards)]` sound without `#[feature(nll)]` Implements rust-lang#15287 (comment). Fixes rust-lang#31287 Fixes rust-lang#27282 r? @matthewjasper
…ewjasper Make `#![feature(bind_by_move_pattern_guards)]` sound without `#[feature(nll)]` Implements rust-lang#15287 (comment). Fixes rust-lang#31287 Fixes rust-lang#27282 r? @matthewjasper
…ewjasper Make `#![feature(bind_by_move_pattern_guards)]` sound without `#[feature(nll)]` Implements rust-lang#15287 (comment) making `#![feature(bind_by_move_pattern_guards)]]` sound without also having `#![feature(nll)]`. The logic here is that if we see a `match` guard, we will refuse to downgrade NLL errors to warnings. This is in preparation for hopefully stabilizing the former feature in rust-lang#63118. As fall out from the implementation we also: Fixes rust-lang#31287 Fixes rust-lang#27282 r? @matthewjasper
Make `#![feature(bind_by_move_pattern_guards)]` sound without `#[feature(nll)]` Implements #15287 (comment) making `#![feature(bind_by_move_pattern_guards)]]` sound without also having `#![feature(nll)]`. The logic here is that if we see a `match` guard, we will refuse to downgrade NLL errors to warnings. This is in preparation for hopefully stabilizing the former feature in #63118. As fall out from the implementation we also: Fixes #31287 Fixes #27282 r? @matthewjasper
…wck-test, r=Nilstrieb Test the borrowck behavior of if-let guards Add some tests to make sure that if-let guards behave the same as if guards with respect to borrow-checking. Most of them are a naive adaptation, replacing an `if` guard with `if let Some(())`. This includes regression tests for notable issues that arose for if guards (rust-lang#24535, rust-lang#27282, rust-lang#29723, rust-lang#31287) as suggested in rust-lang#51114 (comment). cc `@pnkfelix` are there any other tests that you would want to see? cc tracking issue rust-lang#51114
Following compiles, and crashes when trying to print moved from value:
The text was updated successfully, but these errors were encountered: