| //@ check-pass |
| //@ edition:2018 |
| |
| // This is a regression test for https://github.com/rust-lang/rust/issues/105501. |
| // It was minified from the published `msf-ice:0.2.1` crate which failed in a crater run. |
| // A faulty compiler was triggering a `higher-ranked lifetime error`: |
| // |
| // > could not prove `[async block@...]: Send` |
| |
| use mini_futures::Stream; |
| |
| fn is_send(_: impl Send) {} |
| |
| pub fn main() { |
| let fut = async { |
| let mut stream = mini_futures::iter([()]) |
| .then(|_| async {}) |
| .map(|_| async { None }) |
| .buffered() |
| .filter_map(std::future::ready); |
| |
| stream.next().await |
| }; |
| |
| is_send(async move { |
| let _: Option<()> = fut.await; |
| }); |
| } |
| |
| // this is a simplified subset of `futures::StreamExt` and related types |
| mod mini_futures { |
| use std::future::Future; |
| use std::pin::Pin; |
| use std::task::{Context, Poll}; |
| |
| pub fn iter<I>(_: I) -> Iter<I::IntoIter> |
| where |
| I: IntoIterator, |
| { |
| todo!() |
| } |
| |
| pub trait Stream { |
| type Item; |
| |
| fn then<Fut, F>(self, _: F) -> Then<Self, Fut, F> |
| where |
| F: FnMut(Self::Item) -> Fut, |
| Fut: Future, |
| Self: Sized, |
| { |
| todo!() |
| } |
| |
| fn map<T, F>(self, _: F) -> Map<Self, F> |
| where |
| F: FnMut(Self::Item) -> T, |
| Self: Sized, |
| { |
| todo!() |
| } |
| |
| fn buffered(self) -> Buffered<Self> |
| where |
| Self::Item: Future, |
| Self: Sized, |
| { |
| todo!() |
| } |
| |
| fn filter_map<Fut, T, F>(self, _: F) -> FilterMap<Self, Fut, F> |
| where |
| F: FnMut(Self::Item) -> Fut, |
| Fut: Future<Output = Option<T>>, |
| Self: Sized, |
| { |
| todo!() |
| } |
| |
| fn next(&mut self) -> Next<'_, Self> { |
| todo!() |
| } |
| } |
| |
| pub struct Iter<I> { |
| __: I, |
| } |
| impl<I> Stream for Iter<I> |
| where |
| I: Iterator, |
| { |
| type Item = I::Item; |
| } |
| |
| pub struct Then<St, Fut, F> { |
| __: (St, Fut, F), |
| } |
| impl<St, Fut, F> Stream for Then<St, Fut, F> |
| where |
| St: Stream, |
| F: FnMut(St::Item) -> Fut, |
| Fut: Future, |
| { |
| type Item = Fut::Output; |
| } |
| |
| pub struct Map<St, F> { |
| __: (St, F), |
| } |
| impl<St, F> Stream for Map<St, F> |
| where |
| St: Stream, |
| F: FnMut1<St::Item>, |
| { |
| type Item = F::Output; |
| } |
| |
| pub trait FnMut1<A> { |
| type Output; |
| } |
| impl<T, A, R> FnMut1<A> for T |
| where |
| T: FnMut(A) -> R, |
| { |
| type Output = R; |
| } |
| |
| pub struct Buffered<St> |
| where |
| St: Stream, |
| St::Item: Future, |
| { |
| __: (St, St::Item), |
| } |
| impl<St> Stream for Buffered<St> |
| where |
| St: Stream, |
| St::Item: Future, |
| { |
| type Item = <St::Item as Future>::Output; |
| } |
| |
| pub struct FilterMap<St, Fut, F> { |
| __: (St, Fut, F), |
| } |
| impl<St, Fut, F, T> Stream for FilterMap<St, Fut, F> |
| where |
| St: Stream, |
| F: FnMut1<St::Item, Output = Fut>, |
| Fut: Future<Output = Option<T>>, |
| { |
| type Item = T; |
| } |
| |
| pub struct Next<'a, St: ?Sized> { |
| __: &'a mut St, |
| } |
| impl<St: ?Sized + Stream> Future for Next<'_, St> { |
| type Output = Option<St::Item>; |
| |
| fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> { |
| todo!() |
| } |
| } |
| } |