Skip to content
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

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

Open
bytefall opened this issue Oct 9, 2019 · 1 comment
Open
Labels
A-borrow-checker Area: The borrow checker A-NLL Area: Non-lexical lifetimes (NLL) C-enhancement Category: An issue proposing an enhancement or a PR with one. NLL-polonius Issues related for using Polonius in the borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bytefall
Copy link

bytefall commented Oct 9, 2019

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

@jonas-schievink jonas-schievink added A-borrow-checker Area: The borrow checker A-NLL Area: Non-lexical lifetimes (NLL) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 9, 2019
@matthewjasper matthewjasper added C-enhancement Category: An issue proposing an enhancement or a PR with one. NLL-polonius Issues related for using Polonius in the borrow checker and removed C-bug Category: This is a bug. labels Oct 9, 2019
@bytefall
Copy link
Author

This issue became a warning since rustc 1.34.0-nightly (00aae71 2019-02-25):

rustup run nightly-2019-02-26 cargo build

warning[E0505]: cannot move out of `_` because it is borrowed
  --> src\main.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
   |
   = 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

Looks like #57609 has affected this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-NLL Area: Non-lexical lifetimes (NLL) C-enhancement Category: An issue proposing an enhancement or a PR with one. NLL-polonius Issues related for using Polonius in the borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants