diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index f5cc9623..928edf0e 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs @@ -1,74 +1,13 @@ //! Misc utilities mod forever; -mod select_all; +mod select; +mod steal; +mod unborrow; mod yield_now; pub use forever::*; -pub use select_all::*; +pub use select::*; +pub use steal::*; +pub use unborrow::*; pub use yield_now::*; - -/// Unsafely unborrow an owned singleton out of a `&mut`. -/// -/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`. -/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T. -/// -/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have -/// to store pointers in the borrowed case. -/// -/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause -/// immediate UB when copied, and must not cause UB when copies are later used, provided they -/// are only used according the [`Self::unborrow`] safety contract. -/// -pub unsafe trait Unborrow { - /// Unborrow result type - type Target; - - /// Unborrow a value. - /// - /// Safety: This returns a copy of a singleton that's normally not - /// copiable. The returned copy must ONLY be used while the lifetime of `self` is - /// valid, as if it were accessed through `self` every time. - unsafe fn unborrow(self) -> Self::Target; -} - -unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T { - type Target = T::Target; - unsafe fn unborrow(self) -> Self::Target { - T::unborrow(core::ptr::read(self)) - } -} - -pub trait Steal { - unsafe fn steal() -> Self; -} - -macro_rules! unsafe_impl_unborrow_tuples { - ($($t:ident),+) => { - unsafe impl<$($t),+> Unborrow for ($($t),+) - where - $( - $t: Unborrow - ),+ - { - type Target = ($($t),+); - unsafe fn unborrow(self) -> Self::Target { - self - } - } - - - }; -} - -unsafe_impl_unborrow_tuples!(A, B); -unsafe_impl_unborrow_tuples!(A, B, C); -unsafe_impl_unborrow_tuples!(A, B, C, D); -unsafe_impl_unborrow_tuples!(A, B, C, D, E); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K); -unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L); diff --git a/embassy/src/util/select_all.rs b/embassy/src/util/select.rs similarity index 100% rename from embassy/src/util/select_all.rs rename to embassy/src/util/select.rs diff --git a/embassy/src/util/steal.rs b/embassy/src/util/steal.rs new file mode 100644 index 00000000..a0d5f135 --- /dev/null +++ b/embassy/src/util/steal.rs @@ -0,0 +1,3 @@ +pub trait Steal { + unsafe fn steal() -> Self; +} diff --git a/embassy/src/util/unborrow.rs b/embassy/src/util/unborrow.rs new file mode 100644 index 00000000..dacfa3d4 --- /dev/null +++ b/embassy/src/util/unborrow.rs @@ -0,0 +1,60 @@ +/// Unsafely unborrow an owned singleton out of a `&mut`. +/// +/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`. +/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T. +/// +/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have +/// to store pointers in the borrowed case. +/// +/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause +/// immediate UB when copied, and must not cause UB when copies are later used, provided they +/// are only used according the [`Self::unborrow`] safety contract. +/// +pub unsafe trait Unborrow { + /// Unborrow result type + type Target; + + /// Unborrow a value. + /// + /// Safety: This returns a copy of a singleton that's normally not + /// copiable. The returned copy must ONLY be used while the lifetime of `self` is + /// valid, as if it were accessed through `self` every time. + unsafe fn unborrow(self) -> Self::Target; +} + +unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T { + type Target = T::Target; + unsafe fn unborrow(self) -> Self::Target { + T::unborrow(core::ptr::read(self)) + } +} + +macro_rules! unsafe_impl_unborrow_tuples { + ($($t:ident),+) => { + unsafe impl<$($t),+> Unborrow for ($($t),+) + where + $( + $t: Unborrow + ),+ + { + type Target = ($($t),+); + unsafe fn unborrow(self) -> Self::Target { + self + } + } + + + }; +} + +unsafe_impl_unborrow_tuples!(A, B); +unsafe_impl_unborrow_tuples!(A, B, C); +unsafe_impl_unborrow_tuples!(A, B, C, D); +unsafe_impl_unborrow_tuples!(A, B, C, D, E); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K); +unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);