160b26363Sopenharmony_ci/// A pinned projection of a struct field. 260b26363Sopenharmony_ci/// 360b26363Sopenharmony_ci/// # Safety 460b26363Sopenharmony_ci/// 560b26363Sopenharmony_ci/// To make using this macro safe, three things need to be ensured: 660b26363Sopenharmony_ci/// - If the struct implements [`Drop`], the [`drop`] method is not allowed to 760b26363Sopenharmony_ci/// move the value of the field. 860b26363Sopenharmony_ci/// - If the struct wants to implement [`Unpin`], it has to do so conditionally: 960b26363Sopenharmony_ci/// The struct can only implement [`Unpin`] if the field's type is [`Unpin`]. 1060b26363Sopenharmony_ci/// - The struct must not be `#[repr(packed)]`. 1160b26363Sopenharmony_ci/// 1260b26363Sopenharmony_ci/// # Example 1360b26363Sopenharmony_ci/// 1460b26363Sopenharmony_ci/// ```rust 1560b26363Sopenharmony_ci/// use pin_utils::unsafe_pinned; 1660b26363Sopenharmony_ci/// use std::marker::Unpin; 1760b26363Sopenharmony_ci/// use std::pin::Pin; 1860b26363Sopenharmony_ci/// 1960b26363Sopenharmony_ci/// struct Foo<T> { 2060b26363Sopenharmony_ci/// field: T, 2160b26363Sopenharmony_ci/// } 2260b26363Sopenharmony_ci/// 2360b26363Sopenharmony_ci/// impl<T> Foo<T> { 2460b26363Sopenharmony_ci/// unsafe_pinned!(field: T); 2560b26363Sopenharmony_ci/// 2660b26363Sopenharmony_ci/// fn baz(mut self: Pin<&mut Self>) { 2760b26363Sopenharmony_ci/// let _: Pin<&mut T> = self.field(); // Pinned reference to the field 2860b26363Sopenharmony_ci/// } 2960b26363Sopenharmony_ci/// } 3060b26363Sopenharmony_ci/// 3160b26363Sopenharmony_ci/// impl<T: Unpin> Unpin for Foo<T> {} // Conditional Unpin impl 3260b26363Sopenharmony_ci/// ``` 3360b26363Sopenharmony_ci/// 3460b26363Sopenharmony_ci/// Note: borrowing the field multiple times requires using `.as_mut()` to 3560b26363Sopenharmony_ci/// avoid consuming the `Pin`. 3660b26363Sopenharmony_ci/// 3760b26363Sopenharmony_ci/// [`Unpin`]: core::marker::Unpin 3860b26363Sopenharmony_ci/// [`drop`]: Drop::drop 3960b26363Sopenharmony_ci#[macro_export] 4060b26363Sopenharmony_cimacro_rules! unsafe_pinned { 4160b26363Sopenharmony_ci ($f:tt: $t:ty) => ( 4260b26363Sopenharmony_ci #[allow(unsafe_code)] 4360b26363Sopenharmony_ci fn $f<'__a>( 4460b26363Sopenharmony_ci self: $crate::core_reexport::pin::Pin<&'__a mut Self> 4560b26363Sopenharmony_ci ) -> $crate::core_reexport::pin::Pin<&'__a mut $t> { 4660b26363Sopenharmony_ci unsafe { 4760b26363Sopenharmony_ci $crate::core_reexport::pin::Pin::map_unchecked_mut( 4860b26363Sopenharmony_ci self, |x| &mut x.$f 4960b26363Sopenharmony_ci ) 5060b26363Sopenharmony_ci } 5160b26363Sopenharmony_ci } 5260b26363Sopenharmony_ci ) 5360b26363Sopenharmony_ci} 5460b26363Sopenharmony_ci 5560b26363Sopenharmony_ci/// An unpinned projection of a struct field. 5660b26363Sopenharmony_ci/// 5760b26363Sopenharmony_ci/// # Safety 5860b26363Sopenharmony_ci/// 5960b26363Sopenharmony_ci/// This macro is unsafe because it creates a method that returns a normal 6060b26363Sopenharmony_ci/// non-pin reference to the struct field. It is up to the programmer to ensure 6160b26363Sopenharmony_ci/// that the contained value can be considered not pinned in the current 6260b26363Sopenharmony_ci/// context. 6360b26363Sopenharmony_ci/// 6460b26363Sopenharmony_ci/// # Example 6560b26363Sopenharmony_ci/// 6660b26363Sopenharmony_ci/// ```rust 6760b26363Sopenharmony_ci/// use pin_utils::unsafe_unpinned; 6860b26363Sopenharmony_ci/// use std::pin::Pin; 6960b26363Sopenharmony_ci/// 7060b26363Sopenharmony_ci/// struct Bar; 7160b26363Sopenharmony_ci/// struct Foo { 7260b26363Sopenharmony_ci/// field: Bar, 7360b26363Sopenharmony_ci/// } 7460b26363Sopenharmony_ci/// 7560b26363Sopenharmony_ci/// impl Foo { 7660b26363Sopenharmony_ci/// unsafe_unpinned!(field: Bar); 7760b26363Sopenharmony_ci/// 7860b26363Sopenharmony_ci/// fn baz(mut self: Pin<&mut Self>) { 7960b26363Sopenharmony_ci/// let _: &mut Bar = self.field(); // Normal reference to the field 8060b26363Sopenharmony_ci/// } 8160b26363Sopenharmony_ci/// } 8260b26363Sopenharmony_ci/// ``` 8360b26363Sopenharmony_ci/// 8460b26363Sopenharmony_ci/// Note: borrowing the field multiple times requires using `.as_mut()` to 8560b26363Sopenharmony_ci/// avoid consuming the [`Pin`]. 8660b26363Sopenharmony_ci/// 8760b26363Sopenharmony_ci/// [`Pin`]: core::pin::Pin 8860b26363Sopenharmony_ci#[macro_export] 8960b26363Sopenharmony_cimacro_rules! unsafe_unpinned { 9060b26363Sopenharmony_ci ($f:tt: $t:ty) => ( 9160b26363Sopenharmony_ci #[allow(unsafe_code)] 9260b26363Sopenharmony_ci fn $f<'__a>( 9360b26363Sopenharmony_ci self: $crate::core_reexport::pin::Pin<&'__a mut Self> 9460b26363Sopenharmony_ci ) -> &'__a mut $t { 9560b26363Sopenharmony_ci unsafe { 9660b26363Sopenharmony_ci &mut $crate::core_reexport::pin::Pin::get_unchecked_mut(self).$f 9760b26363Sopenharmony_ci } 9860b26363Sopenharmony_ci } 9960b26363Sopenharmony_ci ) 10060b26363Sopenharmony_ci} 101