about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-10 10:54:59 -0400
committerMichael Goulet <michael@errs.io>2024-09-10 10:55:05 -0400
commit5cf117ed0514af068a6e0e42f732dd93ff5e90dc (patch)
treec04b6f61d48d7417d294fb67099d0e845273ad8f
parentf827364a95b93ab70afd0383fcf3caa9da40e1fb (diff)
downloadrust-5cf117ed0514af068a6e0e42f732dd93ff5e90dc.tar.gz
rust-5cf117ed0514af068a6e0e42f732dd93ff5e90dc.zip
Don't call closure_by_move_body_def_id on FnOnce async closures in MIR validation
-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 56fcfe8e798..fe162fe8303 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3173,7 +3173,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 0bbbf047f63..c83b9139801 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -326,7 +326,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 18865c73f75..da36ddd1e9b 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;
@@ -716,10 +715,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));
+}