diff --git a/embassy-executor-macros/src/macros/task.rs b/embassy-executor-macros/src/macros/task.rs
index 1efb2788b..82579cbbe 100644
--- a/embassy-executor-macros/src/macros/task.rs
+++ b/embassy-executor-macros/src/macros/task.rs
@@ -93,10 +93,22 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
     #[cfg(feature = "nightly")]
     let mut task_outer: ItemFn = parse_quote! {
         #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
-            type Fut = impl ::core::future::Future + 'static;
+            trait Task {
+                type Fut: core::future::Future + 'static;
+                fn construct(#fargs) -> Self::Fut;
+            }
+
+            struct ThisTask;
+            impl Task for ThisTask {
+                type Fut = impl core::future::Future + 'static;
+                fn construct(#fargs) -> Self::Fut {
+                    #task_inner_ident(#(#full_args,)*)
+                }
+            }
+
             const POOL_SIZE: usize = #pool_size;
-            static POOL: ::embassy_executor::raw::TaskPool<Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new();
-            unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) }
+            static POOL: ::embassy_executor::raw::TaskPool<<ThisTask as Task>::Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new();
+            unsafe { POOL._spawn_async_fn(move || ThisTask::construct(#(#full_args,)*)) }
         }
     };
     #[cfg(not(feature = "nightly"))]