E0507
Rust Programming Language
Severity: ModerateWhat Does This Error Mean?
You tried to move a value out of a shared reference (an immutable borrow). Moving would leave the original reference pointing at nothing. Clone the value, or restructure to take ownership instead of borrowing.
Affected Models
- Rust stable
- Rust nightly
- Cargo build
- Rust 2021 edition
Common Causes
- Calling a method that takes ownership on a value accessed through an immutable reference
- Trying to return an owned value from a function that only has a reference to it
- Destructuring a reference with a pattern that attempts to move fields out
- Using a for loop over a reference to a collection and trying to move elements
- Calling .into_iter() on a reference instead of the owned collection
How to Fix It
-
Clone the value to get an owned copy you can move freely.
Example: let owned = my_ref.clone(); — this creates a new owned value. The type must implement Clone.
-
Change the function to take ownership instead of a reference.
Change fn foo(x: &MyType) to fn foo(x: MyType) if the caller can give up ownership of the value.
-
Borrow the value instead of moving it — use a reference where ownership is not needed.
If the receiving function only reads the value, pass a reference to it rather than moving it.
-
For iteration, iterate over owned values instead of references.
Change for item in &my_vec (which gives references) to for item in my_vec (which moves each element out).
-
Use .to_owned() or .to_string() for common types like str and String.
my_str_ref.to_owned() converts a str reference into an owned String you can move.
When to Call a Professional
E0507 is a compile-time error safe to fix yourself. It usually reveals an ownership design issue. A Rust expert can help redesign the ownership flow if cloning is too expensive.
Frequently Asked Questions
What is the difference between E0505 and E0507?
E0505 means you tried to move a value while an active borrow of that same value exists. E0507 means you tried to move a value out through a reference — the reference itself prevents the move. Both are borrow checker errors; E0507 specifically involves moving through an existing reference.
Why can Rust not just copy the value instead of moving?
Rust only copies types that implement the Copy trait — simple types like integers and booleans. For heap-allocated types like String and Vec, copying requires an explicit .clone() call. This design makes performance costs visible — you always know when a heap allocation happens.
When is cloning too expensive and what should I do instead?
Cloning a large Vec or complex struct copies all the heap data — this can be slow in tight loops. Instead, redesign the ownership so the consumer takes ownership from the start. Or use Arc<T> to share the data between multiple owners without copying.