@@ -11,6 +11,8 @@ use tracing::debug;
1111/// once with `apply`. This is useful for MIR transformation passes.
1212pub ( crate ) struct MirPatch < ' tcx > {
1313 term_patch_map : FxHashMap < BasicBlock , TerminatorKind < ' tcx > > ,
14+ /// Set of statements that should be replaced by `Nop`.
15+ nop_statements : Vec < Location > ,
1416 new_blocks : Vec < BasicBlockData < ' tcx > > ,
1517 new_statements : Vec < ( Location , StatementKind < ' tcx > ) > ,
1618 new_locals : Vec < LocalDecl < ' tcx > > ,
@@ -33,6 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
3335 pub ( crate ) fn new ( body : & Body < ' tcx > ) -> Self {
3436 let mut result = MirPatch {
3537 term_patch_map : Default :: default ( ) ,
38+ nop_statements : vec ! [ ] ,
3639 new_blocks : vec ! [ ] ,
3740 new_statements : vec ! [ ] ,
3841 new_locals : vec ! [ ] ,
@@ -212,6 +215,15 @@ impl<'tcx> MirPatch<'tcx> {
212215 self . term_patch_map . insert ( block, new) ;
213216 }
214217
218+ /// Mark given statement to be replaced by a `Nop`.
219+ ///
220+ /// This method only works on statements from the initial body, and cannot be used to remove
221+ /// statements from `add_statement` or `add_assign`.
222+ #[ tracing:: instrument( level = "debug" , skip( self ) ) ]
223+ pub ( crate ) fn nop_statement ( & mut self , loc : Location ) {
224+ self . nop_statements . push ( loc) ;
225+ }
226+
215227 /// Queues the insertion of a statement at a given location. The statement
216228 /// currently at that location, and all statements that follow, are shifted
217229 /// down. If multiple statements are queued for addition at the same
@@ -257,11 +269,8 @@ impl<'tcx> MirPatch<'tcx> {
257269 bbs. extend ( self . new_blocks ) ;
258270 body. local_decls . extend ( self . new_locals ) ;
259271
260- // The order in which we patch terminators does not change the result.
261- #[ allow( rustc:: potential_query_instability) ]
262- for ( src, patch) in self . term_patch_map {
263- debug ! ( "MirPatch: patching block {:?}" , src) ;
264- bbs[ src] . terminator_mut ( ) . kind = patch;
272+ for loc in self . nop_statements {
273+ bbs[ loc. block ] . statements [ loc. statement_index ] . make_nop ( ) ;
265274 }
266275
267276 let mut new_statements = self . new_statements ;
@@ -285,6 +294,17 @@ impl<'tcx> MirPatch<'tcx> {
285294 . insert ( loc. statement_index , Statement :: new ( source_info, stmt) ) ;
286295 delta += 1 ;
287296 }
297+
298+ // The order in which we patch terminators does not change the result.
299+ #[ allow( rustc:: potential_query_instability) ]
300+ for ( src, patch) in self . term_patch_map {
301+ debug ! ( "MirPatch: patching block {:?}" , src) ;
302+ let bb = & mut bbs[ src] ;
303+ if let TerminatorKind :: Unreachable = patch {
304+ bb. statements . clear ( ) ;
305+ }
306+ bb. terminator_mut ( ) . kind = patch;
307+ }
288308 }
289309
290310 fn source_info_for_index ( data : & BasicBlockData < ' _ > , loc : Location ) -> SourceInfo {
0 commit comments