|
17 | 17 | //! [`SpanMarker`]: rustc_middle::mir::coverage::CoverageKind::SpanMarker |
18 | 18 |
|
19 | 19 | use rustc_middle::mir::coverage::CoverageKind; |
20 | | -use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, TerminatorKind}; |
| 20 | +use rustc_middle::mir::*; |
21 | 21 | use rustc_middle::ty::TyCtxt; |
22 | 22 | use rustc_middle::ty::adjustment::PointerCoercion; |
23 | 23 |
|
24 | 24 | pub(super) struct CleanupPostBorrowck; |
25 | 25 |
|
26 | 26 | impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { |
27 | 27 | fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { |
28 | | - for basic_block in body.basic_blocks.as_mut() { |
| 28 | + // Manually invalidate CFG caches if we actually change a terminator's edges. |
| 29 | + let mut invalidate_cfg = false; |
| 30 | + for basic_block in body.basic_blocks.as_mut_preserves_cfg().iter_mut() { |
29 | 31 | for statement in basic_block.statements.iter_mut() { |
30 | 32 | match statement.kind { |
31 | 33 | StatementKind::AscribeUserType(..) |
@@ -59,16 +61,23 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { |
59 | 61 | _ => (), |
60 | 62 | } |
61 | 63 | } |
| 64 | + |
| 65 | + // If we change any terminator, we need to ensure that we invalidated the CFG cache. |
62 | 66 | let terminator = basic_block.terminator_mut(); |
63 | 67 | match terminator.kind { |
64 | 68 | TerminatorKind::FalseEdge { real_target, .. } |
65 | 69 | | TerminatorKind::FalseUnwind { real_target, .. } => { |
| 70 | + invalidate_cfg = true; |
66 | 71 | terminator.kind = TerminatorKind::Goto { target: real_target }; |
67 | 72 | } |
68 | 73 | _ => {} |
69 | 74 | } |
70 | 75 | } |
71 | 76 |
|
| 77 | + if invalidate_cfg { |
| 78 | + body.basic_blocks.invalidate_cfg_cache(); |
| 79 | + } |
| 80 | + |
72 | 81 | body.user_type_annotations.raw.clear(); |
73 | 82 |
|
74 | 83 | for decl in &mut body.local_decls { |
|
0 commit comments