From 201adb7406d3265abd76f49c04dbafbf2ee00301 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 17 Feb 2024 16:50:23 -0500 Subject: [PATCH] clone values for Futures --- .../computed/async_derived/async_derived.rs | 7 +++-- .../computed/async_derived/future_impls.rs | 26 +++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/reactive_graph/src/computed/async_derived/async_derived.rs b/reactive_graph/src/computed/async_derived/async_derived.rs index 81075f94a..ea2a7268d 100644 --- a/reactive_graph/src/computed/async_derived/async_derived.rs +++ b/reactive_graph/src/computed/async_derived/async_derived.rs @@ -135,8 +135,11 @@ impl DefinedAt for AsyncDerived { } } -impl IntoFuture for AsyncDerived { - type Output = ReadGuard>, T>>; +impl IntoFuture for AsyncDerived +where + T: Clone, +{ + type Output = T; type IntoFuture = AsyncDerivedFuture; #[track_caller] diff --git a/reactive_graph/src/computed/async_derived/future_impls.rs b/reactive_graph/src/computed/async_derived/future_impls.rs index 43c5b7fb9..7ec7ab312 100644 --- a/reactive_graph/src/computed/async_derived/future_impls.rs +++ b/reactive_graph/src/computed/async_derived/future_impls.rs @@ -44,8 +44,11 @@ pub struct AsyncDerivedFuture { wakers: Arc>>, } -impl IntoFuture for ArcAsyncDerived { - type Output = ReadGuard>, T>>; +impl IntoFuture for ArcAsyncDerived +where + T: Clone + 'static, +{ + type Output = T; type IntoFuture = AsyncDerivedFuture; fn into_future(self) -> Self::IntoFuture { @@ -57,8 +60,13 @@ impl IntoFuture for ArcAsyncDerived { } } -impl Future for AsyncDerivedFuture { - type Output = ReadGuard>, T>>; +// this is implemented to output T by cloning it because read guards should not be held across +// .await points, and it's way too easy to trip up by doing that! +impl Future for AsyncDerivedFuture +where + T: Clone + 'static, +{ + type Output = T; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let waker = cx.waker(); @@ -70,15 +78,7 @@ impl Future for AsyncDerivedFuture { self.wakers.write().or_poisoned().push(waker.clone()); Poll::Pending } - AsyncState::Complete(_) => { - Poll::Ready(ReadGuard::new(Mapped::new(value, |inner| { - match inner { - AsyncState::Complete(value) => value, - // we've just checked this value is Complete - _ => unreachable!(), - } - }))) - } + AsyncState::Complete(value) => Poll::Ready(value.clone()), } } }