Rollup merge of #130201 - compiler-errors:foreign-synthetic-body, r=lcnr
Encode `coroutine_by_move_body_def_id` in crate metadata We synthesize the MIR for a by-move body for the `FnOnce` implementation of async closures. It can be accessed with the `coroutine_by_move_body_def_id` query. We weren't encoding this query in the metadata though, nor were we properly recording that synthetic MIR in `mir_keys`, so the `optimized_mir` wasn't getting encoded either! Stacked on top is a fix to consider `DefKind::SyntheticCoroutineBody` to return true in several places I missed. Specifically, we should consider the def-kind in `fn DefKind::is_fn_like()`, since that's what we were using to make sure we ensure `query mir_inliner_callees` before the MIR gets stolen for the body. This led to some CI failures that were caught by miri but which I added a test for.
This commit is contained in:
commit
ddcb9c132a
9 changed files with 82 additions and 21 deletions
|
@ -24,7 +24,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
|||
|
||||
// This just reproduces the logic from Instance::requires_inline.
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Ctor(..) | DefKind::Closure => return true,
|
||||
DefKind::Ctor(..) | DefKind::Closure | DefKind::SyntheticCoroutineBody => return true,
|
||||
DefKind::Fn | DefKind::AssocFn => {}
|
||||
_ => return false,
|
||||
}
|
||||
|
|
|
@ -21,9 +21,8 @@ use rustc_const_eval::util;
|
|||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::{
|
||||
AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
|
||||
|
@ -224,26 +223,31 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
|||
/// MIR associated with them.
|
||||
fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
|
||||
// All body-owners have MIR associated with them.
|
||||
let set: FxIndexSet<_> = tcx.hir().body_owners().collect();
|
||||
let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
|
||||
|
||||
// Additionally, tuple struct/variant constructors have MIR, but
|
||||
// they don't have a BodyId, so we need to build them separately.
|
||||
struct GatherCtors {
|
||||
set: FxIndexSet<LocalDefId>,
|
||||
}
|
||||
impl<'tcx> Visitor<'tcx> for GatherCtors {
|
||||
fn visit_variant_data(&mut self, v: &'tcx hir::VariantData<'tcx>) {
|
||||
if let hir::VariantData::Tuple(_, _, def_id) = *v {
|
||||
self.set.insert(def_id);
|
||||
}
|
||||
intravisit::walk_struct_def(self, v)
|
||||
// Coroutine-closures (e.g. async closures) have an additional by-move MIR
|
||||
// body that isn't in the HIR.
|
||||
for body_owner in tcx.hir().body_owners() {
|
||||
if let DefKind::Closure = tcx.def_kind(body_owner)
|
||||
&& tcx.needs_coroutine_by_move_body_def_id(body_owner.to_def_id())
|
||||
{
|
||||
set.insert(tcx.coroutine_by_move_body_def_id(body_owner).expect_local());
|
||||
}
|
||||
}
|
||||
|
||||
let mut gather_ctors = GatherCtors { set };
|
||||
tcx.hir().visit_all_item_likes_in_crate(&mut gather_ctors);
|
||||
// tuple struct/variant constructors have MIR, but they don't have a BodyId,
|
||||
// so we need to build them separately.
|
||||
for item in tcx.hir_crate_items(()).free_items() {
|
||||
if let DefKind::Struct | DefKind::Enum = tcx.def_kind(item.owner_id) {
|
||||
for variant in tcx.adt_def(item.owner_id).variants() {
|
||||
if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
|
||||
set.insert(ctor_def_id.expect_local());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gather_ctors.set
|
||||
set
|
||||
}
|
||||
|
||||
fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue