From d5b665e28f2996eaf69af6b4afecf3ba7e0d47cb Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 9 Aug 2019 14:08:44 +0200 Subject: [PATCH] A fix that stops panics from the old MaybeUninit impl --- src/export.rs | 59 +++++++++++---------------------------------------- 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/src/export.rs b/src/export.rs index cf7293b620..2f08b2678c 100644 --- a/src/export.rs +++ b/src/export.rs @@ -64,13 +64,11 @@ impl Priority { } } -#[cfg(feature = "nightly")] pub struct MaybeUninit { // we newtype so the end-user doesn't need `#![feature(maybe_uninit)]` in their code inner: core::mem::MaybeUninit, } -#[cfg(feature = "nightly")] impl MaybeUninit { pub const fn uninit() -> Self { MaybeUninit { @@ -86,61 +84,28 @@ impl MaybeUninit { self.inner.as_mut_ptr() } + #[cfg(feature = "nightly")] pub fn write(&mut self, value: T) -> &mut T { self.inner.write(value) } -} - -#[cfg(not(feature = "nightly"))] -pub struct MaybeUninit { - value: Option, -} - -#[cfg(not(feature = "nightly"))] -const MSG: &str = - "you have hit a bug (UB) in RTFM implementation; try enabling this crate 'nightly' feature"; - -#[cfg(not(feature = "nightly"))] -impl MaybeUninit { - pub const fn uninit() -> Self { - MaybeUninit { value: None } - } - - pub fn as_ptr(&self) -> *const T { - if let Some(x) = self.value.as_ref() { - x - } else { - unreachable!(MSG) - } - } - - pub fn as_mut_ptr(&mut self) -> *mut T { - if let Some(x) = self.value.as_mut() { - x - } else { - unreachable!(MSG) - } - } + #[cfg(not(feature = "nightly"))] pub unsafe fn get_ref(&self) -> &T { - if let Some(x) = self.value.as_ref() { - x - } else { - unreachable!(MSG) - } + &*self.inner.as_ptr() } + #[cfg(not(feature = "nightly"))] pub unsafe fn get_mut(&mut self) -> &mut T { - if let Some(x) = self.value.as_mut() { - x - } else { - unreachable!(MSG) - } + &mut *self.inner.as_mut_ptr() } - pub fn write(&mut self, val: T) { - // NOTE(volatile) we have observed UB when this uses a plain `ptr::write` - unsafe { ptr::write_volatile(&mut self.value, Some(val)) } + #[cfg(not(feature = "nightly"))] + pub fn write(&mut self, value: T) -> &mut T { + let ptr = self.inner.as_mut_ptr(); + unsafe { + ptr::write_volatile(ptr, value); + &mut *ptr + } } }