Change:
<!-- [31mICE[0m: Rustc '-Zvalidate-mir -ooutputfile -Zdump-mir-dir=dir' 'error: internal compiler error: unexpected body ty: {type error} phase Runtime(PostCleanup)', 'error: internal compiler error: unexpected body ty: {type error} phase Runtime(PostCleanup)' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [mirdropselaboratedandconstchecked] elaborating drops for [analysis] running analysis passes on this crate --
cc :D (note you'll need which was merged 10 minutes ago ^^ )

Discussion:
ty::Closure(..) => Abi::RustCall, ty::CoroutineClosure(..) => Abi::RustCall, ty::Coroutine(..) => Abi::Rust, <ins> // No need to do MIR validation on error bodies ty::Error(_) => return, </ins> _ => { span_bug!(body.span, "unexpected body ty: {:?} phase {:?}", body_ty, mir_phase) }

))), ) } <del> ty::CoroutineClosure(did, _args) => { // FIXME(async_closures): Recover the proper error signature let inputs = tcx .closure_user_provided_sig(did.expect_local()) .value .skip_binder() .inputs(); let err = Ty::new_error(tcx, guar); (inputs.iter().map(|_| err).collect(), err, None) </del> <ins> ty::CoroutineClosure(did, args) => { let args = args.as_coroutine_closure(); let sig = tcx.liberate_late_bound_regions( def_id.to_def_id(), args.coroutine_closure_sig(), ); let self_ty = match args.kind() { ty::ClosureKind::Fn => { Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, closure_ty) } ty::ClosureKind::FnMut => { Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, closure_ty) } ty::ClosureKind::FnOnce => closure_ty, }; ( [self_ty].into_iter().chain(sig.tupled_inputs_ty.tuple_fields()).collect(), sig.to_coroutine( tcx, args.parent_args(), args.kind_ty(), tcx.coroutine_for_closure(*did), Ty::new_error(tcx, guar), ), None, ) </ins> } ty::Error(_) => (vec![closure_ty, closure_ty], closure_ty, None), kind => {

use rustc_hir as hir; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::{self, dump_mir, MirPass}; <del> use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt}; </del> <ins> use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, TypeVisitableExt}; </ins> use rustc_target::abi::FieldIdx; pub struct ByMoveBody;

return; }; let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty; <del> let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!() }; </del> <ins> if coroutine_ty.references_error() { return; } let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") }; </ins> let coroutine_kind = args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(); if coroutine_kind == ty::ClosureKind::FnOnce {

<ins> // edition:2021 #![feature(async_closure)] // Don't ICE in ByMove shim builder when MIR body is tainted by writeback errors fn main() { let _ = async || { used_fn(); //~^ ERROR cannot find function `used_fn` in this scope 0 }; } </ins>

<ins> error[E0425]: cannot find function `used_fn` in this scope --> $DIR/tainted-body.rs:9:9 | LL |         used_fn(); |         ^^^^^^^ not found in this scope error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. </ins>

<ins> // compile-flags: -Zvalidate-mir fn _test() { let x = || 45; missing(); //~^ ERROR cannot find function `missing` in this scope } fn main() {} </ins>

<ins> error[E0425]: cannot find function `missing` in this scope --> $DIR/error-body.rs:5:5 | LL |     missing(); |     ^^^^^^^ not found in this scope error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0425`. </ins>