AsyncDrop trait without sync Drop generates an error

This commit is contained in:
Andrew Zhogin 2025-06-17 10:14:05 +07:00
parent 55d436467c
commit eee2d7b101
5 changed files with 49 additions and 1 deletions

View file

@ -46,6 +46,9 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the {$
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
hir_analysis_async_drop_without_sync_drop = `AsyncDrop` impl without `Drop` impl
.help = type implementing `AsyncDrop` trait must also implement `Drop` trait to be used in sync context and unwinds
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
.label = deref recursion limit reached
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)

View file

@ -113,7 +113,15 @@ pub fn provide(providers: &mut Providers) {
}
fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor> {
tcx.calculate_dtor(def_id, always_applicable::check_drop_impl)
let dtor = tcx.calculate_dtor(def_id, always_applicable::check_drop_impl);
if dtor.is_none() && tcx.features().async_drop() {
if let Some(async_dtor) = adt_async_destructor(tcx, def_id) {
// When type has AsyncDrop impl, but doesn't have Drop impl, generate error
let span = tcx.def_span(async_dtor.impl_did);
tcx.dcx().emit_err(errors::AsyncDropWithoutSyncDrop { span });
}
}
dtor
}
fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {

View file

@ -1712,3 +1712,11 @@ pub(crate) struct AbiCustomClothedFunction {
)]
pub naked_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_async_drop_without_sync_drop)]
#[help]
pub(crate) struct AsyncDropWithoutSyncDrop {
#[primary_span]
pub span: Span,
}

View file

@ -0,0 +1,19 @@
//@ edition: 2024
#![feature(async_drop)]
#![allow(incomplete_features)]
#![crate_type = "lib"]
use std::future::AsyncDrop;
use std::pin::Pin;
async fn foo() {
let _st = St;
}
struct St;
impl AsyncDrop for St { //~ ERROR: `AsyncDrop` impl without `Drop` impl
async fn drop(self: Pin<&mut Self>) {
println!("123");
}
}

View file

@ -0,0 +1,10 @@
error: `AsyncDrop` impl without `Drop` impl
--> $DIR/async-without-sync.rs:15:1
|
LL | impl AsyncDrop for St {
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: type implementing `AsyncDrop` trait must also implement `Drop` trait to be used in sync context and unwinds
error: aborting due to 1 previous error