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/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 ++ 6 files changed, 174 insertions(+), 1 deletion(-) 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 (limited to 'embassy-executor/tests') 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