Improving our example 4-pinning to the rescue 247 It won't even let us poll the future anymore without us pinning it first since poll is only callable for Pin<&mut Self> types and not &mut self anymore. So, we have to decide whether we pin the value to the stack or the heap before we even try to poll it. In our case, our whole executor works by heap allocating futures, so that's the only thing that makes sense to do. Let's remove our optimization entirely and change one line of code to make our executor work again: ch09/e-coroutines-pin/src/runtime/executor. rs match future. as_mut(). poll(&waker) { If you try to run the program again by writing cargo run, you should get the expected output back and not have to worry about the coroutine/wait generated futures being moved again (the output has been abbreviated slightly): Finished dev [unoptimized + debuginfo] target(s) in 0. 02s Running `target\debug\e-coroutines-pin. exe` Program starting FIRST POLL-START OPERATION main: 1 pending tasks. Sleep until notified. FIRST POLL-START OPERATION main: 1 pending tasks. Sleep until notified. BUFFER:----HTTP/1. 1 200 OK content-length: 15 [=== ABBREVIATED ===] date: Sun, 03 Dec 2023 23:18:12 GMT Hello Async Await main: All tasks are finished Y ou now have self-referential coroutines that can safely store both data and references across wait points. Congratulations! Even though making these changes took up quite a few pages, the changes themselves were part pretty trivial for the most part. Most of the changes were due to Pin having a different API than what we had when using references before. The good thing is that this sets us up nicely for migrating our whole runtime over to futures created by async/await instead of our own futures created by coroutine/wait with very few changes.