polish

Changed files
+49 -8
futures
src
combinators
+49 -8
futures/src/combinators/join.rs
··· 5 use std::mem; 6 use std::{pin::Pin, sync::atomic::Ordering}; 7 use std::{sync::atomic::AtomicBool, task::Poll}; 8 /// from yoshuawuyts/futures-concurrency 9 /// Wait for all futures to complete. 10 /// ··· 13 pub trait Join<'scope> { 14 /// The resulting output type. 15 type Output; 16 - /// The [`Future`] implementation returned by this method. 17 type Future: ScopedFuture<'scope, Output = Self::Output>; 18 /// Waits for multiple futures to complete. 19 /// ··· 87 } 88 89 macro_rules! impl_join_tuple { 90 - ($StructName:ident $($F:ident)+) => { 91 - #[allow(non_snake_case)] 92 - struct Wakers<'scope> { 93 - $($F: WakeStore<'scope>,)* 94 } 95 96 #[allow(non_snake_case)] 97 pub struct $StructName<'scope, $($F: ScopedFuture<'scope>),+> { 98 $($F: MaybeDone<'scope, $F>,)* 99 - wakers: Wakers<'scope>, 100 } 101 102 impl<'scope, $($F: ScopedFuture<'scope> + 'scope),+> ScopedFuture<'scope> ··· 113 114 if let MaybeDone::Future(fut) = &mut this.$F { 115 ready &= if this.wakers.$F.take_ready() { 116 unsafe { 117 Pin::new_unchecked(fut).poll( 118 mem::transmute::<&dyn Wake<'scope>, &'scope dyn Wake<'scope>>( ··· 129 if ready { 130 Poll::Ready(( 131 $( 132 unsafe { 133 Pin::new_unchecked(&mut this.$F) 134 .take_output() ··· 152 153 $StructName { 154 $($F: maybe_done($F),)* 155 - wakers: Wakers { $($F: WakeStore::new(),)* }, 156 } 157 } 158 } 159 }; 160 } 161 162 - impl_join_tuple!(Join2 A B);
··· 5 use std::mem; 6 use std::{pin::Pin, sync::atomic::Ordering}; 7 use std::{sync::atomic::AtomicBool, task::Poll}; 8 + 9 /// from yoshuawuyts/futures-concurrency 10 /// Wait for all futures to complete. 11 /// ··· 14 pub trait Join<'scope> { 15 /// The resulting output type. 16 type Output; 17 + /// The [`ScopedFuture`] implementation returned by this method. 18 type Future: ScopedFuture<'scope, Output = Self::Output>; 19 /// Waits for multiple futures to complete. 20 /// ··· 88 } 89 90 macro_rules! impl_join_tuple { 91 + ($namespace: ident $StructName:ident $($F:ident)+) => { 92 + 93 + mod $namespace { 94 + use super::WakeStore; 95 + 96 + #[allow(non_snake_case)] 97 + pub struct Wakers<'scope> { 98 + $(pub $F: WakeStore<'scope>,)* 99 + } 100 } 101 102 #[allow(non_snake_case)] 103 pub struct $StructName<'scope, $($F: ScopedFuture<'scope>),+> { 104 $($F: MaybeDone<'scope, $F>,)* 105 + wakers: $namespace::Wakers<'scope>, 106 } 107 108 impl<'scope, $($F: ScopedFuture<'scope> + 'scope),+> ScopedFuture<'scope> ··· 119 120 if let MaybeDone::Future(fut) = &mut this.$F { 121 ready &= if this.wakers.$F.take_ready() { 122 + // # Safety 123 + // 124 + // mem::transmute is necessary to convert between 125 + // `&'poll dyn Wake<'scope>` and 126 + // `&'scope dyn Wake<'scope>`, where `'poll` is the 127 + // lifetime implicitly assigned to the `&mut self` 128 + // argument. 129 + // 130 + // This is safe because 131 + // - `Self: 'scope` (all data inside `Join` live 132 + // for at least `'scope`) 133 + // - `this.wakers.$F` is pinned 134 + // - mutation to `this.wakers.$F.parent` doesn't 135 + // violate the `&'scope dyn Wake` 136 unsafe { 137 Pin::new_unchecked(fut).poll( 138 mem::transmute::<&dyn Wake<'scope>, &'scope dyn Wake<'scope>>( ··· 149 if ready { 150 Poll::Ready(( 151 $( 152 + // # Safety 153 + // 154 + // All $Fs start as `MaybeDone::Future`. 155 + // 156 + // `ready == true` is only hit when we know every 157 + // future either just finished or previously 158 + // finished, meaning they are all 159 + // `MaybeDone::Done`. 160 + // 161 + // `MaybeDone::Done::take_output()` always returns 162 + // the owned output of the inner future. 163 unsafe { 164 Pin::new_unchecked(&mut this.$F) 165 .take_output() ··· 183 184 $StructName { 185 $($F: maybe_done($F),)* 186 + wakers: $namespace::Wakers { $($F: WakeStore::new(),)* }, 187 } 188 } 189 } 190 }; 191 } 192 193 + impl_join_tuple!(join2 Join2 A B); 194 + impl_join_tuple!(join3 Join3 A B C); 195 + impl_join_tuple!(join4 Join4 A B C D); 196 + impl_join_tuple!(join5 Join5 A B C D E); 197 + impl_join_tuple!(join6 Join6 A B C D E F); 198 + impl_join_tuple!(join7 Join7 A B C D E F G); 199 + impl_join_tuple!(join8 Join8 A B C D E F G H); 200 + impl_join_tuple!(join9 Join9 A B C D E F G H I); 201 + impl_join_tuple!(join10 Join10 A B C D E F G H I J); 202 + impl_join_tuple!(join11 Join11 A B C D E F G H I J K); 203 + impl_join_tuple!(join12 Join12 A B C D E F G H I J K L);