I have a mutable reference to a structure and I want to change one of its fields by passing it through a function and set the result as the new value of the field. However, I get a "cannot move out of borrowed content" compile error.
This is a minimalistic example that demonstrates my issue:
struct InnerStruct {
num: usize,
}
struct MyStruct {
inner_struct: InnerStruct,
}
fn do_something(inner_struct: InnerStruct) -> InnerStruct {
inner_struct
}
fn main() {
let mut my_struct = MyStruct {
inner_struct: InnerStruct { num: 0 },
};
let my_struct_ref = &mut my_struct;
// This line compiles:
// my_struct_ref.inner_struct = InnerStruct { num: 0 };
my_struct_ref.inner_struct = do_something(my_struct_ref.inner_struct);
}
This is the compilation error that I get:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:21:47
|
21 | my_struct_ref.inner_struct = do_something(my_struct_ref.inner_struct);
| ^^^^^^^^^^^^^ cannot move out of borrowed content
The function do_something
has to take ownership over inner structure to perform its job (In the real source it operates on Tokio futures).
I've many posts with the same title "cannot move out of borrowed content", and the solution to all of them was to clone something or pass a reference instead of move ownership, but I can not apply these solutions to my case.
I can't understand what the Rust compiler is trying to defend against in this case. In every possibility that I can think of my_struct
is kept consistent.
Having this line instead compiles successfully:
my_struct_ref.inner_struct = InnerStruct { num: 0 };
The following three lines also work:
let inner_struct2 = InnerStruct { num: 0 };
let inner_struct = std::mem::replace(&mut my_struct_ref.inner_struct, inner_struct2);
my_struct_ref.inner_struct = do_something(inner_struct);
How come this is considered safe, while the first code isn't?
I will appreciate any ideas about how to solve this, or explanations about what is wrong/unsafe with what I'm trying to do.