@@ -124,6 +124,8 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
124
124
self . collapse_goto_chain ( successor, & mut changed) ;
125
125
}
126
126
127
+ changed |= self . simplify_unwind ( & mut terminator) ;
128
+
127
129
let mut new_stmts = vec ! [ ] ;
128
130
let mut inner_changed = true ;
129
131
while inner_changed {
@@ -238,6 +240,38 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
238
240
true
239
241
}
240
242
243
+ // turn an unwind branch to a resume block into a None
244
+ fn simplify_unwind ( & mut self , terminator : & mut Terminator < ' tcx > ) -> bool {
245
+ let unwind = match terminator. kind {
246
+ TerminatorKind :: Drop { ref mut unwind, .. } |
247
+ TerminatorKind :: DropAndReplace { ref mut unwind, .. } |
248
+ TerminatorKind :: Call { cleanup : ref mut unwind, .. } |
249
+ TerminatorKind :: Assert { cleanup : ref mut unwind, .. } =>
250
+ unwind,
251
+ _ => return false
252
+ } ;
253
+
254
+ if let & mut Some ( unwind_block) = unwind {
255
+ let is_resume_block = match self . basic_blocks [ unwind_block] {
256
+ BasicBlockData {
257
+ ref statements,
258
+ terminator : Some ( Terminator {
259
+ kind : TerminatorKind :: Resume , ..
260
+ } ) , ..
261
+ } if statements. is_empty ( ) => true ,
262
+ _ => false
263
+ } ;
264
+ if is_resume_block {
265
+ debug ! ( "simplifying unwind to {:?} from {:?}" ,
266
+ unwind_block, terminator. source_info) ;
267
+ * unwind = None ;
268
+ }
269
+ return is_resume_block;
270
+ }
271
+
272
+ false
273
+ }
274
+
241
275
fn strip_nops ( & mut self ) {
242
276
for blk in self . basic_blocks . iter_mut ( ) {
243
277
blk. statements . retain ( |stmt| if let StatementKind :: Nop = stmt. kind {
0 commit comments