diff --git a/async-stream-impl/src/lib.rs b/async-stream-impl/src/lib.rs index 11cffb6..c99ab34 100644 --- a/async-stream-impl/src/lib.rs +++ b/async-stream-impl/src/lib.rs @@ -9,7 +9,6 @@ struct Scrub<'a> { is_try: bool, /// The unit expression, `()`. unit: Box, - has_yielded: bool, crate_path: &'a TokenStream2, } @@ -28,7 +27,6 @@ impl<'a> Scrub<'a> { Self { is_try, unit: syn::parse_quote!(()), - has_yielded: false, crate_path, } } @@ -112,12 +110,8 @@ impl VisitMut for Scrub<'_> { fn visit_expr_mut(&mut self, i: &mut syn::Expr) { match i { syn::Expr::Yield(yield_expr) => { - self.has_yielded = true; - let value_expr = yield_expr.expr.as_ref().unwrap_or(&self.unit); - // let ident = &self.yielder; - *i = if self.is_try { syn::parse_quote! { __yield_tx.send(::core::result::Result::Ok(#value_expr)).await } } else { @@ -126,7 +120,6 @@ impl VisitMut for Scrub<'_> { } syn::Expr::Try(try_expr) => { syn::visit_mut::visit_expr_try_mut(self, try_expr); - // let ident = &self.yielder; let e = &try_expr.expr; *i = syn::parse_quote! { @@ -211,23 +204,10 @@ pub fn stream_inner(input: TokenStream) -> TokenStream { }; let mut scrub = Scrub::new(false, &crate_path); - - for mut stmt in &mut stmts { - scrub.visit_stmt_mut(&mut stmt); - } - - let dummy_yield = if scrub.has_yielded { - None - } else { - Some(quote!(if false { - __yield_tx.send(()).await; - })) - }; - + stmts.iter_mut().for_each(|s| scrub.visit_stmt_mut(s)); quote!({ let (mut __yield_tx, __yield_rx) = #crate_path::yielder::pair(); #crate_path::AsyncStream::new(__yield_rx, async move { - #dummy_yield #(#stmts)* }) }) @@ -245,23 +225,10 @@ pub fn try_stream_inner(input: TokenStream) -> TokenStream { }; let mut scrub = Scrub::new(true, &crate_path); - - for mut stmt in &mut stmts { - scrub.visit_stmt_mut(&mut stmt); - } - - let dummy_yield = if scrub.has_yielded { - None - } else { - Some(quote!(if false { - __yield_tx.send(()).await; - })) - }; - + stmts.iter_mut().for_each(|s| scrub.visit_stmt_mut(s)); quote!({ let (mut __yield_tx, __yield_rx) = #crate_path::yielder::pair(); #crate_path::AsyncStream::new(__yield_rx, async move { - #dummy_yield #(#stmts)* }) }) diff --git a/async-stream/tests/stream.rs b/async-stream/tests/stream.rs index 77b3813..2354692 100644 --- a/async-stream/tests/stream.rs +++ b/async-stream/tests/stream.rs @@ -8,7 +8,25 @@ use tokio_test::assert_ok; #[tokio::test] async fn noop_stream() { - let s = stream! {}; + fn any() -> impl Stream { + stream! {} + } + + let s = any::<()>(); + pin_mut!(s); + + while let Some(_) = s.next().await { + unreachable!(); + } + + let s = any::(); + pin_mut!(s); + + while let Some(_) = s.next().await { + unreachable!(); + } + + let s = any::(); pin_mut!(s); while let Some(_) = s.next().await { @@ -21,11 +39,14 @@ async fn empty_stream() { let mut ran = false; { - let r = &mut ran; - let s = stream! { - *r = true; - println!("hello world!"); - }; + fn unit(r: &mut bool) -> impl Stream + '_ { + stream! { + *r = true; + println!("hello world!"); + } + } + + let s = unit(&mut ran); pin_mut!(s); while let Some(_) = s.next().await { diff --git a/async-stream/tests/ui/yield_in_nested_fn.stderr b/async-stream/tests/ui/yield_in_nested_fn.stderr index a562555..21c81f8 100644 --- a/async-stream/tests/ui/yield_in_nested_fn.stderr +++ b/async-stream/tests/ui/yield_in_nested_fn.stderr @@ -6,11 +6,23 @@ error[E0658]: yield syntax is experimental | = note: see issue #43122 for more information +error[E0282]: type annotations needed for `(async_stream::yielder::Sender, async_stream::yielder::Receiver)` + --> $DIR/yield_in_nested_fn.rs:4:5 + | +4 | / stream! { +5 | | fn foo() { +6 | | yield "hello"; +7 | | } +8 | | }; + | | ^ + | | | + | |______consider giving this pattern the explicit type `(async_stream::yielder::Sender, async_stream::yielder::Receiver)`, where the type parameter `T` is specified + | cannot infer type for type parameter `T` declared on the function `pair` + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0627]: yield expression outside of generator literal --> $DIR/yield_in_nested_fn.rs:6:13 | 6 | yield "hello"; | ^^^^^^^^^^^^^ - -Some errors have detailed explanations: E0627, E0658. -For more information about an error, try `rustc --explain E0627`.