{
"$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"
}