172172//! # #![feature(extern_types)]
173173//! use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure};
174174//! use core::{
175- //! ptr::addr_of_mut,
176175//! marker::PhantomPinned,
177176//! cell::UnsafeCell,
178177//! pin::Pin,
211210//! unsafe {
212211//! pin_init_from_closure(move |slot: *mut Self| {
213212//! // `slot` contains uninit memory, avoid creating a reference.
214- //! let foo = addr_of_mut!(( *slot).foo) ;
213+ //! let foo = &raw mut ( *slot).foo;
215214//! let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>();
216215//!
217216//! // Initialize the `foo`
264263//! [`impl Init<T, E>`]: crate::Init
265264//! [Rust-for-Linux]: https://rust-for-linux.com/
266265
267- #![ cfg_attr( not( RUSTC_LINT_REASONS_IS_STABLE ) , feature( lint_reasons) ) ]
266+ #![ cfg_attr( USE_RUSTC_FEATURES , feature( lint_reasons) ) ]
267+ #![ cfg_attr( USE_RUSTC_FEATURES , feature( raw_ref_op) ) ]
268268#![ cfg_attr(
269- all(
270- any( feature = "alloc" , feature = "std" ) ,
271- not( RUSTC_NEW_UNINIT_IS_STABLE )
272- ) ,
269+ all( any( feature = "alloc" , feature = "std" ) , USE_RUSTC_FEATURES ) ,
273270 feature( new_uninit)
274271) ]
275272#![ forbid( missing_docs, unsafe_op_in_unsafe_fn) ]
279276 all( feature = "unsafe-pinned" , CONFIG_RUSTC_HAS_UNSAFE_PINNED ) ,
280277 feature( unsafe_pinned)
281278) ]
279+ #![ cfg_attr( all( USE_RUSTC_FEATURES , doc) , allow( internal_features) ) ]
280+ #![ cfg_attr( all( USE_RUSTC_FEATURES , doc) , feature( rustdoc_internals) ) ]
282281
283282use core:: {
284283 cell:: UnsafeCell ,
@@ -755,7 +754,7 @@ macro_rules! stack_try_pin_init {
755754///
756755/// ```rust
757756/// # use pin_init::*;
758- /// # use core::{ptr::addr_of_mut, marker::PhantomPinned} ;
757+ /// # use core::marker::PhantomPinned;
759758/// #[pin_data]
760759/// #[derive(Zeroable)]
761760/// struct Buf {
@@ -769,7 +768,7 @@ macro_rules! stack_try_pin_init {
769768/// let init = pin_init!(&this in Buf {
770769/// buf: [0; 64],
771770/// // SAFETY: TODO.
772- /// ptr: unsafe { addr_of_mut!( (*this.as_ptr()).buf).cast() },
771+ /// ptr: unsafe { (&raw mut (*this.as_ptr()).buf).cast() },
773772/// pin: PhantomPinned,
774773/// });
775774/// let init = pin_init!(Buf {
@@ -1147,9 +1146,12 @@ pub const unsafe fn cast_pin_init<T, U, E>(init: impl PinInit<T, E>) -> impl Pin
11471146 // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety
11481147 // requirements.
11491148 let res = unsafe { pin_init_from_closure ( |ptr : * mut U | init. __pinned_init ( ptr. cast :: < T > ( ) ) ) } ;
1150- // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
1151- // cycle when computing the type returned by this function)
1152- #[ allow( clippy:: let_and_return) ]
1149+ // FIXME: this let binding is required to avoid a compiler error (cycle when computing the opaque
1150+ // type returned by this function) before Rust 1.81. Remove after MSRV bump.
1151+ #[ allow(
1152+ clippy:: let_and_return,
1153+ reason = "some clippy versions warn about the let binding"
1154+ ) ]
11531155 res
11541156}
11551157
@@ -1163,9 +1165,12 @@ pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E>
11631165 // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety
11641166 // requirements.
11651167 let res = unsafe { init_from_closure ( |ptr : * mut U | init. __init ( ptr. cast :: < T > ( ) ) ) } ;
1166- // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a
1167- // cycle when computing the type returned by this function)
1168- #[ allow( clippy:: let_and_return) ]
1168+ // FIXME: this let binding is required to avoid a compiler error (cycle when computing the opaque
1169+ // type returned by this function) before Rust 1.81. Remove after MSRV bump.
1170+ #[ allow(
1171+ clippy:: let_and_return,
1172+ reason = "some clippy versions warn about the let binding"
1173+ ) ]
11691174 res
11701175}
11711176
@@ -1610,13 +1615,6 @@ impl_zeroable! {
16101615 // SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.
16111616 { <T : ?Sized + Zeroable >} UnsafeCell <T >,
16121617
1613- // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:
1614- // <https://doc.rust-lang.org/stable/std/option/index.html#representation>).
1615- Option <NonZeroU8 >, Option <NonZeroU16 >, Option <NonZeroU32 >, Option <NonZeroU64 >,
1616- Option <NonZeroU128 >, Option <NonZeroUsize >,
1617- Option <NonZeroI8 >, Option <NonZeroI16 >, Option <NonZeroI32 >, Option <NonZeroI64 >,
1618- Option <NonZeroI128 >, Option <NonZeroIsize >,
1619-
16201618 // SAFETY: `null` pointer is valid.
16211619 //
16221620 // We cannot use `T: ?Sized`, since the VTABLE pointer part of fat pointers is not allowed to be
@@ -1635,8 +1633,14 @@ impl_zeroable! {
16351633}
16361634
16371635macro_rules! impl_tuple_zeroable {
1638- ( $( , ) ?) => { } ;
1636+ ( $first: ident, $( , ) ?) => {
1637+ #[ cfg_attr( all( USE_RUSTC_FEATURES , doc) , doc( fake_variadic) ) ]
1638+ /// Implemented for tuples up to 10 items long.
1639+ // SAFETY: All elements are zeroable and padding can be zero.
1640+ unsafe impl <$first: Zeroable > Zeroable for ( $first, ) { }
1641+ } ;
16391642 ( $first: ident, $( $t: ident) ,* $( , ) ?) => {
1643+ #[ cfg_attr( doc, doc( hidden) ) ]
16401644 // SAFETY: All elements are zeroable and padding can be zero.
16411645 unsafe impl <$first: Zeroable , $( $t: Zeroable ) ,* > Zeroable for ( $first, $( $t) ,* ) { }
16421646 impl_tuple_zeroable!( $( $t) ,* , ) ;
@@ -1651,7 +1655,16 @@ macro_rules! impl_fn_zeroable_option {
16511655 $( impl_fn_zeroable_option!( { unsafe extern $abi} $args) ; ) *
16521656 } ;
16531657 ( { $( $prefix: tt) * } { $( , ) ?} ) => { } ;
1658+ ( { $( $prefix: tt) * } { $ret: ident, $arg: ident $( , ) ?} ) => {
1659+ #[ cfg_attr( all( USE_RUSTC_FEATURES , doc) , doc( fake_variadic) ) ]
1660+ /// Implemented for function pointers with up to 20 arity.
1661+ // SAFETY: function pointers are part of the option layout optimization:
1662+ // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
1663+ unsafe impl <$ret, $arg> ZeroableOption for $( $prefix) * fn ( $arg) -> $ret { }
1664+ impl_fn_zeroable_option!( { $( $prefix) * } { $arg, } ) ;
1665+ } ;
16541666 ( { $( $prefix: tt) * } { $ret: ident, $( $rest: ident) ,* $( , ) ?} ) => {
1667+ #[ cfg_attr( doc, doc( hidden) ) ]
16551668 // SAFETY: function pointers are part of the option layout optimization:
16561669 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>.
16571670 unsafe impl <$ret, $( $rest) ,* > ZeroableOption for $( $prefix) * fn ( $( $rest) ,* ) -> $ret { }
@@ -1661,6 +1674,20 @@ macro_rules! impl_fn_zeroable_option {
16611674
16621675impl_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 } ) ;
16631676
1677+ macro_rules! impl_non_zero_int_zeroable_option {
1678+ ( $( $int: ty) ,* $( , ) ?) => {
1679+ // SAFETY: Safety comment written in the macro invocation.
1680+ $( unsafe impl ZeroableOption for $int { } ) *
1681+ } ;
1682+ }
1683+
1684+ impl_non_zero_int_zeroable_option ! {
1685+ // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee:
1686+ // <https://doc.rust-lang.org/stable/std/option/index.html#representation>).
1687+ NonZeroU8 , NonZeroU16 , NonZeroU32 , NonZeroU64 , NonZeroU128 , NonZeroUsize ,
1688+ NonZeroI8 , NonZeroI16 , NonZeroI32 , NonZeroI64 , NonZeroI128 , NonZeroIsize ,
1689+ }
1690+
16641691/// This trait allows creating an instance of `Self` which contains exactly one
16651692/// [structurally pinned value](https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning).
16661693///
0 commit comments