Unsafe 2 @WaffleLapkin @BoxyUwU

Warning: this quiz is still "work-in-progress", some questions might not have good explanations (or any at all), formatting/structure/titles/etc are not final, and so on. You might want to return here on a later date.

Note: the question is whether the code, as executed, is UB or whether it is sound. When the snippet has UB, explain exactly where it is UB and why.

use std::mem::MaybeUninit;

fn main() {
    // Safety: all bitpatterns are valid for u16
    let random_number: u8 = unsafe { MaybeUninit::uninit().assume_init() };

    let very_random_number = if random_number <= 100 {
        unsafe {
            // Safety: all bitpatterns are valid for u16
            let rng_array: [u32; 100] = MaybeUninit::uninit().assume_init();
            // Safety: The `random_number` is in bounds
            *rng_array.get_unchecked(random_number as usize)
        }
    } else {
        // chosen by a fair dice roll
        4
    };

    dbg!(very_random_number);
}
Solution
warning: the type `u8` does not permit being left uninitialized
 --> examples/unsafe_2.rs:5:38
  |
5 |     let random_number: u8 = unsafe { MaybeUninit::uninit().assume_init() };
  |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                                      |
  |                                      this code causes undefined behavior when executed
  |                                      help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
  |
  = note: integers must be initialized
  = note: `#[warn(invalid_value)]` on by default

warning: the type `[u32; 100]` does not permit being left uninitialized
  --> examples/unsafe_2.rs:10:41
   |
10 |             let rng_array: [u32; 100] = MaybeUninit::uninit().assume_init();
   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                                         |
   |                                         this code causes undefined behavior when executed
   |                                         help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
   |
   = note: integers must be initialized

error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
 --> examples/unsafe_2.rs:5:38
  |
5 |     let random_number: u8 = unsafe { MaybeUninit::uninit().assume_init() };
  |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
  |
  = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
  = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
  = note: BACKTRACE:
  = note: inside `main` at examples/unsafe_2.rs:5:38: 5:73

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error; 2 warnings emitted

Even though all bitpatterns are valid for a u16 (and all integer types in general), creating an integer value from uninitialized memory is still undefined behavior. Since uninitialized memory does not have a fixed value, it cannot be used to generate an integer, which are for fixed bit patterns. More details can be found in the MaybeUnint documentation.