about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-17 10:33:09 +0200
committerGitHub <noreply@github.com>2025-05-17 10:33:09 +0200
commit04bc9d13caa5231facfb28ddf02ba6b148ee25fb (patch)
tree0184594c8c608a4ab929662135bd00af37f879fa
parent642cd65ab256fe70e4e185def0816ab39077f5c6 (diff)
parent7b2dcf298909f1493a57387be564fc2f07a3c6ad (diff)
downloadrust-04bc9d13caa5231facfb28ddf02ba6b148ee25fb.tar.gz
rust-04bc9d13caa5231facfb28ddf02ba6b148ee25fb.zip
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?
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--tests/ui/async-await/async-drop/auxiliary/async-drop-dep.rs28
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.rs34
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.run.stdout1
5 files changed, 65 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 83b318435f9..657bda23bc4 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -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)]
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 6fe5927c29f..9676aa40448 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -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
diff --git a/tests/ui/async-await/async-drop/auxiliary/async-drop-dep.rs b/tests/ui/async-await/async-drop/auxiliary/async-drop-dep.rs
new file mode 100644
index 00000000000..1729599f7b3
--- /dev/null
+++ b/tests/ui/async-await/async-drop/auxiliary/async-drop-dep.rs
@@ -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");
+    }
+}
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.rs b/tests/ui/async-await/async-drop/dependency-dropped.rs
new file mode 100644
index 00000000000..f763bb32b17
--- /dev/null
+++ b/tests/ui/async-await/async-drop/dependency-dropped.rs
@@ -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());
+}
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.run.stdout b/tests/ui/async-await/async-drop/dependency-dropped.run.stdout
new file mode 100644
index 00000000000..7aaf70c12d6
--- /dev/null
+++ b/tests/ui/async-await/async-drop/dependency-dropped.run.stdout
@@ -0,0 +1 @@
+Async drop