diff options
| author | bors <bors@rust-lang.org> | 2022-01-20 20:44:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-01-20 20:44:14 +0000 |
| commit | 777bb86bcdbc568be7cff6eeeaaf81a89b4aa50b (patch) | |
| tree | 82f458e6da62ec8cd4baa7cf5c1b4c2eed5f3cc5 /library/core/src | |
| parent | 74fbbefea8d13683cca5eee62e4740706cb3144a (diff) | |
| parent | dbc97490bbca00e6913c34b8864791d660c60312 (diff) | |
| download | rust-777bb86bcdbc568be7cff6eeeaaf81a89b4aa50b.tar.gz rust-777bb86bcdbc568be7cff6eeeaaf81a89b4aa50b.zip | |
Auto merge of #93119 - matthiaskrgr:rollup-ku3cn5j, r=matthiaskrgr
Rollup of 13 pull requests Successful merges: - #89747 (Add MaybeUninit::(slice_)as_bytes(_mut)) - #89764 (Fix variant index / discriminant confusion in uninhabited enum branching) - #91606 (Stabilize `-Z print-link-args` as `--print link-args`) - #91694 (rustdoc: decouple stability and const-stability) - #92183 (Point at correct argument when async fn output type lifetime disagrees with signature) - #92582 (improve `_` constants in item signature handling) - #92680 (intra-doc: Use the impl's assoc item where possible) - #92704 (Change lint message to be stronger for &T -> &mut T transmute) - #92861 (Rustdoc mobile: put out-of-band info on its own line) - #92992 (Help optimize out backtraces when disabled) - #93038 (Fix star handling in block doc comments) - #93108 (:arrow_up: rust-analyzer) - #93112 (Fix CVE-2022-21658) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/mem/maybe_uninit.rs | 125 |
1 files changed, 124 insertions, 1 deletions
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 56bdc6beb90..e38c0412a0a 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1,8 +1,9 @@ use crate::any::type_name; use crate::fmt; use crate::intrinsics; -use crate::mem::ManuallyDrop; +use crate::mem::{self, ManuallyDrop}; use crate::ptr; +use crate::slice; /// A wrapper type to construct uninitialized instances of `T`. /// @@ -1160,4 +1161,126 @@ impl<T> MaybeUninit<T> { // SAFETY: Valid elements have just been written into `this` so it is initialized unsafe { MaybeUninit::slice_assume_init_mut(this) } } + + /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes. + /// + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still + /// contain padding bytes which are left uninitialized. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_slice)] + /// use std::mem::MaybeUninit; + /// + /// let val = 0x12345678i32; + /// let uninit = MaybeUninit::new(val); + /// let uninit_bytes = uninit.as_bytes(); + /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) }; + /// assert_eq!(bytes, val.to_ne_bytes()); + /// ``` + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + pub fn as_bytes(&self) -> &[MaybeUninit<u8>] { + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes + unsafe { + slice::from_raw_parts(self.as_ptr() as *const MaybeUninit<u8>, mem::size_of::<T>()) + } + } + + /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized + /// bytes. + /// + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still + /// contain padding bytes which are left uninitialized. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_as_bytes)] + /// use std::mem::MaybeUninit; + /// + /// let val = 0x12345678i32; + /// let mut uninit = MaybeUninit::new(val); + /// let uninit_bytes = uninit.as_bytes_mut(); + /// if cfg!(target_endian = "little") { + /// uninit_bytes[0].write(0xcd); + /// } else { + /// uninit_bytes[3].write(0xcd); + /// } + /// let val2 = unsafe { uninit.assume_init() }; + /// assert_eq!(val2, 0x123456cd); + /// ``` + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] { + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes + unsafe { + slice::from_raw_parts_mut( + self.as_mut_ptr() as *mut MaybeUninit<u8>, + mem::size_of::<T>(), + ) + } + } + + /// Returns the contents of this slice of `MaybeUninit` as a slice of potentially uninitialized + /// bytes. + /// + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still + /// contain padding bytes which are left uninitialized. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_write_slice, maybe_uninit_slice)] + /// use std::mem::MaybeUninit; + /// + /// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)]; + /// let uninit_bytes = MaybeUninit::slice_as_bytes(&uninit); + /// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(&uninit_bytes) }; + /// let val1 = u16::from_ne_bytes(bytes[0..2].try_into().unwrap()); + /// let val2 = u16::from_ne_bytes(bytes[2..4].try_into().unwrap()); + /// assert_eq!(&[val1, val2], &[0x1234u16, 0x5678u16]); + /// ``` + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>] { + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes + unsafe { + slice::from_raw_parts( + this.as_ptr() as *const MaybeUninit<u8>, + this.len() * mem::size_of::<T>(), + ) + } + } + + /// Returns the contents of this mutable slice of `MaybeUninit` as a mutable slice of + /// potentially uninitialized bytes. + /// + /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still + /// contain padding bytes which are left uninitialized. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_as_bytes, maybe_uninit_write_slice, maybe_uninit_slice)] + /// use std::mem::MaybeUninit; + /// + /// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()]; + /// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit); + /// MaybeUninit::write_slice(uninit_bytes, &[0x12, 0x34, 0x56, 0x78]); + /// let vals = unsafe { MaybeUninit::slice_assume_init_ref(&uninit) }; + /// if cfg!(target_endian = "little") { + /// assert_eq!(vals, &[0x3412u16, 0x7856u16]); + /// } else { + /// assert_eq!(vals, &[0x1234u16, 0x5678u16]); + /// } + /// ``` + #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] + pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>] { + // SAFETY: MaybeUninit<u8> is always valid, even for padding bytes + unsafe { + slice::from_raw_parts_mut( + this.as_mut_ptr() as *mut MaybeUninit<u8>, + this.len() * mem::size_of::<T>(), + ) + } + } } |
