Error "reinitialization might get skipped" actually will not get skipped in this case

The following code should compile but it does not

struct S;

fn main() {
    let mut cs = S{};
    let mut flag = false;
    for i in 1..3 {
        if !flag {
            cs = S{};
            flag = true;
        }
        if flag {
            let t = cs;
            flag = false;
        }
    }
}

The code will complain that


error[[E0382]](https://doc.rust-lang.org/stable/error-index.html#E0382): use of moved value: `cs`
  --> src/main.rs:13:21
   |
5  |     let mut cs = S{};
   |         ------ move occurs because `cs` has type `S`, which does not implement the `Copy` trait
...
9  |             cs = S{};
   |             -------- this reinitialization might get skipped
...
13 |             let t = cs;
   |                     ^^ value moved here, in previous iteration of loop

For more information about this error, try `rustc --explain E0382`.
warning: `playground` (bin "playground") generated 2 warnings
error: could not compile `playground` due to previous error; 2 warnings emitted
Standard Output

Found a similar issue in the rust github repo
https://github.com/rust-lang/rust/issues/92858

The compiler does not do any analysis to prove that the first if statement implies the next; initialization logic is based only on the lexical constructs, not on values involved. For all the compiler frontend knows, the second if statement could execute without the first executing. If you know that your control flow makes situations like double-moves impossible, you can put the value of the variable in an Option, and .take().unwrap() it when you use it. This causes a panic only if your code reached an impossible state.

6 Likes

That makes sense. I'll try to use the Option . Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.