aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/tests
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-07-08 20:19:01 +0200
committerDario Nieuwenhuis <[email protected]>2025-07-08 20:27:35 +0200
commit2fe2a0cf9c15bf7e84134cd7fec48017bb0a0db7 (patch)
treee9603081d1c84297878ace77762adbbaa92cb7a3 /embassy-executor/tests
parent504261a8d0bc58fcfa8b73245eaf859f88d62a94 (diff)
excutor: fix Send unsoundness with `-> impl Future` tasks.
Diffstat (limited to 'embassy-executor/tests')
-rw-r--r--embassy-executor/tests/ui.rs2
-rw-r--r--embassy-executor/tests/ui/return_impl_future_nonsend.rs21
-rw-r--r--embassy-executor/tests/ui/return_impl_future_nonsend.stderr17
-rw-r--r--embassy-executor/tests/ui/return_impl_send.stderr8
-rw-r--r--embassy-executor/tests/ui/spawn_nonsend.rs16
-rw-r--r--embassy-executor/tests/ui/spawn_nonsend.stderr41
6 files changed, 101 insertions, 4 deletions
diff --git a/embassy-executor/tests/ui.rs b/embassy-executor/tests/ui.rs
index c4a1a601c..7757775ee 100644
--- a/embassy-executor/tests/ui.rs
+++ b/embassy-executor/tests/ui.rs
@@ -17,6 +17,8 @@ fn ui() {
17 t.compile_fail("tests/ui/nonstatic_struct_elided.rs"); 17 t.compile_fail("tests/ui/nonstatic_struct_elided.rs");
18 t.compile_fail("tests/ui/nonstatic_struct_generic.rs"); 18 t.compile_fail("tests/ui/nonstatic_struct_generic.rs");
19 t.compile_fail("tests/ui/not_async.rs"); 19 t.compile_fail("tests/ui/not_async.rs");
20 t.compile_fail("tests/ui/spawn_nonsend.rs");
21 t.compile_fail("tests/ui/return_impl_future_nonsend.rs");
20 if rustversion::cfg!(stable) { 22 if rustversion::cfg!(stable) {
21 // output is slightly different on nightly 23 // output is slightly different on nightly
22 t.compile_fail("tests/ui/bad_return_impl_future.rs"); 24 t.compile_fail("tests/ui/bad_return_impl_future.rs");
diff --git a/embassy-executor/tests/ui/return_impl_future_nonsend.rs b/embassy-executor/tests/ui/return_impl_future_nonsend.rs
new file mode 100644
index 000000000..b8c184b21
--- /dev/null
+++ b/embassy-executor/tests/ui/return_impl_future_nonsend.rs
@@ -0,0 +1,21 @@
1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
2
3use core::future::Future;
4
5use embassy_executor::SendSpawner;
6
7#[embassy_executor::task]
8fn task() -> impl Future<Output = ()> {
9 // runs in spawning thread
10 let non_send: *mut () = core::ptr::null_mut();
11 async move {
12 // runs in executor thread
13 println!("{}", non_send as usize);
14 }
15}
16
17fn send_spawn(s: SendSpawner) {
18 s.spawn(task()).unwrap();
19}
20
21fn main() {}
diff --git a/embassy-executor/tests/ui/return_impl_future_nonsend.stderr b/embassy-executor/tests/ui/return_impl_future_nonsend.stderr
new file mode 100644
index 000000000..8aeb9738a
--- /dev/null
+++ b/embassy-executor/tests/ui/return_impl_future_nonsend.stderr
@@ -0,0 +1,17 @@
1error: future cannot be sent between threads safely
2 --> tests/ui/return_impl_future_nonsend.rs:18:13
3 |
418 | s.spawn(task()).unwrap();
5 | ^^^^^^ future created by async block is not `Send`
6 |
7 = help: within `impl Sized`, the trait `Send` is not implemented for `*mut ()`
8note: captured value is not `Send`
9 --> tests/ui/return_impl_future_nonsend.rs:13:24
10 |
1113 | println!("{}", non_send as usize);
12 | ^^^^^^^^ has type `*mut ()` which is not `Send`
13note: required by a bound in `SendSpawner::spawn`
14 --> src/spawner.rs
15 |
16 | pub fn spawn<S: Send>(&self, token: SpawnToken<S>) -> Result<(), SpawnError> {
17 | ^^^^ required by this bound in `SendSpawner::spawn`
diff --git a/embassy-executor/tests/ui/return_impl_send.stderr b/embassy-executor/tests/ui/return_impl_send.stderr
index cd693af2b..759be1cde 100644
--- a/embassy-executor/tests/ui/return_impl_send.stderr
+++ b/embassy-executor/tests/ui/return_impl_send.stderr
@@ -91,14 +91,14 @@ error[E0277]: `impl Send` is not a future
91 | ^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Send` is not a future 91 | ^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Send` is not a future
92 | 92 |
93 = help: the trait `Future` is not implemented for `impl Send` 93 = help: the trait `Future` is not implemented for `impl Send`
94note: required by a bound in `TaskPool::<F, N>::_spawn_async_fn` 94note: required by a bound in `TaskPool::<F, N>::spawn`
95 --> src/raw/mod.rs 95 --> src/raw/mod.rs
96 | 96 |
97 | impl<F: Future + 'static, const N: usize> TaskPool<F, N> { 97 | impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
98 | ^^^^^^ required by this bound in `TaskPool::<F, N>::_spawn_async_fn` 98 | ^^^^^^ required by this bound in `TaskPool::<F, N>::spawn`
99... 99...
100 | pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> SpawnToken<impl Sized> 100 | pub fn spawn(&'static self, future: impl FnOnce() -> F) -> SpawnToken<impl Sized> {
101 | --------------- required by a bound in this associated function 101 | ----- required by a bound in this associated function
102 = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) 102 = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info)
103 103
104error[E0277]: task futures must resolve to `()` or `!` 104error[E0277]: task futures must resolve to `()` or `!`
diff --git a/embassy-executor/tests/ui/spawn_nonsend.rs b/embassy-executor/tests/ui/spawn_nonsend.rs
new file mode 100644
index 000000000..4c4cc7697
--- /dev/null
+++ b/embassy-executor/tests/ui/spawn_nonsend.rs
@@ -0,0 +1,16 @@
1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
2
3use core::future::Future;
4
5use embassy_executor::SendSpawner;
6
7#[embassy_executor::task]
8async fn task(non_send: *mut ()) {
9 println!("{}", non_send as usize);
10}
11
12fn send_spawn(s: SendSpawner) {
13 s.spawn(task(core::ptr::null_mut())).unwrap();
14}
15
16fn main() {}
diff --git a/embassy-executor/tests/ui/spawn_nonsend.stderr b/embassy-executor/tests/ui/spawn_nonsend.stderr
new file mode 100644
index 000000000..2a06c8b94
--- /dev/null
+++ b/embassy-executor/tests/ui/spawn_nonsend.stderr
@@ -0,0 +1,41 @@
1warning: unused import: `core::future::Future`
2 --> tests/ui/spawn_nonsend.rs:3:5
3 |
43 | use core::future::Future;
5 | ^^^^^^^^^^^^^^^^^^^^
6 |
7 = note: `#[warn(unused_imports)]` on by default
8
9error[E0277]: `*mut ()` cannot be sent between threads safely
10 --> tests/ui/spawn_nonsend.rs:13:13
11 |
127 | #[embassy_executor::task]
13 | ------------------------- within this `impl Sized`
14...
1513 | s.spawn(task(core::ptr::null_mut())).unwrap();
16 | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be sent between threads safely
17 | |
18 | required by a bound introduced by this call
19 |
20 = help: within `impl Sized`, the trait `Send` is not implemented for `*mut ()`
21note: required because it's used within this closure
22 --> tests/ui/spawn_nonsend.rs:7:1
23 |
247 | #[embassy_executor::task]
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^
26note: required because it appears within the type `impl Sized`
27 --> src/raw/mod.rs
28 |
29 | pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> SpawnToken<impl Sized>
30 | ^^^^^^^^^^
31note: required because it appears within the type `impl Sized`
32 --> tests/ui/spawn_nonsend.rs:7:1
33 |
347 | #[embassy_executor::task]
35 | ^^^^^^^^^^^^^^^^^^^^^^^^^
36note: required by a bound in `SendSpawner::spawn`
37 --> src/spawner.rs
38 |
39 | pub fn spawn<S: Send>(&self, token: SpawnToken<S>) -> Result<(), SpawnError> {
40 | ^^^^ required by this bound in `SendSpawner::spawn`
41 = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info)