From dc794f18a425a20563943ea4201b34ebea2aa017 Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Wed, 21 May 2025 15:21:01 +0700 Subject: When AsyncDrop impl is empty, sync drop generated in elaborator (Fixes #140974) --- compiler/rustc_mir_transform/src/elaborate_drop.rs | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_mir_transform/src') diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 73a58160a6a..5d86b1353c0 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -251,7 +251,29 @@ where span_bug!(span, "invalid `AsyncDrop` impl_source: {:?}", impl_source); } }; - let drop_fn_def_id = tcx.associated_item_def_ids(drop_trait)[0]; + // impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...' + // (#140974). + // Such code will report error, so just generate sync drop here and return + let Some(drop_fn_def_id) = + tcx.associated_item_def_ids(drop_trait).into_iter().nth(0).copied() + else { + tcx.dcx().span_delayed_bug( + self.elaborator.body().span, + "AsyncDrop type without correct `async fn drop(...)`.", + ); + self.elaborator.patch().patch_terminator( + pin_obj_bb, + TerminatorKind::Drop { + place, + target: succ, + unwind: unwind.into_action(), + replace: false, + drop: None, + async_fut: None, + }, + ); + return pin_obj_bb; + }; let drop_fn = Ty::new_fn_def(tcx, drop_fn_def_id, trait_args); let sig = drop_fn.fn_sig(tcx); let sig = tcx.instantiate_bound_regions_with_erased(sig); -- cgit 1.4.1-3-g733a5 From 7c38b6fd28b1972659b662683866c359f198a6f7 Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Tue, 20 May 2025 22:36:03 +0700 Subject: Async drop fix for 'broken mir in AsyncDropGlue, place has deref as a later projection' (#140975) --- compiler/rustc_mir_transform/src/elaborate_drop.rs | 21 ++++++++++------- tests/crashes/140975.rs | 22 ------------------ .../async-drop/deref-later-projection.rs | 26 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 30 deletions(-) delete mode 100644 tests/crashes/140975.rs create mode 100644 tests/ui/async-await/async-drop/deref-later-projection.rs (limited to 'compiler/rustc_mir_transform/src') diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 73a58160a6a..61312eb7d1a 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -318,15 +318,20 @@ where bug!(); }; let obj_ptr_ty = Ty::new_mut_ptr(tcx, drop_ty); - let obj_ptr_place = Place::from(self.new_temp(obj_ptr_ty)); let unwrap_ty = adt_def.non_enum_variant().fields[FieldIdx::ZERO].ty(tcx, adt_args); - let addr = Rvalue::RawPtr( - RawPtrKind::Mut, - pin_obj_place.project_deeper( - &[ProjectionElem::Field(FieldIdx::ZERO, unwrap_ty), ProjectionElem::Deref], - tcx, - ), - ); + let obj_ref_place = Place::from(self.new_temp(unwrap_ty)); + call_statements.push(self.assign( + obj_ref_place, + Rvalue::Use(Operand::Copy(tcx.mk_place_field( + pin_obj_place, + FieldIdx::ZERO, + unwrap_ty, + ))), + )); + + let obj_ptr_place = Place::from(self.new_temp(obj_ptr_ty)); + + let addr = Rvalue::RawPtr(RawPtrKind::Mut, tcx.mk_place_deref(obj_ref_place)); call_statements.push(self.assign(obj_ptr_place, addr)); obj_ptr_place }; diff --git a/tests/crashes/140975.rs b/tests/crashes/140975.rs deleted file mode 100644 index e11dd40612c..00000000000 --- a/tests/crashes/140975.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #140975 -//@ compile-flags: --crate-type lib -Zvalidate-mir -//@ edition: 2021 -#![feature(async_drop)] -use std::{future::AsyncDrop, pin::Pin}; - -struct HasAsyncDrop ; -impl Drop for HasAsyncDrop { - fn drop(&mut self) {} -} -impl AsyncDrop for HasAsyncDrop { - async fn drop(self: Pin<&mut Self>) {} -} - -struct Holder { - inner: HasAsyncDrop, -} -async fn bar() { - Holder { - inner: HasAsyncDrop - }; -} diff --git a/tests/ui/async-await/async-drop/deref-later-projection.rs b/tests/ui/async-await/async-drop/deref-later-projection.rs new file mode 100644 index 00000000000..baf81daf766 --- /dev/null +++ b/tests/ui/async-await/async-drop/deref-later-projection.rs @@ -0,0 +1,26 @@ +// Ex-ICE: #140975 +//@ compile-flags: -Zvalidate-mir +//@ build-pass +//@ edition:2021 +#![crate_type = "lib"] +#![feature(async_drop)] +#![allow(incomplete_features)] + +use std::{future::AsyncDrop, pin::Pin}; + +struct HasAsyncDrop ; +impl Drop for HasAsyncDrop { + fn drop(&mut self) {} +} +impl AsyncDrop for HasAsyncDrop { + async fn drop(self: Pin<&mut Self>) {} +} + +struct Holder { + inner: HasAsyncDrop, +} +async fn bar() { + Holder { + inner: HasAsyncDrop + }; +} -- cgit 1.4.1-3-g733a5