Skip to content

Commit e23c14c

Browse files
committed
Don't force zero-yield stream item type of '()'
1 parent 8bf33a6 commit e23c14c

File tree

4 files changed

+35
-44
lines changed

4 files changed

+35
-44
lines changed

async-stream-impl/src/lib.rs

+2-35
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct Scrub<'a> {
99
is_try: bool,
1010
/// The unit expression, `()`.
1111
unit: Box<syn::Expr>,
12-
has_yielded: bool,
1312
crate_path: &'a TokenStream2,
1413
}
1514

@@ -28,7 +27,6 @@ impl<'a> Scrub<'a> {
2827
Self {
2928
is_try,
3029
unit: syn::parse_quote!(()),
31-
has_yielded: false,
3230
crate_path,
3331
}
3432
}
@@ -112,12 +110,8 @@ impl VisitMut for Scrub<'_> {
112110
fn visit_expr_mut(&mut self, i: &mut syn::Expr) {
113111
match i {
114112
syn::Expr::Yield(yield_expr) => {
115-
self.has_yielded = true;
116-
117113
let value_expr = yield_expr.expr.as_ref().unwrap_or(&self.unit);
118114

119-
// let ident = &self.yielder;
120-
121115
*i = if self.is_try {
122116
syn::parse_quote! { __yield_tx.send(::core::result::Result::Ok(#value_expr)).await }
123117
} else {
@@ -126,7 +120,6 @@ impl VisitMut for Scrub<'_> {
126120
}
127121
syn::Expr::Try(try_expr) => {
128122
syn::visit_mut::visit_expr_try_mut(self, try_expr);
129-
// let ident = &self.yielder;
130123
let e = &try_expr.expr;
131124

132125
*i = syn::parse_quote! {
@@ -211,23 +204,10 @@ pub fn stream_inner(input: TokenStream) -> TokenStream {
211204
};
212205

213206
let mut scrub = Scrub::new(false, &crate_path);
214-
215-
for mut stmt in &mut stmts {
216-
scrub.visit_stmt_mut(&mut stmt);
217-
}
218-
219-
let dummy_yield = if scrub.has_yielded {
220-
None
221-
} else {
222-
Some(quote!(if false {
223-
__yield_tx.send(()).await;
224-
}))
225-
};
226-
207+
stmts.iter_mut().for_each(|s| scrub.visit_stmt_mut(s));
227208
quote!({
228209
let (mut __yield_tx, __yield_rx) = #crate_path::yielder::pair();
229210
#crate_path::AsyncStream::new(__yield_rx, async move {
230-
#dummy_yield
231211
#(#stmts)*
232212
})
233213
})
@@ -245,23 +225,10 @@ pub fn try_stream_inner(input: TokenStream) -> TokenStream {
245225
};
246226

247227
let mut scrub = Scrub::new(true, &crate_path);
248-
249-
for mut stmt in &mut stmts {
250-
scrub.visit_stmt_mut(&mut stmt);
251-
}
252-
253-
let dummy_yield = if scrub.has_yielded {
254-
None
255-
} else {
256-
Some(quote!(if false {
257-
__yield_tx.send(()).await;
258-
}))
259-
};
260-
228+
stmts.iter_mut().for_each(|s| scrub.visit_stmt_mut(s));
261229
quote!({
262230
let (mut __yield_tx, __yield_rx) = #crate_path::yielder::pair();
263231
#crate_path::AsyncStream::new(__yield_rx, async move {
264-
#dummy_yield
265232
#(#stmts)*
266233
})
267234
})

async-stream/tests/stream.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ use tokio_test::assert_ok;
88

99
#[tokio::test]
1010
async fn noop_stream() {
11-
let s = stream! {};
11+
fn unit() -> impl Stream<Item = ()> {
12+
stream! {}
13+
}
14+
15+
let s = unit();
1216
pin_mut!(s);
1317

1418
while let Some(_) = s.next().await {
@@ -21,11 +25,14 @@ async fn empty_stream() {
2125
let mut ran = false;
2226

2327
{
24-
let r = &mut ran;
25-
let s = stream! {
26-
*r = true;
27-
println!("hello world!");
28-
};
28+
fn unit(r: &mut bool) -> impl Stream<Item = ()> + '_ {
29+
stream! {
30+
*r = true;
31+
println!("hello world!");
32+
}
33+
}
34+
35+
let s = unit(&mut ran);
2936
pin_mut!(s);
3037

3138
while let Some(_) = s.next().await {

async-stream/tests/ui/yield_in_async.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ error[E0271]: type mismatch resolving `<[static generator@$DIR/src/lib.rs:201:9:
2424
10 | | };
2525
| |______^ expected `()`, found integer
2626
|
27+
::: $RUST/core/src/future/mod.rs
28+
|
29+
| T: Generator<ResumeTy, Yield = ()>,
30+
| ---------- required by this bound in `from_generator`
31+
|
2732
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
2833

2934
error[E0698]: type inside `async` block must be known in this context

async-stream/tests/ui/yield_in_nested_fn.stderr

+15-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,23 @@ error[E0658]: yield syntax is experimental
66
|
77
= note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
88

9+
error[E0282]: type annotations needed for `(async_stream::yielder::Sender<T>, async_stream::yielder::Receiver<T>)`
10+
--> $DIR/yield_in_nested_fn.rs:4:5
11+
|
12+
4 | / stream! {
13+
5 | | fn foo() {
14+
6 | | yield "hello";
15+
7 | | }
16+
8 | | };
17+
| | ^
18+
| | |
19+
| |______consider giving this pattern the explicit type `(async_stream::yielder::Sender<T>, async_stream::yielder::Receiver<T>)`, where the type parameter `T` is specified
20+
| cannot infer type for type parameter `T` declared on the function `pair`
21+
|
22+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
23+
924
error[E0627]: yield expression outside of generator literal
1025
--> $DIR/yield_in_nested_fn.rs:6:13
1126
|
1227
6 | yield "hello";
1328
| ^^^^^^^^^^^^^
14-
15-
Some errors have detailed explanations: E0627, E0658.
16-
For more information about an error, try `rustc --explain E0627`.

0 commit comments

Comments
 (0)