How to force ignore "used here but it is possibly-uninitialized" error?

Hi,

The compiler is wrong saying that a variable "used here but it is possibly-uninitialized". Even the wording "possible" here indicates the compiler is taking too much responsibility. Probability is 0 in my case:

enum Importance
{
    Very,
    Notvery,
}

fn main()
{   
    let test = Importance::Very;

    let mut a: u32;
    let mut importance_evaluated: bool = false;

    match test
    {
        Importance::Very =>
        {
            a = 99;
            importance_evaluated = true;
        }
        Importance::Notvery => (),

    }

    if importance_evaluated == false
    {
        return
    }

    println!("{}", a);

}

The code does not compile because of the error:

error[E0381]: used binding `a` is possibly-uninitialized
  --> main.rs:31:20
   |
12 |     let mut a: u32;
   |         ----- binding declared here but left uninitialized
...
22 |         Importance::Notvery => (),
   |         ------------------- if this pattern is matched, `a` is not initialized
...
31 |     println!("{}", a);
   |                    ^ `a` used here but it is possibly-uninitialized
   |

But I'm sure 100% that uninitialized variable will never reach the println, and the compiler is wrong.

Is there a way to force compiler to ignore this line?

No, rustc doesn't have an option for this. Not even with unsafe can you use a variable for which rustc can't prove that it is initialized.

     match test {
         Importance::Very => {
             a = 99;
             importance_evaluated = true;
         }
-        Importance::Notvery => (),
+        Importance::Notvery => unreachable!(),
     }

No, it is not necessary unreachable, it just does not do anything in the example.

Try to change let test = Importance::Notvery; and should not print anything. But with your change it panics

If this doesn't suit your needs then probably you're out of luck without unsafe or such.

(Edit: Or, yeah, just initialize it. Your example is to trivialized to have a handle on what's practical or not.)

6 Likes

One way is to just initialize a to 0.
The second way is to make a an Option as @quinedot suggests. This will also eliminate the need for a separate importance_evaluated variable.
A third way is to use MaybeUninit.

3 Likes

...and note that whenever you invoke unsafe to use uninitialized value in any way, that's insta-UB.

1 Like

:smiley:

Thanks! Marked as answer, but also copying here the code from the playground in case it gets deleted:

enum Importance
{
    Very,
    Notvery,
}

fn main()
{
    let test = Importance::Very;

    let maybe_a = match test
    {
        Importance::Very => Some(99),
        Importance::Notvery => None,
    };

    let Some(a) = maybe_a else { return };

    println!("{}", a);
}