about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/messages.ftl2
-rw-r--r--compiler/rustc_parse/src/errors.rs7
-rw-r--r--compiler/rustc_parse/src/parser/item.rs6
-rw-r--r--tests/ui/coroutine/async_gen_fn.rs11
-rw-r--r--tests/ui/coroutine/async_gen_fn.stderr8
5 files changed, 34 insertions, 0 deletions
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 1c3c433d8b7..da51d9dbe9f 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -23,6 +23,8 @@ parse_async_block_in_2015 = `async` blocks are only allowed in Rust 2018 or late
 parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015
     .label = to use `async fn`, switch to Rust 2018 or later
 
+parse_async_gen_fn = `async gen` functions are not supported
+
 parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 2018 or later
 
 parse_async_move_order_incorrect = the order of `move` and `async` is incorrect
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 03e047b297d..4bd7c99de9a 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -563,6 +563,13 @@ pub(crate) struct GenFn {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_async_gen_fn)]
+pub(crate) struct AsyncGenFn {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_comma_after_base_struct)]
 #[note]
 pub(crate) struct CommaAfterBaseStruct {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 766ec50e75b..c6d1ea882e9 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2414,6 +2414,12 @@ impl<'a> Parser<'a> {
             self.sess.gated_spans.gate(sym::gen_blocks, span);
         }
 
+        if let (Async::Yes { span: async_span, .. }, Gen::Yes { span: gen_span, .. }) =
+            (asyncness, genness)
+        {
+            self.sess.emit_err(errors::AsyncGenFn { span: async_span.to(gen_span) });
+        }
+
         if !self.eat_keyword_case(kw::Fn, case) {
             // It is possible for `expect_one_of` to recover given the contents of
             // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
diff --git a/tests/ui/coroutine/async_gen_fn.rs b/tests/ui/coroutine/async_gen_fn.rs
new file mode 100644
index 00000000000..f8860e07f6c
--- /dev/null
+++ b/tests/ui/coroutine/async_gen_fn.rs
@@ -0,0 +1,11 @@
+// edition: 2024
+// compile-flags: -Zunstable-options
+#![feature(gen_blocks)]
+
+// async generators are not yet supported, so this test makes sure they make some kind of reasonable
+// error.
+
+async gen fn foo() {}
+//~^ `async gen` functions are not supported
+
+fn main() {}
diff --git a/tests/ui/coroutine/async_gen_fn.stderr b/tests/ui/coroutine/async_gen_fn.stderr
new file mode 100644
index 00000000000..6857ebe6c79
--- /dev/null
+++ b/tests/ui/coroutine/async_gen_fn.stderr
@@ -0,0 +1,8 @@
+error: `async gen` functions are not supported
+  --> $DIR/async_gen_fn.rs:8:1
+   |
+LL | async gen fn foo() {}
+   | ^^^^^^^^^
+
+error: aborting due to 1 previous error
+