Cannot move out of `self.***` which is behind a mutable reference

Say I have a struct Inside:

struct Inside {
    a: i32,
}

And another struct Test that holds Inside in it:

struct Test<'a>{
    inside: &'a mut Inside,
}

In the implementation of Test, I would like to modify the value a:

impl<'a> Test<'a>{
    fn helper(&mut self){
        let check = self.inside; // fails; cannot move out of `self.inside` which is behind a mutable reference
    }
}

Why does this fail? All I'm trying to do is get a reference to inside, so I can modify it. I can't directly change it via self.inside.a = 6 because I want to assign check to something else (it's like a linkedList and check is just a current node that keeps moving along the list, modifying its values.

The inexplicable thing is that forcing the type of check works:

impl <'a> Test<'a>{
    fn helper(&mut self){
        let check: &mut Inside = self.inside; //This works!
        check.a = 6;
    }
}

Unfortunately, my own use case is a little more complicated than this, and my a value is actually an option. Whenever I try to return a mutable reference of the value in a from helper(), I start to get lifetime errors (cannot infer an appropriate lifetime due to conflicting requirements at line &mut Inside)

But the question remains: Why does forcing the type of check work?

Mutable references can't be copied, so assigning one to a new variable will “move” the reference by default, making the original variable unusable.

To get a new temporary reference based on an existing one, you can explicitly dereference and then re-borrow it, like this:

let check = &mut *self.inside;

The compiler will automatically perform this re-borrowing in certain circumstances, when assigning to a variable or function parameter with an explicit &mut type.

1 Like

You have an Option<&mut T>? Try calling Option::as_deref_mut on it.

3 Likes

I think I get it, thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.