about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-19 18:08:43 +0200
committerGitHub <noreply@github.com>2025-05-19 18:08:43 +0200
commite95315d37ad8906fe2098a47dfb745e6d11f16ba (patch)
treed47b5af5c13d74aa20a1d5cdefe4f62bba72c44c
parent421230fce76c185ae2fc7d6282b64a73b0b9d781 (diff)
parent61059282eb9ea1f37804790b182e5821337924b4 (diff)
downloadrust-e95315d37ad8906fe2098a47dfb745e6d11f16ba.tar.gz
rust-e95315d37ad8906fe2098a47dfb745e6d11f16ba.zip
Rollup merge of #141253 - azhogin:azhogin/async-drop-feature-inconsistency-warning, r=oli-obk
Warning added when dependency crate has async drop types, and the feature is disabled

In continue of https://github.com/rust-lang/rust/pull/141031.

When dependency crate has non-empty `adt_async_destructor` table in metadata, and `async_drop` feature is disabled for local crate, warning will be emitted.

Test `dependency-dropped` has two revisions - with and without feature enabled. With feature enabled, async drop for dropee is executed ("Async drop" printed). Without the feature enabled, sync drop is executed ("Sync drop" printed) and warning is emitted.

Warning example:
```
warning: found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
  --> $DIR/dependency-dropped.rs:7:1
   |
LL | #![cfg_attr(with_feature, feature(async_drop))]
   | ^
   |
   = help: if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
```
-rw-r--r--compiler/rustc_interface/src/passes.rs1
-rw-r--r--compiler/rustc_metadata/messages.ftl4
-rw-r--r--compiler/rustc_metadata/src/creader.rs21
-rw-r--r--compiler/rustc_metadata/src/errors.rs10
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs4
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.rs5
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.with_feature.run.stdout (renamed from tests/ui/async-await/async-drop/dependency-dropped.run.stdout)0
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout1
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr10
9 files changed, 55 insertions, 1 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index e28639576f0..8f6c5b47ee2 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -282,6 +282,7 @@ fn configure_and_expand(
     resolver.resolve_crate(&krate);
 
     CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate);
+    CStore::from_tcx(tcx).report_incompatible_async_drop_feature(tcx, &krate);
     krate
 }
 
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index d997ba198ac..cac8f34b0fa 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -1,6 +1,10 @@
 metadata_as_needed_compatibility =
     linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
 
+metadata_async_drop_types_in_dependency =
+    found async drop types in dependecy `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
+    .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
+
 metadata_bad_panic_strategy =
     the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 07fb2de8a3e..c7e9a2936f5 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -473,6 +473,27 @@ impl CStore {
         }
     }
 
+    // Report about async drop types in dependency if async drop feature is disabled
+    pub fn report_incompatible_async_drop_feature(&self, tcx: TyCtxt<'_>, krate: &Crate) {
+        if tcx.features().async_drop() {
+            return;
+        }
+        for (_cnum, data) in self.iter_crate_data() {
+            if data.is_proc_macro_crate() {
+                continue;
+            }
+            if data.has_async_drops() {
+                let extern_crate = data.name();
+                let local_crate = tcx.crate_name(LOCAL_CRATE);
+                tcx.dcx().emit_warn(errors::AsyncDropTypesInDependency {
+                    span: krate.spans.inner_span.shrink_to_lo(),
+                    extern_crate,
+                    local_crate,
+                });
+            }
+        }
+    }
+
     pub fn new(metadata_loader: Box<MetadataLoaderDyn>) -> CStore {
         CStore {
             metadata_loader,
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index c45daeda85d..16f59793e63 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -811,3 +811,13 @@ pub struct UnknownTargetModifierUnsafeAllowed {
     pub span: Span,
     pub flag_name: String,
 }
+
+#[derive(Diagnostic)]
+#[diag(metadata_async_drop_types_in_dependency)]
+#[help]
+pub struct AsyncDropTypesInDependency {
+    #[primary_span]
+    pub span: Span,
+    pub extern_crate: Symbol,
+    pub local_crate: Symbol,
+}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index bd813cadedc..2e4352ca532 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1984,6 +1984,10 @@ impl CrateMetadata {
         self.root.header.hash
     }
 
+    pub(crate) fn has_async_drops(&self) -> bool {
+        self.root.tables.adt_async_destructor.len > 0
+    }
+
     fn num_def_ids(&self) -> usize {
         self.root.tables.def_keys.size()
     }
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.rs b/tests/ui/async-await/async-drop/dependency-dropped.rs
index f763bb32b17..c8670be4e8b 100644
--- a/tests/ui/async-await/async-drop/dependency-dropped.rs
+++ b/tests/ui/async-await/async-drop/dependency-dropped.rs
@@ -1,9 +1,12 @@
 //@ run-pass
 //@ check-run-results
+//@ revisions: with_feature without_feature
 //@ aux-build:async-drop-dep.rs
 //@ edition:2021
 
-#![feature(async_drop)]
+#![cfg_attr(with_feature, feature(async_drop))]
+//[without_feature]~^ WARN found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
+
 #![allow(incomplete_features)]
 
 extern crate async_drop_dep;
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.run.stdout b/tests/ui/async-await/async-drop/dependency-dropped.with_feature.run.stdout
index 7aaf70c12d6..7aaf70c12d6 100644
--- a/tests/ui/async-await/async-drop/dependency-dropped.run.stdout
+++ b/tests/ui/async-await/async-drop/dependency-dropped.with_feature.run.stdout
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout
new file mode 100644
index 00000000000..80eeeefc222
--- /dev/null
+++ b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout
@@ -0,0 +1 @@
+Sync drop
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr
new file mode 100644
index 00000000000..56e49568e10
--- /dev/null
+++ b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr
@@ -0,0 +1,10 @@
+warning: found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
+  --> $DIR/dependency-dropped.rs:7:1
+   |
+LL | #![cfg_attr(with_feature, feature(async_drop))]
+   | ^
+   |
+   = help: if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
+
+warning: 1 warning emitted
+