|
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)structCleanupPostBorrowck; |
25 | 25 |
|
26 | 26 | impl<'tcx>crate::MirPass<'tcx>forCleanupPostBorrowck{ |
27 | 27 | fnrun_pass(&self,_tcx:TyCtxt<'tcx>,body:&mutBody<'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 | +letmut 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