Questions about `&mut T` and move semantics, `&mut T` is "move-only"?

@alice Adding lifetime annotation also helps to understand why deref coercion happens here. In a function call context, the reference of input params doesn't have to live too long in the caller context, so compiler can add an anonymous scope around the function call. Following the illustrations in 3.3 Lifetimes, Rustomonicon we can informally de-sugar the program

fn f(y: &mut i32) {}

fn main() {
    let mut x: i32 = 0;
    let y = &mut x;
    f(y);
}

to the following:

// Doesn't compile, just a thought model.
fn f<'a>(y: &'a mut i32) {}

fn main() {
    'a {
        let mut x: i32 = 0;
        'b {
            let y = &'b mut x;
            'c {
                f::<'c>(&'c mut *y);
            }
        }
    }
}

Now we can see that, due to a lifetime difference (from 'b to 'c), deref coercion must happen. These are indeed different mut reference "types" if you take lifetime into account, so no direct assignment(i.e., move) is happening here.

3 Likes