Skip to content

Commit 597493d

Browse files
committed
Make the async SpiDevice trait unsafe to implement
1 parent d8ddd73 commit 597493d

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

embedded-hal-async/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313

1414
- spi: device helper methods (`read`, `write`, `transfer`...) are now default methods in `SpiDevice` instead of an `SpiDeviceExt` extension trait.
1515
- spi: the `SpiDevice::transaction` closure now gets a raw pointer to the `SpiBus` to work around Rust borrow checker limitations.
16+
- spi: the `SpiDevice` trait is now unsafe to implement due to the raw pointer workaround.
1617

1718

1819
## [v0.1.0-alpha.0] - 2022-04-17

embedded-hal-async/src/spi.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ where
4141
/// with a CS (Chip Select) pin.
4242
///
4343
/// See (the docs on embedded-hal)[embedded_hal::spi::blocking] for important information on SPI Bus vs Device traits.
44-
pub trait SpiDevice: ErrorType {
44+
///
45+
/// # Safety
46+
///
47+
/// See [`SpiDevice::transaction`] for details.
48+
pub unsafe trait SpiDevice: ErrorType {
4549
/// SPI Bus type for this device.
4650
type Bus: ErrorType;
4751

@@ -69,9 +73,13 @@ pub trait SpiDevice: ErrorType {
6973
/// On bus errors the implementation should try to deassert CS.
7074
/// If an error occurs while deasserting CS the bus error should take priority as the return value.
7175
///
76+
/// # Safety
77+
///
7278
/// The current state of the Rust typechecker doesn't allow expressing the necessary lifetime constraints, so
73-
/// the `f` closure receives a lifetime-less `*mut Bus` raw pointer instead. The pointer is guaranteed
74-
/// to be valid for the entire duration the closure is running, so dereferencing it is safe.
79+
/// the `f` closure receives a lifetime-less `*mut Bus` raw pointer instead.
80+
///
81+
/// Implementers of the `SpiDevice` trait must guarantee that the pointer is valid and dereferencable
82+
/// for the entire duration of the closure.
7583
fn transaction<'a, R, F, Fut>(&'a mut self, f: F) -> Self::TransactionFuture<'a, R, F, Fut>
7684
where
7785
F: FnOnce(*mut Self::Bus) -> Fut + 'a,
@@ -153,7 +161,7 @@ pub trait SpiDevice: ErrorType {
153161
}
154162
}
155163

156-
impl<T: SpiDevice> SpiDevice for &mut T {
164+
unsafe impl<T: SpiDevice> SpiDevice for &mut T {
157165
type Bus = T::Bus;
158166

159167
type TransactionFuture<'a, R, F, Fut> = T::TransactionFuture<'a, R, F, Fut>
@@ -377,7 +385,7 @@ where
377385
}
378386
}
379387

380-
impl<BUS, CS> SpiDevice for ExclusiveDevice<BUS, CS>
388+
unsafe impl<BUS, CS> SpiDevice for ExclusiveDevice<BUS, CS>
381389
where
382390
BUS: SpiBusFlush,
383391
CS: OutputPin,

0 commit comments

Comments
 (0)