Skip to content

Commit 22e2942

Browse files
taiki-ecramertj
authored andcommitted
Add Future/Stream bounds to FusedFuture/FusedStream
1 parent ab7743d commit 22e2942

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+181
-65
lines changed

futures-core/src/future/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ pub type BoxFuture<'a, T> = Pin<alloc::boxed::Box<dyn Future<Output = T> + Send
1818
#[cfg(feature = "alloc")]
1919
pub type LocalBoxFuture<'a, T> = Pin<alloc::boxed::Box<dyn Future<Output = T> + 'a>>;
2020

21-
/// A `Future` or `TryFuture` which tracks whether or not the underlying future
21+
/// A future which tracks whether or not the underlying future
2222
/// should no longer be polled.
2323
///
2424
/// `is_terminated` will return `true` if a future should no longer be polled.
2525
/// Usually, this state occurs after `poll` (or `try_poll`) returned
2626
/// `Poll::Ready`. However, `is_terminated` may also return `true` if a future
2727
/// has become inactive and can no longer make progress and should be ignored
2828
/// or dropped rather than being `poll`ed again.
29-
pub trait FusedFuture {
29+
pub trait FusedFuture: Future {
3030
/// Returns `true` if the underlying future should no longer be polled.
3131
fn is_terminated(&self) -> bool;
3232
}
3333

34-
impl<F: FusedFuture + ?Sized> FusedFuture for &mut F {
34+
impl<F: FusedFuture + ?Sized + Unpin> FusedFuture for &mut F {
3535
fn is_terminated(&self) -> bool {
3636
<F as FusedFuture>::is_terminated(&**self)
3737
}
@@ -92,7 +92,7 @@ mod if_alloc {
9292
use alloc::boxed::Box;
9393
use super::*;
9494

95-
impl<F: FusedFuture + ?Sized> FusedFuture for Box<F> {
95+
impl<F: FusedFuture + ?Sized + Unpin> FusedFuture for Box<F> {
9696
fn is_terminated(&self) -> bool {
9797
<F as FusedFuture>::is_terminated(&**self)
9898
}

futures-core/src/stream.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,20 @@ where
8787
}
8888
}
8989

90-
/// A `Stream` or `TryStream` which tracks whether or not the underlying stream
90+
/// A stream which tracks whether or not the underlying stream
9191
/// should no longer be polled.
9292
///
9393
/// `is_terminated` will return `true` if a future should no longer be polled.
9494
/// Usually, this state occurs after `poll_next` (or `try_poll_next`) returned
9595
/// `Poll::Ready(None)`. However, `is_terminated` may also return `true` if a
9696
/// stream has become inactive and can no longer make progress and should be
9797
/// ignored or dropped rather than being polled again.
98-
pub trait FusedStream {
98+
pub trait FusedStream: Stream {
9999
/// Returns `true` if the stream should no longer be polled.
100100
fn is_terminated(&self) -> bool;
101101
}
102102

103-
impl<F: ?Sized + FusedStream> FusedStream for &mut F {
103+
impl<F: ?Sized + FusedStream + Unpin> FusedStream for &mut F {
104104
fn is_terminated(&self) -> bool {
105105
<F as FusedStream>::is_terminated(&**self)
106106
}
@@ -194,7 +194,7 @@ mod if_alloc {
194194
}
195195
}
196196

197-
impl<S: ?Sized + FusedStream> FusedStream for Box<S> {
197+
impl<S: ?Sized + FusedStream + Unpin> FusedStream for Box<S> {
198198
fn is_terminated(&self) -> bool {
199199
<S as FusedStream>::is_terminated(&**self)
200200
}

futures-util/src/future/either.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ where
6969
impl<A, B> FusedFuture for Either<A, B>
7070
where
7171
A: FusedFuture,
72-
B: FusedFuture,
72+
B: FusedFuture<Output = A::Output>,
7373
{
7474
fn is_terminated(&self) -> bool {
7575
match self {
@@ -99,7 +99,7 @@ where
9999
impl<A, B> FusedStream for Either<A, B>
100100
where
101101
A: FusedStream,
102-
B: FusedStream,
102+
B: FusedStream<Item = A::Item>,
103103
{
104104
fn is_terminated(&self) -> bool {
105105
match self {

futures-util/src/future/inspect.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ impl<Fut: Future, F: FnOnce(&Fut::Output)> Inspect<Fut, F> {
2525

2626
impl<Fut: Future + Unpin, F> Unpin for Inspect<Fut, F> {}
2727

28-
impl<Fut: Future + FusedFuture, F> FusedFuture for Inspect<Fut, F> {
28+
impl<Fut, F> FusedFuture for Inspect<Fut, F>
29+
where Fut: FusedFuture,
30+
F: FnOnce(&Fut::Output),
31+
{
2932
fn is_terminated(&self) -> bool { self.future.is_terminated() }
3033
}
3134

futures-util/src/future/lazy.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ pub fn lazy<F, R>(f: F) -> Lazy<F>
3838
Lazy { f: Some(f) }
3939
}
4040

41-
impl<F> FusedFuture for Lazy<F> {
41+
impl<F, R> FusedFuture for Lazy<F>
42+
where F: FnOnce(&mut Context<'_>) -> R,
43+
{
4244
fn is_terminated(&self) -> bool { self.f.is_none() }
4345
}
4446

45-
impl<R, F> Future for Lazy<F>
47+
impl<F, R> Future for Lazy<F>
4648
where F: FnOnce(&mut Context<'_>) -> R,
4749
{
4850
type Output = R;

futures-util/src/future/map.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ impl<Fut, F> Map<Fut, F> {
2323

2424
impl<Fut: Unpin, F> Unpin for Map<Fut, F> {}
2525

26-
impl<Fut, F> FusedFuture for Map<Fut, F> {
26+
impl<Fut, F, T> FusedFuture for Map<Fut, F>
27+
where Fut: Future,
28+
F: FnOnce(Fut::Output) -> T,
29+
{
2730
fn is_terminated(&self) -> bool { self.f.is_none() }
2831
}
2932

futures-util/src/future/shared.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,19 @@ where
173173
}
174174
}
175175

176-
impl<Fut: Future> FusedFuture for Shared<Fut> {
176+
impl<Fut> FusedFuture for Shared<Fut>
177+
where
178+
Fut: Future,
179+
Fut::Output: Clone,
180+
{
177181
fn is_terminated(&self) -> bool {
178182
self.inner.is_none()
179183
}
180184
}
181185

182-
impl<Fut: Future> Future for Shared<Fut>
186+
impl<Fut> Future for Shared<Fut>
183187
where
188+
Fut: Future,
184189
Fut::Output: Clone,
185190
{
186191
type Output = Fut::Output;

futures-util/src/future/then.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ impl<Fut1, Fut2, F> Then<Fut1, Fut2, F>
2525
}
2626
}
2727

28-
impl<Fut1, Fut2, F> FusedFuture for Then<Fut1, Fut2, F> {
28+
impl<Fut1, Fut2, F> FusedFuture for Then<Fut1, Fut2, F>
29+
where Fut1: Future,
30+
Fut2: Future,
31+
F: FnOnce(Fut1::Output) -> Fut2,
32+
{
2933
fn is_terminated(&self) -> bool { self.chain.is_terminated() }
3034
}
3135

futures-util/src/stream/chain.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ where St1: Stream,
2727
}
2828
}
2929

30-
impl<St1, St2: FusedStream> FusedStream for Chain<St1, St2> {
30+
impl<St1, St2> FusedStream for Chain<St1, St2>
31+
where St1: Stream,
32+
St2: FusedStream<Item=St1::Item>,
33+
{
3134
fn is_terminated(&self) -> bool {
3235
self.first.is_none() && self.second.is_terminated()
3336
}

futures-util/src/stream/collect.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ impl<St: Stream, C: Default> Collect<St, C> {
3131
}
3232
}
3333

34-
impl<St: FusedStream, C> FusedFuture for Collect<St, C> {
34+
impl<St, C> FusedFuture for Collect<St, C>
35+
where St: FusedStream,
36+
C: Default + Extend<St:: Item>
37+
{
3538
fn is_terminated(&self) -> bool {
3639
self.stream.is_terminated()
3740
}

futures-util/src/stream/flatten.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ where
7575

7676
impl<St> FusedStream for Flatten<St>
7777
where
78-
St: Stream + FusedStream,
78+
St: FusedStream,
79+
St::Item: Stream,
7980
{
8081
fn is_terminated(&self) -> bool {
8182
self.next.is_none() && self.stream.is_terminated()

futures-util/src/stream/fold.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ where St: Stream,
5151
}
5252
}
5353

54-
impl<St, Fut, T, F> FusedFuture for Fold<St, Fut, T, F> {
54+
impl<St, Fut, T, F> FusedFuture for Fold<St, Fut, T, F>
55+
where St: Stream,
56+
F: FnMut(T, St::Item) -> Fut,
57+
Fut: Future<Output = T>,
58+
{
5559
fn is_terminated(&self) -> bool {
5660
self.accum.is_none() && self.future.is_none()
5761
}

futures-util/src/stream/for_each.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ where St: Stream,
5050
}
5151
}
5252

53-
impl<St: FusedStream, Fut, F> FusedFuture for ForEach<St, Fut, F> {
53+
impl<St, Fut, F> FusedFuture for ForEach<St, Fut, F>
54+
where St: FusedStream,
55+
F: FnMut(St::Item) -> Fut,
56+
Fut: Future<Output = ()>,
57+
{
5458
fn is_terminated(&self) -> bool {
5559
self.future.is_none() && self.stream.is_terminated()
5660
}

futures-util/src/stream/for_each_concurrent.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ where St: Stream,
5757
}
5858
}
5959

60-
impl<St, Fut, F> FusedFuture for ForEachConcurrent<St, Fut, F> {
60+
impl<St, Fut, F> FusedFuture for ForEachConcurrent<St, Fut, F>
61+
where St: Stream,
62+
F: FnMut(St::Item) -> Fut,
63+
Fut: Future<Output = ()>,
64+
{
6165
fn is_terminated(&self) -> bool {
6266
self.stream.is_none() && self.futures.is_empty()
6367
}

futures-util/src/stream/forward.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ where
5353
}
5454
}
5555

56-
impl<St: TryStream, Si: Sink<St::Ok> + Unpin> FusedFuture for Forward<St, Si> {
56+
impl<St, Si, Item, E> FusedFuture for Forward<St, Si>
57+
where
58+
Si: Sink<Item, Error = E>,
59+
St: Stream<Item = Result<Item, E>>,
60+
{
5761
fn is_terminated(&self) -> bool {
5862
self.sink.is_none()
5963
}

futures-util/src/stream/fuse.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl<St> Fuse<St> {
6565
}
6666
}
6767

68-
impl<S> FusedStream for Fuse<S> {
68+
impl<S: Stream> FusedStream for Fuse<S> {
6969
fn is_terminated(&self) -> bool {
7070
self.done
7171
}

futures-util/src/stream/inspect.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ impl<St, F> Inspect<St, F>
7070
}
7171
}
7272

73-
impl<St: Stream + FusedStream, F> FusedStream for Inspect<St, F> {
73+
impl<St, F> FusedStream for Inspect<St, F>
74+
where St: FusedStream,
75+
F: FnMut(&St::Item),
76+
{
7477
fn is_terminated(&self) -> bool {
7578
self.stream.is_terminated()
7679
}

futures-util/src/stream/into_future.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<St: Stream + Unpin> StreamFuture<St> {
7171
}
7272
}
7373

74-
impl<St> FusedFuture for StreamFuture<St> {
74+
impl<St: Stream + Unpin> FusedFuture for StreamFuture<St> {
7575
fn is_terminated(&self) -> bool {
7676
self.stream.is_none()
7777
}

futures-util/src/stream/map.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ impl<St, T, F> Map<St, F>
7070
}
7171
}
7272

73-
impl<St: FusedStream, F> FusedStream for Map<St, F> {
73+
impl<St, F, T> FusedStream for Map<St, F>
74+
where St: FusedStream,
75+
F: FnMut(St::Item) -> T,
76+
{
7477
fn is_terminated(&self) -> bool {
7578
self.stream.is_terminated()
7679
}

futures-util/src/stream/next.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl<'a, St: ?Sized + Stream + Unpin> Next<'a, St> {
1919
}
2020
}
2121

22-
impl<St: ?Sized + FusedStream> FusedFuture for Next<'_, St> {
22+
impl<St: ?Sized + FusedStream + Unpin> FusedFuture for Next<'_, St> {
2323
fn is_terminated(&self) -> bool {
2424
self.stream.is_terminated()
2525
}

futures-util/src/stream/select.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ impl<St1, St2> Select<St1, St2> {
7272
}
7373
}
7474

75-
impl<St1, St2> FusedStream for Select<St1, St2> {
75+
impl<St1, St2> FusedStream for Select<St1, St2>
76+
where St1: Stream,
77+
St2: Stream<Item = St1::Item>
78+
{
7679
fn is_terminated(&self) -> bool {
7780
self.stream1.is_terminated() && self.stream2.is_terminated()
7881
}

futures-util/src/stream/select_next_some.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::pin::Pin;
2-
use futures_core::stream::{Stream, FusedStream};
2+
use futures_core::stream::FusedStream;
33
use futures_core::future::{Future, FusedFuture};
44
use futures_core::task::{Context, Poll};
55
use crate::stream::StreamExt;
@@ -18,13 +18,13 @@ impl<'a, St: ?Sized> SelectNextSome<'a, St> {
1818
}
1919
}
2020

21-
impl<St: ?Sized + FusedStream> FusedFuture for SelectNextSome<'_, St> {
21+
impl<St: ?Sized + FusedStream + Unpin> FusedFuture for SelectNextSome<'_, St> {
2222
fn is_terminated(&self) -> bool {
2323
self.stream.is_terminated()
2424
}
2525
}
2626

27-
impl<St: ?Sized + Stream + FusedStream + Unpin> Future for SelectNextSome<'_, St> {
27+
impl<St: ?Sized + FusedStream + Unpin> Future for SelectNextSome<'_, St> {
2828
type Output = St::Item;
2929

3030
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

futures-util/src/stream/skip_while.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ impl<St, Fut, F> SkipWhile<St, Fut, F>
8989
}
9090
}
9191

92-
impl<St: Stream + FusedStream, Fut, F> FusedStream for SkipWhile<St, Fut, F> {
92+
impl<St, Fut, F> FusedStream for SkipWhile<St, Fut, F>
93+
where St: FusedStream,
94+
F: FnMut(&St::Item) -> Fut,
95+
Fut: Future<Output = bool>,
96+
{
9397
fn is_terminated(&self) -> bool {
9498
self.stream.is_terminated()
9599
}

futures-util/src/stream/then.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ impl<St, Fut, F> Then<St, Fut, F>
8181
}
8282
}
8383

84-
impl<St: FusedStream, Fut, F> FusedStream for Then<St, Fut, F> {
84+
impl<St, Fut, F> FusedStream for Then<St, Fut, F>
85+
where St: FusedStream,
86+
F: FnMut(St::Item) -> Fut,
87+
Fut: Future,
88+
{
8589
fn is_terminated(&self) -> bool {
8690
self.future.is_none() && self.stream.is_terminated()
8791
}

futures-util/src/stream/unfold.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ use pin_utils::{unsafe_pinned, unsafe_unpinned};
5050
/// assert_eq!(result, vec![0, 2, 4]);
5151
/// # });
5252
/// ```
53-
pub fn unfold<T, F, Fut, It>(init: T, f: F) -> Unfold<T, F, Fut>
53+
pub fn unfold<T, F, Fut, Item>(init: T, f: F) -> Unfold<T, F, Fut>
5454
where F: FnMut(T) -> Fut,
55-
Fut: Future<Output = Option<(It, T)>>,
55+
Fut: Future<Output = Option<(Item, T)>>,
5656
{
5757
Unfold {
5858
f,
@@ -90,22 +90,25 @@ impl<T, F, Fut> Unfold<T, F, Fut> {
9090
unsafe_pinned!(fut: Option<Fut>);
9191
}
9292

93-
impl<T, F, Fut> FusedStream for Unfold<T, F, Fut> {
93+
impl<T, F, Fut, Item> FusedStream for Unfold<T, F, Fut>
94+
where F: FnMut(T) -> Fut,
95+
Fut: Future<Output = Option<(Item, T)>>,
96+
{
9497
fn is_terminated(&self) -> bool {
9598
self.state.is_none() && self.fut.is_none()
9699
}
97100
}
98101

99-
impl<T, F, Fut, It> Stream for Unfold<T, F, Fut>
102+
impl<T, F, Fut, Item> Stream for Unfold<T, F, Fut>
100103
where F: FnMut(T) -> Fut,
101-
Fut: Future<Output = Option<(It, T)>>,
104+
Fut: Future<Output = Option<(Item, T)>>,
102105
{
103-
type Item = It;
106+
type Item = Item;
104107

105108
fn poll_next(
106109
mut self: Pin<&mut Self>,
107110
cx: &mut Context<'_>,
108-
) -> Poll<Option<It>> {
111+
) -> Poll<Option<Self::Item>> {
109112
if let Some(state) = self.as_mut().state().take() {
110113
let fut = (self.as_mut().f())(state);
111114
self.as_mut().fut().set(Some(fut));

0 commit comments

Comments
 (0)