Skip to content

Commit

Permalink
Unrolled build for rust-lang#129847
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#129847 - compiler-errors:async-cycle, r=davidtwco

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
rust-timer committed Sep 8, 2024
2 parents 12b26c1 + 384aed8 commit 9df04fd
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 9df04fd

Please sign in to comment.