about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2024-09-14 11:53:12 +1000
committerGitHub <noreply@github.com>2024-09-14 11:53:12 +1000
commit04e744e77d1389a366aa4c9477abf026eb360411 (patch)
tree251e695e2b7dfc2a8dd415d1c10478f6581cd484
parent2bf0dd2735d0165a95036594f5f900a12217f6a0 (diff)
parent5cf117ed0514af068a6e0e42f732dd93ff5e90dc (diff)
downloadrust-04e744e77d1389a366aa4c9477abf026eb360411.tar.gz
rust-04e744e77d1389a366aa4c9477abf026eb360411.zip
Rollup merge of #130199 - compiler-errors:by-move, r=cjgillot
Don't call closure_by_move_body_def_id on FnOnce async closures in MIR validation

Refactors the check in #129847 to not unncessarily call the `closure_by_move_body_def_id` query for async closures that don't *need* a by-move body.

Fixes #130167
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs6
-rw-r--r--tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs20
5 files changed, 24 insertions, 8 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index c4a38047b5e..b93bc3ed84f 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -788,7 +788,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
     rustc_hir_analysis::check_crate(tcx);
     sess.time("MIR_coroutine_by_move_body", || {
         tcx.hir().par_body_owners(|def_id| {
-            if tcx.needs_coroutine_by_move_body_def_id(def_id) {
+            if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) {
                 tcx.ensure_with_value().coroutine_by_move_body_def_id(def_id);
             }
         });
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 5ec7e80ee45..cd06d7b8e53 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3171,7 +3171,7 @@ impl<'tcx> TyCtxt<'tcx> {
         self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
     }
 
-    pub fn needs_coroutine_by_move_body_def_id(self, def_id: LocalDefId) -> bool {
+    pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
         if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
             self.coroutine_kind(def_id)
             && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind()
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 84d07d38330..424e7008326 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -330,7 +330,7 @@ fn mir_promoted(
     tcx.ensure_with_value().has_ffi_unwind_calls(def);
 
     // the `by_move_body` query uses the raw mir, so make sure it is run.
-    if tcx.needs_coroutine_by_move_body_def_id(def) {
+    if tcx.needs_coroutine_by_move_body_def_id(def.to_def_id()) {
         tcx.ensure_with_value().coroutine_by_move_body_def_id(def);
     }
 
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 3b84755dded..e5837b1b475 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1,7 +1,6 @@
 //! Validates the MIR to ensure that invariants are upheld.
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir as hir;
 use rustc_hir::LangItem;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
@@ -717,10 +716,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             // first place.
                             let layout = if def_id == self.caller_body.source.def_id() {
                                 self.caller_body.coroutine_layout_raw()
-                            } else if let Some(hir::CoroutineKind::Desugared(
-                                _,
-                                hir::CoroutineSource::Closure,
-                            )) = self.tcx.coroutine_kind(def_id)
+                            } else if self.tcx.needs_coroutine_by_move_body_def_id(def_id)
                                 && let ty::ClosureKind::FnOnce =
                                     args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap()
                                 && self.caller_body.source.def_id()
diff --git a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs
new file mode 100644
index 00000000000..4382a689e75
--- /dev/null
+++ b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs
@@ -0,0 +1,20 @@
+//@ aux-build:block-on.rs
+//@ edition:2021
+//@ build-pass
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+// Make sure that we don't call `coroutine_by_move_body_def_id` query
+// on async closures that are `FnOnce`. See issue: #130167.
+
+async fn empty() {}
+
+pub async fn call_once<F: async FnOnce()>(f: F) {
+    f().await;
+}
+
+fn main() {
+    block_on::block_on(call_once(async || empty().await));
+}