diff options
Diffstat (limited to 'embassy-executor-macros/src')
| -rw-r--r-- | embassy-executor-macros/src/macros/task.rs | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs index 91d6beee8..1c5e3571d 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(); |
| @@ -125,15 +131,21 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 125 | )); | 131 | )); |
| 126 | } | 132 | } |
| 127 | 133 | ||
| 134 | let spawn = if returns_impl_trait { | ||
| 135 | quote!(spawn) | ||
| 136 | } else { | ||
| 137 | quote!(_spawn_async_fn) | ||
| 138 | }; | ||
| 139 | |||
| 128 | #[cfg(feature = "nightly")] | 140 | #[cfg(feature = "nightly")] |
| 129 | let mut task_outer_body = quote! { | 141 | let mut task_outer_body = quote! { |
| 130 | trait _EmbassyInternalTaskTrait { | 142 | trait _EmbassyInternalTaskTrait { |
| 131 | type Fut: ::core::future::Future + 'static; | 143 | type Fut: ::core::future::Future<Output: #embassy_executor::_export::TaskReturnValue> + 'static; |
| 132 | fn construct(#fargs) -> Self::Fut; | 144 | fn construct(#fargs) -> Self::Fut; |
| 133 | } | 145 | } |
| 134 | 146 | ||
| 135 | impl _EmbassyInternalTaskTrait for () { | 147 | impl _EmbassyInternalTaskTrait for () { |
| 136 | type Fut = impl core::future::Future + 'static; | 148 | type Fut = impl core::future::Future<Output: #embassy_executor::_export::TaskReturnValue> + 'static; |
| 137 | fn construct(#fargs) -> Self::Fut { | 149 | fn construct(#fargs) -> Self::Fut { |
| 138 | #task_inner_ident(#(#full_args,)*) | 150 | #task_inner_ident(#(#full_args,)*) |
| 139 | } | 151 | } |
| @@ -141,7 +153,7 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 141 | 153 | ||
| 142 | const POOL_SIZE: usize = #pool_size; | 154 | const POOL_SIZE: usize = #pool_size; |
| 143 | static POOL: #embassy_executor::raw::TaskPool<<() as _EmbassyInternalTaskTrait>::Fut, POOL_SIZE> = #embassy_executor::raw::TaskPool::new(); | 155 | static POOL: #embassy_executor::raw::TaskPool<<() as _EmbassyInternalTaskTrait>::Fut, POOL_SIZE> = #embassy_executor::raw::TaskPool::new(); |
| 144 | unsafe { POOL._spawn_async_fn(move || <() as _EmbassyInternalTaskTrait>::construct(#(#full_args,)*)) } | 156 | unsafe { POOL.#spawn(move || <() as _EmbassyInternalTaskTrait>::construct(#(#full_args,)*)) } |
| 145 | }; | 157 | }; |
| 146 | #[cfg(not(feature = "nightly"))] | 158 | #[cfg(not(feature = "nightly"))] |
| 147 | let mut task_outer_body = quote! { | 159 | let mut task_outer_body = quote! { |
| @@ -158,7 +170,7 @@ pub fn run(args: TokenStream, item: TokenStream) -> TokenStream { | |||
| 158 | {#embassy_executor::_export::task_pool_size::<_, _, _, POOL_SIZE>(#task_inner_ident)}, | 170 | {#embassy_executor::_export::task_pool_size::<_, _, _, POOL_SIZE>(#task_inner_ident)}, |
| 159 | {#embassy_executor::_export::task_pool_align::<_, _, _, POOL_SIZE>(#task_inner_ident)}, | 171 | {#embassy_executor::_export::task_pool_align::<_, _, _, POOL_SIZE>(#task_inner_ident)}, |
| 160 | > = unsafe { ::core::mem::transmute(#embassy_executor::_export::task_pool_new::<_, _, _, POOL_SIZE>(#task_inner_ident)) }; | 172 | > = unsafe { ::core::mem::transmute(#embassy_executor::_export::task_pool_new::<_, _, _, POOL_SIZE>(#task_inner_ident)) }; |
| 161 | unsafe { __task_pool_get(#task_inner_ident)._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) } | 173 | unsafe { __task_pool_get(#task_inner_ident).#spawn(move || #task_inner_ident(#(#full_args,)*)) } |
| 162 | }; | 174 | }; |
| 163 | 175 | ||
| 164 | let task_outer_attrs = task_inner.attrs.clone(); | 176 | let task_outer_attrs = task_inner.attrs.clone(); |
