From 875a17f032124202ee5fd542b6db560a55c87cf2 Mon Sep 17 00:00:00 2001
From: Russel Arbore <russel.jma@gmail.com>
Date: Wed, 19 Feb 2025 21:22:12 -0600
Subject: [PATCH] Just add the type I want...

---
 hercules_cg/src/rt.rs  |  9 +++------
 hercules_rt/src/lib.rs | 42 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/hercules_cg/src/rt.rs b/hercules_cg/src/rt.rs
index beb83f51..d3013239 100644
--- a/hercules_cg/src/rt.rs
+++ b/hercules_cg/src/rt.rs
@@ -594,7 +594,7 @@ impl<'a> RTContext<'a> {
                     (_, true) => {
                         write!(block, "{}", self.clone_arc(id).unwrap())?;
                         format!(
-                            "*async_call_{}.lock().await = Some(::async_std::task::spawn(async move {{ ",
+                            "*async_call_{}.lock().await = ::hercules_rt::__FutureSlotWrapper::new(::async_std::task::spawn(async move {{ ",
                             id.idx(),
                         )
                     }
@@ -1106,7 +1106,7 @@ impl<'a> RTContext<'a> {
             if is_async_call {
                 write!(
                     w,
-                    "let mut async_call_{} = ::std::sync::Arc::new(::async_std::sync::Mutex::new(None));",
+                    "let mut async_call_{} = ::std::sync::Arc::new(::async_std::sync::Mutex::new(::hercules_rt::__FutureSlotWrapper::empty()));",
                     idx,
                 )?;
             } else {
@@ -1382,10 +1382,7 @@ impl<'a> RTContext<'a> {
             && func.schedules[id.idx()].contains(&Schedule::AsyncCall)
         {
             assert!(!lhs);
-            format!(
-                "async_call_{}.lock().await.as_mut().unwrap().await",
-                id.idx(),
-            )
+            format!("async_call_{}.lock().await.inspect().await", id.idx(),)
         } else {
             format!("node_{}", id.idx())
         }
diff --git a/hercules_rt/src/lib.rs b/hercules_rt/src/lib.rs
index 090a38a0..d19a0a5a 100644
--- a/hercules_rt/src/lib.rs
+++ b/hercules_rt/src/lib.rs
@@ -1,10 +1,10 @@
 #![feature(once_cell_try)]
 
 use std::alloc::{alloc, dealloc, GlobalAlloc, Layout, System};
+use std::future::Future;
 use std::marker::PhantomData;
 use std::ptr::{copy_nonoverlapping, write_bytes, NonNull};
 use std::slice::{from_raw_parts, from_raw_parts_mut};
-
 use std::sync::OnceLock;
 
 /*
@@ -426,6 +426,46 @@ impl __RawPtrSendSync {
 unsafe impl Send for __RawPtrSendSync {}
 unsafe impl Sync for __RawPtrSendSync {}
 
+#[derive(Clone, Debug)]
+pub struct __FutureSlotWrapper<T, F>
+where
+    T: Copy,
+    F: Future<Output = T>,
+{
+    future: Option<F>,
+    slot: Option<T>,
+}
+
+impl<T, F> __FutureSlotWrapper<T, F>
+where
+    T: Copy,
+    F: Future<Output = T>,
+{
+    pub fn empty() -> Self {
+        Self {
+            future: None,
+            slot: None,
+        }
+    }
+
+    pub fn new(f: F) -> Self {
+        Self {
+            future: Some(f),
+            slot: None,
+        }
+    }
+
+    pub async fn inspect(&mut self) -> T {
+        if let Some(slot) = self.slot {
+            slot
+        } else {
+            let result = self.future.take().unwrap().await;
+            self.slot = Some(result);
+            result
+        }
+    }
+}
+
 /*
  * A HerculesBox holds memory that can be on any device and provides a common interface to moving
  * data where it is needed.
-- 
GitLab