diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-07-22 15:22:00 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-07-23 01:33:22 +0200 |
| commit | f9f2de3dfb131d71c4948405452e9529aea3c539 (patch) | |
| tree | c0a6f588f5dc5fc824a9c66326c1da780ecfc2e0 /embassy-hal-common | |
| parent | 715fa5146840a81b0ecbf35852eb3a7caf741e83 (diff) | |
wip
Diffstat (limited to 'embassy-hal-common')
| -rw-r--r-- | embassy-hal-common/src/macros.rs | 10 | ||||
| -rw-r--r-- | embassy-hal-common/src/unborrow.rs | 73 |
2 files changed, 18 insertions, 65 deletions
diff --git a/embassy-hal-common/src/macros.rs b/embassy-hal-common/src/macros.rs index 115325c82..7aa197908 100644 --- a/embassy-hal-common/src/macros.rs +++ b/embassy-hal-common/src/macros.rs | |||
| @@ -82,14 +82,12 @@ macro_rules! unborrow { | |||
| 82 | #[macro_export] | 82 | #[macro_export] |
| 83 | macro_rules! unsafe_impl_unborrow { | 83 | macro_rules! unsafe_impl_unborrow { |
| 84 | ($type:ident) => { | 84 | ($type:ident) => { |
| 85 | unsafe impl $crate::Unborrow for $type { | 85 | impl $crate::Unborrow for $type { |
| 86 | type Target = $type; | 86 | type Target = $type; |
| 87 | |||
| 87 | #[inline] | 88 | #[inline] |
| 88 | fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target> | 89 | unsafe fn unborrow_unchecked(&mut self) -> Self::Target { |
| 89 | where | 90 | $type { ..*self } |
| 90 | Self: 'a, | ||
| 91 | { | ||
| 92 | $crate::Unborrowed::new(self) | ||
| 93 | } | 91 | } |
| 94 | } | 92 | } |
| 95 | }; | 93 | }; |
diff --git a/embassy-hal-common/src/unborrow.rs b/embassy-hal-common/src/unborrow.rs index c05a070c9..7ed823c52 100644 --- a/embassy-hal-common/src/unborrow.rs +++ b/embassy-hal-common/src/unborrow.rs | |||
| @@ -43,75 +43,30 @@ impl<'a, T> DerefMut for Unborrowed<'a, T> { | |||
| 43 | /// | 43 | /// |
| 44 | /// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have | 44 | /// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have |
| 45 | /// to store pointers in the borrowed case. | 45 | /// to store pointers in the borrowed case. |
| 46 | /// | 46 | pub trait Unborrow: Sized { |
| 47 | /// Safety: this trait can be used to copy non-Copy types. Implementors must not cause | ||
| 48 | /// immediate UB when copied, and must not cause UB when copies are later used, provided they | ||
| 49 | /// are only used according the [`Self::unborrow`] safety contract. | ||
| 50 | /// | ||
| 51 | pub unsafe trait Unborrow { | ||
| 52 | /// Unborrow result type | 47 | /// Unborrow result type |
| 53 | type Target; | 48 | type Target; |
| 54 | 49 | ||
| 55 | /// Unborrow a value. | 50 | unsafe fn unborrow_unchecked(&mut self) -> Self::Target; |
| 56 | fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> | ||
| 57 | where | ||
| 58 | Self: 'a; | ||
| 59 | } | ||
| 60 | 51 | ||
| 61 | unsafe impl<'b, T: Unborrow> Unborrow for &'b mut T { | 52 | /// Unborrow a value. |
| 62 | type Target = T::Target; | 53 | #[inline] |
| 63 | 54 | fn unborrow<'a>(mut self) -> Unborrowed<'a, Self::Target> | |
| 64 | fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> | ||
| 65 | where | 55 | where |
| 66 | Self: 'a, | 56 | Self: 'a, |
| 67 | { | 57 | { |
| 68 | // Safety: This returns a copy of a singleton that's normally not | 58 | Unborrowed::new(unsafe { self.unborrow_unchecked() }) |
| 69 | // copiable. The returned copy must ONLY be used while the lifetime of `self` is | ||
| 70 | // valid, as if it were accessed through `self` every time. | ||
| 71 | T::unborrow(unsafe { core::ptr::read(self) }) | ||
| 72 | } | 59 | } |
| 73 | } | 60 | } |
| 74 | 61 | ||
| 75 | unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> { | 62 | impl<'b, T: DerefMut> Unborrow for T |
| 76 | type Target = T; | 63 | where |
| 64 | T::Target: Unborrow, | ||
| 65 | { | ||
| 66 | type Target = <T::Target as Unborrow>::Target; | ||
| 77 | 67 | ||
| 78 | fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> | 68 | #[inline] |
| 79 | where | 69 | unsafe fn unborrow_unchecked(&mut self) -> Self::Target { |
| 80 | Self: 'a, | 70 | self.deref_mut().unborrow_unchecked() |
| 81 | { | ||
| 82 | self | ||
| 83 | } | 71 | } |
| 84 | } | 72 | } |
| 85 | |||
| 86 | macro_rules! unsafe_impl_unborrow_tuples { | ||
| 87 | ($($t:ident),+) => { | ||
| 88 | unsafe impl<$($t),+> Unborrow for ($($t),+) | ||
| 89 | where | ||
| 90 | $( | ||
| 91 | $t: Unborrow<Target = $t> | ||
| 92 | ),+ | ||
| 93 | { | ||
| 94 | type Target = ($($t),+); | ||
| 95 | fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> | ||
| 96 | where | ||
| 97 | Self: 'a | ||
| 98 | { | ||
| 99 | Unborrowed::new(self) | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | |||
| 104 | }; | ||
| 105 | } | ||
| 106 | |||
| 107 | unsafe_impl_unborrow_tuples!(A, B); | ||
| 108 | unsafe_impl_unborrow_tuples!(A, B, C); | ||
| 109 | unsafe_impl_unborrow_tuples!(A, B, C, D); | ||
| 110 | unsafe_impl_unborrow_tuples!(A, B, C, D, E); | ||
| 111 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F); | ||
| 112 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G); | ||
| 113 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H); | ||
| 114 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I); | ||
| 115 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J); | ||
| 116 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K); | ||
| 117 | unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L); | ||
