148
148
//! fn new() -> impl PinInit<Self, Error> {
149
149
//! try_pin_init!(Self {
150
150
//! status <- CMutex::new(0),
151
- //! buffer: Box::init(pin_init::zeroed ())?,
151
+ //! buffer: Box::init(pin_init::init_zeroed ())?,
152
152
//! }? Error)
153
153
//! }
154
154
//! }
@@ -742,7 +742,7 @@ macro_rules! stack_try_pin_init {
742
742
/// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
743
743
/// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
744
744
/// pointer named `this` inside of the initializer.
745
- /// - Using struct update syntax one can place `..Zeroable::zeroed ()` at the very end of the
745
+ /// - Using struct update syntax one can place `..Zeroable::init_zeroed ()` at the very end of the
746
746
/// struct, this initializes every field with 0 and then runs all initializers specified in the
747
747
/// body. This can only be done if [`Zeroable`] is implemented for the struct.
748
748
///
@@ -769,7 +769,7 @@ macro_rules! stack_try_pin_init {
769
769
/// });
770
770
/// let init = pin_init!(Buf {
771
771
/// buf: [1; 64],
772
- /// ..Zeroable::zeroed ()
772
+ /// ..Zeroable::init_zeroed ()
773
773
/// });
774
774
/// ```
775
775
///
@@ -805,7 +805,7 @@ macro_rules! pin_init {
805
805
/// ```rust
806
806
/// # #![feature(allocator_api)]
807
807
/// # #[path = "../examples/error.rs"] mod error; use error::Error;
808
- /// use pin_init::{pin_data, try_pin_init, PinInit, InPlaceInit, zeroed };
808
+ /// use pin_init::{pin_data, try_pin_init, PinInit, InPlaceInit, init_zeroed };
809
809
///
810
810
/// #[pin_data]
811
811
/// struct BigBuf {
@@ -817,7 +817,7 @@ macro_rules! pin_init {
817
817
/// impl BigBuf {
818
818
/// fn new() -> impl PinInit<Self, Error> {
819
819
/// try_pin_init!(Self {
820
- /// big: Box::init(zeroed ())?,
820
+ /// big: Box::init(init_zeroed ())?,
821
821
/// small: [0; 1024 * 1024],
822
822
/// ptr: core::ptr::null_mut(),
823
823
/// }? Error)
@@ -866,7 +866,7 @@ macro_rules! try_pin_init {
866
866
/// # #[path = "../examples/error.rs"] mod error; use error::Error;
867
867
/// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;
868
868
/// # use pin_init::InPlaceInit;
869
- /// use pin_init::{init, Init, zeroed };
869
+ /// use pin_init::{init, Init, init_zeroed };
870
870
///
871
871
/// struct BigBuf {
872
872
/// small: [u8; 1024 * 1024],
@@ -875,7 +875,7 @@ macro_rules! try_pin_init {
875
875
/// impl BigBuf {
876
876
/// fn new() -> impl Init<Self> {
877
877
/// init!(Self {
878
- /// small <- zeroed (),
878
+ /// small <- init_zeroed (),
879
879
/// })
880
880
/// }
881
881
/// }
@@ -913,7 +913,7 @@ macro_rules! init {
913
913
/// # #![feature(allocator_api)]
914
914
/// # use core::alloc::AllocError;
915
915
/// # use pin_init::InPlaceInit;
916
- /// use pin_init::{try_init, Init, zeroed };
916
+ /// use pin_init::{try_init, Init, init_zeroed };
917
917
///
918
918
/// struct BigBuf {
919
919
/// big: Box<[u8; 1024 * 1024 * 1024]>,
@@ -923,7 +923,7 @@ macro_rules! init {
923
923
/// impl BigBuf {
924
924
/// fn new() -> impl Init<Self, AllocError> {
925
925
/// try_init!(Self {
926
- /// big: Box::init(zeroed ())?,
926
+ /// big: Box::init(init_zeroed ())?,
927
927
/// small: [0; 1024 * 1024],
928
928
/// }? AllocError)
929
929
/// }
@@ -1170,7 +1170,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
1170
1170
///
1171
1171
/// ```rust
1172
1172
/// # #![expect(clippy::disallowed_names)]
1173
- /// use pin_init::{init, zeroed , Init};
1173
+ /// use pin_init::{init, init_zeroed , Init};
1174
1174
///
1175
1175
/// struct Foo {
1176
1176
/// buf: [u8; 1_000_000],
@@ -1183,7 +1183,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
1183
1183
/// }
1184
1184
///
1185
1185
/// let foo = init!(Foo {
1186
- /// buf <- zeroed ()
1186
+ /// buf <- init_zeroed ()
1187
1187
/// }).chain(|foo| {
1188
1188
/// foo.setup();
1189
1189
/// Ok(())
@@ -1495,7 +1495,45 @@ pub unsafe trait PinnedDrop: __internal::HasPinData {
1495
1495
/// ```rust,ignore
1496
1496
/// let val: Self = unsafe { core::mem::zeroed() };
1497
1497
/// ```
1498
- pub unsafe trait Zeroable { }
1498
+ pub unsafe trait Zeroable {
1499
+ /// Create a new zeroed `Self`.
1500
+ ///
1501
+ /// The returned initializer will write `0x00` to every byte of the given `slot`.
1502
+ #[ inline]
1503
+ fn init_zeroed ( ) -> impl Init < Self >
1504
+ where
1505
+ Self : Sized ,
1506
+ {
1507
+ init_zeroed ( )
1508
+ }
1509
+
1510
+ /// Create a `Self` consisting of all zeroes.
1511
+ ///
1512
+ /// Whenever a type implements [`Zeroable`], this function should be preferred over
1513
+ /// [`core::mem::zeroed()`] or using `MaybeUninit<T>::zeroed().assume_init()`.
1514
+ ///
1515
+ /// # Examples
1516
+ ///
1517
+ /// ```
1518
+ /// use pin_init::{Zeroable, zeroed};
1519
+ ///
1520
+ /// #[derive(Zeroable)]
1521
+ /// struct Point {
1522
+ /// x: u32,
1523
+ /// y: u32,
1524
+ /// }
1525
+ ///
1526
+ /// let point: Point = zeroed();
1527
+ /// assert_eq!(point.x, 0);
1528
+ /// assert_eq!(point.y, 0);
1529
+ /// ```
1530
+ fn zeroed ( ) -> Self
1531
+ where
1532
+ Self : Sized ,
1533
+ {
1534
+ zeroed ( )
1535
+ }
1536
+ }
1499
1537
1500
1538
/// Marker trait for types that allow `Option<Self>` to be set to all zeroes in order to write
1501
1539
/// `None` to that location.
@@ -1508,11 +1546,21 @@ pub unsafe trait ZeroableOption {}
1508
1546
// SAFETY: by the safety requirement of `ZeroableOption`, this is valid.
1509
1547
unsafe impl < T : ZeroableOption > Zeroable for Option < T > { }
1510
1548
1511
- /// Create a new zeroed T.
1549
+ // SAFETY: `Option<&T>` is part of the option layout optimization guarantee:
1550
+ // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1551
+ unsafe impl < T > ZeroableOption for & T { }
1552
+ // SAFETY: `Option<&mut T>` is part of the option layout optimization guarantee:
1553
+ // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1554
+ unsafe impl < T > ZeroableOption for & mut T { }
1555
+ // SAFETY: `Option<NonNull<T>>` is part of the option layout optimization guarantee:
1556
+ // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1557
+ unsafe impl < T > ZeroableOption for NonNull < T > { }
1558
+
1559
+ /// Create an initializer for a zeroed `T`.
1512
1560
///
1513
1561
/// The returned initializer will write `0x00` to every byte of the given `slot`.
1514
1562
#[ inline]
1515
- pub fn zeroed < T : Zeroable > ( ) -> impl Init < T > {
1563
+ pub fn init_zeroed < T : Zeroable > ( ) -> impl Init < T > {
1516
1564
// SAFETY: Because `T: Zeroable`, all bytes zero is a valid bit pattern for `T`
1517
1565
// and because we write all zeroes, the memory is initialized.
1518
1566
unsafe {
@@ -1523,6 +1571,31 @@ pub fn zeroed<T: Zeroable>() -> impl Init<T> {
1523
1571
}
1524
1572
}
1525
1573
1574
+ /// Create a `T` consisting of all zeroes.
1575
+ ///
1576
+ /// Whenever a type implements [`Zeroable`], this function should be preferred over
1577
+ /// [`core::mem::zeroed()`] or using `MaybeUninit<T>::zeroed().assume_init()`.
1578
+ ///
1579
+ /// # Examples
1580
+ ///
1581
+ /// ```
1582
+ /// use pin_init::{Zeroable, zeroed};
1583
+ ///
1584
+ /// #[derive(Zeroable)]
1585
+ /// struct Point {
1586
+ /// x: u32,
1587
+ /// y: u32,
1588
+ /// }
1589
+ ///
1590
+ /// let point: Point = zeroed();
1591
+ /// assert_eq!(point.x, 0);
1592
+ /// assert_eq!(point.y, 0);
1593
+ /// ```
1594
+ pub const fn zeroed < T : Zeroable > ( ) -> T {
1595
+ // SAFETY:By the type invariants of `Zeroable`, all zeroes is a valid bit pattern for `T`.
1596
+ unsafe { core:: mem:: zeroed ( ) }
1597
+ }
1598
+
1526
1599
macro_rules! impl_zeroable {
1527
1600
( $( $( { $( $generics: tt) * } ) ? $t: ty, ) * ) => {
1528
1601
// SAFETY: Safety comments written in the macro invocation.
@@ -1560,7 +1633,6 @@ impl_zeroable! {
1560
1633
Option <NonZeroU128 >, Option <NonZeroUsize >,
1561
1634
Option <NonZeroI8 >, Option <NonZeroI16 >, Option <NonZeroI32 >, Option <NonZeroI64 >,
1562
1635
Option <NonZeroI128 >, Option <NonZeroIsize >,
1563
- { <T >} Option <NonNull <T >>,
1564
1636
1565
1637
// SAFETY: `null` pointer is valid.
1566
1638
//
@@ -1590,6 +1662,22 @@ macro_rules! impl_tuple_zeroable {
1590
1662
1591
1663
impl_tuple_zeroable ! ( A , B , C , D , E , F , G , H , I , J ) ;
1592
1664
1665
+ macro_rules! impl_fn_zeroable_option {
1666
+ ( [ $( $abi: literal) ,* $( , ) ?] $args: tt) => {
1667
+ $( impl_fn_zeroable_option!( { extern $abi} $args) ; ) *
1668
+ $( impl_fn_zeroable_option!( { unsafe extern $abi} $args) ; ) *
1669
+ } ;
1670
+ ( { $( $prefix: tt) * } { $( , ) ?} ) => { } ;
1671
+ ( { $( $prefix: tt) * } { $ret: ident, $( $rest: ident) ,* $( , ) ?} ) => {
1672
+ // SAFETY: function pointers are part of the option layout optimization:
1673
+ // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1674
+ unsafe impl <$ret, $( $rest) ,* > ZeroableOption for $( $prefix) * fn ( $( $rest) ,* ) -> $ret { }
1675
+ impl_fn_zeroable_option!( { $( $prefix) * } { $( $rest) ,* , } ) ;
1676
+ } ;
1677
+ }
1678
+
1679
+ impl_fn_zeroable_option ! ( [ "Rust" , "C" ] { A , B , C , D , E , F , G , H , I , J , K , L , M , N , O , P , Q , R , S , T , U } ) ;
1680
+
1593
1681
/// This trait allows creating an instance of `Self` which contains exactly one
1594
1682
/// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).
1595
1683
///
0 commit comments