Skip to content

Commit 812471b

Browse files
bors[bot]Dirbaio
andauthored
Merge #407
407: async: switch to async-fn-in-traits, release v0.2.0-alpha.0 r=eldruin a=Dirbaio Latest Rust nightlies have somewhat usable async-fn-in-trait support already! 🎉 embassy-nrf updated here embassy-rs/embassy#974 Paprecuts encountered: - there's this annoying error [playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=f04fca1f2a3d643c323fb49c05bd3ed3), workaround is to use the concrete type instead of `Self::Error`. This is a limitation of all `async fn`s, not just in traits, but it hits especially hard within traits, so I dunno if there's plans to improve it. > `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - The SpiDevice trait ICEs, issue filed rust-lang/rust#102310 - default methods don't work, but there's a PR already rust-lang/rust#102308 Due to the last 2 I've left `SpiDevice` alone for now. Co-authored-by: Dario Nieuwenhuis <[email protected]>
2 parents aa86d21 + ad0b9f2 commit 812471b

File tree

9 files changed

+95
-261
lines changed

9 files changed

+95
-261
lines changed

.github/workflows/clippy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
profile: minimal
1515
# embedded-hal-async needs nightly.
1616
# Use a pinned version to avoid spontaneous breakages (new clippy lints are added often)
17-
toolchain: nightly-2022-09-25
17+
toolchain: nightly-2022-11-22
1818
override: true
1919
components: clippy
2020
- run: cargo clippy -- --deny=warnings

