I found this code compiles:
let mut s1 = String::from("hello");
let _s2 = s1;
s1 = String::from("world");
println!("{}", s1);
If the third line is not there, I will get an error complaining that a moved variable cannot be borrowed, which is understandable to me:
error[E0382]: borrow of moved value: `s1`
--> src/main.rs:5:16
|
2 | let mut s1 = String::from("hello");
| ------ move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait
3 | let _s2 = s1;
| -- value moved here
4 | //s1 = String::from("world");
5 | println!("{}", s1);
| ^^ value borrowed here after move
With the third line, the code compiles.
Here's my understanding: after s1 is moved, s1 is still in some kind of valid state, it's just the compiler that prevents you from accessing it; if you re-assign it, it gets new ownership, and the compiler understands it so it compiles.
Am I right? Where can I find any doc/spec that explains this officially?