-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
Here is a test that already exists in the run-pass
suite:
fn main() {
let x: Box<_> = box 1;
let v = (1, 2);
match v {
(2, 1) if take(x) => (),
(1, 2) if take(x) => (),
_ => (),
}
}
fn take<T>(_: T) -> bool { false }
The above is accepted under AST-borrowck. Unfortunately, it is rejected by MIR-borrowck:
% ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc -Z borrowck=compare ../src/test/run-pass/move-guard-const.rs
error[E0382]: use of moved value: `x` (Mir)
--> /home/pnkfelix/Dev/Mozilla/rust.git/src/test/run-pass/move-guard-const.rs:22:24
|
21 | (2, 1) if take(x) => (),
| - value moved here
22 | (1, 2) if take(x) => (),
| ^ value used here after move
|
= note: move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
error: aborting due to previous error
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).