diff options
| author | Jorge Aparicio <jorge@japaric.io> | 2018-08-19 15:51:35 +0200 |
|---|---|---|
| committer | Jorge Aparicio <jorge@japaric.io> | 2018-09-22 21:01:21 +0200 |
| commit | 7bb5b3eb3228df648a08b02c85eddcd9b9cc85bd (patch) | |
| tree | 4e4850f64c5f199af91a6cabcbcac9282626bb83 /src/libcore | |
| parent | af50e3822c4ceda60445c4a2adbb3bfa480ebd39 (diff) | |
| download | rust-7bb5b3eb3228df648a08b02c85eddcd9b9cc85bd.tar.gz rust-7bb5b3eb3228df648a08b02c85eddcd9b9cc85bd.zip | |
add MaybeUninit and deprecate mem::{uninitialized,zeroed}
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/mem.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 1803adee3c1..91522885b59 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -514,6 +514,7 @@ pub fn needs_drop<T>() -> bool { /// assert_eq!(0, x); /// ``` #[inline] +#[rustc_deprecated(since = "1.30.0", reason = "use `mem::MaybeUninit::zeroed` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn zeroed<T>() -> T { intrinsics::init() @@ -608,6 +609,7 @@ pub unsafe fn zeroed<T>() -> T { /// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html /// [`Drop`]: ../ops/trait.Drop.html #[inline] +#[rustc_deprecated(since = "1.30.0", reason = "use `mem::MaybeUninit::uninitialized` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized<T>() -> T { intrinsics::uninit() @@ -1024,3 +1026,96 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> { &mut self.value } } + +/// A newtype to construct uninitialized instances of `T` +#[allow(missing_debug_implementations)] +#[unstable(feature = "maybe_uninit", issue = "53491")] +pub union MaybeUninit<T> { + uninit: (), + value: ManuallyDrop<T>, +} + +impl<T> MaybeUninit<T> { + /// Create a new `MaybeUninit` in an uninitialized state. + /// + /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. + /// It is your responsibility to make sure `T` gets dropped if it got initialized. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub const fn uninitialized() -> MaybeUninit<T> { + MaybeUninit { uninit: () } + } + + /// Create a new `MaybeUninit` in an uninitialized state, with the memory being + /// filled with `0` bytes. It depends on `T` whether that already makes for + /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized, + /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not + /// be null. + /// + /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. + /// It is your responsibility to make sure `T` gets dropped if it got initialized. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub fn zeroed() -> MaybeUninit<T> { + let mut u = MaybeUninit::<T>::uninitialized(); + unsafe { + u.as_mut_ptr().write_bytes(0u8, 1); + } + u + } + + /// Set the value of the `MaybeUninit`. This overwrites any previous value without dropping it. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub fn set(&mut self, val: T) { + unsafe { + self.value = ManuallyDrop::new(val); + } + } + + /// Extract the value from the `MaybeUninit` container. This is a great way + /// to ensure that the data will get dropped, because the resulting `T` is + /// subject to the usual drop handling. + /// + /// # Unsafety + /// + /// It is up to the caller to guarantee that the the `MaybeUninit` really is in an initialized + /// state, otherwise this will immediately cause undefined behavior. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub unsafe fn into_inner(self) -> T { + ManuallyDrop::into_inner(self.value) + } + + /// Get a reference to the contained value. + /// + /// # Unsafety + /// + /// It is up to the caller to guarantee that the the `MaybeUninit` really is in an initialized + /// state, otherwise this will immediately cause undefined behavior. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub unsafe fn get_ref(&self) -> &T { + &*self.value + } + + /// Get a mutable reference to the contained value. + /// + /// # Unsafety + /// + /// It is up to the caller to guarantee that the the `MaybeUninit` really is in an initialized + /// state, otherwise this will immediately cause undefined behavior. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub unsafe fn get_mut(&mut self) -> &mut T { + &mut *self.value + } + + /// Get a pointer to the contained value. Reading from this pointer will be undefined + /// behavior unless the `MaybeUninit` is initialized. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub fn as_ptr(&self) -> *const T { + unsafe { &*self.value as *const T } + } + + /// Get a mutable pointer to the contained value. Reading from this pointer will be undefined + /// behavior unless the `MaybeUninit` is initialized. + #[unstable(feature = "maybe_uninit", issue = "53491")] + pub fn as_mut_ptr(&mut self) -> *mut T { + unsafe { &mut *self.value as *mut T } + } +} |
