Do not call query to compute coroutine layout for synthetic body of a… · rust-lang/rust@384aed8 (original) (raw)

File tree

2 files changed

lines changed

2 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
1 1 //! Validates the MIR to ensure that invariants are upheld.
2 2
3 3 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4 +use rustc_hir as hir;
4 5 use rustc_hir::LangItem;
5 6 use rustc_index::bit_set::BitSet;
6 7 use rustc_index::IndexVec;
@@ -714,7 +715,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
714 715 // since we may be in the process of computing this MIR in the
715 716 // first place.
716 717 let layout = if def_id == self.caller_body.source.def_id() {
717 -// FIXME: This is not right for async closures.
718 +self.caller_body.coroutine_layout_raw()
719 +} else if let Some(hir::CoroutineKind::Desugared(
720 + _,
721 + hir::CoroutineSource::Closure,
722 +)) = self.tcx.coroutine_kind(def_id)
723 + && let ty::ClosureKind::FnOnce =
724 + args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap()
725 + && self.caller_body.source.def_id()
726 + == self.tcx.coroutine_by_move_body_def_id(def_id)
727 +{
728 +// Same if this is the by-move body of a coroutine-closure.
718 729 self.caller_body.coroutine_layout_raw()
719 730 } else {
720 731 self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty())
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
1 +//@ check-pass
2 +//@ edition: 2021
3 +
4 +#![feature(async_closure)]
5 +
6 +// Make sure that we don't hit a query cycle when validating
7 +// the by-move coroutine body for an async closure.
8 +
9 +use std::future::Future;
10 +
11 +async fn test<Fut: Future>(operation: impl Fn() -> Fut) {
12 +operation().await;
13 +}
14 +
15 +pub async fn orchestrate_simple_crud() {
16 +test(async |
17 +}
18 +
19 +fn main() {}