about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs16
-rw-r--r--tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir2
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir2
-rw-r--r--tests/run-make/panic-abort-eh_frame/Makefile2
-rw-r--r--tests/run-make/panic-abort-eh_frame/foo.rs24
5 files changed, 43 insertions, 3 deletions
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 797a1a86846..2bd759ab1e5 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -50,8 +50,10 @@
 //! For generators with state 1 (returned) and state 2 (poisoned) it does nothing.
 //! Otherwise it drops all the values in scope at the last suspension point.
 
+use crate::abort_unwinding_calls;
 use crate::deref_separator::deref_finder;
 use crate::errors;
+use crate::pass_manager as pm;
 use crate::simplify;
 use crate::MirPass;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -64,6 +66,7 @@ use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::dump_mir;
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::*;
+use rustc_middle::ty::InstanceDef;
 use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
 use rustc_middle::ty::{GeneratorArgs, GenericArgsRef};
 use rustc_mir_dataflow::impls::{
@@ -1147,6 +1150,17 @@ fn create_generator_drop_shim<'tcx>(
     // unrelated code from the resume part of the function
     simplify::remove_dead_blocks(tcx, &mut body);
 
+    // Update the body's def to become the drop glue.
+    let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
+    body.source.instance = InstanceDef::DropGlue(drop_in_place, Some(gen_ty));
+
+    pm::run_passes_no_validate(
+        tcx,
+        &mut body,
+        &[&abort_unwinding_calls::AbortUnwindingCalls],
+        None,
+    );
+
     dump_mir(tcx, false, "generator_drop", &0, &body, |_, _| Ok(()));
 
     body
@@ -1317,6 +1331,8 @@ fn create_generator_resume_function<'tcx>(
     // unrelated code from the drop part of the function
     simplify::remove_dead_blocks(tcx, body);
 
+    pm::run_passes_no_validate(tcx, body, &[&abort_unwinding_calls::AbortUnwindingCalls], None);
+
     dump_mir(tcx, false, "generator_resume", &0, body, |_, _| Ok(()));
 }
 
diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
index 074ebddf78b..9be5b8509c7 100644
--- a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
@@ -30,7 +30,7 @@ fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]>
     }
 
     bb2: {
-        assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind continue];
+        assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind unreachable];
     }
 
     bb3: {
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
index f774f32eb23..80ac92d59f3 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
@@ -310,7 +310,7 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>,
     }
 
     bb28: {
-        assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind continue];
+        assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind unreachable];
     }
 
     bb29: {
diff --git a/tests/run-make/panic-abort-eh_frame/Makefile b/tests/run-make/panic-abort-eh_frame/Makefile
index 1cb7bf575cb..7020455b742 100644
--- a/tests/run-make/panic-abort-eh_frame/Makefile
+++ b/tests/run-make/panic-abort-eh_frame/Makefile
@@ -6,5 +6,5 @@
 include ../tools.mk
 
 all:
-	$(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort
+	$(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir
 	objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA'
diff --git a/tests/run-make/panic-abort-eh_frame/foo.rs b/tests/run-make/panic-abort-eh_frame/foo.rs
index e1853529455..e2274d469e7 100644
--- a/tests/run-make/panic-abort-eh_frame/foo.rs
+++ b/tests/run-make/panic-abort-eh_frame/foo.rs
@@ -1,5 +1,13 @@
 #![no_std]
 
+use core::future::Future;
+
+pub struct NeedsDrop;
+
+impl Drop for NeedsDrop {
+    fn drop(&mut self) {}
+}
+
 #[panic_handler]
 fn handler(_: &core::panic::PanicInfo<'_>) -> ! {
     loop {}
@@ -8,3 +16,19 @@ fn handler(_: &core::panic::PanicInfo<'_>) -> ! {
 pub unsafe fn oops(x: *const u32) -> u32 {
     *x
 }
+
+pub async fn foo(_: NeedsDrop) {
+    async fn bar() {}
+    bar().await;
+}
+
+pub fn poll_foo(x: &mut core::task::Context<'_>) {
+    let _g = NeedsDrop;
+    let mut p = core::pin::pin!(foo(NeedsDrop));
+    let _ = p.as_mut().poll(x);
+    let _ = p.as_mut().poll(x);
+}
+
+pub fn drop_foo() {
+    drop(foo(NeedsDrop));
+}