From d5a9a005188322cd08dca018402e1593d3a5ebd5 Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Tue, 3 Jun 2025 03:27:21 +0700 Subject: Fix for async drop inside async gen fn --- compiler/rustc_mir_transform/src/coroutine/drop.rs | 34 ++++++++++++++++++---- tests/crashes/140530.rs | 8 ----- .../async-drop/assign-incompatible-types.rs | 9 ++++++ 3 files changed, 37 insertions(+), 14 deletions(-) delete mode 100644 tests/crashes/140530.rs create mode 100644 tests/ui/async-await/async-drop/assign-incompatible-types.rs diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 6b266da5a69..625e53f9959 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -382,12 +382,34 @@ pub(super) fn expand_async_drops<'tcx>( dropline_call_bb = Some(drop_call_bb); } - // value needed only for return-yields or gen-coroutines, so just const here - let value = Operand::Constant(Box::new(ConstOperand { - span: body.span, - user_ty: None, - const_: Const::from_bool(tcx, false), - })); + let value = + if matches!(coroutine_kind, CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) + { + // For AsyncGen we need `yield Poll::Pending` + let full_yield_ty = body.yield_ty().unwrap(); + let ty::Adt(_poll_adt, args) = *full_yield_ty.kind() else { bug!() }; + let ty::Adt(_option_adt, args) = *args.type_at(0).kind() else { bug!() }; + let yield_ty = args.type_at(0); + Operand::Constant(Box::new(ConstOperand { + span: source_info.span, + const_: Const::Unevaluated( + UnevaluatedConst::new( + tcx.require_lang_item(LangItem::AsyncGenPending, None), + tcx.mk_args(&[yield_ty.into()]), + ), + full_yield_ty, + ), + user_ty: None, + })) + } else { + // value needed only for return-yields or gen-coroutines, so just const here + Operand::Constant(Box::new(ConstOperand { + span: body.span, + user_ty: None, + const_: Const::from_bool(tcx, false), + })) + }; + use rustc_middle::mir::AssertKind::ResumedAfterDrop; let panic_bb = insert_panic_block(tcx, body, ResumedAfterDrop(coroutine_kind)); diff --git a/tests/crashes/140530.rs b/tests/crashes/140530.rs deleted file mode 100644 index 7e0372a4bd8..00000000000 --- a/tests/crashes/140530.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #140530 -//@ edition: 2024 - -#![feature(async_drop, gen_blocks)] -async gen fn a() { - _ = async {} -} -fn main() {} diff --git a/tests/ui/async-await/async-drop/assign-incompatible-types.rs b/tests/ui/async-await/async-drop/assign-incompatible-types.rs new file mode 100644 index 00000000000..359939ff9ac --- /dev/null +++ b/tests/ui/async-await/async-drop/assign-incompatible-types.rs @@ -0,0 +1,9 @@ +// ex-ice: #140530 +//@ edition: 2024 +//@ build-pass +#![feature(async_drop, gen_blocks)] +#![allow(incomplete_features)] +async gen fn a() { + _ = async {} +} +fn main() {} -- cgit 1.4.1-3-g733a5