summaryrefslogtreecommitdiff
path: root/embassy-hal-common
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2022-07-22 15:22:00 +0200
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2022-07-23 01:33:22 +0200
commitf9f2de3dfb131d71c4948405452e9529aea3c539 (patch)
treec0a6f588f5dc5fc824a9c66326c1da780ecfc2e0 /embassy-hal-common
parent715fa5146840a81b0ecbf35852eb3a7caf741e83 (diff)
downloadembassy-f9f2de3dfb131d71c4948405452e9529aea3c539.zip
wip
Diffstat (limited to 'embassy-hal-common')
-rw-r--r--embassy-hal-common/src/macros.rs10
-rw-r--r--embassy-hal-common/src/unborrow.rs73
2 files changed, 18 insertions, 65 deletions
diff --git a/embassy-hal-common/src/macros.rs b/embassy-hal-common/src/macros.rs
index 115325c8..7aa19790 100644
--- a/embassy-hal-common/src/macros.rs
+++ b/embassy-hal-common/src/macros.rs
@@ -82,14 +82,12 @@ macro_rules! unborrow {
#[macro_export]
macro_rules! unsafe_impl_unborrow {
($type:ident) => {
- unsafe impl $crate::Unborrow for $type {
+ impl $crate::Unborrow for $type {
type Target = $type;
+
#[inline]
- fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target>
- where
- Self: 'a,
- {
- $crate::Unborrowed::new(self)
+ unsafe fn unborrow_unchecked(&mut self) -> Self::Target {
+ $type { ..*self }
}
}
};
diff --git a/embassy-hal-common/src/unborrow.rs b/embassy-hal-common/src/unborrow.rs
index c05a070c..7ed823c5 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> {
///
/// 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 {
+pub trait Unborrow: Sized {
/// Unborrow result type
type Target;
- /// Unborrow a value.
- fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
- where
- Self: 'a;
-}
+ unsafe fn unborrow_unchecked(&mut self) -> Self::Target;
-unsafe impl<'b, T: Unborrow> Unborrow for &'b mut T {
- type Target = T::Target;
-
- fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
+ /// Unborrow a value.
+ #[inline]
+ fn unborrow<'a>(mut self) -> Unborrowed<'a, Self::Target>
where
Self: 'a,
{
- // 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.
- T::unborrow(unsafe { core::ptr::read(self) })
+ Unborrowed::new(unsafe { self.unborrow_unchecked() })
}
}
-unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> {
- type Target = T;
+impl<'b, T: DerefMut> Unborrow for T
+where
+ T::Target: Unborrow,
+{
+ type Target = <T::Target as Unborrow>::Target;
- fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
- where
- Self: 'a,
- {
- self
+ #[inline]
+ unsafe fn unborrow_unchecked(&mut self) -> Self::Target {
+ self.deref_mut().unborrow_unchecked()
}
}
-
-macro_rules! unsafe_impl_unborrow_tuples {
- ($($t:ident),+) => {
- unsafe impl<$($t),+> Unborrow for ($($t),+)
- where
- $(
- $t: Unborrow<Target = $t>
- ),+
- {
- type Target = ($($t),+);
- fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
- where
- Self: 'a
- {
- Unborrowed::new(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);