Why is the mutable reference copied?

Hi,

I learned that shared references can be copied, but mutable references cannot, and gave it a try. But the result is confusing.

Rust rejected t1 as expected, but it accepts t2. Why?

fn main() {
    t1();
    t2();
}

fn t1() {
    let mut a: i32 = 0;
    let r1 = &mut a;

    let r2 = r1;            // error[E0382]: borrow of moved value: `r1`

    println!("{}", r1);
}

fn t2() {
    let mut a: i32 = 0;
    let r1 = &mut a;

    let r2: &mut i32 = r1;  // OK!

    println!("{}", r1);
}
1 Like

r2 is a reborrow of r1. you can use r1 again after the last use of r2.

for example, this is OK:

    let mut a: i32 = 0;
    let r1 = &mut a;

    let r2: &mut i32 = r1;

    println!("{}", r2);
    println!("{}", r1);

but this is NOT:

    let mut a: i32 = 0;
    let r1 = &mut a;

    let r2: &mut i32 = r1;

    println!("{}", r1);
    println!("{}", r2);

see also this recent thread:

1 Like

Hello,

So the second is wrong because r2 depend of r1 that is already used ?

let r2 = r1; moves the reference r1 into r2, thus invaliding r1. This happens because exclusive references are intentionally not Copy.

As nerditation already mentioned, adding the type hint causes a reborrow instead of a move, which is equivalent to let r2 = &mut *r1;.

It's wrong because they are exclusive. While r2 is active r1 can't be used/read there.

I think there's some confusion here. In the OP there is no double exclusive borrow error. It's a use-after-move error.

I'm talking about this (comment is mine), which is what I interpreted @debrunbaix was asking about, which is not the OP.

Yes. This is a multiple mutable borrow error, constructed by nerditation, which has nothing to do with the actual error OP faced in their initial post.