From a4d4f62a1e0e808ec3dd93e282f517a2f8ad9fa5 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Wed, 28 May 2025 22:00:25 -0500 Subject: Allow `-> impl Future` in #[task] --- embassy-executor-macros/src/macros/task.rs | 34 +++--- embassy-executor/src/lib.rs | 47 +++++++- embassy-executor/tests/test.rs | 24 ++++- embassy-executor/tests/ui.rs | 4 + embassy-executor/tests/ui/bad_return_impl_trait.rs | 9 ++ .../tests/ui/bad_return_impl_trait.stderr | 120 +++++++++++++++++++++ .../tests/ui/bad_return_impl_trait_nightly.rs | 9 ++ .../tests/ui/bad_return_impl_trait_nightly.stderr | 9 ++ 8 files changed, 239 insertions(+), 17 deletions(-) create mode 100644 embassy-executor/tests/ui/bad_return_impl_trait.rs create mode 100644 embassy-executor/tests/ui/bad_return_impl_trait.stderr create mode 100644 embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs create mode 100644 embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index 91d6beee8..91bf8e940 100644 --- a/embassy-executor-macros/src/macros/task.rs +++ b/embassy-executor-macros/src/macros/task.rs @@ -51,7 +51,11 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { .embassy_executor .unwrap_or(Expr::Verbatim(TokenStream::from_str("::embassy_executor").unwrap())); - if f.sig.asyncness.is_none() { + let returns_impl_trait = match &f.sig.output { + ReturnType::Type(_, ty) => matches!(**ty, Type::ImplTrait(_)), + _ => false, + }; + if f.sig.asyncness.is_none() && !returns_impl_trait { error(&mut errors, &f.sig, "task functions must be async"); } if !f.sig.generics.params.is_empty() { @@ -66,17 +70,19 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { if !f.sig.variadic.is_none() { error(&mut errors, &f.sig, "task functions must not be variadic"); } - match &f.sig.output { - ReturnType::Default => {} - ReturnType::Type(_, ty) => match &**ty { - Type::Tuple(tuple) if tuple.elems.is_empty() => {} - Type::Never(_) => {} - _ => error( - &mut errors, - &f.sig, - "task functions must either not return a value, return `()` or return `!`", - ), - }, + if f.sig.asyncness.is_some() { + match &f.sig.output { + ReturnType::Default => {} + ReturnType::Type(_, ty) => match &**ty { + Type::Tuple(tuple) if tuple.elems.is_empty() => {} + Type::Never(_) => {} + _ => error( + &mut errors, + &f.sig, + "task functions must either not return a value, return `()` or return `!`", + ), + }, + } } let mut args = Vec::new(); @@ -128,12 +134,12 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { #[cfg(feature = "nightly")] let mut task_outer_body = quote! { trait _EmbassyInternalTaskTrait { - type Fut: ::core::future::Future + 'static; + type Fut: ::core::future::Future + 'static; fn construct(#fargs) -> Self::Fut; } impl _EmbassyInternalTaskTrait for () { - type Fut = impl core::future::Future + 'static; + type Fut = impl core::future::Future + 'static; fn construct(#fargs) -> Self::Fut { #task_inner_ident(#(#full_args,)*) } diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index dfe420bab..70abfcc3a 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -65,8 +65,17 @@ pub mod _export { use crate::raw::TaskPool; + trait TaskReturnValue {} + impl TaskReturnValue for () {} + impl TaskReturnValue for Never {} + + #[diagnostic::on_unimplemented( + message = "task function futures must resolve to `()`", + note = "use `async fn` or change the return type to `impl Future`" + )] + #[allow(private_bounds)] pub trait TaskFn: Copy { - type Fut: Future + 'static; + type Fut: Future + 'static; } macro_rules! task_fn_impl { @@ -74,7 +83,7 @@ pub mod _export { impl TaskFn<($($Tn,)*)> for F where F: Copy + FnOnce($($Tn,)*) -> Fut, - Fut: Future + 'static, + Fut: Future + 'static, { type Fut = Fut; } @@ -205,4 +214,38 @@ pub mod _export { Align268435456: 268435456, Align536870912: 536870912, ); + + #[allow(dead_code)] + trait HasOutput { + type Output; + } + + impl HasOutput for fn() -> O { + type Output = O; + } + + #[allow(dead_code)] + type Never = ! as HasOutput>::Output; +} + +/// Implementation details for embassy macros. +/// Do not use. Used for macros and HALs only. Not covered by semver guarantees. +#[doc(hidden)] +#[cfg(feature = "nightly")] +pub mod _export { + pub trait TaskReturnValue {} + impl TaskReturnValue for () {} + impl TaskReturnValue for Never {} + + #[allow(dead_code)] + trait HasOutput { + type Output; + } + + impl HasOutput for fn() -> O { + type Output = O; + } + + #[allow(dead_code)] + type Never = ! as HasOutput>::Output; } diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs index 78c49c071..c7ff4554c 100644 --- a/embassy-executor/tests/test.rs +++ b/embassy-executor/tests/test.rs @@ -1,7 +1,7 @@ #![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] use std::boxed::Box; -use std::future::poll_fn; +use std::future::{poll_fn, Future}; use std::sync::{Arc, Mutex}; use std::task::Poll; @@ -73,6 +73,28 @@ fn executor_task() { ) } +#[test] +fn executor_task_rpit() { + #[task] + fn task1(trace: Trace) -> impl Future { + async move { trace.push("poll task1") } + } + + let (executor, trace) = setup(); + executor.spawner().spawn(task1(trace.clone())).unwrap(); + + unsafe { executor.poll() }; + unsafe { executor.poll() }; + + assert_eq!( + trace.get(), + &[ + "pend", // spawning a task pends the executor + "poll task1", // poll only once. + ] + ) +} + #[test] fn executor_task_self_wake() { #[task] diff --git a/embassy-executor/tests/ui.rs b/embassy-executor/tests/ui.rs index 278a4b903..ed8228e27 100644 --- a/embassy-executor/tests/ui.rs +++ b/embassy-executor/tests/ui.rs @@ -17,6 +17,10 @@ fn ui() { t.compile_fail("tests/ui/nonstatic_struct_elided.rs"); t.compile_fail("tests/ui/nonstatic_struct_generic.rs"); t.compile_fail("tests/ui/not_async.rs"); + // #[cfg(not(feature = "nightly"))] // output differs on stable and nightly + // t.compile_fail("tests/ui/bad_return_impl_trait.rs"); + #[cfg(feature = "nightly")] + t.compile_fail("tests/ui/bad_return_impl_trait_nightly.rs"); t.compile_fail("tests/ui/self_ref.rs"); t.compile_fail("tests/ui/self.rs"); t.compile_fail("tests/ui/type_error.rs"); diff --git a/embassy-executor/tests/ui/bad_return_impl_trait.rs b/embassy-executor/tests/ui/bad_return_impl_trait.rs new file mode 100644 index 000000000..baaa7dc5a --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_trait.rs @@ -0,0 +1,9 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] +use core::future::Future; + +#[embassy_executor::task] +fn task() -> impl Future { + async { 5 } +} + +fn main() {} diff --git a/embassy-executor/tests/ui/bad_return_impl_trait.stderr b/embassy-executor/tests/ui/bad_return_impl_trait.stderr new file mode 100644 index 000000000..9e2df353e --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_trait.stderr @@ -0,0 +1,120 @@ +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_size` + --> src/lib.rs + | + | pub const fn task_pool_size(_: F) -> usize + | -------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_size` + +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_size` + --> src/lib.rs + | + | pub const fn task_pool_size(_: F) -> usize + | -------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_size` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_align` + --> src/lib.rs + | + | pub const fn task_pool_align(_: F) -> usize + | --------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_align` + +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_align` + --> src/lib.rs + | + | pub const fn task_pool_align(_: F) -> usize + | --------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_align` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_new` + --> src/lib.rs + | + | pub const fn task_pool_new(_: F) -> TaskPool + | ------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_new` + +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_new` + --> src/lib.rs + | + | pub const fn task_pool_new(_: F) -> TaskPool + | ------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_new` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task function futures must resolve to `()` + --> tests/ui/bad_return_impl_trait.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `__task_pool_get` + --> tests/ui/bad_return_impl_trait.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__task_pool_get` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs new file mode 100644 index 000000000..baaa7dc5a --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs @@ -0,0 +1,9 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] +use core::future::Future; + +#[embassy_executor::task] +fn task() -> impl Future { + async { 5 } +} + +fn main() {} diff --git a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr new file mode 100644 index 000000000..21e20d5c0 --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `u32: TaskReturnValue` is not satisfied + --> tests/ui/bad_return_impl_trait_nightly.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskReturnValue` is not implemented for `u32` + | + = help: the following other types implement trait `TaskReturnValue`: + () + ! as _export::HasOutput>::Output -- cgit From dbff432e19b326d7cef109bc4d2a0cd51260562d Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Thu, 29 May 2025 05:18:16 -0500 Subject: Add test for -> impl Future --- embassy-executor/tests/test.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs index c7ff4554c..c1e7ec5d7 100644 --- a/embassy-executor/tests/test.rs +++ b/embassy-executor/tests/test.rs @@ -1,4 +1,5 @@ #![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] +#![cfg_attr(feature = "nightly", feature(never_type))] use std::boxed::Box; use std::future::{poll_fn, Future}; @@ -58,6 +59,11 @@ fn executor_task() { trace.push("poll task1") } + #[task] + async fn task2() -> ! { + panic!() + } + let (executor, trace) = setup(); executor.spawner().spawn(task1(trace.clone())).unwrap(); @@ -80,6 +86,12 @@ fn executor_task_rpit() { async move { trace.push("poll task1") } } + #[cfg(feature = "nightly")] + #[task] + fn task2() -> impl Future { + async { panic!() } + } + let (executor, trace) = setup(); executor.spawner().spawn(task1(trace.clone())).unwrap(); -- cgit From b06a708f81d208236763a121797807fd5b48aee6 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Thu, 29 May 2025 05:54:25 -0500 Subject: Mention ! in diagnostic --- embassy-executor/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 70abfcc3a..e26e8ee7d 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -70,7 +70,7 @@ pub mod _export { impl TaskReturnValue for Never {} #[diagnostic::on_unimplemented( - message = "task function futures must resolve to `()`", + message = "task futures must resolve to `()` or `!`", note = "use `async fn` or change the return type to `impl Future`" )] #[allow(private_bounds)] -- cgit From 0d83fbbb57cf17186a1b8f40f57ef7a35b3e9627 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Sun, 1 Jun 2025 10:32:24 -0500 Subject: Add diagnostic::on_unimplemented for nightly --- embassy-executor/src/lib.rs | 4 ++++ embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index e26e8ee7d..e174a0594 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -233,6 +233,10 @@ pub mod _export { #[doc(hidden)] #[cfg(feature = "nightly")] pub mod _export { + #[diagnostic::on_unimplemented( + message = "task futures must resolve to `()` or `!`", + note = "use `async fn` or change the return type to `impl Future`" + )] pub trait TaskReturnValue {} impl TaskReturnValue for () {} impl TaskReturnValue for Never {} diff --git a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr index 21e20d5c0..a51251bb8 100644 --- a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr +++ b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr @@ -1,9 +1,10 @@ -error[E0277]: the trait bound `u32: TaskReturnValue` is not satisfied +error[E0277]: task futures must resolve to `()` or `!` --> tests/ui/bad_return_impl_trait_nightly.rs:4:1 | 4 | #[embassy_executor::task] | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskReturnValue` is not implemented for `u32` | + = note: use `async fn` or change the return type to `impl Future` = help: the following other types implement trait `TaskReturnValue`: () ! as _export::HasOutput>::Output -- cgit From 3cef4f0c04a1f0f56c84950d8fd408979299fa50 Mon Sep 17 00:00:00 2001 From: Matthew Tran <0e4ef622@gmail.com> Date: Sun, 1 Jun 2025 11:42:33 -0500 Subject: Update tests --- embassy-executor/Cargo.toml | 1 + embassy-executor/tests/ui.rs | 13 +- .../tests/ui/bad_return_impl_future.rs | 9 ++ .../tests/ui/bad_return_impl_future.stderr | 120 ++++++++++++++++++ .../tests/ui/bad_return_impl_future_nightly.rs | 9 ++ .../tests/ui/bad_return_impl_future_nightly.stderr | 10 ++ embassy-executor/tests/ui/bad_return_impl_trait.rs | 9 -- .../tests/ui/bad_return_impl_trait.stderr | 120 ------------------ .../tests/ui/bad_return_impl_trait_nightly.rs | 9 -- .../tests/ui/bad_return_impl_trait_nightly.stderr | 10 -- embassy-executor/tests/ui/return_impl_send.rs | 6 + embassy-executor/tests/ui/return_impl_send.stderr | 137 +++++++++++++++++++++ .../tests/ui/return_impl_send_nightly.rs | 6 + .../tests/ui/return_impl_send_nightly.stderr | 10 ++ 14 files changed, 317 insertions(+), 152 deletions(-) create mode 100644 embassy-executor/tests/ui/bad_return_impl_future.rs create mode 100644 embassy-executor/tests/ui/bad_return_impl_future.stderr create mode 100644 embassy-executor/tests/ui/bad_return_impl_future_nightly.rs create mode 100644 embassy-executor/tests/ui/bad_return_impl_future_nightly.stderr delete mode 100644 embassy-executor/tests/ui/bad_return_impl_trait.rs delete mode 100644 embassy-executor/tests/ui/bad_return_impl_trait.stderr delete mode 100644 embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs delete mode 100644 embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr create mode 100644 embassy-executor/tests/ui/return_impl_send.rs create mode 100644 embassy-executor/tests/ui/return_impl_send.stderr create mode 100644 embassy-executor/tests/ui/return_impl_send_nightly.rs create mode 100644 embassy-executor/tests/ui/return_impl_send_nightly.stderr diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index f014ccf30..2dbf2c29a 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -59,6 +59,7 @@ avr-device = { version = "0.7.0", optional = true } critical-section = { version = "1.1", features = ["std"] } trybuild = "1.0" embassy-sync = { path = "../embassy-sync" } +rustversion = "1.0.21" [features] diff --git a/embassy-executor/tests/ui.rs b/embassy-executor/tests/ui.rs index ed8228e27..c4a1a601c 100644 --- a/embassy-executor/tests/ui.rs +++ b/embassy-executor/tests/ui.rs @@ -17,10 +17,15 @@ fn ui() { t.compile_fail("tests/ui/nonstatic_struct_elided.rs"); t.compile_fail("tests/ui/nonstatic_struct_generic.rs"); t.compile_fail("tests/ui/not_async.rs"); - // #[cfg(not(feature = "nightly"))] // output differs on stable and nightly - // t.compile_fail("tests/ui/bad_return_impl_trait.rs"); - #[cfg(feature = "nightly")] - t.compile_fail("tests/ui/bad_return_impl_trait_nightly.rs"); + if rustversion::cfg!(stable) { + // output is slightly different on nightly + t.compile_fail("tests/ui/bad_return_impl_future.rs"); + t.compile_fail("tests/ui/return_impl_send.rs"); + } + if cfg!(feature = "nightly") { + t.compile_fail("tests/ui/bad_return_impl_future_nightly.rs"); + t.compile_fail("tests/ui/return_impl_send_nightly.rs"); + } t.compile_fail("tests/ui/self_ref.rs"); t.compile_fail("tests/ui/self.rs"); t.compile_fail("tests/ui/type_error.rs"); diff --git a/embassy-executor/tests/ui/bad_return_impl_future.rs b/embassy-executor/tests/ui/bad_return_impl_future.rs new file mode 100644 index 000000000..baaa7dc5a --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_future.rs @@ -0,0 +1,9 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] +use core::future::Future; + +#[embassy_executor::task] +fn task() -> impl Future { + async { 5 } +} + +fn main() {} diff --git a/embassy-executor/tests/ui/bad_return_impl_future.stderr b/embassy-executor/tests/ui/bad_return_impl_future.stderr new file mode 100644 index 000000000..2980fd18b --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_future.stderr @@ -0,0 +1,120 @@ +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_size` + --> src/lib.rs + | + | pub const fn task_pool_size(_: F) -> usize + | -------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_size` + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_size` + --> src/lib.rs + | + | pub const fn task_pool_size(_: F) -> usize + | -------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_size` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_align` + --> src/lib.rs + | + | pub const fn task_pool_align(_: F) -> usize + | --------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_align` + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_align` + --> src/lib.rs + | + | pub const fn task_pool_align(_: F) -> usize + | --------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_align` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_new` + --> src/lib.rs + | + | pub const fn task_pool_new(_: F) -> TaskPool + | ------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_new` + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_new` + --> src/lib.rs + | + | pub const fn task_pool_new(_: F) -> TaskPool + | ------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_new` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future.rs:5:4 + | +4 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +5 | fn task() -> impl Future { + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `__task_pool_get` + --> tests/ui/bad_return_impl_future.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__task_pool_get` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/embassy-executor/tests/ui/bad_return_impl_future_nightly.rs b/embassy-executor/tests/ui/bad_return_impl_future_nightly.rs new file mode 100644 index 000000000..baaa7dc5a --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_future_nightly.rs @@ -0,0 +1,9 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] +use core::future::Future; + +#[embassy_executor::task] +fn task() -> impl Future { + async { 5 } +} + +fn main() {} diff --git a/embassy-executor/tests/ui/bad_return_impl_future_nightly.stderr b/embassy-executor/tests/ui/bad_return_impl_future_nightly.stderr new file mode 100644 index 000000000..73ceb989d --- /dev/null +++ b/embassy-executor/tests/ui/bad_return_impl_future_nightly.stderr @@ -0,0 +1,10 @@ +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/bad_return_impl_future_nightly.rs:4:1 + | +4 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskReturnValue` is not implemented for `u32` + | + = note: use `async fn` or change the return type to `impl Future` + = help: the following other types implement trait `TaskReturnValue`: + () + ! as _export::HasOutput>::Output diff --git a/embassy-executor/tests/ui/bad_return_impl_trait.rs b/embassy-executor/tests/ui/bad_return_impl_trait.rs deleted file mode 100644 index baaa7dc5a..000000000 --- a/embassy-executor/tests/ui/bad_return_impl_trait.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] -use core::future::Future; - -#[embassy_executor::task] -fn task() -> impl Future { - async { 5 } -} - -fn main() {} diff --git a/embassy-executor/tests/ui/bad_return_impl_trait.stderr b/embassy-executor/tests/ui/bad_return_impl_trait.stderr deleted file mode 100644 index 9e2df353e..000000000 --- a/embassy-executor/tests/ui/bad_return_impl_trait.stderr +++ /dev/null @@ -1,120 +0,0 @@ -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:5:4 - | -4 | #[embassy_executor::task] - | ------------------------- required by a bound introduced by this call -5 | fn task() -> impl Future { - | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `task_pool_size` - --> src/lib.rs - | - | pub const fn task_pool_size(_: F) -> usize - | -------------- required by a bound in this function - | where - | F: TaskFn, - | ^^^^^^^^^ required by this bound in `task_pool_size` - -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:4:1 - | -4 | #[embassy_executor::task] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `task_pool_size` - --> src/lib.rs - | - | pub const fn task_pool_size(_: F) -> usize - | -------------- required by a bound in this function - | where - | F: TaskFn, - | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_size` - = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:5:4 - | -4 | #[embassy_executor::task] - | ------------------------- required by a bound introduced by this call -5 | fn task() -> impl Future { - | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `task_pool_align` - --> src/lib.rs - | - | pub const fn task_pool_align(_: F) -> usize - | --------------- required by a bound in this function - | where - | F: TaskFn, - | ^^^^^^^^^ required by this bound in `task_pool_align` - -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:4:1 - | -4 | #[embassy_executor::task] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `task_pool_align` - --> src/lib.rs - | - | pub const fn task_pool_align(_: F) -> usize - | --------------- required by a bound in this function - | where - | F: TaskFn, - | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_align` - = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:5:4 - | -4 | #[embassy_executor::task] - | ------------------------- required by a bound introduced by this call -5 | fn task() -> impl Future { - | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `task_pool_new` - --> src/lib.rs - | - | pub const fn task_pool_new(_: F) -> TaskPool - | ------------- required by a bound in this function - | where - | F: TaskFn, - | ^^^^^^^^^ required by this bound in `task_pool_new` - -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:4:1 - | -4 | #[embassy_executor::task] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `task_pool_new` - --> src/lib.rs - | - | pub const fn task_pool_new(_: F) -> TaskPool - | ------------- required by a bound in this function - | where - | F: TaskFn, - | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_new` - = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: task function futures must resolve to `()` - --> tests/ui/bad_return_impl_trait.rs:5:4 - | -4 | #[embassy_executor::task] - | ------------------------- required by a bound introduced by this call -5 | fn task() -> impl Future { - | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future {__task_task}` - | - = note: use `async fn` or change the return type to `impl Future` -note: required by a bound in `__task_pool_get` - --> tests/ui/bad_return_impl_trait.rs:4:1 - | -4 | #[embassy_executor::task] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__task_pool_get` - = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs deleted file mode 100644 index baaa7dc5a..000000000 --- a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] -use core::future::Future; - -#[embassy_executor::task] -fn task() -> impl Future { - async { 5 } -} - -fn main() {} diff --git a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr b/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr deleted file mode 100644 index a51251bb8..000000000 --- a/embassy-executor/tests/ui/bad_return_impl_trait_nightly.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0277]: task futures must resolve to `()` or `!` - --> tests/ui/bad_return_impl_trait_nightly.rs:4:1 - | -4 | #[embassy_executor::task] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskReturnValue` is not implemented for `u32` - | - = note: use `async fn` or change the return type to `impl Future` - = help: the following other types implement trait `TaskReturnValue`: - () - ! as _export::HasOutput>::Output diff --git a/embassy-executor/tests/ui/return_impl_send.rs b/embassy-executor/tests/ui/return_impl_send.rs new file mode 100644 index 000000000..6ddb0e722 --- /dev/null +++ b/embassy-executor/tests/ui/return_impl_send.rs @@ -0,0 +1,6 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] + +#[embassy_executor::task] +fn task() -> impl Send {} + +fn main() {} diff --git a/embassy-executor/tests/ui/return_impl_send.stderr b/embassy-executor/tests/ui/return_impl_send.stderr new file mode 100644 index 000000000..7e3e468b8 --- /dev/null +++ b/embassy-executor/tests/ui/return_impl_send.stderr @@ -0,0 +1,137 @@ +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:4:4 + | +3 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +4 | fn task() -> impl Send {} + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_size` + --> src/lib.rs + | + | pub const fn task_pool_size(_: F) -> usize + | -------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_size` + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:3:1 + | +3 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_size` + --> src/lib.rs + | + | pub const fn task_pool_size(_: F) -> usize + | -------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_size` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:4:4 + | +3 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +4 | fn task() -> impl Send {} + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_align` + --> src/lib.rs + | + | pub const fn task_pool_align(_: F) -> usize + | --------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_align` + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:3:1 + | +3 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_align` + --> src/lib.rs + | + | pub const fn task_pool_align(_: F) -> usize + | --------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_align` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:4:4 + | +3 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +4 | fn task() -> impl Send {} + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_new` + --> src/lib.rs + | + | pub const fn task_pool_new(_: F) -> TaskPool + | ------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^ required by this bound in `task_pool_new` + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:3:1 + | +3 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `task_pool_new` + --> src/lib.rs + | + | pub const fn task_pool_new(_: F) -> TaskPool + | ------------- required by a bound in this function + | where + | F: TaskFn, + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `task_pool_new` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: task futures must resolve to `()` or `!` + --> tests/ui/return_impl_send.rs:4:4 + | +3 | #[embassy_executor::task] + | ------------------------- required by a bound introduced by this call +4 | fn task() -> impl Send {} + | ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Send {__task_task}` + | + = note: use `async fn` or change the return type to `impl Future` +note: required by a bound in `__task_pool_get` + --> tests/ui/return_impl_send.rs:3:1 + | +3 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__task_pool_get` + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `impl Send` is not a future + --> tests/ui/return_impl_send.rs:3:1 + | +3 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Send` is not a future + | + = help: the trait `Future` is not implemented for `impl Send` +note: required by a bound in `TaskPool::::_spawn_async_fn` + --> src/raw/mod.rs + | + | impl TaskPool { + | ^^^^^^ required by this bound in `TaskPool::::_spawn_async_fn` +... + | pub unsafe fn _spawn_async_fn(&'static self, future: FutFn) -> SpawnToken + | --------------- required by a bound in this associated function + = note: this error originates in the attribute macro `embassy_executor::task` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/embassy-executor/tests/ui/return_impl_send_nightly.rs b/embassy-executor/tests/ui/return_impl_send_nightly.rs new file mode 100644 index 000000000..6ddb0e722 --- /dev/null +++ b/embassy-executor/tests/ui/return_impl_send_nightly.rs @@ -0,0 +1,6 @@ +#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))] + +#[embassy_executor::task] +fn task() -> impl Send {} + +fn main() {} diff --git a/embassy-executor/tests/ui/return_impl_send_nightly.stderr b/embassy-executor/tests/ui/return_impl_send_nightly.stderr new file mode 100644 index 000000000..de9ba6243 --- /dev/null +++ b/embassy-executor/tests/ui/return_impl_send_nightly.stderr @@ -0,0 +1,10 @@ +error[E0277]: `impl Send` is not a future + --> tests/ui/return_impl_send_nightly.rs:3:1 + | +3 | #[embassy_executor::task] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `impl Send` is not a future + | return type was inferred to be `impl Send` here + | + = help: the trait `Future` is not implemented for `impl Send` -- cgit