1

Why is mutable borrowing not allowed in both the assignment and the else block of an if-let statement in Rust?

struct Parent {
    a: Option<()>,
    b: (),
}
impl Parent {
    fn mutate(&mut self) {}
}

fn main() {
    let mut parent = Parent { a: Some(()), b: () };

    if let Some(value) = &mut parent.a {
        //some mutation on value
    } else {
        parent.mutate(); //error: cannot borrow `parent` as mutable more than once at a time
    }
}

Replacing if-else with the equivalent code below compiles but is not as nice.

if let Some(value) = &mut parent.a {
    //some mutation on value
}
if let None = &mut parent.a { //or parent.a.is_none()
    parent.mutate();
}
Victor Basso
  • 5,556
  • 5
  • 42
  • 60
  • 1
    Note that it does work with edition 2018, because non-linear lifetimes are enabled. – mcarton Jan 12 '19 at 13:26
  • Your code [compiles](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=30026ae288696da58657408804bebddd) fine with the [Non-lexical lifetimes](https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md) feature, you may consider to upgrade rust version. – Ömer Erden Jan 12 '19 at 13:26
  • This was a limitation of a borrow checker before the Rust 2018. If you really limited with the old Rust version you can by-pass the issue with scoping the if-else blocks(get block inside to curly brackets) explicitly. – Akiner Alkan Jan 12 '19 at 15:29
  • I'm on `rustc 1.31.1 (b6c32da9b 2018-12-18)` and it doesn't compile. It does compile if I switch to nightly and add `#![feature(nll)]`. Is that what you mean? – Victor Basso Jan 12 '19 at 17:52
  • 1
    To use Rust 2018, you need to be in a Cargo project [configured for Rust 2018](https://rust-lang-nursery.github.io/edition-guide/print.html#creating-a-new-project), or use `rustc --edition=2018` if you’re not in a Cargo project. – Anders Kaseorg Jan 13 '19 at 04:08
  • Yes, it works now after enabling Rust 2018! – Victor Basso Jan 13 '19 at 17:13

0 Answers0