Is this error happening because of variance or not?. Explain mental model

#![allow(warnings)]
fn main() {
   
   
    let mut z = 4;

    // x: &{8,11} mut u32 = &{8,11} mut 4
    let mut x: &mut u32 = &mut z;

   // f: &{11} mut &{8,11} mut u32 =&{11} mut &{8,11} mut 4
    let mut f: &mut &mut u32 = &mut x;

   
    let mut q = 44;

    // s: &{17,25} mut u32 = &{17,25} mut 4
    let mut s: &mut u32 = &mut q;

    // x: &{20} mut u32 = &{20} mut 44
    x = &mut s;
    
   // f: &{23,25} mut &{17,25} mut u32 =&{23,25} mut &{17,25} mut 4
    f = &mut s;
   
   println!("{}",f);


}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `s` as mutable more than once at a time
  --> src/main.rs:23:9
   |
20 |     x = &mut s;
   |         ------ first mutable borrow occurs here
...
23 |     f = &mut s;
   |         ^^^^^^
   |         |
   |         second mutable borrow occurs here
   |         first borrow later used here

For more information about this error, try `rustc --explain E0499`.
error: could not compile `playground` (bin "playground") due to 1 previous error

I believe so. If you make only this change, it compiles.

-    let mut f: &mut &mut u32 = &mut x;
+    let mut f: &    &mut u32 = &mut x;

I don't think anyone's "walking around" mental model goes this deep, especially if we assume polonius isn't buggy -- as in that case, we're just poking at code to find the limitations of the current NLL implementation.

So the NLL RFC may be a better bet than someone's mental model. Even then, the RFC isn't an exact reflection of the implementation.[1]


  1. Location sensitive outlives relations are not implemented in NLL for example. ↩︎

#![allow(warnings)]
fn main() {
   
    let mut q = 44;

    let mut z = 4;


    let mut x: &mut u32 = &mut z;

    let mut f: &mut &mut u32 = &mut x;

    println!("{}", z);

    let mut s: &mut u32 = &mut q;

    x = &mut s;

    f = &mut s;
    println!("{}", f);
}

(Playground)

If you want to create a bunch of contrived examples to help yourself understand how the borrow checker works, that's fine, but please keep it to one discussion thread instead of opening a new one for each example?

(I've merged the new thread into this one, for that reason.)

I believe there are no relevant differences in the latest version.

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.