{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreicispp2d7mblzqbfc2g4xqklo5prkty4ehcv2rc2emm4mjdndkpti",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mmhd5bfs46w2"
  },
  "path": "/t/another-experiment-to-make-unsafe-rust-safer-preventing-ub-in-maybeuninit-with-compile-time-error/24352#post_1",
  "publishedAt": "2026-05-22T12:22:33.000Z",
  "site": "https://internals.rust-lang.org",
  "textContent": "Hello, I'm doing this experiment. What do you guys think? :]\n\n\n    use std::mem::MaybeUninit;\n    use std::marker::PhantomData;\n\n    pub struct Uninit;\n    pub struct Init;\n\n    pub struct UninitStorage<T>(MaybeUninit<T>);\n\n    pub struct InitStorage<T>(MaybeUninit<T>);\n\n    impl<T> Drop for InitStorage<T> {\n        fn drop(&mut self) {\n            unsafe {\n                self.0.assume_init_drop();\n            }\n        }\n    }\n\n    pub struct UninitGuard<T, State> {\n        storage: State,\n        _marker: PhantomData<T>,\n    }\n\n    #[diagnostic::on_unimplemented(\n        message = \"Illegal access: Memory is not initialized yet!\",\n        label = \"Attempted to operate on data here, but the status is still `Uninit`\",\n        note = \"Call `.write(val)` on the UninitGuard first before accessing its references or pointers.\"\n    )]\n    pub trait IsInitialized<State> {}\n\n    #[diagnostic::do_not_recommend]\n    impl<T> IsInitialized<InitStorage<T>> for UninitGuard<T, InitStorage<T>> {}\n\n    impl<T> UninitGuard<T, UninitStorage<T>> {\n        pub fn new() -> Self {\n            Self {\n                storage: UninitStorage(MaybeUninit::uninit()),\n                _marker: PhantomData,\n            }\n        }\n\n        pub fn zeroed() -> Self {\n            Self {\n                storage: UninitStorage(MaybeUninit::zeroed()),\n                _marker: PhantomData,\n            }\n        }\n\n        pub const fn uninit() -> Self {\n            Self {\n                storage: UninitStorage(MaybeUninit::uninit()),\n                _marker: PhantomData,\n            }\n        }\n\n        pub fn write(self, val: T) -> UninitGuard<T, InitStorage<T>> {\n            let mut storage = MaybeUninit::uninit();\n            storage.write(val);\n            UninitGuard {\n                storage: InitStorage(storage),\n                _marker: PhantomData,\n            }\n        }\n    }\n\n    impl<T, State> UninitGuard<T, State>\n    where\n        Self: IsInitialized<State>,\n    {\n        pub fn as_ptr(&self) -> *const T {\n            let storage = unsafe { &*( &self.storage as *const State as *const MaybeUninit<T> ) };\n            storage.as_ptr()\n        }\n\n        pub fn as_mut_ptr(&mut self) -> *mut T {\n            let storage = unsafe { &mut *( &mut self.storage as *mut State as *mut MaybeUninit<T> ) };\n            storage.as_mut_ptr()\n        }\n\n        pub fn get_ref(&self) -> &T {\n            let storage = unsafe { &*( &self.storage as *const State as *const MaybeUninit<T> ) };\n            unsafe { storage.assume_init_ref() }\n        }\n\n        pub fn get_mut(&mut self) -> &mut T {\n            let storage = unsafe { &mut *( &mut self.storage as *mut State as *mut MaybeUninit<T> ) };\n            unsafe { storage.assume_init_mut() }\n        }\n\n        pub fn assume_init(self) -> T {\n            let mut this = std::mem::ManuallyDrop::new(self);\n            let storage = unsafe { &mut *( &mut this.storage as *mut State as *mut MaybeUninit<T> ) };\n            unsafe { storage.assume_init_read() }\n        }\n\n        pub fn replace(&mut self, val: T) -> T {\n            let storage = unsafe { &mut *( &mut self.storage as *mut State as *mut MaybeUninit<T> ) };\n            let old = unsafe { storage.assume_init_read() };\n            storage.write(val);\n            old\n        }\n    }\n\n    impl<T> UninitGuard<T, InitStorage<T>> {\n        pub const fn new_init(val: T) -> Self {\n            Self {\n                storage: InitStorage(MaybeUninit::new(val)),\n                _marker: PhantomData,\n            }\n        }\n    }\n\n    fn a() {\n        let guard = UninitGuard::<String, _>::new();\n        let tes = guard.assume_init();\n    }\n\n    fn main() {\n\n    }\n\n\nIt will cause compile time error if we call assume_init, get reference, get pointer when the memory is uninitialized yet\n\n\n       Compiling playground v0.0.1 (/playground)\n    error[E0599]: Illegal access: Memory is not initialized yet!\n       --> src/main.rs:115:21\n        |\n     19 | pub struct UninitGuard<T, State> {\n        | -------------------------------- method `assume_init` not found for this struct because it doesn't satisfy `_: IsInitialized<UninitStorage<String>>`\n    ...\n    115 |     let tes = guard.assume_init();\n        |                     ^^^^^^^^^^^ Attempted to operate on data here, but the status is still `Uninit`\n        |\n    note: trait bound `UninitGuard<String, UninitStorage<String>>: IsInitialized<UninitStorage<String>>` was not satisfied\n       --> src/main.rs:68:11\n        |\n     66 | impl<T, State> UninitGuard<T, State>\n        |                ---------------------\n     67 | where\n     68 |     Self: IsInitialized<State>,\n        |           ^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here\n        = note: Call `.write(val)` on the UninitGuard first before accessing its references or pointers.\n    note: the trait `IsInitialized` must be implemented\n       --> src/main.rs:29:1\n        |\n     29 | pub trait IsInitialized<State> {}\n        | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n    For more information about this error, try `rustc --explain E0599`.\n    error: could not compile `playground` (bin \"playground\") due to 1 previous error\n    Standard Output\n\n\nWhat is the escape hatch that you guys spot in this code?\n\nIf this experiment is successful, it would be a valuable addition to the standard library. Because it prevents many UBs that are related to uninitialized memory",
  "title": "Another Experiment To Make Unsafe Rust Safer: Preventing UB In MaybeUninit With Compile Time Error"
}