mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-26 20:00:27 +00:00
Merge pull request #4266 from 0e4ef622/task-rpit
Allow `-> impl Future<Output = ()>` in #[task]
This commit is contained in:
commit
8a23a4dfa4
@ -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<Output: #embassy_executor::_export::TaskReturnValue> + 'static;
|
||||
fn construct(#fargs) -> Self::Fut;
|
||||
}
|
||||
|
||||
impl _EmbassyInternalTaskTrait for () {
|
||||
type Fut = impl core::future::Future + 'static;
|
||||
type Fut = impl core::future::Future<Output: #embassy_executor::_export::TaskReturnValue> + 'static;
|
||||
fn construct(#fargs) -> Self::Fut {
|
||||
#task_inner_ident(#(#full_args,)*)
|
||||
}
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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 futures must resolve to `()` or `!`",
|
||||
note = "use `async fn` or change the return type to `impl Future<Output = ()>`"
|
||||
)]
|
||||
#[allow(private_bounds)]
|
||||
pub trait TaskFn<Args>: Copy {
|
||||
type Fut: Future + 'static;
|
||||
type Fut: Future<Output: TaskReturnValue> + 'static;
|
||||
}
|
||||
|
||||
macro_rules! task_fn_impl {
|
||||
@ -74,7 +83,7 @@ pub mod _export {
|
||||
impl<F, Fut, $($Tn,)*> TaskFn<($($Tn,)*)> for F
|
||||
where
|
||||
F: Copy + FnOnce($($Tn,)*) -> Fut,
|
||||
Fut: Future + 'static,
|
||||
Fut: Future<Output: TaskReturnValue> + 'static,
|
||||
{
|
||||
type Fut = Fut;
|
||||
}
|
||||
@ -205,4 +214,42 @@ pub mod _export {
|
||||
Align268435456: 268435456,
|
||||
Align536870912: 536870912,
|
||||
);
|
||||
|
||||
#[allow(dead_code)]
|
||||
trait HasOutput {
|
||||
type Output;
|
||||
}
|
||||
|
||||
impl<O> HasOutput for fn() -> O {
|
||||
type Output = O;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
type Never = <fn() -> ! 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 {
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "task futures must resolve to `()` or `!`",
|
||||
note = "use `async fn` or change the return type to `impl Future<Output = ()>`"
|
||||
)]
|
||||
pub trait TaskReturnValue {}
|
||||
impl TaskReturnValue for () {}
|
||||
impl TaskReturnValue for Never {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
trait HasOutput {
|
||||
type Output;
|
||||
}
|
||||
|
||||
impl<O> HasOutput for fn() -> O {
|
||||
type Output = O;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
type Never = <fn() -> ! as HasOutput>::Output;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#![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;
|
||||
use std::future::{poll_fn, Future};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::task::Poll;
|
||||
|
||||
@ -58,6 +59,39 @@ fn executor_task() {
|
||||
trace.push("poll task1")
|
||||
}
|
||||
|
||||
#[task]
|
||||
async fn task2() -> ! {
|
||||
panic!()
|
||||
}
|
||||
|
||||
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_rpit() {
|
||||
#[task]
|
||||
fn task1(trace: Trace) -> impl Future<Output = ()> {
|
||||
async move { trace.push("poll task1") }
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
#[task]
|
||||
fn task2() -> impl Future<Output = !> {
|
||||
async { panic!() }
|
||||
}
|
||||
|
||||
let (executor, trace) = setup();
|
||||
executor.spawner().spawn(task1(trace.clone())).unwrap();
|
||||
|
||||
|
@ -17,6 +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");
|
||||
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");
|
||||
|
9
embassy-executor/tests/ui/bad_return_impl_future.rs
Normal file
9
embassy-executor/tests/ui/bad_return_impl_future.rs
Normal file
@ -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<Output = u32> {
|
||||
async { 5 }
|
||||
}
|
||||
|
||||
fn main() {}
|
120
embassy-executor/tests/ui/bad_return_impl_future.stderr
Normal file
120
embassy-executor/tests/ui/bad_return_impl_future.stderr
Normal file
@ -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<Output = u32> {
|
||||
| ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
note: required by a bound in `task_pool_size`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_size<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| -------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^ 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<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
note: required by a bound in `task_pool_size`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_size<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| -------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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<Output = u32> {
|
||||
| ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
note: required by a bound in `task_pool_align`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_align<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| --------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^ 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<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
note: required by a bound in `task_pool_align`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_align<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| --------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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<Output = u32> {
|
||||
| ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
note: required by a bound in `task_pool_new`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_new<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> TaskPool<Fut, POOL_SIZE>
|
||||
| ------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^ 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<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
note: required by a bound in `task_pool_new`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_new<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> TaskPool<Fut, POOL_SIZE>
|
||||
| ------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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<Output = u32> {
|
||||
| ^^^^ the trait `TaskFn<_>` is not implemented for fn item `fn() -> impl Future<Output = u32> {__task_task}`
|
||||
|
|
||||
= note: use `async fn` or change the return type to `impl Future<Output = ()>`
|
||||
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)
|
@ -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<Output = u32> {
|
||||
async { 5 }
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -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<Output = ()>`
|
||||
= help: the following other types implement trait `TaskReturnValue`:
|
||||
()
|
||||
<fn() -> ! as _export::HasOutput>::Output
|
6
embassy-executor/tests/ui/return_impl_send.rs
Normal file
6
embassy-executor/tests/ui/return_impl_send.rs
Normal file
@ -0,0 +1,6 @@
|
||||
#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
|
||||
|
||||
#[embassy_executor::task]
|
||||
fn task() -> impl Send {}
|
||||
|
||||
fn main() {}
|
137
embassy-executor/tests/ui/return_impl_send.stderr
Normal file
137
embassy-executor/tests/ui/return_impl_send.stderr
Normal file
@ -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<Output = ()>`
|
||||
note: required by a bound in `task_pool_size`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_size<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| -------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^ 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<Output = ()>`
|
||||
note: required by a bound in `task_pool_size`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_size<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| -------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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<Output = ()>`
|
||||
note: required by a bound in `task_pool_align`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_align<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| --------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^ 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<Output = ()>`
|
||||
note: required by a bound in `task_pool_align`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_align<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> usize
|
||||
| --------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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<Output = ()>`
|
||||
note: required by a bound in `task_pool_new`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_new<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> TaskPool<Fut, POOL_SIZE>
|
||||
| ------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^ 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<Output = ()>`
|
||||
note: required by a bound in `task_pool_new`
|
||||
--> src/lib.rs
|
||||
|
|
||||
| pub const fn task_pool_new<F, Args, Fut, const POOL_SIZE: usize>(_: F) -> TaskPool<Fut, POOL_SIZE>
|
||||
| ------------- required by a bound in this function
|
||||
| where
|
||||
| F: TaskFn<Args, Fut = Fut>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ 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<Output = ()>`
|
||||
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::<F, N>::_spawn_async_fn`
|
||||
--> src/raw/mod.rs
|
||||
|
|
||||
| impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
|
||||
| ^^^^^^ required by this bound in `TaskPool::<F, N>::_spawn_async_fn`
|
||||
...
|
||||
| pub unsafe fn _spawn_async_fn<FutFn>(&'static self, future: FutFn) -> SpawnToken<impl Sized>
|
||||
| --------------- 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)
|
6
embassy-executor/tests/ui/return_impl_send_nightly.rs
Normal file
6
embassy-executor/tests/ui/return_impl_send_nightly.rs
Normal file
@ -0,0 +1,6 @@
|
||||
#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
|
||||
|
||||
#[embassy_executor::task]
|
||||
fn task() -> impl Send {}
|
||||
|
||||
fn main() {}
|
10
embassy-executor/tests/ui/return_impl_send_nightly.stderr
Normal file
10
embassy-executor/tests/ui/return_impl_send_nightly.stderr
Normal file
@ -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`
|
Loading…
x
Reference in New Issue
Block a user