Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add regression test for #105501 #106264

Merged
merged 1 commit into from
Dec 30, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions src/test/ui/async-await/issue-105501.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// 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!()
}
}
}