about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-12-18 01:45:09 +0000
committerMichael Goulet <michael@errs.io>2023-12-18 01:45:42 +0000
commitbb33200047722e321480f7e5004a74395804958d (patch)
treeb57fa97aeb025ee084c6ce158cb5096f47ba98ec
parent454bff768228e8dee53462ee63f766521191f8b0 (diff)
downloadrust-bb33200047722e321480f7e5004a74395804958d.tar.gz
rust-bb33200047722e321480f7e5004a74395804958d.zip
Make sure all kinds of generators only return unit
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs7
-rw-r--r--tests/ui/coroutine/return-types.rs21
-rw-r--r--tests/ui/coroutine/return-types.stderr31
3 files changed, 56 insertions, 3 deletions
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 7e43d67587b..d19d304128a 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -650,9 +650,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         },
                     )
                 }
-                // For a `gen {}` block created as a `gen fn` body, we need the return type to be
-                // ().
-                Some(hir::CoroutineKind::Gen(hir::CoroutineSource::Fn)) => self.tcx.types.unit,
+                // All `gen {}` and `async gen {}` must return unit.
+                Some(hir::CoroutineKind::Gen(_) | hir::CoroutineKind::AsyncGen(_)) => {
+                    self.tcx.types.unit
+                }
 
                 _ => astconv.ty_infer(None, decl.output.span()),
             },
diff --git a/tests/ui/coroutine/return-types.rs b/tests/ui/coroutine/return-types.rs
new file mode 100644
index 00000000000..3543d6293f7
--- /dev/null
+++ b/tests/ui/coroutine/return-types.rs
@@ -0,0 +1,21 @@
+// compile-flags: --edition 2024 -Zunstable-options
+
+#![feature(gen_blocks)]
+
+async gen fn async_gen_fn() -> i32 { 0 }
+//~^ ERROR mismatched types
+
+gen fn gen_fn() -> i32 { 0 }
+//~^ ERROR mismatched types
+
+fn async_gen_block() {
+    async gen { yield (); 1 };
+    //~^ ERROR mismatched types
+}
+
+fn gen_block() {
+    gen { yield (); 1 };
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/coroutine/return-types.stderr b/tests/ui/coroutine/return-types.stderr
new file mode 100644
index 00000000000..7be96e538d9
--- /dev/null
+++ b/tests/ui/coroutine/return-types.stderr
@@ -0,0 +1,31 @@
+error[E0308]: mismatched types
+  --> $DIR/return-types.rs:5:38
+   |
+LL | async gen fn async_gen_fn() -> i32 { 0 }
+   |                                ---   ^ expected `()`, found integer
+   |                                |
+   |                                expected `()` because of return type
+
+error[E0308]: mismatched types
+  --> $DIR/return-types.rs:8:26
+   |
+LL | gen fn gen_fn() -> i32 { 0 }
+   |                    ---   ^ expected `()`, found integer
+   |                    |
+   |                    expected `()` because of return type
+
+error[E0308]: mismatched types
+  --> $DIR/return-types.rs:12:27
+   |
+LL |     async gen { yield (); 1 };
+   |                           ^ expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/return-types.rs:17:21
+   |
+LL |     gen { yield (); 1 };
+   |                     ^ expected `()`, found integer
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.