0

In the below example, I mutably borrow p twice, but the program compiles. Why is this?

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
    x_vel: i32,
    y_vel: i32,
}

fn step(p: &mut Point) {
    p.x += p.x_vel;
    p.y += p.y_vel;
}

fn main() {
    println!("Hello, world!");
    let mut p = Point {
        x: 0,
        y: 0,
        x_vel: 3,
        y_vel: 2,
    };
    println!("{:?}", p);
    step(&mut p);
    println!("{:?}", p);
    step(&mut p);
    println!("{:?}", p); 
}

edit

To make it very clear two mutable borrows are happening, see the below code. This also compiles without error. Why is this allowed?

println!("{:?}", p);
let pref = &mut p;
step(pref);
println!("{:?}", p);
let pref2 = &mut p;
step(pref2);
println!("{:?}", p); 
Blue7
  • 1,750
  • 4
  • 31
  • 55
  • 1
    If you want to see an error, try to use `pref` after the code you have shown (e.g. add `println!("{:?}", pref);` at the end of your `main` function). – Jmb May 31 '22 at 13:59
  • There aren't actually overlapping borrows anywhere, because the compiler can see that `pref` is dead after the call to `step`, which is also why you can immediately print `p` (`println` requires a shared borrow, which is not compatible with a unique / mutable borrow). If you add an active use of `pref` at some later point (after the last line of your second snippet) the compiler will reject the code. – Masklinn May 31 '22 at 13:59
  • 1
    Does this answer your question? [What are non-lexical lifetimes?](https://stackoverflow.com/questions/50251487/what-are-non-lexical-lifetimes) – Chayim Friedman May 31 '22 at 16:38

1 Answers1

4

First mutable borrow ends when execution returns from step to main function. So the second borrow is possible because there is no other borrow at that moment.

ozan k
  • 485
  • 5
  • 18