0

Can someone explain why the second codeblock fails? I think this is somehow related to type auto deduction.

When I explicitely write out the types it compiles

    {
        let mut ref1: &mut i32 = &mut 4;
        let mut ref2: &mut &mut i32 = &mut ref1;
        let mut ref3: &mut i32 = *ref2; //perfectly fine
        println!("{:?}", ref3);
    }

// this does not compile

    {
        let mut ref1 = &mut 4;
        let mut ref2 = &mut ref1;
        let mut ref3 = *ref2; // this causes 'cannot move out of `*ref2` which is behind a mutable reference'
        println!("{:?}", ref3);
    }

EDIT

I think the same issue here

let mut ref1: &mut &mut i32 = &mut &mut 4;
let mut x = *ref1; // same compile error

while this compiles

   let mut ref1: &mut &mut i32 = &mut &mut 4;
   let mut x: &mut i32 = *ref1;

so it seems 're-borrowing' a mutable inner reference mutably is okay, while moving it out is not okay, which makes sense

thank you: @kmdreko

Daniel
  • 21
  • 1
  • 1
    Essentially, there is a quirk in the compiler that it doesn't consider inserting a mutable reborrow when the target type is inferred, but seemingly does if a specific type is expected. So without the annotation it tries to *move* the mutable reference (since they are not `Copy`), but you can't move from behind a mutable reference. It is definitely unintuitive that one works and the other doesn't even when `ref3` is the same type in both cases (except technically their lifetimes may be different). – kmdreko Feb 22 '23 at 18:26

0 Answers0