Rollup merge of #141031 - azhogin:azhogin/async-drop-dependency-fix, r=oli-obk

Async drop fix for dropee from another crate (#140858)

Fixes https://github.com/rust-lang/rust/issues/140858.

For `AsyncDestructor` impl def id was wrongly kept as a LocalDefId, which causes crash when dropee is declared in another crate.

Also, potential problem found:
when user crate drops type with async drop in dependency crate, and user crate doesn't enable `feature(async_drop)`, then sync drop version will be used.

Is it a problem? Do we need some notification about such situations?
This commit is contained in:
Matthias Krüger 2025-05-17 10:33:09 +02:00 committed by GitHub
commit 04bc9d13ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 65 additions and 2 deletions

View file

@ -1185,7 +1185,7 @@ pub struct Destructor {
#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
pub struct AsyncDestructor {
/// The `DefId` of the `impl AsyncDrop`
pub impl_did: LocalDefId,
pub impl_did: DefId,
}
#[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]

View file

@ -465,7 +465,7 @@ impl<'tcx> TyCtxt<'tcx> {
dtor_candidate = Some(impl_did);
}
Some(ty::AsyncDestructor { impl_did: dtor_candidate? })
Some(ty::AsyncDestructor { impl_did: dtor_candidate?.into() })
}
/// Returns the set of types that are required to be alive in

View file

@ -0,0 +1,28 @@
//@ edition:2021
#![feature(async_drop)]
#![allow(incomplete_features)]
pub struct HasDrop;
impl Drop for HasDrop{
fn drop(&mut self) {
println!("Sync drop");
}
}
pub struct MongoDrop;
impl MongoDrop {
pub async fn new() -> Result<Self, HasDrop> {
Ok(Self)
}
}
impl Drop for MongoDrop{
fn drop(&mut self) {
println!("Sync drop");
}
}
impl std::future::AsyncDrop for MongoDrop {
async fn drop(self: std::pin::Pin<&mut Self>) {
println!("Async drop");
}
}

View file

@ -0,0 +1,34 @@
//@ run-pass
//@ check-run-results
//@ aux-build:async-drop-dep.rs
//@ edition:2021
#![feature(async_drop)]
#![allow(incomplete_features)]
extern crate async_drop_dep;
use async_drop_dep::MongoDrop;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
use std::future::Future;
async fn asyncdrop() {
let _ = MongoDrop::new().await;
}
pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
let mut fut = pin!(fut);
let ctx = &mut Context::from_waker(Waker::noop());
loop {
match fut.as_mut().poll(ctx) {
Poll::Pending => {}
Poll::Ready(t) => break t,
}
}
}
fn main() {
let _ = block_on(asyncdrop());
}

View file

@ -0,0 +1 @@
Async drop