diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index b0bf7f484bedf..e6f56b509af63 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -17,7 +17,7 @@ //! [`SpanMarker`]: rustc_middle::mir::coverage::CoverageKind::SpanMarker use rustc_middle::mir::coverage::CoverageKind; -use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, TerminatorKind}; +use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use rustc_middle::ty::adjustment::PointerCoercion; @@ -25,7 +25,9 @@ pub(super) struct CleanupPostBorrowck; impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - for basic_block in body.basic_blocks.as_mut() { + // Manually invalidate CFG caches if we actually change a terminator's edges. + let mut invalidate_cfg = false; + for basic_block in body.basic_blocks.as_mut_preserves_cfg().iter_mut() { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) @@ -59,16 +61,23 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { _ => (), } } + + // If we change any terminator, we need to ensure that we invalidated the CFG cache. let terminator = basic_block.terminator_mut(); match terminator.kind { TerminatorKind::FalseEdge { real_target, .. } | TerminatorKind::FalseUnwind { real_target, .. } => { + invalidate_cfg = true; terminator.kind = TerminatorKind::Goto { target: real_target }; } _ => {} } } + if invalidate_cfg { + body.basic_blocks.invalidate_cfg_cache(); + } + body.user_type_annotations.raw.clear(); for decl in &mut body.local_decls {