aboutsummaryrefslogtreecommitdiff
path: root/embassy-hal-common
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-07-22 15:22:00 +0200
committerDario Nieuwenhuis <[email protected]>2022-07-23 01:33:22 +0200
commitf9f2de3dfb131d71c4948405452e9529aea3c539 (patch)
treec0a6f588f5dc5fc824a9c66326c1da780ecfc2e0 /embassy-hal-common
parent715fa5146840a81b0ecbf35852eb3a7caf741e83 (diff)
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 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]
83macro_rules! unsafe_impl_unborrow { 83macro_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/// 46pub 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///
51pub 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
61unsafe 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
75unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> { 62impl<'b, T: DerefMut> Unborrow for T
76 type Target = T; 63where
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
86macro_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
107unsafe_impl_unborrow_tuples!(A, B);
108unsafe_impl_unborrow_tuples!(A, B, C);
109unsafe_impl_unborrow_tuples!(A, B, C, D);
110unsafe_impl_unborrow_tuples!(A, B, C, D, E);
111unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
112unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
113unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
114unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
115unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
116unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
117unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);