aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-05-20 04:14:38 +0200
committerGitHub <[email protected]>2021-05-20 04:14:38 +0200
commitb5cdd296dd875c42974e85671473efeaadd70345 (patch)
treef97cc2fdcc44058d1f0c1a53d94522dd802e0de8
parent63cceb2a53502e2b503c897e690b6c619ab14795 (diff)
parent1c0ad538410b61f8011c7d8facd136a85138be61 (diff)
Merge pull request #195 from embassy-rs/unborrow-mk2
Unborrow fixes
-rw-r--r--embassy-extras/src/macros.rs22
-rw-r--r--embassy-macros/src/lib.rs9
-rw-r--r--embassy-nrf/src/gpio.rs8
-rw-r--r--embassy-nrf/src/gpiote.rs4
-rw-r--r--embassy-nrf/src/ppi.rs8
-rw-r--r--embassy-nrf/src/saadc.rs2
-rw-r--r--embassy-rp/src/gpio.rs4
-rw-r--r--embassy-stm32/src/exti.rs4
-rw-r--r--embassy-stm32/src/gpio.rs6
-rw-r--r--embassy/src/util/mod.rs65
10 files changed, 62 insertions, 70 deletions
diff --git a/embassy-extras/src/macros.rs b/embassy-extras/src/macros.rs
index fba752619..771db40f6 100644
--- a/embassy-extras/src/macros.rs
+++ b/embassy-extras/src/macros.rs
@@ -16,7 +16,7 @@ macro_rules! peripherals {
16 } 16 }
17 17
18 $(#[$cfg])? 18 $(#[$cfg])?
19 impl embassy::util::Unborrow for $name { 19 unsafe impl embassy::util::Unborrow for $name {
20 type Target = $name; 20 type Target = $name;
21 #[inline] 21 #[inline]
22 unsafe fn unborrow(self) -> $name { 22 unsafe fn unborrow(self) -> $name {
@@ -24,14 +24,6 @@ macro_rules! peripherals {
24 } 24 }
25 } 25 }
26 26
27 $(#[$cfg])?
28 impl embassy::util::Unborrow for &mut $name {
29 type Target = $name;
30 #[inline]
31 unsafe fn unborrow(self) -> $name {
32 ::core::ptr::read(self)
33 }
34 }
35 )* 27 )*
36 } 28 }
37 29
@@ -86,23 +78,15 @@ macro_rules! unborrow {
86} 78}
87 79
88#[macro_export] 80#[macro_export]
89macro_rules! impl_unborrow { 81macro_rules! unsafe_impl_unborrow {
90 ($type:ident) => { 82 ($type:ident) => {
91 impl ::embassy::util::Unborrow for $type { 83 unsafe impl ::embassy::util::Unborrow for $type {
92 type Target = $type; 84 type Target = $type;
93 #[inline] 85 #[inline]
94 unsafe fn unborrow(self) -> Self::Target { 86 unsafe fn unborrow(self) -> Self::Target {
95 self 87 self
96 } 88 }
97 } 89 }
98
99 impl<'a> ::embassy::util::Unborrow for &'a mut $type {
100 type Target = $type;
101 #[inline]
102 unsafe fn unborrow(self) -> Self::Target {
103 unsafe { ::core::ptr::read(self) }
104 }
105 }
106 }; 90 };
107} 91}
108 92
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index c2f928b93..d23526aa2 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -210,19 +210,12 @@ pub fn interrupt_declare(item: TokenStream) -> TokenStream {
210 } 210 }
211 } 211 }
212 212
213 impl ::embassy::util::Unborrow for #name_interrupt { 213 unsafe impl ::embassy::util::Unborrow for #name_interrupt {
214 type Target = #name_interrupt; 214 type Target = #name_interrupt;
215 unsafe fn unborrow(self) -> #name_interrupt { 215 unsafe fn unborrow(self) -> #name_interrupt {
216 self 216 self
217 } 217 }
218 } 218 }
219
220 impl ::embassy::util::Unborrow for &mut #name_interrupt {
221 type Target = #name_interrupt;
222 unsafe fn unborrow(self) -> #name_interrupt {
223 ::core::ptr::read(self)
224 }
225 }
226 }; 219 };
227 result.into() 220 result.into()
228} 221}
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index 223247d60..3ae160ca8 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -5,7 +5,7 @@ use core::hint::unreachable_unchecked;
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6 6
7use embassy::util::Unborrow; 7use embassy::util::Unborrow;
8use embassy_extras::{impl_unborrow, unborrow}; 8use embassy_extras::{unborrow, unsafe_impl_unborrow};
9use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 9use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
10use gpio::pin_cnf::DRIVE_A; 10use gpio::pin_cnf::DRIVE_A;
11 11
@@ -330,7 +330,7 @@ pub(crate) mod sealed {
330 pub trait OptionalPin {} 330 pub trait OptionalPin {}
331} 331}
332 332
333pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized { 333pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized + 'static {
334 /// Number of the pin within the port (0..31) 334 /// Number of the pin within the port (0..31)
335 #[inline] 335 #[inline]
336 fn pin(&self) -> u8 { 336 fn pin(&self) -> u8 {
@@ -374,7 +374,7 @@ impl AnyPin {
374 } 374 }
375} 375}
376 376
377impl_unborrow!(AnyPin); 377unsafe_impl_unborrow!(AnyPin);
378impl Pin for AnyPin {} 378impl Pin for AnyPin {}
379impl sealed::Pin for AnyPin { 379impl sealed::Pin for AnyPin {
380 #[inline] 380 #[inline]
@@ -469,7 +469,7 @@ impl<T: Pin> OptionalPin for T {
469 469
470#[derive(Clone, Copy, Debug)] 470#[derive(Clone, Copy, Debug)]
471pub struct NoPin; 471pub struct NoPin;
472impl_unborrow!(NoPin); 472unsafe_impl_unborrow!(NoPin);
473impl sealed::OptionalPin for NoPin {} 473impl sealed::OptionalPin for NoPin {}
474impl OptionalPin for NoPin { 474impl OptionalPin for NoPin {
475 type Pin = AnyPin; 475 type Pin = AnyPin;
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 7e0220e79..2ef26e36a 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -5,7 +5,7 @@ use core::task::{Context, Poll};
5use embassy::interrupt::{Interrupt, InterruptExt}; 5use embassy::interrupt::{Interrupt, InterruptExt};
6use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow}; 6use embassy::traits::gpio::{WaitForAnyEdge, WaitForHigh, WaitForLow};
7use embassy::util::AtomicWaker; 7use embassy::util::AtomicWaker;
8use embassy_extras::impl_unborrow; 8use embassy_extras::unsafe_impl_unborrow;
9use embedded_hal::digital::v2::{InputPin, StatefulOutputPin}; 9use embedded_hal::digital::v2::{InputPin, StatefulOutputPin};
10use futures::future::poll_fn; 10use futures::future::poll_fn;
11 11
@@ -382,7 +382,7 @@ pub trait Channel: sealed::Channel + Sized {
382pub struct AnyChannel { 382pub struct AnyChannel {
383 number: u8, 383 number: u8,
384} 384}
385impl_unborrow!(AnyChannel); 385unsafe_impl_unborrow!(AnyChannel);
386impl sealed::Channel for AnyChannel {} 386impl sealed::Channel for AnyChannel {}
387impl Channel for AnyChannel { 387impl Channel for AnyChannel {
388 fn number(&self) -> usize { 388 fn number(&self) -> usize {
diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs
index e8bcbd603..c91a69c10 100644
--- a/embassy-nrf/src/ppi.rs
+++ b/embassy-nrf/src/ppi.rs
@@ -12,7 +12,7 @@
12use core::marker::PhantomData; 12use core::marker::PhantomData;
13use core::ptr::NonNull; 13use core::ptr::NonNull;
14use embassy::util::Unborrow; 14use embassy::util::Unborrow;
15use embassy_extras::{impl_unborrow, unborrow}; 15use embassy_extras::{unborrow, unsafe_impl_unborrow};
16 16
17use crate::{pac, peripherals}; 17use crate::{pac, peripherals};
18 18
@@ -146,7 +146,7 @@ pub trait Group: sealed::Group + Sized {
146pub struct AnyChannel { 146pub struct AnyChannel {
147 number: u8, 147 number: u8,
148} 148}
149impl_unborrow!(AnyChannel); 149unsafe_impl_unborrow!(AnyChannel);
150impl sealed::Channel for AnyChannel {} 150impl sealed::Channel for AnyChannel {}
151impl Channel for AnyChannel { 151impl Channel for AnyChannel {
152 fn number(&self) -> usize { 152 fn number(&self) -> usize {
@@ -157,7 +157,7 @@ impl Channel for AnyChannel {
157pub struct AnyConfigurableChannel { 157pub struct AnyConfigurableChannel {
158 number: u8, 158 number: u8,
159} 159}
160impl_unborrow!(AnyConfigurableChannel); 160unsafe_impl_unborrow!(AnyConfigurableChannel);
161impl sealed::Channel for AnyConfigurableChannel {} 161impl sealed::Channel for AnyConfigurableChannel {}
162impl sealed::ConfigurableChannel for AnyConfigurableChannel {} 162impl sealed::ConfigurableChannel for AnyConfigurableChannel {}
163impl ConfigurableChannel for AnyConfigurableChannel {} 163impl ConfigurableChannel for AnyConfigurableChannel {}
@@ -226,7 +226,7 @@ impl_channel!(PPI_CH31, 31);
226pub struct AnyGroup { 226pub struct AnyGroup {
227 number: u8, 227 number: u8,
228} 228}
229impl_unborrow!(AnyGroup); 229unsafe_impl_unborrow!(AnyGroup);
230impl sealed::Group for AnyGroup {} 230impl sealed::Group for AnyGroup {}
231impl Group for AnyGroup { 231impl Group for AnyGroup {
232 fn number(&self) -> usize { 232 fn number(&self) -> usize {
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 65276a309..c1afd00de 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -190,7 +190,7 @@ impl<'d, T: PositivePin> Sample for OneShot<'d, T> {
190/// A pin that can be used as the positive end of a ADC differential in the SAADC periperhal. 190/// A pin that can be used as the positive end of a ADC differential in the SAADC periperhal.
191/// 191///
192/// Currently negative is always shorted to ground (0V). 192/// Currently negative is always shorted to ground (0V).
193pub trait PositivePin { 193pub trait PositivePin: Unborrow<Target = Self> {
194 fn channel(&self) -> PositiveChannel; 194 fn channel(&self) -> PositiveChannel;
195} 195}
196 196
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index ecfad1878..88d5d0936 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -6,7 +6,7 @@ use crate::pac::SIO;
6use crate::peripherals; 6use crate::peripherals;
7 7
8use embassy::util::Unborrow; 8use embassy::util::Unborrow;
9use embassy_extras::{impl_unborrow, unborrow}; 9use embassy_extras::{unborrow, unsafe_impl_unborrow};
10use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 10use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
11 11
12/// Represents a digital input or output level. 12/// Represents a digital input or output level.
@@ -209,7 +209,7 @@ pub trait Pin: sealed::Pin {
209pub struct AnyPin { 209pub struct AnyPin {
210 pin_bank: u8, 210 pin_bank: u8,
211} 211}
212impl_unborrow!(AnyPin); 212unsafe_impl_unborrow!(AnyPin);
213impl Pin for AnyPin {} 213impl Pin for AnyPin {}
214impl sealed::Pin for AnyPin { 214impl sealed::Pin for AnyPin {
215 fn pin_bank(&self) -> u8 { 215 fn pin_bank(&self) -> u8 {
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index fb1c6cd39..418e56fc0 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -7,7 +7,7 @@ use core::task::{Context, Poll};
7use embassy::interrupt::{Interrupt, InterruptExt}; 7use embassy::interrupt::{Interrupt, InterruptExt};
8use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge}; 8use embassy::traits::gpio::{WaitForAnyEdge, WaitForFallingEdge, WaitForRisingEdge};
9use embassy::util::{AtomicWaker, Unborrow}; 9use embassy::util::{AtomicWaker, Unborrow};
10use embassy_extras::impl_unborrow; 10use embassy_extras::unsafe_impl_unborrow;
11use embedded_hal::digital::v2::InputPin; 11use embedded_hal::digital::v2::InputPin;
12use pac::exti::{regs, vals}; 12use pac::exti::{regs, vals};
13 13
@@ -214,7 +214,7 @@ pub trait Channel: sealed::Channel + Sized {
214pub struct AnyChannel { 214pub struct AnyChannel {
215 number: u8, 215 number: u8,
216} 216}
217impl_unborrow!(AnyChannel); 217unsafe_impl_unborrow!(AnyChannel);
218impl sealed::Channel for AnyChannel {} 218impl sealed::Channel for AnyChannel {}
219impl Channel for AnyChannel { 219impl Channel for AnyChannel {
220 fn number(&self) -> usize { 220 fn number(&self) -> usize {
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index d36d4a29d..9dc5858c8 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -2,7 +2,7 @@
2use core::convert::Infallible; 2use core::convert::Infallible;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use embassy::util::Unborrow; 4use embassy::util::Unborrow;
5use embassy_extras::{impl_unborrow, unborrow}; 5use embassy_extras::{unborrow, unsafe_impl_unborrow};
6use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 6use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
7 7
8use crate::pac; 8use crate::pac;
@@ -254,7 +254,7 @@ impl AnyPin {
254 } 254 }
255} 255}
256 256
257impl_unborrow!(AnyPin); 257unsafe_impl_unborrow!(AnyPin);
258impl Pin for AnyPin { 258impl Pin for AnyPin {
259 type ExtiChannel = crate::exti::AnyChannel; 259 type ExtiChannel = crate::exti::AnyChannel;
260} 260}
@@ -297,7 +297,7 @@ impl<T: Pin> OptionalPin for T {
297 297
298#[derive(Clone, Copy, Debug)] 298#[derive(Clone, Copy, Debug)]
299pub struct NoPin; 299pub struct NoPin;
300impl_unborrow!(NoPin); 300unsafe_impl_unborrow!(NoPin);
301impl sealed::OptionalPin for NoPin {} 301impl sealed::OptionalPin for NoPin {}
302impl OptionalPin for NoPin { 302impl OptionalPin for NoPin {
303 type Pin = AnyPin; 303 type Pin = AnyPin;
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs
index 7de15d4ad..88ae5c285 100644
--- a/embassy/src/util/mod.rs
+++ b/embassy/src/util/mod.rs
@@ -17,18 +17,44 @@ pub use portal::*;
17pub use signal::*; 17pub use signal::*;
18pub use waker::*; 18pub use waker::*;
19 19
20pub trait Unborrow { 20/// Unsafely unborrow an owned singleton out of a `&mut`.
21///
22/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
23/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T.
24///
25/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
26/// to store pointers in the borrowed case.
27///
28/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause
29/// immediate UB when copied, and must not cause UB when copies are later used, provided they
30/// are only used according the [`Self::unborrow`] safety contract.
31///
32pub unsafe trait Unborrow {
33 /// Unborrow result type
21 type Target; 34 type Target;
35
36 /// Unborrow a value.
37 ///
38 /// Safety: This returns a copy of a singleton that's normally not
39 /// copiable. The returned copy must ONLY be used while the lifetime of `self` is
40 /// valid, as if it were accessed through `self` every time.
22 unsafe fn unborrow(self) -> Self::Target; 41 unsafe fn unborrow(self) -> Self::Target;
23} 42}
24 43
44unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T {
45 type Target = T::Target;
46 unsafe fn unborrow(self) -> Self::Target {
47 T::unborrow(core::ptr::read(self))
48 }
49}
50
25pub trait Steal { 51pub trait Steal {
26 unsafe fn steal() -> Self; 52 unsafe fn steal() -> Self;
27} 53}
28 54
29macro_rules! impl_unborrow_tuples { 55macro_rules! unsafe_impl_unborrow_tuples {
30 ($($t:ident),+) => { 56 ($($t:ident),+) => {
31 impl<$($t),+> Unborrow for ($($t),+) 57 unsafe impl<$($t),+> Unborrow for ($($t),+)
32 where 58 where
33 $( 59 $(
34 $t: Unborrow<Target = $t> 60 $t: Unborrow<Target = $t>
@@ -40,29 +66,18 @@ macro_rules! impl_unborrow_tuples {
40 } 66 }
41 } 67 }
42 68
43 impl<'a, $($t),+> Unborrow for &'a mut($($t),+)
44 where
45 $(
46 $t: Unborrow<Target = $t>
47 ),+
48 {
49 type Target = ($($t),+);
50 unsafe fn unborrow(self) -> Self::Target {
51 ::core::ptr::read(self)
52 }
53 }
54 69
55 }; 70 };
56} 71}
57 72
58impl_unborrow_tuples!(A, B); 73unsafe_impl_unborrow_tuples!(A, B);
59impl_unborrow_tuples!(A, B, C); 74unsafe_impl_unborrow_tuples!(A, B, C);
60impl_unborrow_tuples!(A, B, C, D); 75unsafe_impl_unborrow_tuples!(A, B, C, D);
61impl_unborrow_tuples!(A, B, C, D, E); 76unsafe_impl_unborrow_tuples!(A, B, C, D, E);
62impl_unborrow_tuples!(A, B, C, D, E, F); 77unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
63impl_unborrow_tuples!(A, B, C, D, E, F, G); 78unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
64impl_unborrow_tuples!(A, B, C, D, E, F, G, H); 79unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
65impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I); 80unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
66impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J); 81unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
67impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K); 82unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
68impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L); 83unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);