embedded-hal-async/CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
## [v0.2.0-alpha.0] - 2022-11-23
11+
12+
- Switch all traits to use [`async_fn_in_trait`](https://blog.rust-lang.org/inside-rust/2022/11/17/async-fn-in-trait-nightly.html) (AFIT). Requires `nightly-2022-11-22` or newer.
1013

1114
## [v0.1.0-alpha.3] - 2022-10-26
1215

@@ -34,7 +37,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3437
First release to crates.io
3538

3639

37-
[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.1.0-alpha.3...HEAD
40+
[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.2.0-alpha.0...HEAD
41+
[v0.2.0-alpha.0]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.1.0-alpha.3...embedded-hal-async-v0.2.0-alpha.0
3842
[v0.1.0-alpha.3]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.1.0-alpha.2...embedded-hal-async-v0.1.0-alpha.3
3943
[v0.1.0-alpha.2]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.1.0-alpha.1...embedded-hal-async-v0.1.0-alpha.2
4044
[v0.1.0-alpha.1]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.1.0-alpha.0...embedded-hal-async-v0.1.0-alpha.1

embedded-hal-async/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0"
1111
name = "embedded-hal-async"
1212
readme = "README.md"
1313
repository = "https://github.com/rust-embedded/embedded-hal"
14-
version = "0.1.0-alpha.3"
14+
version = "0.2.0-alpha.0"
1515

1616
[dependencies]
1717
embedded-hal = { version = "=1.0.0-alpha.9", path = "../embedded-hal" }

embedded-hal-async/src/delay.rs

+6-22
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,17 @@
11
//! Delays
22
3-
use core::future::Future;
4-
53
/// Microsecond delay
64
pub trait DelayUs {
75
/// Enumeration of errors
86
type Error: core::fmt::Debug;
97

10-
/// The future returned by the `delay_us` function.
11-
type DelayUsFuture<'a>: Future<Output = Result<(), Self::Error>>
12-
where
13-
Self: 'a;
14-
158
/// Pauses execution for at minimum `us` microseconds. Pause can be longer
169
/// if the implementation requires it due to precision/timing issues.
17-
fn delay_us(&mut self, us: u32) -> Self::DelayUsFuture<'_>;
18-
19-
/// The future returned by the `delay_ms` function.
20-
type DelayMsFuture<'a>: Future<Output = Result<(), Self::Error>>
21-
where
22-
Self: 'a;
10+
async fn delay_us(&mut self, us: u32) -> Result<(), Self::Error>;
2311

2412
/// Pauses execution for at minimum `ms` milliseconds. Pause can be longer
2513
/// if the implementation requires it due to precision/timing issues.
26-
fn delay_ms(&mut self, ms: u32) -> Self::DelayMsFuture<'_>;
14+
async fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error>;
2715
}
2816

2917
impl<T> DelayUs for &mut T
@@ -32,15 +20,11 @@ where
3220
{
3321
type Error = T::Error;
3422

35-
type DelayUsFuture<'a> = T::DelayUsFuture<'a> where Self: 'a;
36-
37-
fn delay_us(&mut self, us: u32) -> Self::DelayUsFuture<'_> {
38-
T::delay_us(self, us)
23+
async fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
24+
T::delay_us(self, us).await
3925
}
4026

41-
type DelayMsFuture<'a> = T::DelayMsFuture<'a> where Self: 'a;
42-
43-
fn delay_ms(&mut self, ms: u32) -> Self::DelayMsFuture<'_> {
44-
T::delay_ms(self, ms)
27+
async fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
28+
T::delay_ms(self, ms).await
4529
}
4630
}

embedded-hal-async/src/digital.rs

+15-52
Original file line numberDiff line numberDiff line change
@@ -16,93 +16,56 @@
1616
//! }
1717
//! ```
1818
19-
use core::future::Future;
20-
2119
/// Asynchronously wait for GPIO pin state.
2220
pub trait Wait: embedded_hal::digital::ErrorType {
23-
/// The future returned by the `wait_for_high` function.
24-
type WaitForHighFuture<'a>: Future<Output = Result<(), Self::Error>>
25-
where
26-
Self: 'a;
27-
2821
/// Wait until the pin is high. If it is already high, return immediately.
2922
///
3023
/// # Note for implementers
3124
/// The pin may have switched back to low before the task was run after
3225
/// being woken. The future should still resolve in that case.
33-
fn wait_for_high(&mut self) -> Self::WaitForHighFuture<'_>;
34-
35-
/// The future returned by `wait_for_low`.
36-
type WaitForLowFuture<'a>: Future<Output = Result<(), Self::Error>>
37-
where
38-
Self: 'a;
26+
async fn wait_for_high(&mut self) -> Result<(), Self::Error>;
3927

4028
/// Wait until the pin is low. If it is already low, return immediately.
4129
///
4230
/// # Note for implementers
4331
/// The pin may have switched back to high before the task was run after
4432
/// being woken. The future should still resolve in that case.
45-
fn wait_for_low(&mut self) -> Self::WaitForLowFuture<'_>;
46-
47-
/// The future returned from `wait_for_rising_edge`.
48-
type WaitForRisingEdgeFuture<'a>: Future<Output = Result<(), Self::Error>>
49-
where
50-
Self: 'a;
33+
async fn wait_for_low(&mut self) -> Result<(), Self::Error>;
5134

5235
/// Wait for the pin to undergo a transition from low to high.
5336
///
5437
/// If the pin is already high, this does *not* return immediately, it'll wait for the
5538
/// pin to go low and then high again.
56-
fn wait_for_rising_edge(&mut self) -> Self::WaitForRisingEdgeFuture<'_>;
57-
58-
/// The future returned from `wait_for_falling_edge`.
59-
type WaitForFallingEdgeFuture<'a>: Future<Output = Result<(), Self::Error>>
60-
where
61-
Self: 'a;
39+
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error>;
6240

6341
/// Wait for the pin to undergo a transition from high to low.
6442
///
6543
/// If the pin is already low, this does *not* return immediately, it'll wait for the
6644
/// pin to go high and then low again.
67-
fn wait_for_falling_edge(&mut self) -> Self::WaitForFallingEdgeFuture<'_>;
68-
69-
/// The future returned from `wait_for_any_edge`.
70-
type WaitForAnyEdgeFuture<'a>: Future<Output = Result<(), Self::Error>>
71-
where
72-
Self: 'a;
45+
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error>;
7346

7447
/// Wait for the pin to undergo any transition, i.e low to high OR high to low.
75-
fn wait_for_any_edge(&mut self) -> Self::WaitForAnyEdgeFuture<'_>;
48+
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error>;
7649
}
7750

7851
impl<T: Wait> Wait for &mut T {
79-
type WaitForHighFuture<'a> = T::WaitForHighFuture<'a> where Self: 'a;
80-
81-
fn wait_for_high(&mut self) -> Self::WaitForHighFuture<'_> {
82-
T::wait_for_high(self)
52+
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
53+
T::wait_for_high(self).await
8354
}
8455

85-
type WaitForLowFuture<'a> = T::WaitForLowFuture<'a> where Self: 'a;
86-
87-
fn wait_for_low(&mut self) -> Self::WaitForLowFuture<'_> {
88-
T::wait_for_low(self)
56+
async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
57+
T::wait_for_low(self).await
8958
}
9059

91-
type WaitForRisingEdgeFuture<'a> = T::WaitForRisingEdgeFuture<'a> where Self: 'a;
92-
93-
fn wait_for_rising_edge(&mut self) -> Self::WaitForRisingEdgeFuture<'_> {
94-
T::wait_for_rising_edge(self)
60+
async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
61+
T::wait_for_rising_edge(self).await
9562
}
9663

97-
type WaitForFallingEdgeFuture<'a> = T::WaitForFallingEdgeFuture<'a> where Self: 'a;
98-
99-
fn wait_for_falling_edge(&mut self) -> Self::WaitForFallingEdgeFuture<'_> {
100-
T::wait_for_falling_edge(self)
64+
async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
65+
T::wait_for_falling_edge(self).await
10166
}
10267

103-
type WaitForAnyEdgeFuture<'a> = T::WaitForAnyEdgeFuture<'a> where Self: 'a;
104-
105-
fn wait_for_any_edge(&mut self) -> Self::WaitForAnyEdgeFuture<'_> {
106-
T::wait_for_any_edge(self)
68+
async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
69+
T::wait_for_any_edge(self).await
10770
}
10871
}

embedded-hal-async/src/i2c.rs

