1- use core::mem::ManuallyDrop;
21use core::pin::Pin;
32
3+ use futures_core::ready;
4+ use pin_project_lite::pin_project;
5+
46use crate::stream::Stream;
57use crate::task::{Context, Poll};
68
7- /// A stream that will repeatedly yield the same list of elements.
8- #[derive(Debug)]
9- pub struct Cycle<S> {
10- orig: S,
11- source: ManuallyDrop<S>,
9+ pin_project! {
10+ /// A stream that will repeatedly yield the same list of elements.
11+ #[derive(Debug)]
12+ pub struct Cycle<S> {
13+ orig: S,
14+ #[pin]
15+ source: S,
16+ }
1217}
1318
1419impl<S> Cycle<S>
1823 pub(crate) fn new(source: S) -> Self {
1924 Self {
2025 orig: source.clone(),
21- source: ManuallyDrop::new(source),
22- }
23- }
24- }
25-
26- impl<S> Drop for Cycle<S> {
27- fn drop(&mut self) {
28- unsafe {
29- ManuallyDrop::drop(&mut self.source);
26+ source,
3027 }
3128 }
3229}
@@ -38,17 +35,14 @@ where
3835 type Item = S::Item;
3936
4037 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
41- unsafe {
42- let this = self.get_unchecked_mut();
38+ let mut this = self.project();
4339
44- match futures_core::ready!(Pin::new_unchecked(&mut *this.source).poll_next(cx)) {
45- Some(item) => Poll::Ready(Some(item)),
46- None => {
47- ManuallyDrop::drop(&mut this.source);
48- this.source = ManuallyDrop::new(this.orig.clone());
49- Pin::new_unchecked(&mut *this.source).poll_next(cx)
50- }
40+ match ready!(this.source.as_mut().poll_next(cx)) {
41+ None => {
42+ this.source.set(this.orig.clone());
43+ this.source.poll_next(cx)
5144 }
45+ item => Poll::Ready(item),
5246 }
5347 }
5448}
0 commit comments