Having hard time managing compounds of references and dereferences

Viewed 63
let mut x = 1;
let a = &mut x;
let b = &mut *a;
*a = 2; // error. b borrows a
*b = 3; // it works! (only without " *a = 2 ")
let mut x = 1;
let b;
{
    let a = &mut x;
    b = &mut *a;
} // a drops here
*b = 2; // it works!

I'm having hard time getting what &*a means, in the point of lifetime. I don't know how *operator is related to lifetimes of variables.

It seems like b is borrowing x and also a, so that not only x(which is *a) cannot be moved or modified but also a cannot be used.

The error message of compiler is : b borrowing a.

So, I ran the second code. In my understanding, borrowed data cannot be reassigned or moved, or dropped. I deliberately made a to drop before b, to make sure that a's lifetime should be longer than b's.

However, second code still works.

So, how can I understand undergoing lifetimes associated with &mut *a?

2 Answers

The important misconception is in your first line of code. The error is not that b borrows a, it's that b borrows *a, meaning it borrows x. Since Rust downgrades and drops references as early as possible, this "double" mutable reference is allowed as long as you don't ever try to use a. However, when using a, the compiler will now warn you that you have a double mutable reference: one borrowing *a (basically x) in the variable a, and one borrowing *a in the variable b.

With that cleared up, your second piece of code makes sense. a can be dropped, because b is just using *a to borrow x, and x has a long enough lifetime to be accessed.

let mut x = 1;
let a = &mut x; // now a is the mutable owner of x
let b = &mut *a; // *a -> x so, now b is the mutable owner of x

*a = 2; // it will not work as a is not the current mutable owner of x
*b = 3; // it will work as a is the current mutable owner of x
let mut x = 1;
let b;
{
    let a = &mut x; // now a is the mutable owner of x
    b = &mut *a; // *a -> x so, b is the mutable owner of x
} // a dropped but not x
*b = 2; // it will work because b is the current mutable owner of x and x is still in scope.
Related