aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-executor-macros/src/macros/task.rs10
-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
7 files changed, 109 insertions, 6 deletions
diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs
index 91bf8e940..1c5e3571d 100644
--- a/embassy-executor-macros/src/macros/task.rs
+++ b/embassy-executor-macros/src/macros/task.rs
@@ -131,6 +131,12 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
131 )); 131 ));
132 } 132 }
133 133
134 let spawn = if returns_impl_trait {
135 quote!(spawn)
136 } else {
137 quote!(_spawn_async_fn)
138 };
139
134 #[cfg(feature = "nightly")] 140 #[cfg(feature = "nightly")]
135 let mut task_outer_body = quote! { 141 let mut task_outer_body = quote! {
136 trait _EmbassyInternalTaskTrait { 142 trait _EmbassyInternalTaskTrait {
@@ -147,7 +153,7 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
147 153
148 const POOL_SIZE: usize = #pool_size; 154 const POOL_SIZE: usize = #pool_size;
149 static POOL: #embassy_executor::raw::TaskPool<<() as _EmbassyInternalTaskTrait>::Fut, POOL_SIZE> = #embassy_executor::raw::TaskPool::new(); 155 static POOL: #embassy_executor::raw::TaskPool<<() as _EmbassyInternalTaskTrait>::Fut, POOL_SIZE> = #embassy_executor::raw::TaskPool::new();
150 unsafe { POOL._spawn_async_fn(move || <() as _EmbassyInternalTaskTrait>::construct(#(#full_args,)*)) } 156 unsafe { POOL.#spawn(move || <() as _EmbassyInternalTaskTrait>::construct(#(#full_args,)*)) }
151 }; 157 };
152 #[cfg(not(feature = "nightly"))] 158 #[cfg(not(feature = "nightly"))]
153 let mut task_outer_body = quote! { 159 let mut task_outer_body = quote! {
@@ -164,7 +170,7 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
164 {#embassy_executor::_export::task_pool_size::<_, _, _, POOL_SIZE>(#task_inner_ident)}, 170 {#embassy_executor::_export::task_pool_size::<_, _, _, POOL_SIZE>(#task_inner_ident)},
165 {#embassy_executor::_export::task_pool_align::<_, _, _, POOL_SIZE>(#task_inner_ident)}, 171 {#embassy_executor::_export::task_pool_align::<_, _, _, POOL_SIZE>(#task_inner_ident)},
166 > = unsafe { ::core::mem::transmute(#embassy_executor::_export::task_pool_new::<_, _, _, POOL_SIZE>(#task_inner_ident)) }; 172 > = unsafe { ::core::mem::transmute(#embassy_executor::_export::task_pool_new::<_, _, _, POOL_SIZE>(#task_inner_ident)) };
167 unsafe { __task_pool_get(#task_inner_ident)._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } 173 unsafe { __task_pool_get(#task_inner_ident).#spawn(move || #task_inner_ident(#(#full_args,)*)) }
168 }; 174 };
169 175
170 let task_outer_attrs = task_inner.attrs.clone(); 176 let task_outer_attrs = task_inner.attrs.clone();
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)