From bfa81495b1808d7a21b752a6bcc46d5356cb2d58 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 27 Jun 2024 19:48:25 +0200 Subject: [PATCH] better join --- async-experiments/src/{join.rs => join2.rs} | 5 +++++ async-experiments/src/lib.rs | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) rename async-experiments/src/{join.rs => join2.rs} (86%) diff --git a/async-experiments/src/join.rs b/async-experiments/src/join2.rs similarity index 86% rename from async-experiments/src/join.rs rename to async-experiments/src/join2.rs index 7b256a4..e3651bf 100644 --- a/async-experiments/src/join.rs +++ b/async-experiments/src/join2.rs @@ -34,10 +34,15 @@ impl Future for Join2 { type Output = (F1::Output, F2::Output); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // SAFETY: We must never move out of `this`. + // We do indeed not do this, except we do, when the future complets. + // This is okay, as we do this after dropping it. + // We also never expose a `&mut` to anyone. let this = unsafe { self.get_unchecked_mut() }; fn make_progress(field: &mut JoinState, cx: &mut Context<'_>) { match field { + // SAFETY: This is just projecting the pin into the field. JoinState::Pending(fut) => match unsafe { Pin::new_unchecked(fut) }.poll(cx) { Poll::Ready(result) => { *field = JoinState::Ready(result); diff --git a/async-experiments/src/lib.rs b/async-experiments/src/lib.rs index 2ac21ae..b08e90f 100644 --- a/async-experiments/src/lib.rs +++ b/async-experiments/src/lib.rs @@ -1,7 +1,7 @@ mod executor; mod spawn_blocking; -mod join; +mod join2; pub use executor::*; pub use spawn_blocking::*; -pub use join::*; +pub use join2::*;