Skip to content

Commit 42e7df9

Browse files
committed
Add regression test for #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`
1 parent 808be91 commit 42e7df9

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed
+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// check-pass
2+
// edition:2018
3+
4+
// This is a regression test for https://github.com/rust-lang/rust/issues/105501.
5+
// It was minified from the published `msf-ice:0.2.1` crate which failed in a crater run.
6+
// A faulty compiler was triggering a `higher-ranked lifetime error`:
7+
//
8+
// > could not prove `[async block@...]: Send`
9+
10+
use mini_futures::Stream;
11+
12+
fn is_send(_: impl Send) {}
13+
14+
pub fn main() {
15+
let fut = async {
16+
let mut stream = mini_futures::iter([()])
17+
.then(|_| async {})
18+
.map(|_| async { None })
19+
.buffered()
20+
.filter_map(std::future::ready);
21+
22+
stream.next().await
23+
};
24+
25+
is_send(async move {
26+
let _: Option<()> = fut.await;
27+
});
28+
}
29+
30+
// this is a simplified subset of `futures::StreamExt` and related types
31+
mod mini_futures {
32+
use std::future::Future;
33+
use std::pin::Pin;
34+
use std::task::{Context, Poll};
35+
36+
pub fn iter<I>(_: I) -> Iter<I::IntoIter>
37+
where
38+
I: IntoIterator,
39+
{
40+
todo!()
41+
}
42+
43+
pub trait Stream {
44+
type Item;
45+
46+
fn then<Fut, F>(self, _: F) -> Then<Self, Fut, F>
47+
where
48+
F: FnMut(Self::Item) -> Fut,
49+
Fut: Future,
50+
Self: Sized,
51+
{
52+
todo!()
53+
}
54+
55+
fn map<T, F>(self, _: F) -> Map<Self, F>
56+
where
57+
F: FnMut(Self::Item) -> T,
58+
Self: Sized,
59+
{
60+
todo!()
61+
}
62+
63+
fn buffered(self) -> Buffered<Self>
64+
where
65+
Self::Item: Future,
66+
Self: Sized,
67+
{
68+
todo!()
69+
}
70+
71+
fn filter_map<Fut, T, F>(self, _: F) -> FilterMap<Self, Fut, F>
72+
where
73+
F: FnMut(Self::Item) -> Fut,
74+
Fut: Future<Output = Option<T>>,
75+
Self: Sized,
76+
{
77+
todo!()
78+
}
79+
80+
fn next(&mut self) -> Next<'_, Self> {
81+
todo!()
82+
}
83+
}
84+
85+
pub struct Iter<I> {
86+
__: I,
87+
}
88+
impl<I> Stream for Iter<I>
89+
where
90+
I: Iterator,
91+
{
92+
type Item = I::Item;
93+
}
94+
95+
pub struct Then<St, Fut, F> {
96+
__: (St, Fut, F),
97+
}
98+
impl<St, Fut, F> Stream for Then<St, Fut, F>
99+
where
100+
St: Stream,
101+
F: FnMut(St::Item) -> Fut,
102+
Fut: Future,
103+
{
104+
type Item = Fut::Output;
105+
}
106+
107+
pub struct Map<St, F> {
108+
__: (St, F),
109+
}
110+
impl<St, F> Stream for Map<St, F>
111+
where
112+
St: Stream,
113+
F: FnMut1<St::Item>,
114+
{
115+
type Item = F::Output;
116+
}
117+
118+
pub trait FnMut1<A> {
119+
type Output;
120+
}
121+
impl<T, A, R> FnMut1<A> for T
122+
where
123+
T: FnMut(A) -> R,
124+
{
125+
type Output = R;
126+
}
127+
128+
pub struct Buffered<St>
129+
where
130+
St: Stream,
131+
St::Item: Future,
132+
{
133+
__: (St, St::Item),
134+
}
135+
impl<St> Stream for Buffered<St>
136+
where
137+
St: Stream,
138+
St::Item: Future,
139+
{
140+
type Item = <St::Item as Future>::Output;
141+
}
142+
143+
pub struct FilterMap<St, Fut, F> {
144+
__: (St, Fut, F),
145+
}
146+
impl<St, Fut, F, T> Stream for FilterMap<St, Fut, F>
147+
where
148+
St: Stream,
149+
F: FnMut1<St::Item, Output = Fut>,
150+
Fut: Future<Output = Option<T>>,
151+
{
152+
type Item = T;
153+
}
154+
155+
pub struct Next<'a, St: ?Sized> {
156+
__: &'a mut St,
157+
}
158+
impl<St: ?Sized + Stream> Future for Next<'_, St> {
159+
type Output = Option<St::Item>;
160+
161+
fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
162+
todo!()
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)