Rust errors / Ownership and borrowing
Rust compiler error · checked with rustc 1.99.0
Rust error E0506: cannot assign to because it is borrowed
What it meansYou assigned a new value while a reference to the old one was still in use.
What rustc prints
error[E0506]: cannot assign to `fancy_num` because it is borrowed
--> main.rs:9:1
|
8 | let fancy_ref = &fancy_num;
| ---------- `fancy_num` is borrowed here
9 | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fancy_num` is assigned to here but it was already borrowed
...
12 | println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
| ------------- borrow later used hereReal 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
- Updating a variable inside a loop while holding a reference to it from earlier.
- Assigning to a struct field while a borrow of it lives on.
How to fix it
1. End the borrow before assigning
let len = s.len(); // copy what you need
s = String::from("new");
println!("{len}");Other wordings of this error
cannot assign to because it is borrowed, assignment to borrowed occurs here
The compiler team's explanation
An attempt was made to assign to a borrowed value.
Erroneous code example:
struct FancyNum {
num: u8,
}
let mut fancy_num = FancyNum { num: 5 };
let fancy_ref = &fancy_num;
fancy_num = FancyNum { num: 6 };
// error: cannot assign to `fancy_num` because it is borrowed
println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
Because fancy_ref still holds a reference to fancy_num, fancy_num can't be assigned to a new value as it would invalidate the reference.
Alternatively, we can move out of fancy_num into a second fancy_num:
struct FancyNum {
num: u8,
}
let mut fancy_num = FancyNum { num: 5 };
let moved_num = fancy_num;
fancy_num = FancyNum { num: 6 };
println!("Num: {}, Moved num: {}", fancy_num.num, moved_num.num);
If the value has to be borrowed, try limiting the lifetime of the borrow using a scoped block:
struct FancyNum {
num: u8,
}
let mut fancy_num = FancyNum { num: 5 };
{
let fancy_ref = &fancy_num;
println!("Ref: {}", fancy_ref.num);
}
// Works because `fancy_ref` is no longer in scope
fancy_num = FancyNum { num: 6 };
println!("Num: {}", fancy_num.num);
Or by moving the reference into a function:
struct FancyNum {
num: u8,
}
fn print_fancy_ref(fancy_ref: &FancyNum){
println!("Ref: {}", fancy_ref.num);
}
let mut fancy_num = FancyNum { num: 5 };
print_fancy_ref(&fancy_num);
// Works because function borrow has ended
fancy_num = FancyNum { num: 6 };
println!("Num: {}", fancy_num.num);From rustc --explain E0506 (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
- E0505cannot move out of because it is borrowed
- E0507cannot move out of
- E0508cannot move out of type `[NonCopy; 1]`, a non-copy array
Up next
Often hit nextE0382: borrow of moved valueA related error from the same family.Read it next →Did this answer your question?