forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add regression test for rust-lang#105501
The test 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`
- Loading branch information
Showing
1 changed file
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!() | ||
} | ||
} | ||
} |