diff options
| author | Brezak <[email protected]> | 2025-07-23 19:51:31 +0200 |
|---|---|---|
| committer | Brezak <[email protected]> | 2025-07-23 20:55:42 +0200 |
| commit | 539ff78ebbdedbb75d0faf940e3ee69f5e7f276a (patch) | |
| tree | 7096952c556d7262e59178e11f5d81753d08d12a /embassy-executor-macros/src | |
| parent | 1b42e624246f9355a91ef98ddf96d5af1b9b3687 (diff) | |
embassy-executor: explicitly return impl Future in task inner task
Diffstat (limited to 'embassy-executor-macros/src')
| -rw-r--r-- | embassy-executor-macros/src/macros/task.rs | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index 5b360b128..fc8673743 100644 --- a/embassy-executor-macros/src/macros/task.rs +++ b/embassy-executor-macros/src/macros/task.rs | |||
| @@ -5,7 +5,7 @@ use darling::FromMeta; | |||
| 5 | use proc_macro2::{Span, TokenStream}; | 5 | use proc_macro2::{Span, TokenStream}; |
| 6 | use quote::{format_ident, quote}; | 6 | use quote::{format_ident, quote}; |
| 7 | use syn::visit::{self, Visit}; | 7 | use syn::visit::{self, Visit}; |
| 8 | use syn::{Expr, ExprLit, Lit, LitInt, ReturnType, Type}; | 8 | use syn::{Expr, ExprLit, Lit, LitInt, ReturnType, Type, Visibility}; |
| 9 | 9 | ||
| 10 | use crate::util::*; | 10 | use crate::util::*; |
| 11 | 11 | ||
| @@ -135,6 +135,13 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 135 | let task_inner_future_output = match &f.sig.output { | 135 | let task_inner_future_output = match &f.sig.output { |
| 136 | ReturnType::Default => quote! {-> impl ::core::future::Future<Output = ()>}, | 136 | ReturnType::Default => quote! {-> impl ::core::future::Future<Output = ()>}, |
| 137 | // Special case the never type since we can't stuff it into a `impl Future<Output = !>` | 137 | // Special case the never type since we can't stuff it into a `impl Future<Output = !>` |
| 138 | ReturnType::Type(arrow, maybe_never) | ||
| 139 | if f.sig.asyncness.is_some() && matches!(**maybe_never, Type::Never(_)) => | ||
| 140 | { | ||
| 141 | quote! { | ||
| 142 | #arrow impl ::core::future::Future<Output=#embassy_executor::_export::Never> | ||
| 143 | } | ||
| 144 | } | ||
| 138 | ReturnType::Type(arrow, maybe_never) if matches!(**maybe_never, Type::Never(_)) => quote! { | 145 | ReturnType::Type(arrow, maybe_never) if matches!(**maybe_never, Type::Never(_)) => quote! { |
| 139 | #arrow #maybe_never | 146 | #arrow #maybe_never |
| 140 | }, | 147 | }, |
| @@ -149,14 +156,20 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 149 | }, | 156 | }, |
| 150 | }; | 157 | }; |
| 151 | 158 | ||
| 159 | // We have to rename the function since it might be recursive; | ||
| 160 | let mut task_inner_function = f.clone(); | ||
| 161 | let task_inner_function_ident = format_ident!("__{}_task_inner_function", task_ident); | ||
| 162 | task_inner_function.sig.ident = task_inner_function_ident.clone(); | ||
| 163 | task_inner_function.vis = Visibility::Inherited; | ||
| 164 | |||
| 152 | let task_inner_body = if errors.is_empty() { | 165 | let task_inner_body = if errors.is_empty() { |
| 153 | quote! { | 166 | quote! { |
| 154 | #f | 167 | #task_inner_function |
| 155 | 168 | ||
| 156 | // SAFETY: All the preconditions to `#task_ident` apply to | 169 | // SAFETY: All the preconditions to `#task_ident` apply to |
| 157 | // all contexts `#task_inner_ident` is called in | 170 | // all contexts `#task_inner_ident` is called in |
| 158 | #unsafety { | 171 | #unsafety { |
| 159 | #task_ident(#(#full_args,)*) | 172 | #task_inner_function_ident(#(#full_args,)*) |
| 160 | } | 173 | } |
| 161 | } | 174 | } |
| 162 | } else { | 175 | } else { |
