Change:
<ins> // Regression test for issue #72649 // Tests that we don't emit spurious // 'value moved in previous iteration of loop' message struct NonCopy; fn good() { loop { let value = NonCopy{}; let _used = value; } } fn moved_here_1() { loop { let value = NonCopy{}; //~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait let _used = value; //~^ NOTE value moved here let _used2 = value; //~ ERROR use of moved value: `value` //~^ NOTE value used here after move } } fn moved_here_2() { let value = NonCopy{}; //~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait loop { let _used = value; //~^ NOTE value moved here loop { let _used2 = value; //~ ERROR use of moved value: `value` //~^ NOTE value used here after move } } } fn moved_loop_1() { let value = NonCopy{}; //~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait loop { let _used = value; //~ ERROR use of moved value: `value` //~^ NOTE value moved here, in previous iteration of loop } } fn moved_loop_2() { let mut value = NonCopy{}; //~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait let _used = value; value = NonCopy{}; loop { let _used2 = value; //~ ERROR use of moved value: `value` //~^ NOTE value moved here, in previous iteration of loop } } fn uninit_1() { loop { let value: NonCopy; let _used = value; //~ ERROR use of possibly-uninitialized variable: `value` //~^ NOTE use of possibly-uninitialized `value` } } fn uninit_2() { let mut value: NonCopy; loop { let _used = value; //~ ERROR use of possibly-uninitialized variable: `value` //~^ NOTE use of possibly-uninitialized `value` } } fn main() {} </ins>

Discussion:
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: Using a type like does result in the right error: 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.
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.
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.
To add context, I find this example illustrates the problem more clearly for me: the same code with the same types, just outside a loop context: