@@ -11,6 +11,8 @@ use tracing::debug;
11
11
/// once with `apply`. This is useful for MIR transformation passes.
12
12
pub ( crate ) struct MirPatch < ' tcx > {
13
13
term_patch_map : FxHashMap < BasicBlock , TerminatorKind < ' tcx > > ,
14
+ /// Set of statements that should be replaced by `Nop`.
15
+ nop_statements : Vec < Location > ,
14
16
new_blocks : Vec < BasicBlockData < ' tcx > > ,
15
17
new_statements : Vec < ( Location , StatementKind < ' tcx > ) > ,
16
18
new_locals : Vec < LocalDecl < ' tcx > > ,
@@ -33,6 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
33
35
pub ( crate ) fn new ( body : & Body < ' tcx > ) -> Self {
34
36
let mut result = MirPatch {
35
37
term_patch_map : Default :: default ( ) ,
38
+ nop_statements : vec ! [ ] ,
36
39
new_blocks : vec ! [ ] ,
37
40
new_statements : vec ! [ ] ,
38
41
new_locals : vec ! [ ] ,
@@ -212,6 +215,15 @@ impl<'tcx> MirPatch<'tcx> {
212
215
self . term_patch_map . insert ( block, new) ;
213
216
}
214
217
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
+
215
227
/// Queues the insertion of a statement at a given location. The statement
216
228
/// currently at that location, and all statements that follow, are shifted
217
229
/// down. If multiple statements are queued for addition at the same
@@ -257,11 +269,8 @@ impl<'tcx> MirPatch<'tcx> {
257
269
bbs. extend ( self . new_blocks ) ;
258
270
body. local_decls . extend ( self . new_locals ) ;
259
271
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 ( ) ;
265
274
}
266
275
267
276
let mut new_statements = self . new_statements ;
@@ -285,6 +294,17 @@ impl<'tcx> MirPatch<'tcx> {
285
294
. insert ( loc. statement_index , Statement :: new ( source_info, stmt) ) ;
286
295
delta += 1 ;
287
296
}
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
+ }
288
308
}
289
309
290
310
fn source_info_for_index ( data : & BasicBlockData < ' _ > , loc : Location ) -> SourceInfo {
0 commit comments