rust-lang / rust-lang/rust

"variable possibly uninitialized" diagnostic points to the wrong control flow construct

Open
#121,733 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics C-bug D-confusing S-has-mcve T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

fn main() {
    test();
}

fn test() {
    let mut x: i32;
    let a = true;
    
    for i in 0..12 {
        if a {
            x = 5;
        } else {
            return;
        }
        println!("x is initialized in {i}: {x}.");
    }
    
    let z = x;
    println!("{z}");
}

I expected to see this happen: The code compiles and prints the value of z.

Instead, this happened: Compilation failed with the following message

error[E0381]: used binding x is possibly-uninitialized
--> src/main.rs:18:13
|
6 | let mut x: i32;
| ----- binding declared here but left uninitialized
...
12 | } else {
| ------ if the if condition is false and this else arm is executed, x is not initialized
...
18 | let z = x;
| ^ x used here but it is possibly-uninitialized

For more information about this error, try rustc --explain E0381.
error: could not compile playground (bin "playground") due to 1 previous error

I gave a very simple example, the original is much more complex. Here, a is even always true, but the error still appears. In my code, the condition calls a function in each iteration of the loop. Furthermore, the branch it complains about returns, not even reaching the assignment to z below.

To me this seems to be a bug as the code is not asking a ton from the compiler here.

Meta

rustc --version --verbose:

rustc 1.75.0 (82e1608df 2023-12-21)
binary: rustc
commit-hash: 82e1608dfa6e0b5569232559e3d385fea5a93112
commit-date: 2023-12-21
host: aarch64-unknown-linux-gnu
release: 1.75.0
LLVM version: 17.0.6

Happens with 1.76.0 and on nightly as well.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the diagnostic with the Rust example shown in src/main.rs, including the for loop and if/else return path. Trace how the compiler reports the possibly-uninitialized binding and verify that the final diagnostic identifies the relevant control-flow construct accurately.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.