Skip to content

Commit 26b7617

Browse files
committed
re-add iter_pin_ref as public
1 parent 984c173 commit 26b7617

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

futures-util/src/stream/futures_unordered/iter.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@ pub struct IterMut<'a, Fut: Unpin>(pub(super) IterPinMut<'a, Fut>);
1818

1919
#[derive(Debug)]
2020
/// Immutable iterator over all futures in the unordered set.
21-
pub struct Iter<'a, Fut: Unpin> {
21+
pub struct IterPinRef<'a, Fut> {
2222
pub(super) task: *const Task<Fut>,
2323
pub(super) len: usize,
2424
pub(super) pending_next_all: *mut Task<Fut>,
2525
pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>,
2626
}
2727

28+
#[derive(Debug)]
29+
/// Immutable iterator over all the futures in the unordered set.
30+
pub struct Iter<'a, Fut: Unpin>(pub(super) IterPinRef<'a, Fut>);
31+
2832
#[derive(Debug)]
2933
/// Owned iterator over all futures in the unordered set.
3034
pub struct IntoIter<Fut: Unpin> {
@@ -109,10 +113,10 @@ impl<'a, Fut: Unpin> Iterator for IterMut<'a, Fut> {
109113

110114
impl<Fut: Unpin> ExactSizeIterator for IterMut<'_, Fut> {}
111115

112-
impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
113-
type Item = &'a Fut;
116+
impl<'a, Fut: Unpin> Iterator for IterPinRef<'a, Fut> {
117+
type Item = Pin<&'a Fut>;
114118

115-
fn next(&mut self) -> Option<&'a Fut> {
119+
fn next(&mut self) -> Option<Pin<&'a Fut>> {
116120
if self.task.is_null() {
117121
return None;
118122
}
@@ -127,7 +131,7 @@ impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
127131
let next = (*self.task).spin_next_all(self.pending_next_all, Relaxed);
128132
self.task = next;
129133
self.len -= 1;
130-
Some(future)
134+
Some(Pin::new_unchecked(future))
131135
}
132136
}
133137

@@ -136,6 +140,20 @@ impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
136140
}
137141
}
138142

143+
impl<Fut: Unpin> ExactSizeIterator for IterPinRef<'_, Fut> {}
144+
145+
impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
146+
type Item = &'a Fut;
147+
148+
fn next(&mut self) -> Option<&'a Fut> {
149+
self.0.next().map(Pin::get_ref)
150+
}
151+
152+
fn size_hint(&self) -> (usize, Option<usize>) {
153+
self.0.size_hint()
154+
}
155+
}
156+
139157
impl<Fut: Unpin> ExactSizeIterator for Iter<'_, Fut> {}
140158

141159
// SAFETY: we do nothing thread-local and there is no interior mutability,
@@ -146,5 +164,5 @@ unsafe impl<Fut: Sync> Sync for IterPinMut<'_, Fut> {}
146164
unsafe impl<Fut: Send + Unpin> Send for IntoIter<Fut> {}
147165
unsafe impl<Fut: Sync + Unpin> Sync for IntoIter<Fut> {}
148166

149-
unsafe impl<Fut: Send + Unpin> Send for Iter<'_, Fut> {}
150-
unsafe impl<Fut: Sync + Unpin> Sync for Iter<'_, Fut> {}
167+
unsafe impl<Fut: Send + Unpin> Send for IterPinRef<'_, Fut> {}
168+
unsafe impl<Fut: Sync + Unpin> Sync for IterPinRef<'_, Fut> {}

futures-util/src/stream/futures_unordered/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError};
2222
mod abort;
2323

2424
mod iter;
25-
pub use self::iter::{IntoIter, Iter, IterMut, IterPinMut};
25+
pub use self::iter::{IntoIter, Iter, IterMut, IterPinMut, IterPinRef};
2626

2727
mod task;
2828
use self::task::Task;
@@ -190,10 +190,7 @@ impl<Fut> FuturesUnordered<Fut> {
190190
where
191191
Fut: Unpin,
192192
{
193-
let (task, len) = self.atomic_load_head_and_len_all();
194-
let pending_next_all = self.pending_next_all();
195-
196-
Iter { task, len, pending_next_all, _marker: PhantomData }
193+
Iter(Pin::new(self).iter_pin_ref())
197194
}
198195

199196
/// Returns an iterator that allows modifying each future in the set.
@@ -204,6 +201,14 @@ impl<Fut> FuturesUnordered<Fut> {
204201
IterMut(Pin::new(self).iter_pin_mut())
205202
}
206203

204+
/// Returns an iterator that allows inspecting each future in the set.
205+
pub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> {
206+
let (task, len) = self.atomic_load_head_and_len_all();
207+
let pending_next_all = self.pending_next_all();
208+
209+
IterPinRef { task, len, pending_next_all, _marker: PhantomData }
210+
}
211+
207212
/// Returns an iterator that allows modifying each future in the set.
208213
pub fn iter_pin_mut(mut self: Pin<&mut Self>) -> IterPinMut<'_, Fut> {
209214
// `head_all` can be accessed directly and we don't need to spin on

futures/tests/auto_traits.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,6 +1822,12 @@ pub mod stream {
18221822
assert_not_impl!(futures_unordered::IterPinMut<*const ()>: Sync);
18231823
assert_impl!(futures_unordered::IterPinMut<PhantomPinned>: Unpin);
18241824

1825+
assert_impl!(futures_unordered::IterPinRef<()>: Send);
1826+
assert_not_impl!(futures_unordered::IterPinRef<*const ()>: Send);
1827+
assert_impl!(futures_unordered::IterPinRef<()>: Sync);
1828+
assert_not_impl!(futures_unordered::IterPinRef<*const ()>: Sync);
1829+
assert_impl!(futures_unordered::IterPinRef<PhantomPinned>: Unpin);
1830+
18251831
assert_impl!(futures_unordered::IntoIter<()>: Send);
18261832
assert_not_impl!(futures_unordered::IntoIter<*const ()>: Send);
18271833
assert_impl!(futures_unordered::IntoIter<()>: Sync);

0 commit comments

Comments
 (0)