about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/remove_zsts.rs4
-rw-r--r--src/test/ui/mir/remove-zsts-query-cycle.rs16
2 files changed, 20 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs
index 25e3c52132c..d93ffa38c69 100644
--- a/compiler/rustc_mir_transform/src/remove_zsts.rs
+++ b/compiler/rustc_mir_transform/src/remove_zsts.rs
@@ -9,6 +9,10 @@ pub struct RemoveZsts;
 
 impl<'tcx> MirPass<'tcx> for RemoveZsts {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        // Avoid query cycles (generators require optimized MIR for layout).
+        if tcx.type_of(body.source.def_id()).is_generator() {
+            return;
+        }
         let param_env = tcx.param_env(body.source.def_id());
         let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
         for block in basic_blocks.iter_mut() {
diff --git a/src/test/ui/mir/remove-zsts-query-cycle.rs b/src/test/ui/mir/remove-zsts-query-cycle.rs
new file mode 100644
index 00000000000..8f93c6cadff
--- /dev/null
+++ b/src/test/ui/mir/remove-zsts-query-cycle.rs
@@ -0,0 +1,16 @@
+// Regression test for #88972. Used to cause a query cycle:
+//   optimized mir -> remove zsts -> layout of a generator -> optimized mir.
+//
+// edition:2018
+// compile-flags: --crate-type=lib
+// build-pass
+
+pub async fn listen() -> Result<(), std::io::Error> {
+    let f = do_async();
+    std::mem::forget(f);
+    Ok(())
+}
+
+pub async fn do_async() {
+    listen().await.unwrap()
+}