diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-04-25 22:18:52 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-25 22:18:52 +0200 |
| commit | c4cecec10ce262d605e65b47a4772d3b7ec3a543 (patch) | |
| tree | 91708cf98e502d0bb14c47fa9d7514a5d162d963 | |
| parent | b27feb061936d191f456edc22b2f89d4fc172520 (diff) | |
macros: isolate the TAIT into its own mod.
This fixes type inference issues due to the TAIT's defining scope
being the whole parent mod.
| -rw-r--r-- | embassy-macros/src/macros/task.rs | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/embassy-macros/src/macros/task.rs b/embassy-macros/src/macros/task.rs index 0cf6b423b..c37ad212c 100644 --- a/embassy-macros/src/macros/task.rs +++ b/embassy-macros/src/macros/task.rs | |||
| @@ -10,12 +10,10 @@ struct Args { | |||
| 10 | #[darling(default)] | 10 | #[darling(default)] |
| 11 | pool_size: Option<usize>, | 11 | pool_size: Option<usize>, |
| 12 | #[darling(default)] | 12 | #[darling(default)] |
| 13 | send: bool, | ||
| 14 | #[darling(default)] | ||
| 15 | embassy_prefix: ModulePrefix, | 13 | embassy_prefix: ModulePrefix, |
| 16 | } | 14 | } |
| 17 | 15 | ||
| 18 | pub fn run(args: syn::AttributeArgs, mut f: syn::ItemFn) -> Result<TokenStream, TokenStream> { | 16 | pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result<TokenStream, TokenStream> { |
| 19 | let args = Args::from_list(&args).map_err(|e| e.write_errors())?; | 17 | let args = Args::from_list(&args).map_err(|e| e.write_errors())?; |
| 20 | 18 | ||
| 21 | let embassy_prefix = args.embassy_prefix.append("embassy"); | 19 | let embassy_prefix = args.embassy_prefix.append("embassy"); |
| @@ -35,24 +33,27 @@ pub fn run(args: syn::AttributeArgs, mut f: syn::ItemFn) -> Result<TokenStream, | |||
| 35 | ctxt.error_spanned_by(&f.sig, "pool_size must be 1 or greater"); | 33 | ctxt.error_spanned_by(&f.sig, "pool_size must be 1 or greater"); |
| 36 | } | 34 | } |
| 37 | 35 | ||
| 38 | let mut arg_names: syn::punctuated::Punctuated<syn::Ident, syn::Token![,]> = | 36 | let mut arg_types = Vec::new(); |
| 39 | syn::punctuated::Punctuated::new(); | 37 | let mut arg_names = Vec::new(); |
| 38 | let mut arg_indexes = Vec::new(); | ||
| 40 | let mut fargs = f.sig.inputs.clone(); | 39 | let mut fargs = f.sig.inputs.clone(); |
| 41 | 40 | ||
| 42 | for arg in fargs.iter_mut() { | 41 | for (i, arg) in fargs.iter_mut().enumerate() { |
| 43 | match arg { | 42 | match arg { |
| 44 | syn::FnArg::Receiver(_) => { | 43 | syn::FnArg::Receiver(_) => { |
| 45 | ctxt.error_spanned_by(arg, "task functions must not have receiver arguments"); | 44 | ctxt.error_spanned_by(arg, "task functions must not have receiver arguments"); |
| 46 | } | 45 | } |
| 47 | syn::FnArg::Typed(t) => match t.pat.as_mut() { | 46 | syn::FnArg::Typed(t) => match t.pat.as_mut() { |
| 48 | syn::Pat::Ident(i) => { | 47 | syn::Pat::Ident(id) => { |
| 49 | arg_names.push(i.ident.clone()); | 48 | arg_names.push(id.ident.clone()); |
| 50 | i.mutability = None; | 49 | arg_types.push(t.ty.clone()); |
| 50 | arg_indexes.push(syn::Index::from(i)); | ||
| 51 | id.mutability = None; | ||
| 51 | } | 52 | } |
| 52 | _ => { | 53 | _ => { |
| 53 | ctxt.error_spanned_by( | 54 | ctxt.error_spanned_by( |
| 54 | arg, | 55 | arg, |
| 55 | "pattern matching in task arguments is not yet supporteds", | 56 | "pattern matching in task arguments is not yet supported", |
| 56 | ); | 57 | ); |
| 57 | } | 58 | } |
| 58 | }, | 59 | }, |
| @@ -63,40 +64,38 @@ pub fn run(args: syn::AttributeArgs, mut f: syn::ItemFn) -> Result<TokenStream, | |||
| 63 | 64 | ||
| 64 | let task_ident = f.sig.ident.clone(); | 65 | let task_ident = f.sig.ident.clone(); |
| 65 | let task_inner_ident = format_ident!("__{}_task", task_ident); | 66 | let task_inner_ident = format_ident!("__{}_task", task_ident); |
| 66 | let future_ident = format_ident!("__{}_Future", task_ident); | 67 | let mod_ident = format_ident!("__{}_mod", task_ident); |
| 67 | let pool_ident = format_ident!("__{}_POOL", task_ident); | 68 | let args_ident = format_ident!("__{}_args", task_ident); |
| 68 | let new_ts_ident = format_ident!("__{}_NEW_TASKSTORAGE", task_ident); | ||
| 69 | |||
| 70 | let visibility = &f.vis; | ||
| 71 | f.sig.ident = task_inner_ident.clone(); | ||
| 72 | let impl_ty = if args.send { | ||
| 73 | quote!(impl ::core::future::Future + Send + 'static) | ||
| 74 | } else { | ||
| 75 | quote!(impl ::core::future::Future + 'static) | ||
| 76 | }; | ||
| 77 | 69 | ||
| 78 | let attrs = &f.attrs; | 70 | let mut task_inner = f; |
| 79 | 71 | let visibility = task_inner.vis.clone(); | |
| 80 | let spawn_token = quote!(#embassy_path::executor::SpawnToken); | 72 | task_inner.vis = syn::Visibility::Inherited; |
| 81 | let task_storage = quote!(#embassy_path::executor::raw::TaskStorage); | 73 | task_inner.sig.ident = task_inner_ident.clone(); |
| 82 | 74 | ||
| 83 | let result = quote! { | 75 | let result = quote! { |
| 76 | #task_inner | ||
| 84 | 77 | ||
| 85 | #[allow(non_camel_case_types)] | 78 | #[allow(non_camel_case_types)] |
| 86 | type #future_ident = #impl_ty; | 79 | type #args_ident = (#(#arg_types,)*); |
| 80 | |||
| 81 | mod #mod_ident { | ||
| 82 | use #embassy_path::executor::SpawnToken; | ||
| 83 | use #embassy_path::executor::raw::TaskStorage; | ||
| 87 | 84 | ||
| 88 | #(#attrs)* | 85 | type Fut = impl ::core::future::Future + 'static; |
| 89 | #visibility fn #task_ident(#fargs) -> #spawn_token<#future_ident> { | ||
| 90 | #f | ||
| 91 | 86 | ||
| 92 | #[allow(non_upper_case_globals)] | ||
| 93 | #[allow(clippy::declare_interior_mutable_const)] | 87 | #[allow(clippy::declare_interior_mutable_const)] |
| 94 | const #new_ts_ident: #task_storage<#future_ident> = #task_storage::new(); | 88 | const NEW_TS: TaskStorage<Fut> = TaskStorage::new(); |
| 95 | 89 | ||
| 96 | #[allow(non_upper_case_globals)] | 90 | static POOL: [TaskStorage<Fut>; #pool_size] = [NEW_TS; #pool_size]; |
| 97 | static #pool_ident: [#task_storage<#future_ident>; #pool_size] = [#new_ts_ident; #pool_size]; | 91 | |
| 92 | pub(super) fn task(args: super::#args_ident) -> SpawnToken<Fut> { | ||
| 93 | unsafe { TaskStorage::spawn_pool(&POOL, move || super::#task_inner_ident(#(args.#arg_indexes),*)) } | ||
| 94 | } | ||
| 95 | } | ||
| 98 | 96 | ||
| 99 | unsafe { #task_storage::spawn_pool(&#pool_ident, move || #task_inner_ident(#arg_names)) } | 97 | #visibility fn #task_ident(#fargs) -> #embassy_path::executor::SpawnToken<impl ::core::future::Future + 'static> { |
| 98 | #mod_ident::task((#(#arg_names,)*)) | ||
| 100 | } | 99 | } |
| 101 | }; | 100 | }; |
| 102 | 101 | ||
