/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
cat > main.rs <<'EOF'
fn main() {
let s1 = String::from("hello");
let s2 = s1;
println!("{s1} {s2}");
}
EOF
rustc --edition 2021 main.rsOutput · 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
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 && ./mainOutput
hello hello 5 1 2 3 3
Which types move and which copy
| Type | On assignment | Why |
|---|---|---|
| i32, f64, bool, char, &T | copied | They implement Copy (fixed size, no heap data) |
| Tuples and arrays of Copy types | copied | Copy is derived from their elements |
| String, Vec<T>, Box<T>, HashMap | moved | They own heap memory |
| Your struct | moved | Unless it derives Clone and Copy and all fields are Copy |
Sources
Related pages
flags · cargocargo build --release: optimised builds and target/releasecargo build --release uses the release profile (opt-level 3, no overflow checks) and writes to target/release. Debug vs release, and how to tune the profile.cheat sheets · cargoCargo cheat sheet: build, run, test and manage Rust cratesCargo cheat sheet: new packages, check, build and run in debug or release, test, fmt, clippy, add and update dependencies, workspaces and flags for CI.errors · cargoerror: could not find `Cargo.toml` in `...` or any parent directorycargo reports could not find Cargo.toml when run outside a Rust package. cd into the project, pass --manifest-path, or create a package with cargo new.commands · rustrustc --explain E0382: show the explanation of a Rust error coderustc --explain E0382 prints the full explanation of a Rust compiler error code, with an erroneous example and fixes. It works offline; cargo --explain too.glossary · rustWhat is ownership in Rust?Ownership is Rust's rule that every value has one owner, assigning a non-Copy value moves it, and the value is dropped when the owner goes out of scope.