From aceff07bbf70ea78d63c8135e5d4d9466a468c43 Mon Sep 17 00:00:00 2001 From: Pieter-Louis Schoeman Date: Sat, 2 May 2026 00:46:09 +0200 Subject: [PATCH] Fix async drop glue for Box --- compiler/rustc_ty_utils/src/needs_drop.rs | 32 ++++++++++++++----- .../async-await/async-drop/async-drop-box.rs | 3 -- .../async-drop/async-drop-box.run.stdout | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 89c526bf8d70a..e9b79f512853a 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -23,10 +23,11 @@ fn needs_drop_raw<'tcx>( // needs drop. let adt_has_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.destructor(tcx).map(|_| DtorType::Significant); - let res = drop_tys_helper(tcx, query.value, query.typing_env, adt_has_dtor, false, false) - .filter(filter_array_elements(tcx, query.typing_env)) - .next() - .is_some(); + let res = + drop_tys_helper(tcx, query.value, query.typing_env, adt_has_dtor, false, false, false) + .filter(filter_array_elements(tcx, query.typing_env)) + .next() + .is_some(); debug!("needs_drop_raw({:?}) = {:?}", query, res); res @@ -41,10 +42,11 @@ fn needs_async_drop_raw<'tcx>( // it needs async drop. let adt_has_async_dtor = |adt_def: ty::AdtDef<'tcx>| adt_def.async_destructor(tcx).map(|_| DtorType::Significant); - let res = drop_tys_helper(tcx, query.value, query.typing_env, adt_has_async_dtor, false, false) - .filter(filter_array_elements_async(tcx, query.typing_env)) - .next() - .is_some(); + let res = + drop_tys_helper(tcx, query.value, query.typing_env, adt_has_async_dtor, false, false, true) + .filter(filter_array_elements_async(tcx, query.typing_env)) + .next() + .is_some(); debug!("needs_async_drop_raw({:?}) = {:?}", query, res); res @@ -90,6 +92,7 @@ fn has_significant_drop_raw<'tcx>( adt_consider_insignificant_dtor(tcx), true, false, + false, ) .filter(filter_array_elements(tcx, query.typing_env)) .next() @@ -331,6 +334,7 @@ fn drop_tys_helper<'tcx>( adt_has_dtor: impl Fn(ty::AdtDef<'tcx>) -> Option, only_significant: bool, exhaustive: bool, + async_drop_recurses_into_box: bool, ) -> impl Iterator>> { fn with_query_cache<'tcx>( tcx: TyCtxt<'tcx>, @@ -353,6 +357,14 @@ fn drop_tys_helper<'tcx>( if adt_def.is_manually_drop() { debug!("drop_tys_helper: `{:?}` is manually drop", adt_def); Ok(Vec::new()) + } else if async_drop_recurses_into_box && adt_def.is_box() { + let boxed_ty = args.type_at(0); + let allocator_ty = args.get(1).map(|arg| arg.expect_ty()); + let boxed_ty = match boxed_ty.kind() { + ty::Dynamic(..) | ty::Error(_) => None, + _ => Some(boxed_ty), + }; + Ok([boxed_ty, allocator_ty].into_iter().flatten().collect()) } else if let Some(dtor_info) = adt_has_dtor(adt_def) { match dtor_info { DtorType::Significant => { @@ -435,6 +447,7 @@ fn adt_drop_tys<'tcx>( adt_has_dtor, false, false, + false, ) .collect::, _>>() .map(|components| tcx.mk_type_list(&components)) @@ -455,6 +468,7 @@ fn adt_async_drop_tys<'tcx>( adt_has_dtor, false, false, + true, ) .collect::, _>>() .map(|components| tcx.mk_type_list(&components)) @@ -474,6 +488,7 @@ fn adt_significant_drop_tys( adt_consider_insignificant_dtor(tcx), true, false, + false, ) .collect::, _>>() .map(|components| tcx.mk_type_list(&components)) @@ -492,6 +507,7 @@ fn list_significant_drop_tys<'tcx>( adt_consider_insignificant_dtor(tcx), true, true, + false, ) .filter_map(|res| res.ok()) .collect::>(), diff --git a/tests/ui/async-await/async-drop/async-drop-box.rs b/tests/ui/async-await/async-drop/async-drop-box.rs index 0a6ed412863a2..f54176afe89a7 100644 --- a/tests/ui/async-await/async-drop/async-drop-box.rs +++ b/tests/ui/async-await/async-drop/async-drop-box.rs @@ -4,9 +4,6 @@ // `Foo` is always inside `Box` // Sync version is called in sync context, async version is called in async function. -//@ known-bug: #143658 -// async version is never actually called - #![feature(async_drop)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/async-drop/async-drop-box.run.stdout b/tests/ui/async-await/async-drop/async-drop-box.run.stdout index a2dab2ba992b5..cb7d0b0fea59d 100644 --- a/tests/ui/async-await/async-drop/async-drop-box.run.stdout +++ b/tests/ui/async-await/async-drop/async-drop-box.run.stdout @@ -2,5 +2,5 @@ Foo::new() : 7 Foo::drop() : 7 Middle Foo::new() : 10 -Foo::drop() : 10 +Foo::async drop() : 10 Done