@@ -124,6 +124,8 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
124124 self . collapse_goto_chain ( successor, & mut changed) ;
125125 }
126126
127+ changed |= self . simplify_unwind ( & mut terminator) ;
128+
127129 let mut new_stmts = vec ! [ ] ;
128130 let mut inner_changed = true ;
129131 while inner_changed {
@@ -238,6 +240,38 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
238240 true
239241 }
240242
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+
241275 fn strip_nops ( & mut self ) {
242276 for blk in self . basic_blocks . iter_mut ( ) {
243277 blk. statements . retain ( |stmt| if let StatementKind :: Nop = stmt. kind {
0 commit comments