Skip to content

Occasional "cannot move out" error (E0505) when adding a match guard #65236

Open
@bytefall

Description

@bytefall

Given the following snippet:

struct State {
    val: u8,
    xy: bool,
}

struct Test {
    vec: Vec<State>,
}

impl Test {
    fn new() -> Self {
        Test { vec: Vec::new() }
    }
    
    fn get_mut(&mut self, id: usize) -> Result<&mut u8, Option<&mut State>> {
        match self.vec.get_mut(id) {
            Some(State { ref mut val, ref xy }) /*if true*/ => Ok(val),
            other => Err(other),
        }
    }
}

This compiles just fine. Now uncomment the if true match guard and compile fails:

error[E0505]: cannot move out of `_` because it is borrowed
  --> src/lib.rs:18:13
   |
15 |     fn get_mut(&mut self, id: usize) -> Result<&mut u8, Option<&mut State>> {
   |                - let's call the lifetime of this reference `'1`
16 |         match self.vec.get_mut(id) {
17 |             Some(State { ref mut val, ref xy }) if true => Ok(val),
   |                          -----------                       ------- returning this value requires that borrow lasts for `'1`
   |                          |
   |                          borrow of value occurs here
18 |             other => Err(other),
   |             ^^^^^ move out of value occurs here

Why does the insignificant match guard affect the borrowck?

Tested both on stable 1.38.0 and 1.40.0-nightly (032a53a 2019-10-03).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerC-enhancementCategory: An issue proposing an enhancement or a PR with one.NLL-poloniusIssues related for using Polonius in the borrow checkerT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions