Owner-borrower race condition

Hello. I'm just started learning Rust. I've found a similar question from 2018, but the answer, in my opinion, didn't really answer the question. There is a restriction that only one mutable reference can be created, or any number of immutable references. The book says that it prevents data races. This makes sense, since if you have only one mutable reference, then there is nothing else can read the data while this reference is being used to write it. And if you have only immutable references, data can't be changed. But we also have the owner. The owner can read and can change data. So, we can have owner writing while borrower reading data, which creates a race condition. I presume that it is impossible for that to happen, but I didn't find any explanation of why.

The owner cannot write to the object as long as any references to the object exist. Essentially, mutating a value you own has the same requirements as mutating through a mutable reference. An example:

fn main() {
    let mut val = 0;
    
    let r = &val;
    val = 123;
    dbg!(r);
}

This fails to compile with:

error[E0506]: cannot assign to `val` because it is borrowed
 --> src/main.rs:5:5
  |
4 |     let r = &val;
  |             ---- borrow of `val` occurs here
5 |     val = 123;
  |     ^^^^^^^^^ assignment to borrowed `val` occurs here
6 |     dbg!(r);
  |          - borrow later used here
3 Likes

Essentially, to mutate the data, owner must either move the value out, replacing it with something else, or create a temporary mutable reference himself. While there are references to this data elsewhere, both actions are forbidden.

It appears that the owner also can't read if a mutable reference exists. Took me a while, but I think I came up with an example

fn main() {
    let mut s = 0;
    let r = &mut s;
    let g = s;

    println!("{},{}", g,r);
}

Compilation fails with an error

error[E0503]: cannot use `s` because it was mutably borrowed
 --> reference.rs:4:13
  |
3 |     let r = &mut s;
  |             ------ borrow of `s` occurs here
4 |     let g = s;
  |             ^ use of borrowed `s`
5 | 
6 |     println!("{},{}", g,r);
  |                         - borrow later used here
1 Like

This is correct. The main property of &mut references is exclusivity: When one exists, the only way to access the target value is through the reference. This prevents anyone from reading it in an inconsistent, half-updated state.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.