@@ -705,6 +705,58 @@ pub unsafe fn uninitialized<T>() -> T {
705
705
}
706
706
}
707
707
708
+ /// Create a fresh instance of the inhabited ZST type `T`.
709
+ ///
710
+ /// Prefer this to [`zeroed`] or [`uninitialized`] or [`transmute_copy`]
711
+ /// in places where you know that `T` is zero-sized, but don't have a bound
712
+ /// (such as [`Default`]) that would allow you to instantiate it using safe code.
713
+ ///
714
+ /// If you're not sure whether `T` is an inhabited ZST, then you should be
715
+ /// using [`MaybeUninit`], not this function.
716
+ ///
717
+ /// # Safety
718
+ ///
719
+ /// - `size_of::<T>()` must be zero.
720
+ ///
721
+ /// - `T` must be *inhabited*. (It must not be a zero-variant `enum`, for example.)
722
+ ///
723
+ /// - You must use the value only in ways which do not violate any *safety*
724
+ /// invariants of the type.
725
+ ///
726
+ /// While it's easy to create a *valid* instance of an inhabited ZST, since having
727
+ /// no bits in its representation means there's only one possible value, that
728
+ /// doesn't mean that it's always *sound* to do so.
729
+ ///
730
+ /// For example, a library with a global semaphore could give out ZST tokens
731
+ /// on `acquire`, and by them being `!Default`+`!Clone` could consume them
732
+ /// in `release` to ensure that it's called at most once per `acquire`.
733
+ /// Or a library could use a `!Default`+`!Send` token to ensure it's used only
734
+ /// from the thread on which it was initialized.
735
+ ///
736
+ /// # Examples
737
+ ///
738
+ /// ```
739
+ /// #![feature(mem_conjure_zst)]
740
+ /// use std::mem::conjure_zst;
741
+ ///
742
+ /// assert_eq!(unsafe { conjure_zst::<()>() }, ());
743
+ /// assert_eq!(unsafe { conjure_zst::<[i32; 0]>() }, []);
744
+ /// ```
745
+ #[ inline( always) ]
746
+ #[ must_use]
747
+ #[ unstable( feature = "mem_conjure_zst" , issue = "95383" ) ]
748
+ #[ track_caller]
749
+ pub const unsafe fn conjure_zst < T > ( ) -> T {
750
+ // This is not a guarantee exposed to clients, but it'll easily optimize out
751
+ // in the sound cases, so we might as well check because we can.
752
+ assert ! ( size_of:: <T >( ) == 0 ) ; // FIXME: Use assert_eq! once that's allowed in const
753
+
754
+ // SAFETY: because the caller must guarantee that it's inhabited and zero-sized,
755
+ // there's nothing in the representation that needs to be set.
756
+ // `assume_init` calls `assert_inhabited`, so we don't need to here.
757
+ unsafe { MaybeUninit :: uninit ( ) . assume_init ( ) }
758
+ }
759
+
708
760
/// Swaps the values at two mutable locations, without deinitializing either one.
709
761
///
710
762
/// * If you want to swap with a default or dummy value, see [`take`].
0 commit comments