From a88e11011e33df8e6345b1a8527447f3dd5399c5 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Wed, 19 Jul 2023 19:00:04 +0000 Subject: [PATCH 1/8] Add constraints for TryFuture supertrait --- futures-core/src/future.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/futures-core/src/future.rs b/futures-core/src/future.rs index 7540cd027e..acff93cbcb 100644 --- a/futures-core/src/future.rs +++ b/futures-core/src/future.rs @@ -55,7 +55,9 @@ mod private_try_future { /// A convenience for futures that return `Result` values that includes /// a variety of adapters tailored to such futures. -pub trait TryFuture: Future + private_try_future::Sealed { +pub trait TryFuture: + Future> + private_try_future::Sealed +{ /// The type of successful values yielded by this future type Ok; From 60bcaed15e76c7a1b585cb4b39ae0a5fc671a6e7 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Wed, 19 Jul 2023 19:00:40 +0000 Subject: [PATCH 2/8] Remove IntoFuture in trait bounds --- futures-util/src/future/try_future/mod.rs | 24 +++++++++---------- futures-util/src/future/try_join_all.rs | 9 ++++--- .../stream/try_stream/try_buffer_unordered.rs | 5 ++-- .../src/stream/try_stream/try_buffered.rs | 5 ++-- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/futures-util/src/future/try_future/mod.rs b/futures-util/src/future/try_future/mod.rs index e5bc700714..b2ef4c2d19 100644 --- a/futures-util/src/future/try_future/mod.rs +++ b/futures-util/src/future/try_future/mod.rs @@ -89,15 +89,15 @@ delegate_all!( delegate_all!( /// Future for the [`inspect_ok`](super::TryFutureExt::inspect_ok) method. InspectOk( - Inspect, InspectOkFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_ok_fn(f))] + Inspect> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(x, inspect_ok_fn(f))] ); delegate_all!( /// Future for the [`inspect_err`](super::TryFutureExt::inspect_err) method. InspectErr( - Inspect, InspectErrFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_err_fn(f))] + Inspect> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(x, inspect_err_fn(f))] ); #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 @@ -106,29 +106,29 @@ pub use self::into_future::IntoFuture; delegate_all!( /// Future for the [`map_ok`](TryFutureExt::map_ok) method. MapOk( - Map, MapOkFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_ok_fn(f))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(x, map_ok_fn(f))] ); delegate_all!( /// Future for the [`map_err`](TryFutureExt::map_err) method. MapErr( - Map, MapErrFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_err_fn(f))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(x, map_err_fn(f))] ); delegate_all!( /// Future for the [`map_ok_or_else`](TryFutureExt::map_ok_or_else) method. MapOkOrElse( - Map, MapOkOrElseFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(IntoFuture::new(x), map_ok_or_else_fn(f, g))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(x, map_ok_or_else_fn(f, g))] ); delegate_all!( /// Future for the [`unwrap_or_else`](TryFutureExt::unwrap_or_else) method. UnwrapOrElse( - Map, UnwrapOrElseFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), unwrap_or_else_fn(f))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(x, unwrap_or_else_fn(f))] ); impl TryFutureExt for Fut {} diff --git a/futures-util/src/future/try_join_all.rs b/futures-util/src/future/try_join_all.rs index 506f450657..bda8bc87b1 100644 --- a/futures-util/src/future/try_join_all.rs +++ b/futures-util/src/future/try_join_all.rs @@ -10,11 +10,10 @@ use core::mem; use core::pin::Pin; use core::task::{Context, Poll}; -use super::{assert_future, join_all, IntoFuture, TryFuture, TryMaybeDone}; +use super::{assert_future, join_all, TryFuture, TryMaybeDone}; #[cfg(not(futures_no_atomic_cas))] use crate::stream::{FuturesOrdered, TryCollect, TryStreamExt}; -use crate::TryFutureExt; enum FinalState { Pending, @@ -36,11 +35,11 @@ where F: TryFuture, { Small { - elems: Pin>]>>, + elems: Pin]>>, }, #[cfg(not(futures_no_atomic_cas))] Big { - fut: TryCollect>, Vec>, + fut: TryCollect, Vec>, }, } @@ -119,7 +118,7 @@ where I: IntoIterator, I::Item: TryFuture, { - let iter = iter.into_iter().map(TryFutureExt::into_future); + let iter = iter.into_iter(); #[cfg(futures_no_atomic_cas)] { diff --git a/futures-util/src/stream/try_stream/try_buffer_unordered.rs b/futures-util/src/stream/try_stream/try_buffer_unordered.rs index 21b00b20ac..1d3c38b1d9 100644 --- a/futures-util/src/stream/try_stream/try_buffer_unordered.rs +++ b/futures-util/src/stream/try_stream/try_buffer_unordered.rs @@ -1,4 +1,3 @@ -use crate::future::{IntoFuture, TryFutureExt}; use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt}; use core::num::NonZeroUsize; use core::pin::Pin; @@ -19,7 +18,7 @@ pin_project! { { #[pin] stream: Fuse>, - in_progress_queue: FuturesUnordered>, + in_progress_queue: FuturesUnordered, max: Option, } } @@ -54,7 +53,7 @@ where // our queue of futures. Propagate errors from the stream immediately. while this.max.map(|max| this.in_progress_queue.len() < max.get()).unwrap_or(true) { match this.stream.as_mut().poll_next(cx)? { - Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut.into_future()), + Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut), Poll::Ready(None) | Poll::Pending => break, } } diff --git a/futures-util/src/stream/try_stream/try_buffered.rs b/futures-util/src/stream/try_stream/try_buffered.rs index 83e9093fbc..6b9dd0f7ec 100644 --- a/futures-util/src/stream/try_stream/try_buffered.rs +++ b/futures-util/src/stream/try_stream/try_buffered.rs @@ -1,4 +1,3 @@ -use crate::future::{IntoFuture, TryFutureExt}; use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt}; use core::num::NonZeroUsize; use core::pin::Pin; @@ -20,7 +19,7 @@ pin_project! { { #[pin] stream: Fuse>, - in_progress_queue: FuturesOrdered>, + in_progress_queue: FuturesOrdered, max: Option, } } @@ -55,7 +54,7 @@ where // our queue of futures. Propagate errors from the stream immediately. while this.max.map(|max| this.in_progress_queue.len() < max.get()).unwrap_or(true) { match this.stream.as_mut().poll_next(cx)? { - Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut.into_future()), + Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut), Poll::Ready(None) | Poll::Pending => break, } } From 75e53ff6a9891471714330207fde9c02986f6cba Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Wed, 19 Jul 2023 19:07:47 +0000 Subject: [PATCH 3/8] Remove try_poll --- futures-core/src/future.rs | 21 ++++--------------- futures-util/src/compat/compat03as01.rs | 2 +- futures-util/src/future/select_ok.rs | 4 ++-- .../src/future/try_future/into_future.rs | 2 +- futures-util/src/future/try_future/mod.rs | 16 +------------- .../src/future/try_future/try_flatten.rs | 8 +++---- .../src/future/try_future/try_flatten_err.rs | 4 ++-- futures-util/src/future/try_join_all.rs | 2 +- futures-util/src/future/try_maybe_done.rs | 2 +- futures-util/src/future/try_select.rs | 6 +++--- futures-util/src/stream/stream/try_fold.rs | 2 +- .../src/stream/stream/try_for_each.rs | 2 +- .../src/stream/try_stream/and_then.rs | 2 +- futures-util/src/stream/try_stream/or_else.rs | 2 +- .../src/stream/try_stream/try_filter_map.rs | 2 +- .../src/stream/try_stream/try_skip_while.rs | 2 +- .../src/stream/try_stream/try_take_while.rs | 2 +- .../src/stream/try_stream/try_unfold.rs | 2 +- 18 files changed, 28 insertions(+), 55 deletions(-) diff --git a/futures-core/src/future.rs b/futures-core/src/future.rs index acff93cbcb..caf53d9fb9 100644 --- a/futures-core/src/future.rs +++ b/futures-core/src/future.rs @@ -2,7 +2,6 @@ use core::ops::DerefMut; use core::pin::Pin; -use core::task::{Context, Poll}; #[doc(no_inline)] pub use core::future::Future; @@ -20,10 +19,10 @@ pub type LocalBoxFuture<'a, T> = Pin + /// should no longer be polled. /// /// `is_terminated` will return `true` if a future should no longer be polled. -/// Usually, this state occurs after `poll` (or `try_poll`) returned -/// `Poll::Ready`. However, `is_terminated` may also return `true` if a future -/// has become inactive and can no longer make progress and should be ignored -/// or dropped rather than being `poll`ed again. +/// Usually, this state occurs after `poll` returned `Poll::Ready`. However, +/// `is_terminated` may also return `true` if a future has become inactive +/// and can no longer make progress and should be ignored or dropped rather +/// than being `poll`ed again. pub trait FusedFuture: Future { /// Returns `true` if the underlying future should no longer be polled. fn is_terminated(&self) -> bool; @@ -63,13 +62,6 @@ pub trait TryFuture: /// The type of failures yielded by this future type Error; - - /// Poll this `TryFuture` as if it were a `Future`. - /// - /// This method is a stopgap for a compiler limitation that prevents us from - /// directly inheriting from the `Future` trait; in the future it won't be - /// needed. - fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; } impl TryFuture for F @@ -78,11 +70,6 @@ where { type Ok = T; type Error = E; - - #[inline] - fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.poll(cx) - } } #[cfg(feature = "alloc")] diff --git a/futures-util/src/compat/compat03as01.rs b/futures-util/src/compat/compat03as01.rs index 5d3a6e920b..5617353f26 100644 --- a/futures-util/src/compat/compat03as01.rs +++ b/futures-util/src/compat/compat03as01.rs @@ -102,7 +102,7 @@ where type Error = Fut::Error; fn poll(&mut self) -> Poll01 { - with_context(self, |inner, cx| poll_03_to_01(inner.try_poll(cx))) + with_context(self, |inner, cx| poll_03_to_01(inner.poll(cx))) } } diff --git a/futures-util/src/future/select_ok.rs b/futures-util/src/future/select_ok.rs index 5d5579930b..afb4c865f9 100644 --- a/futures-util/src/future/select_ok.rs +++ b/futures-util/src/future/select_ok.rs @@ -1,5 +1,5 @@ use super::assert_future; -use crate::future::TryFutureExt; +use crate::future::FutureExt; use alloc::vec::Vec; use core::iter::FromIterator; use core::mem; @@ -49,7 +49,7 @@ impl Future for SelectOk { // loop until we've either exhausted all errors, a success was hit, or nothing is ready loop { let item = - self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) { + self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.poll_unpin(cx) { Poll::Pending => None, Poll::Ready(e) => Some((i, e)), }); diff --git a/futures-util/src/future/try_future/into_future.rs b/futures-util/src/future/try_future/into_future.rs index 9f093d0e2e..05160e144e 100644 --- a/futures-util/src/future/try_future/into_future.rs +++ b/futures-util/src/future/try_future/into_future.rs @@ -31,6 +31,6 @@ impl Future for IntoFuture { #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.project().future.try_poll(cx) + self.project().future.poll(cx) } } diff --git a/futures-util/src/future/try_future/mod.rs b/futures-util/src/future/try_future/mod.rs index b2ef4c2d19..12f9ba73a1 100644 --- a/futures-util/src/future/try_future/mod.rs +++ b/futures-util/src/future/try_future/mod.rs @@ -5,12 +5,7 @@ #[cfg(feature = "compat")] use crate::compat::Compat; -use core::pin::Pin; -use futures_core::{ - future::TryFuture, - stream::TryStream, - task::{Context, Poll}, -}; +use futures_core::{future::TryFuture, stream::TryStream}; #[cfg(feature = "sink")] use futures_sink::Sink; @@ -613,13 +608,4 @@ pub trait TryFutureExt: TryFuture { { assert_future::, _>(IntoFuture::new(self)) } - - /// A convenience method for calling [`TryFuture::try_poll`] on [`Unpin`] - /// future types. - fn try_poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll> - where - Self: Unpin, - { - Pin::new(self).try_poll(cx) - } } diff --git a/futures-util/src/future/try_future/try_flatten.rs b/futures-util/src/future/try_future/try_flatten.rs index 4587ae8493..2749122b03 100644 --- a/futures-util/src/future/try_future/try_flatten.rs +++ b/futures-util/src/future/try_future/try_flatten.rs @@ -43,7 +43,7 @@ where fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(loop { match self.as_mut().project() { - TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { + TryFlattenProj::First { f } => match ready!(f.poll(cx)) { Ok(f) => self.set(Self::Second { f }), Err(e) => { self.set(Self::Empty); @@ -51,7 +51,7 @@ where } }, TryFlattenProj::Second { f } => { - let output = ready!(f.try_poll(cx)); + let output = ready!(f.poll(cx)); self.set(Self::Empty); break output; } @@ -81,7 +81,7 @@ where fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Poll::Ready(loop { match self.as_mut().project() { - TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { + TryFlattenProj::First { f } => match ready!(f.poll(cx)) { Ok(f) => self.set(Self::Second { f }), Err(e) => { self.set(Self::Empty); @@ -112,7 +112,7 @@ where fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Poll::Ready(loop { match self.as_mut().project() { - TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { + TryFlattenProj::First { f } => match ready!(f.poll(cx)) { Ok(f) => self.set(Self::Second { f }), Err(e) => { self.set(Self::Empty); diff --git a/futures-util/src/future/try_future/try_flatten_err.rs b/futures-util/src/future/try_future/try_flatten_err.rs index 6b371644d5..d56d77a76f 100644 --- a/futures-util/src/future/try_future/try_flatten_err.rs +++ b/futures-util/src/future/try_future/try_flatten_err.rs @@ -40,7 +40,7 @@ where fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(loop { match self.as_mut().project() { - TryFlattenErrProj::First { f } => match ready!(f.try_poll(cx)) { + TryFlattenErrProj::First { f } => match ready!(f.poll(cx)) { Err(f) => self.set(Self::Second { f }), Ok(e) => { self.set(Self::Empty); @@ -48,7 +48,7 @@ where } }, TryFlattenErrProj::Second { f } => { - let output = ready!(f.try_poll(cx)); + let output = ready!(f.poll(cx)); self.set(Self::Empty); break output; } diff --git a/futures-util/src/future/try_join_all.rs b/futures-util/src/future/try_join_all.rs index bda8bc87b1..946bb1cd64 100644 --- a/futures-util/src/future/try_join_all.rs +++ b/futures-util/src/future/try_join_all.rs @@ -158,7 +158,7 @@ where let mut state = FinalState::AllDone; for elem in join_all::iter_pin_mut(elems.as_mut()) { - match elem.try_poll(cx) { + match elem.poll(cx) { Poll::Pending => state = FinalState::Pending, Poll::Ready(Ok(())) => {} Poll::Ready(Err(e)) => { diff --git a/futures-util/src/future/try_maybe_done.rs b/futures-util/src/future/try_maybe_done.rs index 24044d2c27..4cb19a49ef 100644 --- a/futures-util/src/future/try_maybe_done.rs +++ b/futures-util/src/future/try_maybe_done.rs @@ -76,7 +76,7 @@ impl Future for TryMaybeDone { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { unsafe { match self.as_mut().get_unchecked_mut() { - TryMaybeDone::Future(f) => match ready!(Pin::new_unchecked(f).try_poll(cx)) { + TryMaybeDone::Future(f) => match ready!(Pin::new_unchecked(f).poll(cx)) { Ok(res) => self.set(Self::Done(res)), Err(e) => { self.set(Self::Gone); diff --git a/futures-util/src/future/try_select.rs b/futures-util/src/future/try_select.rs index bc282f7db1..1c79fea928 100644 --- a/futures-util/src/future/try_select.rs +++ b/futures-util/src/future/try_select.rs @@ -1,4 +1,4 @@ -use crate::future::{Either, TryFutureExt}; +use crate::future::{Either, FutureExt}; use core::pin::Pin; use futures_core::future::{Future, TryFuture}; use futures_core::task::{Context, Poll}; @@ -69,10 +69,10 @@ where fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let (mut a, mut b) = self.inner.take().expect("cannot poll Select twice"); - match a.try_poll_unpin(cx) { + match a.poll_unpin(cx) { Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Left((x, b)))), Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Left((x, b)))), - Poll::Pending => match b.try_poll_unpin(cx) { + Poll::Pending => match b.poll_unpin(cx) { Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Right((x, a)))), Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Right((x, a)))), Poll::Pending => { diff --git a/futures-util/src/stream/stream/try_fold.rs b/futures-util/src/stream/stream/try_fold.rs index fcbc0aef24..e02771234a 100644 --- a/futures-util/src/stream/stream/try_fold.rs +++ b/futures-util/src/stream/stream/try_fold.rs @@ -70,7 +70,7 @@ where Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new accum value - let res = ready!(fut.try_poll(cx)); + let res = ready!(fut.poll(cx)); this.future.set(None); match res { Ok(a) => *this.accum = Some(a), diff --git a/futures-util/src/stream/stream/try_for_each.rs b/futures-util/src/stream/stream/try_for_each.rs index c892eb83c7..7792c27f7b 100644 --- a/futures-util/src/stream/stream/try_for_each.rs +++ b/futures-util/src/stream/stream/try_for_each.rs @@ -54,7 +54,7 @@ where let mut this = self.project(); loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { - ready!(fut.try_poll(cx))?; + ready!(fut.poll(cx))?; this.future.set(None); } else { match ready!(this.stream.as_mut().poll_next(cx)) { diff --git a/futures-util/src/stream/try_stream/and_then.rs b/futures-util/src/stream/try_stream/and_then.rs index 2f8b6f2589..134a731c12 100644 --- a/futures-util/src/stream/try_stream/and_then.rs +++ b/futures-util/src/stream/try_stream/and_then.rs @@ -59,7 +59,7 @@ where Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { - let item = ready!(fut.try_poll(cx)); + let item = ready!(fut.poll(cx)); this.future.set(None); break Some(item); } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { diff --git a/futures-util/src/stream/try_stream/or_else.rs b/futures-util/src/stream/try_stream/or_else.rs index 53aceb8e64..49c3fcf36e 100644 --- a/futures-util/src/stream/try_stream/or_else.rs +++ b/futures-util/src/stream/try_stream/or_else.rs @@ -59,7 +59,7 @@ where Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { - let item = ready!(fut.try_poll(cx)); + let item = ready!(fut.poll(cx)); this.future.set(None); break Some(item); } else { diff --git a/futures-util/src/stream/try_stream/try_filter_map.rs b/futures-util/src/stream/try_stream/try_filter_map.rs index ed1201732b..1220e0c4dd 100644 --- a/futures-util/src/stream/try_stream/try_filter_map.rs +++ b/futures-util/src/stream/try_stream/try_filter_map.rs @@ -67,7 +67,7 @@ where Poll::Ready(loop { if let Some(p) = this.pending.as_mut().as_pin_mut() { // We have an item in progress, poll that until it's done - let res = ready!(p.try_poll(cx)); + let res = ready!(p.poll(cx)); this.pending.set(None); let item = res?; if item.is_some() { diff --git a/futures-util/src/stream/try_stream/try_skip_while.rs b/futures-util/src/stream/try_stream/try_skip_while.rs index 52aa2d478b..fb56c27801 100644 --- a/futures-util/src/stream/try_stream/try_skip_while.rs +++ b/futures-util/src/stream/try_stream/try_skip_while.rs @@ -69,7 +69,7 @@ where Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { - let res = ready!(fut.try_poll(cx)); + let res = ready!(fut.poll(cx)); this.pending_fut.set(None); let skipped = res?; let item = this.pending_item.take(); diff --git a/futures-util/src/stream/try_stream/try_take_while.rs b/futures-util/src/stream/try_stream/try_take_while.rs index 4b5ff1ad38..3b50ee3e43 100644 --- a/futures-util/src/stream/try_stream/try_take_while.rs +++ b/futures-util/src/stream/try_stream/try_take_while.rs @@ -72,7 +72,7 @@ where Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { - let res = ready!(fut.try_poll(cx)); + let res = ready!(fut.poll(cx)); this.pending_fut.set(None); let take = res?; let item = this.pending_item.take(); diff --git a/futures-util/src/stream/try_stream/try_unfold.rs b/futures-util/src/stream/try_stream/try_unfold.rs index fd9cdf1d8c..15256b0020 100644 --- a/futures-util/src/stream/try_stream/try_unfold.rs +++ b/futures-util/src/stream/try_stream/try_unfold.rs @@ -105,7 +105,7 @@ where Poll::Ready(None) } Some(future) => { - let step = ready!(future.try_poll(cx)); + let step = ready!(future.poll(cx)); this.fut.set(None); match step { From 4587897773ed4792eaaa656ceb3589ebe2667f14 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Wed, 19 Jul 2023 19:33:02 +0000 Subject: [PATCH 4/8] Remove IntoFuture --- futures-util/src/future/mod.rs | 4 +-- .../src/future/try_future/into_future.rs | 36 ------------------- futures-util/src/future/try_future/mod.rs | 32 ----------------- futures/tests/auto_traits.rs | 7 ---- 4 files changed, 2 insertions(+), 77 deletions(-) delete mode 100644 futures-util/src/future/try_future/into_future.rs diff --git a/futures-util/src/future/mod.rs b/futures-util/src/future/mod.rs index e3838b7ad2..efe21587b2 100644 --- a/futures-util/src/future/mod.rs +++ b/futures-util/src/future/mod.rs @@ -40,8 +40,8 @@ pub use self::future::{Shared, WeakShared}; mod try_future; pub use self::try_future::{ - AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto, - OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse, + AndThen, ErrInto, InspectErr, InspectOk, MapErr, MapOk, MapOkOrElse, OkInto, OrElse, + TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse, }; #[cfg(feature = "sink")] diff --git a/futures-util/src/future/try_future/into_future.rs b/futures-util/src/future/try_future/into_future.rs deleted file mode 100644 index 05160e144e..0000000000 --- a/futures-util/src/future/try_future/into_future.rs +++ /dev/null @@ -1,36 +0,0 @@ -use core::pin::Pin; -use futures_core::future::{FusedFuture, Future, TryFuture}; -use futures_core::task::{Context, Poll}; -use pin_project_lite::pin_project; - -pin_project! { - /// Future for the [`into_future`](super::TryFutureExt::into_future) method. - #[derive(Debug)] - #[must_use = "futures do nothing unless you `.await` or poll them"] - pub struct IntoFuture { - #[pin] - future: Fut, - } -} - -impl IntoFuture { - #[inline] - pub(crate) fn new(future: Fut) -> Self { - Self { future } - } -} - -impl FusedFuture for IntoFuture { - fn is_terminated(&self) -> bool { - self.future.is_terminated() - } -} - -impl Future for IntoFuture { - type Output = Result; - - #[inline] - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.project().future.poll(cx) - } -} diff --git a/futures-util/src/future/try_future/mod.rs b/futures-util/src/future/try_future/mod.rs index 12f9ba73a1..6686329f92 100644 --- a/futures-util/src/future/try_future/mod.rs +++ b/futures-util/src/future/try_future/mod.rs @@ -18,7 +18,6 @@ use crate::future::{assert_future, Inspect, Map}; use crate::stream::assert_stream; // Combinators -mod into_future; mod try_flatten; mod try_flatten_err; @@ -95,9 +94,6 @@ delegate_all!( ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(x, inspect_err_fn(f))] ); -#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 -pub use self::into_future::IntoFuture; - delegate_all!( /// Future for the [`map_ok`](TryFutureExt::map_ok) method. MapOk( @@ -580,32 +576,4 @@ pub trait TryFutureExt: TryFuture { { Compat::new(self) } - - /// Wraps a [`TryFuture`] into a type that implements - /// [`Future`](std::future::Future). - /// - /// [`TryFuture`]s currently do not implement the - /// [`Future`](std::future::Future) trait due to limitations of the - /// compiler. - /// - /// # Examples - /// - /// ``` - /// use futures::future::{Future, TryFuture, TryFutureExt}; - /// - /// # type T = i32; - /// # type E = (); - /// fn make_try_future() -> impl TryFuture { // ... } - /// # async { Ok::(1) } - /// # } - /// fn take_future(future: impl Future>) { /* ... */ } - /// - /// take_future(make_try_future().into_future()); - /// ``` - fn into_future(self) -> IntoFuture - where - Self: Sized, - { - assert_future::, _>(IntoFuture::new(self)) - } } diff --git a/futures/tests/auto_traits.rs b/futures/tests/auto_traits.rs index f1185d1b7b..5d9029ae00 100644 --- a/futures/tests/auto_traits.rs +++ b/futures/tests/auto_traits.rs @@ -333,13 +333,6 @@ pub mod future { assert_impl!(InspectOk: Unpin); assert_not_impl!(InspectOk: Unpin); - assert_impl!(IntoFuture: Send); - assert_not_impl!(IntoFuture: Send); - assert_impl!(IntoFuture: Sync); - assert_not_impl!(IntoFuture: Sync); - assert_impl!(IntoFuture: Unpin); - assert_not_impl!(IntoFuture: Unpin); - assert_impl!(IntoStream: Send); assert_not_impl!(IntoStream: Send); assert_impl!(IntoStream: Sync); From 9e15e25d1cab668a0ae03cdd92fccfee90d9b2ad Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Wed, 19 Jul 2023 19:34:37 +0000 Subject: [PATCH 5/8] Remove TryFuture sealing --- futures-core/src/future.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/futures-core/src/future.rs b/futures-core/src/future.rs index caf53d9fb9..d60c6dc9e5 100644 --- a/futures-core/src/future.rs +++ b/futures-core/src/future.rs @@ -44,19 +44,9 @@ where } } -mod private_try_future { - use super::Future; - - pub trait Sealed {} - - impl Sealed for F where F: ?Sized + Future> {} -} - /// A convenience for futures that return `Result` values that includes /// a variety of adapters tailored to such futures. -pub trait TryFuture: - Future> + private_try_future::Sealed -{ +pub trait TryFuture: Future> { /// The type of successful values yielded by this future type Ok; From d28bede9ad3c3d0efca54831d826635b6cca801e Mon Sep 17 00:00:00 2001 From: yhx-12243 Date: Sun, 18 Aug 2024 20:28:05 -0400 Subject: [PATCH 6/8] refactor: `TryFuture`s are `Future`s now, `into_future` is no longer need --- futures-core/src/future.rs | 5 +- futures-util/src/future/mod.rs | 4 +- .../src/future/try_future/into_future.rs | 36 ------------ futures-util/src/future/try_future/mod.rs | 55 ++++--------------- futures-util/src/future/try_join_all.rs | 9 ++- .../stream/try_stream/try_buffer_unordered.rs | 5 +- .../src/stream/try_stream/try_buffered.rs | 5 +- futures/tests/auto_traits.rs | 7 --- 8 files changed, 26 insertions(+), 100 deletions(-) delete mode 100644 futures-util/src/future/try_future/into_future.rs diff --git a/futures-core/src/future.rs b/futures-core/src/future.rs index 7540cd027e..c9409ae039 100644 --- a/futures-core/src/future.rs +++ b/futures-core/src/future.rs @@ -55,7 +55,10 @@ mod private_try_future { /// A convenience for futures that return `Result` values that includes /// a variety of adapters tailored to such futures. -pub trait TryFuture: Future + private_try_future::Sealed { +pub trait TryFuture: + Future::Ok, ::Error>> + + private_try_future::Sealed +{ /// The type of successful values yielded by this future type Ok; diff --git a/futures-util/src/future/mod.rs b/futures-util/src/future/mod.rs index 1280ce9864..10eff2ce5b 100644 --- a/futures-util/src/future/mod.rs +++ b/futures-util/src/future/mod.rs @@ -40,8 +40,8 @@ pub use self::future::{Shared, WeakShared}; mod try_future; pub use self::try_future::{ - AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto, - OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse, + AndThen, ErrInto, InspectErr, InspectOk, MapErr, MapOk, MapOkOrElse, OkInto, OrElse, + TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse, }; #[cfg(feature = "sink")] diff --git a/futures-util/src/future/try_future/into_future.rs b/futures-util/src/future/try_future/into_future.rs deleted file mode 100644 index 9f093d0e2e..0000000000 --- a/futures-util/src/future/try_future/into_future.rs +++ /dev/null @@ -1,36 +0,0 @@ -use core::pin::Pin; -use futures_core::future::{FusedFuture, Future, TryFuture}; -use futures_core::task::{Context, Poll}; -use pin_project_lite::pin_project; - -pin_project! { - /// Future for the [`into_future`](super::TryFutureExt::into_future) method. - #[derive(Debug)] - #[must_use = "futures do nothing unless you `.await` or poll them"] - pub struct IntoFuture { - #[pin] - future: Fut, - } -} - -impl IntoFuture { - #[inline] - pub(crate) fn new(future: Fut) -> Self { - Self { future } - } -} - -impl FusedFuture for IntoFuture { - fn is_terminated(&self) -> bool { - self.future.is_terminated() - } -} - -impl Future for IntoFuture { - type Output = Result; - - #[inline] - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.project().future.try_poll(cx) - } -} diff --git a/futures-util/src/future/try_future/mod.rs b/futures-util/src/future/try_future/mod.rs index 4ae544aa91..8e30860039 100644 --- a/futures-util/src/future/try_future/mod.rs +++ b/futures-util/src/future/try_future/mod.rs @@ -23,7 +23,6 @@ use crate::future::{assert_future, Inspect, Map}; use crate::stream::assert_stream; // Combinators -mod into_future; mod try_flatten; mod try_flatten_err; @@ -89,45 +88,43 @@ delegate_all!( delegate_all!( /// Future for the [`inspect_ok`](super::TryFutureExt::inspect_ok) method. InspectOk( - Inspect, InspectOkFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_ok_fn(f))] + Inspect> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(x, inspect_ok_fn(f))] ); delegate_all!( /// Future for the [`inspect_err`](super::TryFutureExt::inspect_err) method. InspectErr( - Inspect, InspectErrFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_err_fn(f))] + Inspect> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(x, inspect_err_fn(f))] ); -pub use self::into_future::IntoFuture; - delegate_all!( /// Future for the [`map_ok`](TryFutureExt::map_ok) method. MapOk( - Map, MapOkFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_ok_fn(f))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(x, map_ok_fn(f))] ); delegate_all!( /// Future for the [`map_err`](TryFutureExt::map_err) method. MapErr( - Map, MapErrFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_err_fn(f))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(x, map_err_fn(f))] ); delegate_all!( /// Future for the [`map_ok_or_else`](TryFutureExt::map_ok_or_else) method. MapOkOrElse( - Map, MapOkOrElseFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(IntoFuture::new(x), map_ok_or_else_fn(f, g))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(x, map_ok_or_else_fn(f, g))] ); delegate_all!( /// Future for the [`unwrap_or_else`](TryFutureExt::unwrap_or_else) method. UnwrapOrElse( - Map, UnwrapOrElseFn> - ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), unwrap_or_else_fn(f))] + Map> + ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(x, unwrap_or_else_fn(f))] ); impl TryFutureExt for Fut {} @@ -585,34 +582,6 @@ pub trait TryFutureExt: TryFuture { Compat::new(self) } - /// Wraps a [`TryFuture`] into a type that implements - /// [`Future`](std::future::Future). - /// - /// [`TryFuture`]s currently do not implement the - /// [`Future`](std::future::Future) trait due to limitations of the - /// compiler. - /// - /// # Examples - /// - /// ``` - /// use futures::future::{Future, TryFuture, TryFutureExt}; - /// - /// # type T = i32; - /// # type E = (); - /// fn make_try_future() -> impl TryFuture { // ... } - /// # async { Ok::(1) } - /// # } - /// fn take_future(future: impl Future>) { /* ... */ } - /// - /// take_future(make_try_future().into_future()); - /// ``` - fn into_future(self) -> IntoFuture - where - Self: Sized, - { - assert_future::, _>(IntoFuture::new(self)) - } - /// A convenience method for calling [`TryFuture::try_poll`] on [`Unpin`] /// future types. fn try_poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll> diff --git a/futures-util/src/future/try_join_all.rs b/futures-util/src/future/try_join_all.rs index 2d6a2a02cb..cbb2f5a072 100644 --- a/futures-util/src/future/try_join_all.rs +++ b/futures-util/src/future/try_join_all.rs @@ -10,11 +10,10 @@ use core::mem; use core::pin::Pin; use core::task::{Context, Poll}; -use super::{assert_future, join_all, IntoFuture, TryFuture, TryMaybeDone}; +use super::{assert_future, join_all, TryFuture, TryMaybeDone}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] use crate::stream::{FuturesOrdered, TryCollect, TryStreamExt}; -use crate::TryFutureExt; enum FinalState { Pending, @@ -36,11 +35,11 @@ where F: TryFuture, { Small { - elems: Pin>]>>, + elems: Pin]>>, }, #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] Big { - fut: TryCollect>, Vec>, + fut: TryCollect, Vec>, }, } @@ -119,7 +118,7 @@ where I: IntoIterator, I::Item: TryFuture, { - let iter = iter.into_iter().map(TryFutureExt::into_future); + let iter = iter.into_iter(); #[cfg(target_os = "none")] #[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))] diff --git a/futures-util/src/stream/try_stream/try_buffer_unordered.rs b/futures-util/src/stream/try_stream/try_buffer_unordered.rs index 21b00b20ac..1d3c38b1d9 100644 --- a/futures-util/src/stream/try_stream/try_buffer_unordered.rs +++ b/futures-util/src/stream/try_stream/try_buffer_unordered.rs @@ -1,4 +1,3 @@ -use crate::future::{IntoFuture, TryFutureExt}; use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt}; use core::num::NonZeroUsize; use core::pin::Pin; @@ -19,7 +18,7 @@ pin_project! { { #[pin] stream: Fuse>, - in_progress_queue: FuturesUnordered>, + in_progress_queue: FuturesUnordered, max: Option, } } @@ -54,7 +53,7 @@ where // our queue of futures. Propagate errors from the stream immediately. while this.max.map(|max| this.in_progress_queue.len() < max.get()).unwrap_or(true) { match this.stream.as_mut().poll_next(cx)? { - Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut.into_future()), + Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut), Poll::Ready(None) | Poll::Pending => break, } } diff --git a/futures-util/src/stream/try_stream/try_buffered.rs b/futures-util/src/stream/try_stream/try_buffered.rs index 83e9093fbc..6b9dd0f7ec 100644 --- a/futures-util/src/stream/try_stream/try_buffered.rs +++ b/futures-util/src/stream/try_stream/try_buffered.rs @@ -1,4 +1,3 @@ -use crate::future::{IntoFuture, TryFutureExt}; use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt}; use core::num::NonZeroUsize; use core::pin::Pin; @@ -20,7 +19,7 @@ pin_project! { { #[pin] stream: Fuse>, - in_progress_queue: FuturesOrdered>, + in_progress_queue: FuturesOrdered, max: Option, } } @@ -55,7 +54,7 @@ where // our queue of futures. Propagate errors from the stream immediately. while this.max.map(|max| this.in_progress_queue.len() < max.get()).unwrap_or(true) { match this.stream.as_mut().poll_next(cx)? { - Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut.into_future()), + Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut), Poll::Ready(None) | Poll::Pending => break, } } diff --git a/futures/tests/auto_traits.rs b/futures/tests/auto_traits.rs index 8d15fa28ef..75ed663f9e 100644 --- a/futures/tests/auto_traits.rs +++ b/futures/tests/auto_traits.rs @@ -337,13 +337,6 @@ mod future { assert_impl!(InspectOk: Unpin); assert_not_impl!(InspectOk: Unpin); - assert_impl!(IntoFuture: Send); - assert_not_impl!(IntoFuture: Send); - assert_impl!(IntoFuture: Sync); - assert_not_impl!(IntoFuture: Sync); - assert_impl!(IntoFuture: Unpin); - assert_not_impl!(IntoFuture: Unpin); - assert_impl!(IntoStream: Send); assert_not_impl!(IntoStream: Send); assert_impl!(IntoStream: Sync); From 9ddeb5b681a63845f1d71ecacc62a3bb34205d2b Mon Sep 17 00:00:00 2001 From: yhx-12243 Date: Sun, 18 Aug 2024 20:59:33 -0400 Subject: [PATCH 7/8] refactor: remove `into_stream` and `IntoStream` --- futures-core/src/stream.rs | 5 +- futures-util/src/stream/mod.rs | 4 +- .../src/stream/try_stream/into_stream.rs | 52 ------------------- futures-util/src/stream/try_stream/mod.rs | 47 +++-------------- .../stream/try_stream/try_buffer_unordered.rs | 8 +-- .../src/stream/try_stream/try_buffered.rs | 8 +-- .../src/stream/try_stream/try_chunks.rs | 12 ++--- .../try_stream/try_flatten_unordered.rs | 6 +-- .../src/stream/try_stream/try_forward.rs | 6 +-- .../src/stream/try_stream/try_ready_chunks.rs | 8 +-- futures/tests/auto_traits.rs | 7 --- 11 files changed, 35 insertions(+), 128 deletions(-) delete mode 100644 futures-util/src/stream/try_stream/into_stream.rs diff --git a/futures-core/src/stream.rs b/futures-core/src/stream.rs index ad5350b795..79aa5cba5e 100644 --- a/futures-core/src/stream.rs +++ b/futures-core/src/stream.rs @@ -164,7 +164,10 @@ mod private_try_stream { /// A convenience for streams that return `Result` values that includes /// a variety of adapters tailored to such futures. -pub trait TryStream: Stream + private_try_stream::Sealed { +pub trait TryStream: + Stream::Ok, ::Error>> + + private_try_stream::Sealed +{ /// The type of successful values yielded by this future type Ok; diff --git a/futures-util/src/stream/mod.rs b/futures-util/src/stream/mod.rs index 789e1ad221..23d28bf445 100644 --- a/futures-util/src/stream/mod.rs +++ b/futures-util/src/stream/mod.rs @@ -52,8 +52,8 @@ pub use self::stream::{ReuniteError, SplitSink, SplitStream}; mod try_stream; pub use self::try_stream::{ - try_unfold, AndThen, ErrInto, InspectErr, InspectOk, IntoStream, MapErr, MapOk, OrElse, TryAll, - TryAny, TryCollect, TryConcat, TryFilter, TryFilterMap, TryFlatten, TryNext, TrySkipWhile, + try_unfold, AndThen, ErrInto, InspectErr, InspectOk, MapErr, MapOk, OrElse, TryAll, TryAny, + TryCollect, TryConcat, TryFilter, TryFilterMap, TryFlatten, TryNext, TrySkipWhile, TryStreamExt, TryTakeWhile, TryUnfold, }; diff --git a/futures-util/src/stream/try_stream/into_stream.rs b/futures-util/src/stream/try_stream/into_stream.rs deleted file mode 100644 index 2126258af7..0000000000 --- a/futures-util/src/stream/try_stream/into_stream.rs +++ /dev/null @@ -1,52 +0,0 @@ -use core::pin::Pin; -use futures_core::stream::{FusedStream, Stream, TryStream}; -use futures_core::task::{Context, Poll}; -#[cfg(feature = "sink")] -use futures_sink::Sink; -use pin_project_lite::pin_project; - -pin_project! { - /// Stream for the [`into_stream`](super::TryStreamExt::into_stream) method. - #[derive(Debug)] - #[must_use = "streams do nothing unless polled"] - pub struct IntoStream { - #[pin] - stream: St, - } -} - -impl IntoStream { - #[inline] - pub(super) fn new(stream: St) -> Self { - Self { stream } - } - - delegate_access_inner!(stream, St, ()); -} - -impl FusedStream for IntoStream { - fn is_terminated(&self) -> bool { - self.stream.is_terminated() - } -} - -impl Stream for IntoStream { - type Item = Result; - - #[inline] - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - self.project().stream.try_poll_next(cx) - } - - fn size_hint(&self) -> (usize, Option) { - self.stream.size_hint() - } -} - -// Forwarding impl of Sink from the underlying stream -#[cfg(feature = "sink")] -impl, Item> Sink for IntoStream { - type Error = S::Error; - - delegate_sink!(stream, Item); -} diff --git a/futures-util/src/stream/try_stream/mod.rs b/futures-util/src/stream/try_stream/mod.rs index fe9317d7a0..970ee0c64e 100644 --- a/futures-util/src/stream/try_stream/mod.rs +++ b/futures-util/src/stream/try_stream/mod.rs @@ -36,32 +36,29 @@ delegate_all!( delegate_all!( /// Stream for the [`inspect_ok`](super::TryStreamExt::inspect_ok) method. InspectOk( - Inspect, InspectOkFn> - ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Inspect::new(IntoStream::new(x), inspect_ok_fn(f))] + Inspect> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St, f: F| Inspect::new(x, inspect_ok_fn(f))] ); delegate_all!( /// Stream for the [`inspect_err`](super::TryStreamExt::inspect_err) method. InspectErr( - Inspect, InspectErrFn> - ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Inspect::new(IntoStream::new(x), inspect_err_fn(f))] + Inspect> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St, f: F| Inspect::new(x, inspect_err_fn(f))] ); -mod into_stream; -pub use self::into_stream::IntoStream; - delegate_all!( /// Stream for the [`map_ok`](super::TryStreamExt::map_ok) method. MapOk( - Map, MapOkFn> - ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Map::new(IntoStream::new(x), map_ok_fn(f))] + Map> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St, f: F| Map::new(x, map_ok_fn(f))] ); delegate_all!( /// Stream for the [`map_err`](super::TryStreamExt::map_err) method. MapErr( - Map, MapErrFn> - ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Map::new(IntoStream::new(x), map_err_fn(f))] + Map> + ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St, f: F| Map::new(x, map_err_fn(f))] ); mod or_else; @@ -352,34 +349,6 @@ pub trait TryStreamExt: TryStream { assert_stream::, _>(InspectErr::new(self, f)) } - /// Wraps a [`TryStream`] into a type that implements - /// [`Stream`](futures_core::stream::Stream) - /// - /// [`TryStream`]s currently do not implement the - /// [`Stream`](futures_core::stream::Stream) trait because of limitations - /// of the compiler. - /// - /// # Examples - /// - /// ``` - /// use futures::stream::{Stream, TryStream, TryStreamExt}; - /// - /// # type T = i32; - /// # type E = (); - /// fn make_try_stream() -> impl TryStream { // ... } - /// # futures::stream::empty() - /// # } - /// fn take_stream(stream: impl Stream>) { /* ... */ } - /// - /// take_stream(make_try_stream().into_stream()); - /// ``` - fn into_stream(self) -> IntoStream - where - Self: Sized, - { - assert_stream::, _>(IntoStream::new(self)) - } - /// Creates a future that attempts to resolve the next item in the stream. /// If an error is encountered before the next item, the error is returned /// instead. diff --git a/futures-util/src/stream/try_stream/try_buffer_unordered.rs b/futures-util/src/stream/try_stream/try_buffer_unordered.rs index 1d3c38b1d9..af6994912e 100644 --- a/futures-util/src/stream/try_stream/try_buffer_unordered.rs +++ b/futures-util/src/stream/try_stream/try_buffer_unordered.rs @@ -1,4 +1,4 @@ -use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt}; +use crate::stream::{Fuse, FuturesUnordered, StreamExt}; use core::num::NonZeroUsize; use core::pin::Pin; use futures_core::future::TryFuture; @@ -17,7 +17,7 @@ pin_project! { where St: TryStream { #[pin] - stream: Fuse>, + stream: Fuse, in_progress_queue: FuturesUnordered, max: Option, } @@ -30,13 +30,13 @@ where { pub(super) fn new(stream: St, n: Option) -> Self { Self { - stream: IntoStream::new(stream).fuse(), + stream: stream.fuse(), in_progress_queue: FuturesUnordered::new(), max: n.and_then(NonZeroUsize::new), } } - delegate_access_inner!(stream, St, (. .)); + delegate_access_inner!(stream, St, (.)); } impl Stream for TryBufferUnordered diff --git a/futures-util/src/stream/try_stream/try_buffered.rs b/futures-util/src/stream/try_stream/try_buffered.rs index 6b9dd0f7ec..4c98615eb0 100644 --- a/futures-util/src/stream/try_stream/try_buffered.rs +++ b/futures-util/src/stream/try_stream/try_buffered.rs @@ -1,4 +1,4 @@ -use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt}; +use crate::stream::{Fuse, FuturesOrdered, StreamExt}; use core::num::NonZeroUsize; use core::pin::Pin; use futures_core::future::TryFuture; @@ -18,7 +18,7 @@ pin_project! { St::Ok: TryFuture, { #[pin] - stream: Fuse>, + stream: Fuse, in_progress_queue: FuturesOrdered, max: Option, } @@ -31,13 +31,13 @@ where { pub(super) fn new(stream: St, n: Option) -> Self { Self { - stream: IntoStream::new(stream).fuse(), + stream: stream.fuse(), in_progress_queue: FuturesOrdered::new(), max: n.and_then(NonZeroUsize::new), } } - delegate_access_inner!(stream, St, (. .)); + delegate_access_inner!(stream, St, (.)); } impl Stream for TryBuffered diff --git a/futures-util/src/stream/try_stream/try_chunks.rs b/futures-util/src/stream/try_stream/try_chunks.rs index ec53f4bd11..a6184ee44a 100644 --- a/futures-util/src/stream/try_stream/try_chunks.rs +++ b/futures-util/src/stream/try_stream/try_chunks.rs @@ -1,4 +1,4 @@ -use crate::stream::{Fuse, IntoStream, StreamExt}; +use crate::stream::{Fuse, StreamExt}; use alloc::vec::Vec; use core::pin::Pin; @@ -16,7 +16,7 @@ pin_project! { #[must_use = "streams do nothing unless polled"] pub struct TryChunks { #[pin] - stream: Fuse>, + stream: Fuse, items: Vec, cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 } @@ -26,11 +26,7 @@ impl TryChunks { pub(super) fn new(stream: St, capacity: usize) -> Self { assert!(capacity > 0); - Self { - stream: IntoStream::new(stream).fuse(), - items: Vec::with_capacity(capacity), - cap: capacity, - } + Self { stream: stream.fuse(), items: Vec::with_capacity(capacity), cap: capacity } } fn take(self: Pin<&mut Self>) -> Vec { @@ -38,7 +34,7 @@ impl TryChunks { mem::replace(self.project().items, Vec::with_capacity(cap)) } - delegate_access_inner!(stream, St, (. .)); + delegate_access_inner!(stream, St, (.)); } type TryChunksStreamError = TryChunksError<::Ok, ::Error>; diff --git a/futures-util/src/stream/try_stream/try_flatten_unordered.rs b/futures-util/src/stream/try_stream/try_flatten_unordered.rs index a74dfc451d..9987b0dc3a 100644 --- a/futures-util/src/stream/try_stream/try_flatten_unordered.rs +++ b/futures-util/src/stream/try_stream/try_flatten_unordered.rs @@ -13,8 +13,6 @@ use crate::future::Either; use crate::stream::stream::flatten_unordered::{ FlattenUnorderedWithFlowController, FlowController, FlowStep, }; -use crate::stream::IntoStream; -use crate::TryStreamExt; delegate_all!( /// Stream for the [`try_flatten_unordered`](super::TryStreamExt::try_flatten_unordered) method. @@ -128,7 +126,7 @@ where { // Item is either an inner stream or a stream containing a single error. // This will allow using `Either`'s `Stream` implementation as both branches are actually streams of `Result`'s. - type Item = Either, SingleStreamResult>; + type Item = Either>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let item = ready!(self.project().stream.try_poll_next(cx)); @@ -136,7 +134,7 @@ where let out = match item { Some(res) => match res { // Emit successful inner stream as is - Ok(stream) => Either::Left(stream.into_stream()), + Ok(stream) => Either::Left(stream), // Wrap an error into a stream containing a single item err @ Err(_) => { let res = err.map(|_: St::Ok| unreachable!()).map_err(Into::into); diff --git a/futures-util/src/stream/try_stream/try_forward.rs b/futures-util/src/stream/try_stream/try_forward.rs index 52c28afa34..74cc33d4e9 100644 --- a/futures-util/src/stream/try_stream/try_forward.rs +++ b/futures-util/src/stream/try_stream/try_forward.rs @@ -1,4 +1,4 @@ -use crate::stream::{Fuse, IntoStream, Stream, TryStream}; +use crate::stream::{Fuse, Stream, TryStream}; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; @@ -15,14 +15,14 @@ pin_project! { #[pin] sink: Option, #[pin] - stream: Fuse>, + stream: Fuse, buffered_item: Option, } } impl TryForward { pub(crate) fn new(stream: St, sink: Si) -> Self { - Self { sink: Some(sink), stream: Fuse::new(IntoStream::new(stream)), buffered_item: None } + Self { sink: Some(sink), stream: Fuse::new(stream), buffered_item: None } } } diff --git a/futures-util/src/stream/try_stream/try_ready_chunks.rs b/futures-util/src/stream/try_stream/try_ready_chunks.rs index 8b1470ea26..8910790935 100644 --- a/futures-util/src/stream/try_stream/try_ready_chunks.rs +++ b/futures-util/src/stream/try_stream/try_ready_chunks.rs @@ -1,4 +1,4 @@ -use crate::stream::{Fuse, IntoStream, StreamExt}; +use crate::stream::{Fuse, StreamExt}; use alloc::vec::Vec; use core::fmt; @@ -15,7 +15,7 @@ pin_project! { #[must_use = "streams do nothing unless polled"] pub struct TryReadyChunks { #[pin] - stream: Fuse>, + stream: Fuse, cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 } } @@ -24,10 +24,10 @@ impl TryReadyChunks { pub(super) fn new(stream: St, capacity: usize) -> Self { assert!(capacity > 0); - Self { stream: IntoStream::new(stream).fuse(), cap: capacity } + Self { stream: stream.fuse(), cap: capacity } } - delegate_access_inner!(stream, St, (. .)); + delegate_access_inner!(stream, St, (.)); } type TryReadyChunksStreamError = diff --git a/futures/tests/auto_traits.rs b/futures/tests/auto_traits.rs index 75ed663f9e..43ba31a4f6 100644 --- a/futures/tests/auto_traits.rs +++ b/futures/tests/auto_traits.rs @@ -1361,13 +1361,6 @@ mod stream { // IntoAsyncRead requires `St: Unpin` // assert_not_impl!(IntoAsyncRead, io::Error>>: Unpin); - assert_impl!(IntoStream<()>: Send); - assert_not_impl!(IntoStream<*const ()>: Send); - assert_impl!(IntoStream<()>: Sync); - assert_not_impl!(IntoStream<*const ()>: Sync); - assert_impl!(IntoStream<()>: Unpin); - assert_not_impl!(IntoStream: Unpin); - assert_impl!(Iter<()>: Send); assert_not_impl!(Iter<*const ()>: Send); assert_impl!(Iter<()>: Sync); From 63b720b7c49be784d4d5bf526b3e76e57bf61486 Mon Sep 17 00:00:00 2001 From: yhx-12243 Date: Sat, 18 Jul 2026 22:41:16 +0800 Subject: [PATCH 8/8] fix: recover --- CHANGELOG.md | 10 ++++++++++ futures-io/Cargo.toml | 2 +- futures-test/Cargo.toml | 2 +- futures-util/Cargo.toml | 2 +- futures/Cargo.toml | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0aaef01c0..8e55ed07a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ Releases may yanked if there is a security bug, a soundness bug, or a regression Note: In this file, do not use the hard wrap in the middle of a sentence for compatibility with GitHub comment style markdown rendering. --> +# 0.3.33 - 2026-07-18 + +* Fix `ReadLine`'s soundness issue regarding to exception safety. (#3020) +* Fix unsound `Send` impl for `IterPinRef` and `Iter`. (#3003) +* Fix stacked borrows violation in `compat01as03` implementation. (#3012) +* Fix memory leak in `FuturesUnordered::IntoIter`. (#3005) +* Add `portable-atomic-alloc` feature and use it in `FuturesUnordered`. (#3007) +* Re-export `alloc::task::Wake`. (#3010) +* Update `spin` to 0.12. (#3014) + # 0.3.32 - 2026-02-15 * Bump MSRV of utility crates to 1.71. (#2989) diff --git a/futures-io/Cargo.toml b/futures-io/Cargo.toml index f77a3938b6..90e893fdcc 100644 --- a/futures-io/Cargo.toml +++ b/futures-io/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "futures-io" -version = "0.3.32" +version = "0.3.33" edition = "2018" # NB: Sync with "Usage" section in README.md and core-msrv job in .github/workflows/ci.yml rust-version = "1.52" diff --git a/futures-test/Cargo.toml b/futures-test/Cargo.toml index abbaf1cac1..5b424e1d8f 100644 --- a/futures-test/Cargo.toml +++ b/futures-test/Cargo.toml @@ -14,7 +14,7 @@ Common utilities for testing components built off futures-rs. [dependencies] futures-core = { version = "=1.0.0-alpha.0", path = "../futures-core", default-features = false } futures-task = { version = "=0.4.0-alpha.0", path = "../futures-task", default-features = false } -futures-io = { version = "0.3.32", path = "../futures-io", default-features = false } +futures-io = { version = "0.3.33", path = "../futures-io", default-features = false } futures-util = { version = "=0.4.0-alpha.0", path = "../futures-util", default-features = false } futures-executor = { version = "=0.4.0-alpha.0", path = "../futures-executor", default-features = false } futures-sink = { version = "=0.4.0-alpha.0", path = "../futures-sink", default-features = false } diff --git a/futures-util/Cargo.toml b/futures-util/Cargo.toml index 2da41797aa..84cc1d35d3 100644 --- a/futures-util/Cargo.toml +++ b/futures-util/Cargo.toml @@ -36,7 +36,7 @@ write-all-vectored = ["io"] futures-core = { path = "../futures-core", version = "=1.0.0-alpha.0", default-features = false } futures-task = { path = "../futures-task", version = "=0.4.0-alpha.0", default-features = false } futures-channel = { path = "../futures-channel", version = "=0.4.0-alpha.0", default-features = false, features = ["std"], optional = true } -futures-io = { path = "../futures-io", version = "0.3.32", default-features = false, features = ["std"], optional = true } +futures-io = { path = "../futures-io", version = "0.3.33", default-features = false, features = ["std"], optional = true } futures-sink = { path = "../futures-sink", version = "=0.4.0-alpha.0", default-features = false, optional = true } futures-macro = { path = "../futures-macro", version = "=0.4.0-alpha.0", default-features = false, optional = true } slab = { version = "0.4.7", default-features = false, optional = true } diff --git a/futures/Cargo.toml b/futures/Cargo.toml index acc46534fb..6c3a8a8266 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -20,7 +20,7 @@ futures-core = { path = "../futures-core", version = "=1.0.0-alpha.0", default-f futures-task = { path = "../futures-task", version = "=0.4.0-alpha.0", default-features = false } futures-channel = { path = "../futures-channel", version = "=0.4.0-alpha.0", default-features = false, features = ["sink"] } futures-executor = { path = "../futures-executor", version = "=0.4.0-alpha.0", default-features = false, optional = true } -futures-io = { path = "../futures-io", version = "0.3.32", default-features = false } +futures-io = { path = "../futures-io", version = "0.3.33", default-features = false } futures-sink = { path = "../futures-sink", version = "=0.4.0-alpha.0", default-features = false } futures-util = { path = "../futures-util", version = "=0.4.0-alpha.0", default-features = false, features = ["sink"] }