+16-46
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,13 @@
1616
//! Since 7-bit addressing is the mode of the majority of I2C devices,
1717
//! `SevenBitAddress` has been set as default mode and thus can be omitted if desired.
1818
19-
use core::future::Future;
2019
pub use embedded_hal::i2c::Operation;
2120
pub use embedded_hal::i2c::{
2221
AddressMode, Error, ErrorKind, ErrorType, NoAcknowledgeSource, SevenBitAddress, TenBitAddress,
2322
};
2423

2524
/// Async i2c
2625
pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
27-
/// Future returned by the `read` method.
28-
type ReadFuture<'a>: Future<Output = Result<(), Self::Error>>
29-
where
30-
Self: 'a;
31-
3226
/// Reads enough bytes from slave with `address` to fill `buffer`
3327
///
3428
/// # I2C Events (contract)
@@ -47,12 +41,7 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
4741
/// - `MAK` = master acknowledge
4842
/// - `NMAK` = master no acknowledge
4943
/// - `SP` = stop condition
50-
fn read<'a>(&'a mut self, address: A, read: &'a mut [u8]) -> Self::ReadFuture<'a>;
51-
52-
/// Future returned by the `write` method.
53-
type WriteFuture<'a>: Future<Output = Result<(), Self::Error>>
54-
where
55-
Self: 'a;
44+
async fn read<'a>(&'a mut self, address: A, read: &'a mut [u8]) -> Result<(), Self::Error>;
5645

5746
/// Writes bytes to slave with address `address`
5847
///
@@ -70,12 +59,7 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
7059
/// - `SAK` = slave acknowledge
7160
/// - `Bi` = ith byte of data
7261
/// - `SP` = stop condition
73-
fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Self::WriteFuture<'a>;
74-
75-
/// Future returned by the `write_read` method.
76-
type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>>
77-
where
78-
Self: 'a;
62+
async fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Result<(), Self::Error>;
7963

8064
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `read` *in a
8165
/// single transaction*.
@@ -99,18 +83,12 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
9983
/// - `MAK` = master acknowledge
10084
/// - `NMAK` = master no acknowledge
10185
/// - `SP` = stop condition
102-
fn write_read<'a>(
86+
async fn write_read<'a>(
10387
&'a mut self,
10488
address: A,
10589
write: &'a [u8],
10690
read: &'a mut [u8],
107-
) -> Self::WriteReadFuture<'a>;
108-
109-
/// Future returned by the `transaction` method.
110-
type TransactionFuture<'a, 'b>: Future<Output = Result<(), Self::Error>>
111-
where
112-
Self: 'a,
113-
'b: 'a;
91+
) -> Result<(), Self::Error>;
11492

11593
/// Execute the provided operations on the I2C bus as a single transaction.
11694
///
@@ -125,44 +103,36 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
125103
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
126104
/// - `SR` = repeated start condition
127105
/// - `SP` = stop condition
128-
fn transaction<'a, 'b>(
106+
async fn transaction<'a, 'b>(
129107
&'a mut self,
130108
address: A,
131109
operations: &'a mut [Operation<'b>],
132-
) -> Self::TransactionFuture<'a, 'b>;
110+
) -> Result<(), Self::Error>;
133111
}
134112

135113
impl<A: AddressMode, T: I2c<A>> I2c<A> for &mut T {
136-
type ReadFuture<'a> = T::ReadFuture<'a> where Self: 'a;
137-
138-
fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
139-
T::read(self, address, buffer)
114+
async fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Result<(), Self::Error> {
115+
T::read(self, address, buffer).await
140116
}
141117

142-
type WriteFuture<'a> = T::WriteFuture<'a> where Self: 'a;
143-
144-
fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
145-
T::write(self, address, bytes)
118+
async fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Result<(), Self::Error> {
119+
T::write(self, address, bytes).await
146120
}
147121

148-
type WriteReadFuture<'a> = T::WriteReadFuture<'a> where Self: 'a;
149-
150-
fn write_read<'a>(
122+
async fn write_read<'a>(
151123
&'a mut self,
152124
address: A,
153125
bytes: &'a [u8],
154126
buffer: &'a mut [u8],
155-
) -> Self::WriteReadFuture<'a> {
156-
T::write_read(self, address, bytes, buffer)
127+
) -> Result<(), Self::Error> {
128+
T::write_read(self, address, bytes, buffer).await
157129
}
158130

159-
type TransactionFuture<'a, 'b> = T::TransactionFuture<'a, 'b> where Self: 'a, 'b: 'a;
160-
161-
fn transaction<'a, 'b>(
131+
async fn transaction<'a, 'b>(
162132
&'a mut self,
163133
address: A,
164134
operations: &'a mut [Operation<'b>],
165-
) -> Self::TransactionFuture<'a, 'b> {
166-
T::transaction(self, address, operations)
135+
) -> Result<(), Self::Error> {
136+
T::transaction(self, address, operations).await
167137
}
168138
}

embedded-hal-async/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
1010
#![warn(missing_docs)]
1111
#![no_std]
12-
#![feature(type_alias_impl_trait)]
12+
#![allow(incomplete_features)]
13+
#![feature(async_fn_in_trait, impl_trait_projections)]
1314

1415
pub mod delay;
1516
pub mod digital;

0 commit comments

Comments
 (0)