{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreigayo675q55r4kv2ml6m5kstctgitrgfje42b764la4use3zfqk2i",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mh7rqs6kurl2"
  },
  "path": "/t/maybeinvalid-t-separate-concepts-of-uninitialized-memory-and-invalid-values/24087#post_1",
  "publishedAt": "2026-03-16T19:16:06.000Z",
  "site": "https://internals.rust-lang.org",
  "tags": [
    "17188",
    "22254",
    "13231"
  ],
  "textContent": "Currently, uninitialized memory is dealt with using a `MaybeUninit<T>` type. But:\n\n  1. Unitialized memory is **difficult**\n  2. It can also store inproperly initialized values\n\n\n\nSo it might be better to dedicate `MaybeUninit` to the first point only and separate the second into a distinct type.\n\n## Idea\n\nCreate a new type that can store `T` without proper initialization, but unlike `MaybeUninit` it must contain a fixed value:\n\n| Valid value | Invalid value | Non-fixed value\n---|---|---|---\n`MaybeUninit<T>` |  |  |\n`MaybeInvalid<T>` |  |  |\n`T` |  |  |\n\n\n    #[repr(transparent)]\n    pub union MaybeInvalid<T> {\n        invalid: (),\n        value: ManuallyDrop<T>,\n    }\n\n    impl<T> MaybeInvalid<T> {\n        ...\n        // similar to MaybeUninit<T>\n    }\n\n\n`MaybeUninit` would get new functions to interact with it:\n\n\n    impl<T> MaybeUninit<T> {\n        ...\n        pub fn written(MaybeInvalid<T>) -> Self;\n        pub unsafe fn assume_written(self) -> MaybeInvalid<T>;\n        pub unsafe fn assume_written_ref(&self) -> &MaybeInvalid<T>;\n        pub unsafe fn assume_written_mut(&mut self) -> &mut MaybeInvalid<T>;\n        pub fn write_raw(&mut self, MaybeInvalid<T>) -> &mut MaybeInvalid<T>;\n    }\n\n\n## Case 1: `enum` optimization\n\nWe could define a trait that gives a compiler \"an example\" of invalid value of this type:\n\n\n    /// ## Safety\n    /// INVALID's value must be actually invalid:\n    /// impossible to obtain in safe Rust\n    pub unsafe trait Invalid: Sized {\n        const INVALID: MaybeInvalid<Self>;\n    }\n\n    // example\n    unsafe impl<'a, T> Invalid for &'a T {\n        const INVALID: MaybeInvalid<Self> = MaybeInvalid::zeroed();\n    }\n\n\nThis could be used to optimize `enum`s layout for arbitrary user types:\n`for<T: Invalid> assert_eq!(size_of::<T>(), size_of::<Option<T>>)`\n\n## Case 2: `freeze`ing uninitialized values\n\nLLVM's `freeze` instruction, mentioned a couple of times (17188, 22254, 13231 from a quick search) here, would become trivial and safe:\n\n\n    impl<T> MaybeUninit<T> {\n        ...\n        pub fn freeze(self) -> MaybeInvalid<T>;\n    }\n\n\nAnd if we had some auto trait for always-valid types, then one could create an \"uninitialized\" buffer without using `unsafe`:\n\n\n    let mut buf = MaybeUninit::<[u8; 256]>::uninit().freeze().valid();\n\n\nThat trait would be mutually exclusive with `Invalid` from case 1 though, which is probably fine - there are `Drop` and `Copy` but these are fundamental.",
  "title": "`MaybeInvalid<T>` - separate concepts of uninitialized memory and invalid values"
}