1 | /// A pinned projection of a struct field. |
2 | /// |
3 | /// # Safety |
4 | /// |
5 | /// To make using this macro safe, three things need to be ensured: |
6 | /// - If the struct implements [`Drop`], the [`drop`] method is not allowed to |
7 | /// move the value of the field. |
8 | /// - If the struct wants to implement [`Unpin`], it has to do so conditionally: |
9 | /// The struct can only implement [`Unpin`] if the field's type is [`Unpin`]. |
10 | /// - The struct must not be `#[repr(packed)]`. |
11 | /// |
12 | /// # Example |
13 | /// |
14 | /// ```rust |
15 | /// use pin_utils::unsafe_pinned; |
16 | /// use std::marker::Unpin; |
17 | /// use std::pin::Pin; |
18 | /// |
19 | /// struct Foo<T> { |
20 | /// field: T, |
21 | /// } |
22 | /// |
23 | /// impl<T> Foo<T> { |
24 | /// unsafe_pinned!(field: T); |
25 | /// |
26 | /// fn baz(mut self: Pin<&mut Self>) { |
27 | /// let _: Pin<&mut T> = self.field(); // Pinned reference to the field |
28 | /// } |
29 | /// } |
30 | /// |
31 | /// impl<T: Unpin> Unpin for Foo<T> {} // Conditional Unpin impl |
32 | /// ``` |
33 | /// |
34 | /// Note: borrowing the field multiple times requires using `.as_mut()` to |
35 | /// avoid consuming the `Pin`. |
36 | /// |
37 | /// [`Unpin`]: core::marker::Unpin |
38 | /// [`drop`]: Drop::drop |
39 | #[macro_export ] |
40 | macro_rules! unsafe_pinned { |
41 | ($f:tt: $t:ty) => ( |
42 | #[allow(unsafe_code)] |
43 | fn $f<'__a>( |
44 | self: $crate::core_reexport::pin::Pin<&'__a mut Self> |
45 | ) -> $crate::core_reexport::pin::Pin<&'__a mut $t> { |
46 | unsafe { |
47 | $crate::core_reexport::pin::Pin::map_unchecked_mut( |
48 | self, |x| &mut x.$f |
49 | ) |
50 | } |
51 | } |
52 | ) |
53 | } |
54 | |
55 | /// An unpinned projection of a struct field. |
56 | /// |
57 | /// # Safety |
58 | /// |
59 | /// This macro is unsafe because it creates a method that returns a normal |
60 | /// non-pin reference to the struct field. It is up to the programmer to ensure |
61 | /// that the contained value can be considered not pinned in the current |
62 | /// context. |
63 | /// |
64 | /// # Example |
65 | /// |
66 | /// ```rust |
67 | /// use pin_utils::unsafe_unpinned; |
68 | /// use std::pin::Pin; |
69 | /// |
70 | /// struct Bar; |
71 | /// struct Foo { |
72 | /// field: Bar, |
73 | /// } |
74 | /// |
75 | /// impl Foo { |
76 | /// unsafe_unpinned!(field: Bar); |
77 | /// |
78 | /// fn baz(mut self: Pin<&mut Self>) { |
79 | /// let _: &mut Bar = self.field(); // Normal reference to the field |
80 | /// } |
81 | /// } |
82 | /// ``` |
83 | /// |
84 | /// Note: borrowing the field multiple times requires using `.as_mut()` to |
85 | /// avoid consuming the [`Pin`]. |
86 | /// |
87 | /// [`Pin`]: core::pin::Pin |
88 | #[macro_export ] |
89 | macro_rules! unsafe_unpinned { |
90 | ($f:tt: $t:ty) => ( |
91 | #[allow(unsafe_code)] |
92 | fn $f<'__a>( |
93 | self: $crate::core_reexport::pin::Pin<&'__a mut Self> |
94 | ) -> &'__a mut $t { |
95 | unsafe { |
96 | &mut $crate::core_reexport::pin::Pin::get_unchecked_mut(self).$f |
97 | } |
98 | } |
99 | ) |
100 | } |
101 | |