Rollup merge of #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 #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 #129811
This commit is contained in:
commit
7b7f2f7f74
@ -1,6 +1,7 @@
|
|||||||
//! Validates the MIR to ensure that invariants are upheld.
|
//! Validates the MIR to ensure that invariants are upheld.
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
use rustc_hir as hir;
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
@ -714,7 +715,17 @@ fn visit_projection_elem(
|
|||||||
// since we may be in the process of computing this MIR in the
|
// since we may be in the process of computing this MIR in the
|
||||||
// first place.
|
// first place.
|
||||||
let layout = if def_id == self.caller_body.source.def_id() {
|
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()
|
self.caller_body.coroutine_layout_raw()
|
||||||
} else {
|
} else {
|
||||||
self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty())
|
self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty())
|
||||||
|
@ -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() {}
|
Loading…
Reference in New Issue
Block a user