diff options
| author | Trevor Gross <tmgross@umich.edu> | 2023-09-28 01:57:01 -0400 |
|---|---|---|
| committer | Trevor Gross <tmgross@umich.edu> | 2023-11-04 15:27:25 -0400 |
| commit | f6ce646d3f840181dcc3f5d9edc4e4cff0051b78 (patch) | |
| tree | 6a4a134859db156b7edadce12e8f5256d2f17461 | |
| parent | 2ba4eb2d49e774b5fbc2a06258ac7b0f60b92b7e (diff) | |
| download | rust-f6ce646d3f840181dcc3f5d9edc4e4cff0051b78.tar.gz rust-f6ce646d3f840181dcc3f5d9edc4e4cff0051b78.zip | |
Stabilize `const_maybe_uninit_zeroed`
Make `MaybeUninit::zeroed` const stable. Newly stable API:
// core::mem
impl<T> MaybeUninit<T> {
pub const fn zeroed() -> MaybeUninit<T>;
}
Use of `const_mut_refs` should be acceptable since we do not leak the
mutability.
Tracking issue: #91850
| -rw-r--r-- | library/alloc/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/mem/maybe_uninit.rs | 17 | ||||
| -rw-r--r-- | library/core/tests/mem.rs | 21 |
3 files changed, 32 insertions, 7 deletions
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index f435f503fc1..5b7062dec7a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -113,7 +113,6 @@ #![feature(const_eval_select)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_write)] -#![feature(const_maybe_uninit_zeroed)] #![feature(const_pin)] #![feature(const_refs_to_cell)] #![feature(const_size_of_val)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index d09a24b4b1d..a86ccaeb839 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -374,6 +374,9 @@ impl<T> MaybeUninit<T> { /// assert_eq!(x, (0, false)); /// ``` /// + /// This can be used in const contexts, such as to indicate the end of static arrays for + /// plugin registration. + /// /// *Incorrect* usage of this function: calling `x.zeroed().assume_init()` /// when `0` is not a valid bit-pattern for the type: /// @@ -387,17 +390,19 @@ impl<T> MaybeUninit<T> { /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant. /// // This is undefined behavior. ⚠️ /// ``` - #[stable(feature = "maybe_uninit", since = "1.36.0")] - #[rustc_const_unstable(feature = "const_maybe_uninit_zeroed", issue = "91850")] - #[must_use] #[inline] + #[must_use] #[rustc_diagnostic_item = "maybe_uninit_zeroed"] + #[stable(feature = "maybe_uninit", since = "1.36.0")] + // These are OK to allow since we do not leak &mut to user-visible API + #[rustc_allow_const_fn_unstable(const_mut_refs)] + #[rustc_allow_const_fn_unstable(const_ptr_write)] + #[rustc_allow_const_fn_unstable(const_maybe_uninit_as_mut_ptr)] + #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "CURRENT_RUSTC_VERSION")] pub const fn zeroed() -> MaybeUninit<T> { let mut u = MaybeUninit::<T>::uninit(); // SAFETY: `u.as_mut_ptr()` points to allocated memory. - unsafe { - u.as_mut_ptr().write_bytes(0u8, 1); - } + unsafe { u.as_mut_ptr().write_bytes(0u8, 1) }; u } diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index 5c2e18745ea..20498b16cb2 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -565,3 +565,24 @@ fn offset_of_addr() { assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.0), ptr::addr_of!(base.z.0).addr()); assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.1), ptr::addr_of!(base.z.1).addr()); } + +#[test] +fn const_maybe_uninit_zeroed() { + // Sanity check for `MaybeUninit::zeroed` in a realistic const situation (plugin array term) + #[repr(C)] + struct Foo { + a: Option<&'static str>, + b: Bar, + c: f32, + d: *const u8, + } + #[repr(C)] + struct Bar(usize); + struct FooPtr(*const Foo); + unsafe impl Sync for FooPtr {} + + static UNINIT: FooPtr = FooPtr([unsafe { MaybeUninit::zeroed().assume_init() }].as_ptr()); + const SIZE: usize = size_of::<Foo>(); + + assert_eq!(unsafe { (*UNINIT.0.cast::<[[u8; SIZE]; 1]>())[0] }, [0u8; SIZE]); +} |
