@@ -1407,3 +1407,55 @@ pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
14071407 // The `{}` is for better error messages
14081408 { builtin # offset_of ( $Container, $( $fields) +) }
14091409}
1410+
1411+ /// Create a fresh instance of the inhabited ZST type `T`.
1412+ ///
1413+ /// Prefer this to [`zeroed`] or [`uninitialized`] or [`transmute_copy`]
1414+ /// in places where you know that `T ` is zero-sized, but don' t have a bound
1415+ /// (such as [`Default`]) that would allow you to instantiate it using safe code.
1416+ ///
1417+ /// If you're not sure whether `T` is an inhabited ZST, then you should be
1418+ /// using [`MaybeUninit`], not this function.
1419+ ///
1420+ /// # Safety
1421+ ///
1422+ /// - `size_of::<T>()` must be zero.
1423+ ///
1424+ /// - `T` must be *inhabited*. (It must not be a zero-variant `enum`, for example.)
1425+ ///
1426+ /// - You must use the value only in ways which do not violate any *safety*
1427+ /// invariants of the type.
1428+ ///
1429+ /// While it's easy to create a *valid* instance of an inhabited ZST, since having
1430+ /// no bits in its representation means there's only one possible value, that
1431+ /// doesn't mean that it's always *sound* to do so.
1432+ ///
1433+ /// For example, a library with a global semaphore could give out ZST tokens
1434+ /// on `acquire`, and by them being `!Default`+`!Clone` could consume them
1435+ /// in `release` to ensure that it's called at most once per `acquire`.
1436+ /// Or a library could use a `!Default`+`!Send` token to ensure it's used only
1437+ /// from the thread on which it was initialized.
1438+ ///
1439+ /// # Examples
1440+ ///
1441+ /// ```
1442+ /// #![feature(mem_conjure_zst)]
1443+ /// use std::mem::conjure_zst;
1444+ ///
1445+ /// assert_eq!(unsafe { conjure_zst::<()>() }, ());
1446+ /// assert_eq!(unsafe { conjure_zst::<[i32; 0]>() }, []);
1447+ /// ```
1448+ #[ unstable( feature = "mem_conjure_zst" , issue = "95383" ) ]
1449+ pub const unsafe fn conjure_zst < T > ( ) -> T {
1450+ // This is not a guarantee exposed to clients, but it'll easily optimize out
1451+ // in the sound cases, so we might as well check because we can.
1452+ assert ! ( size_of:: <T >( ) == 0 ) ; // FIXME: use assert_eq! once it's const
1453+
1454+ // SAFETY: because the caller must guarantee that it's inhabited and zero-sized,
1455+ // there's nothing in the representation that needs to be set.
1456+ // `assume_init` calls `assert_inhabited`, so we don't need to here.
1457+ unsafe {
1458+ #[ allow( clippy:: uninit_assumed_init) ]
1459+ MaybeUninit :: uninit ( ) . assume_init ( )
1460+ }
1461+ }
0 commit comments