Skip to content

Commit

Permalink
Rollup merge of rust-lang#129847 - compiler-errors:async-cycle, r=dav…
Browse files Browse the repository at this point in the history
…idtwco

Do not call query to compute coroutine layout for synthetic body of async closure

There is code in the MIR validator that attempts to prevent query cycles when inlining a coroutine into itself, and will use the coroutine layout directly from the body when it detects that's the same coroutine as the one that's being validated. After rust-lang#128506, this logic didn't take into account the fact that the coroutine def id will differ if it's the "by-move body" of an async closure. This PR implements that.

Fixes rust-lang#129811
  • Loading branch information
matthiaskrgr authored Sep 7, 2024
2 parents 37523d2 + 384aed8 commit 7b7f2f7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
13 changes: 12 additions & 1 deletion compiler/rustc_mir_transform/src/validate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! 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;
Expand Down Expand Up @@ -714,7 +715,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// since we may be in the process of computing this MIR in the
// first place.
let layout = if def_id == self.caller_body.source.def_id() {
// FIXME: This is not right for async closures.
self.caller_body.coroutine_layout_raw()
} else if let Some(hir::CoroutineKind::Desugared(
_,
hir::CoroutineSource::Closure,
)) = self.tcx.coroutine_kind(def_id)
&& let ty::ClosureKind::FnOnce =
args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap()
&& self.caller_body.source.def_id()
== self.tcx.coroutine_by_move_body_def_id(def_id)
{
// Same if this is the by-move body of a coroutine-closure.
self.caller_body.coroutine_layout_raw()
} else {
self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty())
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/async-await/async-closures/validate-synthetic-body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ check-pass
//@ edition: 2021

#![feature(async_closure)]

// Make sure that we don't hit a query cycle when validating
// the by-move coroutine body for an async closure.

use std::future::Future;

async fn test<Fut: Future>(operation: impl Fn() -> Fut) {
operation().await;
}

pub async fn orchestrate_simple_crud() {
test(async || async {}.await).await;
}

fn main() {}

0 comments on commit 7b7f2f7

Please sign in to comment.