Skip to content

Commit eee2d7b

Browse files
committed
AsyncDrop trait without sync Drop generates an error
1 parent 55d4364 commit eee2d7b

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the {$
4646
4747
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
4848
49+
hir_analysis_async_drop_without_sync_drop = `AsyncDrop` impl without `Drop` impl
50+
.help = type implementing `AsyncDrop` trait must also implement `Drop` trait to be used in sync context and unwinds
51+
4952
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
5053
.label = deref recursion limit reached
5154
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,15 @@ pub fn provide(providers: &mut Providers) {
113113
}
114114

115115
fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor> {
116-
tcx.calculate_dtor(def_id, always_applicable::check_drop_impl)
116+
let dtor = tcx.calculate_dtor(def_id, always_applicable::check_drop_impl);
117+
if dtor.is_none() && tcx.features().async_drop() {
118+
if let Some(async_dtor) = adt_async_destructor(tcx, def_id) {
119+
// When type has AsyncDrop impl, but doesn't have Drop impl, generate error
120+
let span = tcx.def_span(async_dtor.impl_did);
121+
tcx.dcx().emit_err(errors::AsyncDropWithoutSyncDrop { span });
122+
}
123+
}
124+
dtor
117125
}
118126

119127
fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,3 +1712,11 @@ pub(crate) struct AbiCustomClothedFunction {
17121712
)]
17131713
pub naked_span: Span,
17141714
}
1715+
1716+
#[derive(Diagnostic)]
1717+
#[diag(hir_analysis_async_drop_without_sync_drop)]
1718+
#[help]
1719+
pub(crate) struct AsyncDropWithoutSyncDrop {
1720+
#[primary_span]
1721+
pub span: Span,
1722+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ edition: 2024
2+
#![feature(async_drop)]
3+
#![allow(incomplete_features)]
4+
#![crate_type = "lib"]
5+
6+
use std::future::AsyncDrop;
7+
use std::pin::Pin;
8+
9+
async fn foo() {
10+
let _st = St;
11+
}
12+
13+
struct St;
14+
15+
impl AsyncDrop for St { //~ ERROR: `AsyncDrop` impl without `Drop` impl
16+
async fn drop(self: Pin<&mut Self>) {
17+
println!("123");
18+
}
19+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: `AsyncDrop` impl without `Drop` impl
2+
--> $DIR/async-without-sync.rs:15:1
3+
|
4+
LL | impl AsyncDrop for St {
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= help: type implementing `AsyncDrop` trait must also implement `Drop` trait to be used in sync context and unwinds
8+
9+
error: aborting due to 1 previous error
10+

0 commit comments

Comments
 (0)