From 1073962e37d1a9464f2f2da3c927b947277f38c1 Mon Sep 17 00:00:00 2001 From: Asa Paparo Date: Thu, 17 Jul 2025 02:48:06 -0400 Subject: [PATCH] formatted? --- .gitignore | 1 + futures/src/combinators/join.rs | 94 +++++++-------------------------- futures/src/future.rs | 5 +- futures/src/lib.rs | 2 - futures/src/utils/maybe_done.rs | 18 +++++-- rustfmt.toml | 1 + 6 files changed, 40 insertions(+), 81 deletions(-) create mode 100644 rustfmt.toml diff --git a/.gitignore b/.gitignore index 9d61051..dfe6f47 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,6 @@ !flake.nix !rust-toolchain.toml !README.md +!rustfmt.toml !/futures/ !/futures/** diff --git a/futures/src/combinators/join.rs b/futures/src/combinators/join.rs index 829050c..a1f2807 100644 --- a/futures/src/combinators/join.rs +++ b/futures/src/combinators/join.rs @@ -5,7 +5,6 @@ use crate::{ use std::mem; use std::{pin::Pin, sync::atomic::Ordering}; use std::{sync::atomic::AtomicBool, task::Poll}; - /// from yoshuawuyts/futures-concurrency /// Wait for all futures to complete. /// @@ -14,10 +13,8 @@ use std::{sync::atomic::AtomicBool, task::Poll}; pub trait Join<'scope> { /// The resulting output type. type Output; - /// The [`Future`] implementation returned by this method. type Future: ScopedFuture<'scope, Output = Self::Output>; - /// Waits for multiple futures to complete. /// /// Awaits multiple futures simultaneously, returning the output of the futures @@ -65,56 +62,10 @@ pub trait Join<'scope> { /// This function returns a new future which polls all futures concurrently. fn join(self) -> Self::Future; } - -// "look at what they need for a fraction of our power" (more efficient join impl is regular join here) -// https://github.com/yoshuawuyts/futures-concurrency/blob/main/src/utils/wakers/array/waker.rs -// possibly copy large portions of futures-concurrency over here - -// struct Waker<'scope> { -// parent_waker: Wake<'scope>, -// } - -// impl<'scope> Waker<'scope> { -// fn wake(&mut self) { -// (*self.parent_waker)(); -// } -// } - -// /// implements unsafe logic for a set of wakers waking one waker -// pub struct WakerArray<'scope, const N: usize> { -// parent_waker: Option<&'scope dyn Wake<'scope>>, -// // TODO bit packing -// child_readiness: [bool; N], -// pub child_wakers: Option<[Waker<'scope>; N]>, -// } - -// impl<'scope, const N: usize> WakerArray<'scope, N> { -// fn new() -> Self { -// Self { -// parent_waker: None, -// child_readiness: [false; N], -// child_wakers: None, -// } -// } - -// fn register_parent_wake(&mut self, wake: Wake<'scope>) { -// self.parent_waker = Some(wake); -// self.child_wakers = Some( -// [Waker { -// parent_waker: &self.parent_waker, -// }; N], -// ); -// } -// } - -// would be rly nice if rust had java functional interfaces for wake(&mut Self) - struct WakeStore<'scope> { - // no extra storage bc None is 0x000 ptr parent: Option<&'scope dyn Wake<'scope>>, ready: AtomicBool, } - impl<'scope> WakeStore<'scope> { fn new() -> Self { Self { @@ -122,12 +73,10 @@ impl<'scope> WakeStore<'scope> { ready: true.into(), } } - fn take_ready(&mut self) -> bool { self.ready.swap(false, Ordering::SeqCst) } } - impl<'scope> Wake<'scope> for WakeStore<'scope> { fn wake(&self) { self.ready.swap(true, Ordering::SeqCst); @@ -137,34 +86,26 @@ impl<'scope> Wake<'scope> for WakeStore<'scope> { } } -// heavily based on https://github.com/yoshuawuyts/futures-concurrency macro_rules! impl_join_tuple { ($StructName:ident $($F:ident)+) => { - - // this exists to work around concatenating idents - // once https://doc.rust-lang.org/stable/unstable-book/language-features/macro-metavar-expr-concat.html is stable, the $StructName can just contain - // future_$F and waker_$F #[allow(non_snake_case)] struct Wakers<'scope> { - // inefficient, needs tt muncher for actual [T; LEN] traversal, fewer cache misses $($F: WakeStore<'scope>,)* } #[allow(non_snake_case)] pub struct $StructName<'scope, $($F: ScopedFuture<'scope>),+> { - // parent_waker: Option<&'scope dyn Wake>, $($F: MaybeDone<'scope, $F>,)* wakers: Wakers<'scope>, } - impl<'scope, $($F: ScopedFuture<'scope> + 'scope),+> ScopedFuture<'scope> for $StructName<'scope, $($F),+> + impl<'scope, $($F: ScopedFuture<'scope> + 'scope),+> ScopedFuture<'scope> + for $StructName<'scope, $($F),+> { type Output = ($($F::Output),+); - fn poll(self: Pin<&mut Self>, wake: &'scope dyn Wake<'scope>) -> Poll - { + fn poll(self: Pin<&mut Self>, wake: &'scope dyn Wake<'scope>) -> Poll { let this = unsafe { self.get_unchecked_mut() }; - let mut ready = true; $( @@ -173,7 +114,11 @@ macro_rules! impl_join_tuple { if let MaybeDone::Future(fut) = &mut this.$F { ready &= if this.wakers.$F.take_ready() { unsafe { - Pin::new_unchecked(fut).poll(mem::transmute(&this.wakers.$F as &dyn Wake)).is_ready() + Pin::new_unchecked(fut).poll( + mem::transmute::<&dyn Wake<'scope>, &'scope dyn Wake<'scope>>( + &this.wakers.$F + ) + ).is_ready() } } else { false @@ -182,17 +127,18 @@ macro_rules! impl_join_tuple { )+ if ready { - Poll::Ready(($( - // unwrap_unchecked is safe here because we know all - // futures have been polled to completion - // (`MaybeDone::Done`) and have never been converted - // to `MaybeDone::Gone` - unsafe { Pin::new_unchecked(&mut this.$F).take_output().unwrap_unchecked() }, - )*)) + Poll::Ready(( + $( + unsafe { + Pin::new_unchecked(&mut this.$F) + .take_output() + .unwrap_unchecked() + }, + )* + )) } else { Poll::Pending } - } } @@ -202,11 +148,11 @@ macro_rules! impl_join_tuple { #[allow(non_snake_case)] fn join(self) -> Self::Future { - let ($($F),+): ($($F),+) = self; + let ($($F),+) = self; + $StructName { - // parent_waker: Option::None, $($F: maybe_done($F),)* - wakers: Wakers { $($F: WakeStore::new(),)* } + wakers: Wakers { $($F: WakeStore::new(),)* }, } } } diff --git a/futures/src/future.rs b/futures/src/future.rs index 2da239e..dea5f6e 100644 --- a/futures/src/future.rs +++ b/futures/src/future.rs @@ -52,5 +52,8 @@ pub trait Wake<'scope> { pub trait ScopedFuture<'scope> { type Output; - fn poll(self: Pin<&mut Self>, wake: &'scope dyn Wake<'scope>) -> Poll; + fn poll( + self: Pin<&mut Self>, + wake: &'scope dyn Wake<'scope>, + ) -> Poll; } diff --git a/futures/src/lib.rs b/futures/src/lib.rs index 4e91420..314b0f0 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -2,8 +2,6 @@ mod combinators; mod future; mod utils; -use std::{pin::Pin, task::Poll}; - /// from yoshuawuyts/futures-concurrency /// Wait for all futures to complete. /// diff --git a/futures/src/utils/maybe_done.rs b/futures/src/utils/maybe_done.rs index 17306ef..d5fa7c3 100644 --- a/futures/src/utils/maybe_done.rs +++ b/futures/src/utils/maybe_done.rs @@ -21,7 +21,10 @@ pub enum MaybeDone<'scope, Fut: ScopedFuture<'scope>> { Gone, } -impl<'scope, Fut: ScopedFuture<'scope> + Unpin> Unpin for MaybeDone<'scope, Fut> {} +impl<'scope, Fut: ScopedFuture<'scope> + Unpin> Unpin + for MaybeDone<'scope, Fut> +{ +} /// Wraps a future into a `MaybeDone` /// @@ -41,7 +44,9 @@ impl<'scope, Fut: ScopedFuture<'scope> + Unpin> Unpin for MaybeDone<'scope, Fut> /// assert_eq!(future.as_mut().take_output(), None); /// # }); /// ``` -pub fn maybe_done<'scope, Fut: ScopedFuture<'scope>>(future: Fut) -> MaybeDone<'scope, Fut> { +pub fn maybe_done<'scope, Fut: ScopedFuture<'scope>>( + future: Fut, +) -> MaybeDone<'scope, Fut> { assert_future::<(), _>(MaybeDone::Future(future)) } @@ -86,10 +91,15 @@ impl<'scope, Fut: ScopedFuture<'scope>> MaybeDone<'scope, Fut> { // } // } -impl<'scope, Fut: ScopedFuture<'scope>> ScopedFuture<'scope> for MaybeDone<'scope, Fut> { +impl<'scope, Fut: ScopedFuture<'scope>> ScopedFuture<'scope> + for MaybeDone<'scope, Fut> +{ type Output = (); - fn poll(mut self: Pin<&mut Self>, cx: &'scope dyn Wake<'scope>) -> Poll + fn poll( + mut self: Pin<&mut Self>, + cx: &'scope dyn Wake<'scope>, + ) -> Poll // where // 'scope: 'react, { diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..df99c69 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +max_width = 80 -- 2.51.2