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