aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor-macros
diff options
context:
space:
mode:
authorMatthew Tran <[email protected]>2025-05-28 22:00:25 -0500
committerMatthew Tran <[email protected]>2025-05-28 23:37:17 -0500
commita4d4f62a1e0e808ec3dd93e282f517a2f8ad9fa5 (patch)
tree30529d5f171a70131885c840b6de040da6c5082a /embassy-executor-macros
parent4766cc6f9756b54bb2e25be5ba5276538ea4917b (diff)
Allow `-> impl Future<Output = ()>` in #[task]
Diffstat (limited to 'embassy-executor-macros')
-rw-r--r--embassy-executor-macros/src/macros/task.rs34
1 files changed, 20 insertions, 14 deletions
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 {
51 .embassy_executor 51 .embassy_executor
52 .unwrap_or(Expr::Verbatim(TokenStream::from_str("::embassy_executor").unwrap())); 52 .unwrap_or(Expr::Verbatim(TokenStream::from_str("::embassy_executor").unwrap()));
53 53
54 if f.sig.asyncness.is_none() { 54 let returns_impl_trait = match &f.sig.output {
55 ReturnType::Type(_, ty) => matches!(**ty, Type::ImplTrait(_)),
56 _ => false,
57 };
58 if f.sig.asyncness.is_none() && !returns_impl_trait {
55 error(&mut errors, &f.sig, "task functions must be async"); 59 error(&mut errors, &f.sig, "task functions must be async");
56 } 60 }
57 if !f.sig.generics.params.is_empty() { 61 if !f.sig.generics.params.is_empty() {
@@ -66,17 +70,19 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
66 if !f.sig.variadic.is_none() { 70 if !f.sig.variadic.is_none() {
67 error(&mut errors, &f.sig, "task functions must not be variadic"); 71 error(&mut errors, &f.sig, "task functions must not be variadic");
68 } 72 }
69 match &f.sig.output { 73 if f.sig.asyncness.is_some() {
70 ReturnType::Default => {} 74 match &f.sig.output {
71 ReturnType::Type(_, ty) => match &**ty { 75 ReturnType::Default => {}
72 Type::Tuple(tuple) if tuple.elems.is_empty() => {} 76 ReturnType::Type(_, ty) => match &**ty {
73 Type::Never(_) => {} 77 Type::Tuple(tuple) if tuple.elems.is_empty() => {}
74 _ => error( 78 Type::Never(_) => {}
75 &mut errors, 79 _ => error(
76 &f.sig, 80 &mut errors,
77 "task functions must either not return a value, return `()` or return `!`", 81 &f.sig,
78 ), 82 "task functions must either not return a value, return `()` or return `!`",
79 }, 83 ),
84 },
85 }
80 } 86 }
81 87
82 let mut args = Vec::new(); 88 let mut args = Vec::new();
@@ -128,12 +134,12 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream {
128 #[cfg(feature = "nightly")] 134 #[cfg(feature = "nightly")]
129 let mut task_outer_body = quote! { 135 let mut task_outer_body = quote! {
130 trait _EmbassyInternalTaskTrait { 136 trait _EmbassyInternalTaskTrait {
131 type Fut: ::core::future::Future + 'static; 137 type Fut: ::core::future::Future<Output: #embassy_executor::_export::TaskReturnValue> + 'static;
132 fn construct(#fargs) -> Self::Fut; 138 fn construct(#fargs) -> Self::Fut;
133 } 139 }
134 140
135 impl _EmbassyInternalTaskTrait for () { 141 impl _EmbassyInternalTaskTrait for () {
136 type Fut = impl core::future::Future + 'static; 142 type Fut = impl core::future::Future<Output: #embassy_executor::_export::TaskReturnValue> + 'static;
137 fn construct(#fargs) -> Self::Fut { 143 fn construct(#fargs) -> Self::Fut {
138 #task_inner_ident(#(#full_args,)*) 144 #task_inner_ident(#(#full_args,)*)
139 } 145 }