2

Consider:

fn main() {
    let mut x: i32 = 5;
    let y = &mut x;
    let z: &i32 = y;
    println!("{}", *z);
    //*y = 5;
    println!("{}", *y);
    println!("{}", *z);
}

Without commenting out line 6 the code compiles.

It seems to me that both the reference y and z are in scope from line 5 to 7. It sure only reads from y, but I've always been told that mutable and immutable reference can not exist at the same time. In fact, it results in a compile error if I replace line 4 with let z: &i32 = &x.

What is going on here?

vbstb
  • 1,261
  • 1
  • 10
  • 14
  • 1
    Does this answer your question? [What are non-lexical lifetimes?](https://stackoverflow.com/questions/50251487/what-are-non-lexical-lifetimes) – L. F. Mar 13 '21 at 09:26
  • @L.F. I don't think this is caused by non-lexical lifetimes. Because `z` is being used line 8, it won't be invalidated by then. Correct me if I'm wrong. – vbstb Mar 14 '21 at 01:06
  • You're right! I retracted my close vote. It seems that the reborrowing somehow downgrades `y` to a non-mutable reference in terms of usage, even though its type is still `&mut i32`. I'm really not sure why this is the case. – L. F. Mar 14 '21 at 03:33

1 Answers1

0

Immutable references do not expect the underlying value to change and this is problematic if we do have a mutable reference. You can however have multiple immutable references because underlying data is not gonna change.

  • Scope of reference starts when it is first introduced and ends when it is used for the last time. That means we can add a third mutable reference underneath the println statement
    fn main() {
        let mut x: i32 = 5;
        // scope of y starts here
        // we can have multiple immutable references so I moved "mut"
        let y = &x;
        // scope of z starts here
        let z: &i32 = y;
        // scope of z ends here
        println!("{}", *z);
        //*y = 5;
        // scope of y ends here
        println!("{}", *y);
    
        // this should work
        let a = &mut x;
    }
Yilmaz
  • 35,338
  • 10
  • 157
  • 202