0

Why does the following code fail in the borrow checker?

struct X(pub i32);
impl X {
    fn run<F>(&mut self, f: F) -> i32
    where
        F: FnOnce() -> i32,
    {
        f() * self.0
    }
}

struct Y {
    a: i32,
    b: X,
}
impl Y {
    fn testme(&mut self) -> i32 {
        let x = || self.a;
        self.b.run(x)
    }
}

fn main() {
    let mut x = Y { a: 100, b: X(100) };
    println!("Result: {}", x.testme());
}

With the error (Playground)

error[E0502]: cannot borrow `self.b` as mutable because `self` is also borrowed as immutable
  --> src/main.rs:18:9
   |
17 |         let x = || self.a;
   |                 -- ---- previous borrow occurs due to use of `self` in closure
   |                 |
   |                 immutable borrow occurs here
18 |         self.b.run(x)
   |         ^^^^^^ mutable borrow occurs here
19 |     }
   |     - immutable borrow ends here

It looks like the closure x borrowed self in testme(); shouldn't it have only borrowed self.a? Maybe I am missing something.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ssb
  • 7,422
  • 10
  • 36
  • 61
  • 3
    I believe your question is answered by the answers of [Mutably borrow one struct field while borrowing another in a closure](https://stackoverflow.com/q/36379242/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 04 '18 at 02:50
  • 1
    TL;DR the duplicate: yes, the entire `self` is borrowed by the closure. You need to split out the borrow of the field before the closure. – Shepmaster Jun 04 '18 at 02:51

0 Answers0