Skip to content

NLL: need to decide match guard static control-flow semantics #47295

@pnkfelix

Description

@pnkfelix

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).

Metadata

Metadata

Assignees

Labels

A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-NLLArea: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerC-enhancementCategory: An issue proposing an enhancement or a PR with one.NLL-soundWorking towards the "invalid code does not compile" goal

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions