Forgetting to initialize a non-Copy variable in a loop and then referring to it gives a 'borrowed after move' error, instead of a 'possibly-uninitialized variable' error:
fn bla(_: &mut String) {}
fn main() {
for _ in 0..10 {
let mut x: String;
bla(&mut x);
}
}
error[E0382]: borrow of moved value: `x`
--> src/main.rs:6:13
|
5 | let mut x: String;
| ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
6 | bla(&mut x);
| ^^^^^^ value borrowed here after move
7 | }
| - value moved here, in previous iteration of loop
Using a Copy type like i32 does result in the right error:
error[E0381]: borrow of possibly-uninitialized variable: `x`
--> src/main.rs:6:13
|
6 | bla(&mut x);
| ^^^^^^ use of possibly-uninitialized `x`
Tested with 1.43.0 (stable) and 1.45.0-nightly.
In both Ada and D languages (in different ways, in Ada it's more refined) there's a way to tell the type system that the input variable to that bla function is not initialized and that bla must initialize it, and inside bla you can't read it before it's initialized. This means you have a way to propagate the not initialized state in function arguments, and safety is preserved. In practice this is not a big problem for Rust because in Rust you can return tuples and now Rustc is getting logic to optimize this usage pattern.
@leonardo-m Uh, this issue is just about the error message. That this code gives an error is fine.
I'd be interested in fixing this myself, but I'm not sure where to start.
This is an issue for a command line program I'm writing. At the beginning of a function, I declare some uninitialized variables, and then I have a loop for each one. In this loop, it will read user input, and if it is valid, assign the variable that value. The loop will never complete without the variable being initialized, but rustc refuses to compile because it thinks the variable could be uninitialized after the loop.
@mpfaff That sounds like a different issue. This issue is about a confusing error message. The example is supposed to not compile. If the compiler rejects correct code, that's another issue.
Most helpful comment
@leonardo-m Uh, this issue is just about the error message. That this code gives an error is fine.