Skip to content

/errors/rust/e0382-borrow-of-moved-value

Rust error[E0382]: borrow of moved value

verified onenvironmentlocal · linux 6.18.44-fc-v180 x64 · GNU bash 5.2.21 · rustc 1.97.0 (2d8144b78 2026-07-07)updated
tool
Rust
exit code
1
versions
Rust 1.x (2018, 2021 and 2024 editions)
os
any

error[E0382]: borrow of moved value means you used a variable after its value was moved somewhere else. In Rust every value has one owner; assigning a non-Copy value (such as String or Vec) to another variable, or passing it by value to a function, transfers ownership and makes the old variable unusable. Borrow it with & instead, or .clone() it if you need two copies.

Reproduce it

bash
cat > main.rs <<'EOF'
fn main() {
    let s1 = String::from("hello");
    let s2 = s1;
    println!("{s1} {s2}");
}
EOF
rustc --edition 2021 main.rs

Output · exit 1

error[E0382]: borrow of moved value: `s1`
 --> main.rs:4:16
  |
2 |     let s1 = String::from("hello");
  |         -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
3 |     let s2 = s1;
  |              -- value moved here
4 |     println!("{s1} {s2}");
  |                ^^ value borrowed here after move
  |
help: consider cloning the value if the performance cost is acceptable
  |
3 |     let s2 = s1.clone();
  |                ++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0382`.

The compiler marks where the move happened, where the value is used afterwards, and suggests a fix (here, cloning).

Fix: borrow or clone

bash
cat > main.rs <<'EOF'
fn length(s: &String) -> usize { s.len() }   // borrows, does not take ownership

fn main() {
    let s1 = String::from("hello");
    let n = length(&s1);                       // s1 is still usable
    let s2 = s1.clone();                       // an independent copy
    println!("{s1} {s2} {n}");

    let v = vec![1, 2, 3];
    for x in &v { print!("{x} "); }            // iterate by reference
    println!("{}", v.len());
}
EOF
rustc --edition 2021 main.rs && ./main

Output

hello hello 5
1 2 3 3

Which types move and which copy

TypeOn assignmentWhy
i32, f64, bool, char, &TcopiedThey implement Copy (fixed size, no heap data)
Tuples and arrays of Copy typescopiedCopy is derived from their elements
String, Vec<T>, Box<T>, HashMapmovedThey own heap memory
Your structmovedUnless it derives Clone and Copy and all fields are Copy

Sources