about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-06-03 07:03:43 +0200
committerGitHub <noreply@github.com>2025-06-03 07:03:43 +0200
commitaed1171c66549b676648aea359ddffc80fd54a8a (patch)
tree9decba3ff5bf57407e678256f02e55b0e84d922f
parent55f7571a7e241830abfd16ac09153470468793b6 (diff)
parentf023a69f32352531a8da2f43e2ca4cd087317f8c (diff)
downloadrust-aed1171c66549b676648aea359ddffc80fd54a8a.tar.gz
rust-aed1171c66549b676648aea359ddffc80fd54a8a.zip
Rollup merge of #141677 - azhogin:azhogin/async-drop-unexpected-type-instead-of-drop-fn-fix, r=oli-obk
Async drop - type instead of async drop fn, fixes #140484

Fixes: rust-lang/rust#140484
Fixes: rust-lang/rust#140500

Fixes ICE, when type is provided in AsyncDrop trait instead of `async fn drop()`.
Fixes ICE, when async drop fn has wrong signature.
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drop.rs16
-rw-r--r--tests/crashes/140484.rs14
-rw-r--r--tests/crashes/140500.rs14
-rw-r--r--tests/ui/async-await/async-drop/type-parameter.rs16
-rw-r--r--tests/ui/async-await/async-drop/type-parameter.stderr11
-rw-r--r--tests/ui/async-await/async-drop/unexpected-sort.rs18
-rw-r--r--tests/ui/async-await/async-drop/unexpected-sort.stderr32
7 files changed, 91 insertions, 30 deletions
diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs
index 211e2a92f73..c15d7d6f732 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drop.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs
@@ -1,6 +1,7 @@
 use std::{fmt, iter, mem};
 
 use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
+use rustc_hir::def::DefKind;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::Idx;
 use rustc_middle::mir::*;
@@ -254,8 +255,19 @@ where
             // 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()
+            let Some(drop_fn_def_id) = tcx
+                .associated_item_def_ids(drop_trait)
+                .first()
+                .and_then(|def_id| {
+                    if tcx.def_kind(def_id) == DefKind::AssocFn
+                        && tcx.check_args_compatible(*def_id, trait_args)
+                    {
+                        Some(def_id)
+                    } else {
+                        None
+                    }
+                })
+                .copied()
             else {
                 tcx.dcx().span_delayed_bug(
                     self.elaborator.body().span,
diff --git a/tests/crashes/140484.rs b/tests/crashes/140484.rs
deleted file mode 100644
index 92ec1984398..00000000000
--- a/tests/crashes/140484.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: #140484
-//@edition:2024
-#![feature(async_drop)]
-use std::future::AsyncDrop;
-struct a;
-impl Drop for a {
-    fn b() {}
-}
-impl AsyncDrop for a {
-    type c;
-}
-async fn bar() {
-    a;
-}
diff --git a/tests/crashes/140500.rs b/tests/crashes/140500.rs
deleted file mode 100644
index ee5b93ab821..00000000000
--- a/tests/crashes/140500.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: #140500
-
-#![feature(async_drop)]
-use std::future::AsyncDrop;
-struct a;
-impl Drop for a {
-    fn b() {}
-}
-impl AsyncDrop for a {
-    fn c(d: impl Sized) {}
-}
-async fn bar() {
-    a;
-}
diff --git a/tests/ui/async-await/async-drop/type-parameter.rs b/tests/ui/async-await/async-drop/type-parameter.rs
new file mode 100644
index 00000000000..dde5f9f8e64
--- /dev/null
+++ b/tests/ui/async-await/async-drop/type-parameter.rs
@@ -0,0 +1,16 @@
+//@ edition: 2024
+// ex-ice: #140500
+#![crate_type = "lib"]
+#![feature(async_drop)]
+#![expect(incomplete_features)]
+use std::future::AsyncDrop;
+struct A;
+impl Drop for A {
+    fn drop(&mut self) {}
+}
+impl AsyncDrop for A {
+    fn drop(_wrong: impl Sized) {} //~ ERROR: method `drop` has a `self: Pin<&mut Self>` declaration in the trait, but not in the impl
+}
+async fn bar() {
+    A;
+}
diff --git a/tests/ui/async-await/async-drop/type-parameter.stderr b/tests/ui/async-await/async-drop/type-parameter.stderr
new file mode 100644
index 00000000000..841576b839e
--- /dev/null
+++ b/tests/ui/async-await/async-drop/type-parameter.stderr
@@ -0,0 +1,11 @@
+error[E0186]: method `drop` has a `self: Pin<&mut Self>` declaration in the trait, but not in the impl
+  --> $DIR/type-parameter.rs:12:5
+   |
+LL |     fn drop(_wrong: impl Sized) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `self: Pin<&mut Self>` in impl
+   |
+   = note: `drop` from trait: `fn(Pin<&mut Self>) -> impl Future<Output = ()>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0186`.
diff --git a/tests/ui/async-await/async-drop/unexpected-sort.rs b/tests/ui/async-await/async-drop/unexpected-sort.rs
new file mode 100644
index 00000000000..659e21eb241
--- /dev/null
+++ b/tests/ui/async-await/async-drop/unexpected-sort.rs
@@ -0,0 +1,18 @@
+// Ex-ice: #140484
+//@ edition: 2024
+#![crate_type = "lib"]
+#![allow(incomplete_features)]
+#![allow(non_camel_case_types)]
+#![feature(async_drop)]
+use std::future::AsyncDrop;
+struct a;
+impl Drop for a { //~ ERROR: not all trait items implemented, missing: `drop`
+    fn b() {} //~ ERROR: method `b` is not a member of trait `Drop`
+}
+impl AsyncDrop for a { //~ ERROR: not all trait items implemented, missing: `drop`
+    type c = ();
+    //~^ ERROR: type `c` is not a member of trait `AsyncDrop`
+}
+async fn bar() {
+    a;
+}
diff --git a/tests/ui/async-await/async-drop/unexpected-sort.stderr b/tests/ui/async-await/async-drop/unexpected-sort.stderr
new file mode 100644
index 00000000000..a6e4f9fd573
--- /dev/null
+++ b/tests/ui/async-await/async-drop/unexpected-sort.stderr
@@ -0,0 +1,32 @@
+error[E0407]: method `b` is not a member of trait `Drop`
+  --> $DIR/unexpected-sort.rs:10:5
+   |
+LL |     fn b() {}
+   |     ^^^^^^^^^ not a member of trait `Drop`
+
+error[E0437]: type `c` is not a member of trait `AsyncDrop`
+  --> $DIR/unexpected-sort.rs:13:5
+   |
+LL |     type c = ();
+   |     ^^^^^^^^^^^^ not a member of trait `AsyncDrop`
+
+error[E0046]: not all trait items implemented, missing: `drop`
+  --> $DIR/unexpected-sort.rs:9:1
+   |
+LL | impl Drop for a {
+   | ^^^^^^^^^^^^^^^ missing `drop` in implementation
+   |
+   = help: implement the missing item: `fn drop(&mut self) { todo!() }`
+
+error[E0046]: not all trait items implemented, missing: `drop`
+  --> $DIR/unexpected-sort.rs:12:1
+   |
+LL | impl AsyncDrop for a {
+   | ^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
+   |
+   = help: implement the missing item: `async fn drop(self: Pin<&mut Self>) { todo!() }`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0046, E0407, E0437.
+For more information about an error, try `rustc --explain E0046`.