Rust errors / Ownership and borrowing
Rust compiler error · checked with rustc 1.99.0
Rust error E0505: cannot move out of because it is borrowed
What it meansYou moved a value while a reference to it was still in use. After the move the reference would point at nothing.
What rustc prints
error[E0505]: cannot move out of `x` because it is borrowed --> main.rs:10:9 | 8 | let x = Value{}; | - binding `x` declared here 9 | let _ref_to_val: &Value = &x; | -- borrow of `x` occurs here 10 | eat(x); | ^ move out of `x` occurs here 11 | borrow(_ref_to_val); | ----------- borrow later used here | note: if `Value` implemented `Clone`, you could clone the value --> main.rs:1:1 | 1 | struct Value {} | ^^^^^^^^^^^^ consider implementing `Clone` for this type ... 9 | let _ref_to_val: &Value = &x; | - you could clone this value
Real output of rustc 1.99.0 compiling the official example below (2021 edition). Your names and line numbers will differ; the first line is the part to match.
Why it happens
- Passing a value to a function by value while a
&to it is used later. - Moving a value into a thread or closure while a borrow is alive.
How to fix it
1. Finish using the borrow first
Move the last use of the reference above the move.
let r = &v;
println!("{}", r.len()); // last use of r
consume(v); // move is fine now2. Clone, or pass a reference
consume(v.clone());
// or change consume to take &Vec<T> / &[T]Other wordings of this error
cannot move out of because it is borrowed, move out of occurs here, borrow of occurs here
The compiler team's explanation
A value was moved out while it was still borrowed.
Erroneous code example:
struct Value {}
fn borrow(val: &Value) {}
fn eat(val: Value) {}
fn main() {
let x = Value{};
let _ref_to_val: &Value = &x;
eat(x);
borrow(_ref_to_val);
}
Here, the function eat takes ownership of x. However, x cannot be moved because the borrow to _ref_to_val needs to last till the function borrow. To fix that you can do a few different things:
- Try to avoid moving the variable.
- Release borrow before move.
- Implement the
Copytrait on the type.
Examples:
struct Value {}
fn borrow(val: &Value) {}
fn eat(val: &Value) {}
fn main() {
let x = Value{};
let ref_to_val: &Value = &x;
eat(&x); // pass by reference, if it's possible
borrow(ref_to_val);
}
Or:
struct Value {}
fn borrow(val: &Value) {}
fn eat(val: Value) {}
fn main() {
let x = Value{};
let ref_to_val: &Value = &x;
borrow(ref_to_val);
// ref_to_val is no longer used.
eat(x);
}
Or:
#[derive(Clone, Copy)] // implement Copy trait
struct Value {}
fn borrow(val: &Value) {}
fn eat(val: Value) {}
fn main() {
let x = Value{};
let ref_to_val: &Value = &x;
eat(x); // it will be copied here.
borrow(ref_to_val);
}
For more information on Rust's ownership system, take a look at the References & Borrowing section of the Book.
From rustc --explain E0505 (1.99.0), part of the Rust project, MIT or Apache-2.0. Official page.
Related errors
- E0382borrow of moved value
- E0499cannot borrow as mutable more than once at a time
- E0502cannot borrow as mutable because it is also borrowed as immutable
- E0106missing lifetime specifier
- E0503cannot use `value` because it was mutably borrowed
- E0506cannot assign to because it is borrowed
- E0507cannot move out of
Up next
Often hit nextE0382: borrow of moved valueA related error from the same family.Read it next →Did this answer your question?