@@ -1055,11 +1055,37 @@ fn create_generator_resume_function<'tcx>(
10551055 body : & mut BodyAndCache < ' tcx > ,
10561056 can_return : bool ,
10571057) {
1058+ let can_unwind = can_unwind ( tcx, body) ;
1059+
10581060 // Poison the generator when it unwinds
1059- for block in body. basic_blocks_mut ( ) {
1060- let source_info = block. terminator ( ) . source_info ;
1061- if let & TerminatorKind :: Resume = & block. terminator ( ) . kind {
1062- block. statements . push ( transform. set_discr ( VariantIdx :: new ( POISONED ) , source_info) ) ;
1061+ if can_unwind {
1062+ let poison_block = BasicBlock :: new ( body. basic_blocks ( ) . len ( ) ) ;
1063+ let source_info = source_info ( body) ;
1064+ body. basic_blocks_mut ( ) . push ( BasicBlockData {
1065+ statements : vec ! [ transform. set_discr( VariantIdx :: new( POISONED ) , source_info) ] ,
1066+ terminator : Some ( Terminator { source_info, kind : TerminatorKind :: Resume } ) ,
1067+ is_cleanup : true ,
1068+ } ) ;
1069+
1070+ for ( idx, block) in body. basic_blocks_mut ( ) . iter_enumerated_mut ( ) {
1071+ let source_info = block. terminator ( ) . source_info ;
1072+
1073+ if let TerminatorKind :: Resume = block. terminator ( ) . kind {
1074+ // An existing `Resume` terminator is redirected to jump to our dedicated
1075+ // "poisoning block" above.
1076+ if idx != poison_block {
1077+ * block. terminator_mut ( ) = Terminator {
1078+ source_info,
1079+ kind : TerminatorKind :: Goto { target : poison_block } ,
1080+ } ;
1081+ }
1082+ } else if !block. is_cleanup {
1083+ // Any terminators that *can* unwind but don't have an unwind target set are also
1084+ // pointed at our poisoning block (unless they're part of the cleanup path).
1085+ if let Some ( unwind @ None ) = block. terminator_mut ( ) . unwind_mut ( ) {
1086+ * unwind = Some ( poison_block) ;
1087+ }
1088+ }
10631089 }
10641090 }
10651091
@@ -1080,7 +1106,7 @@ fn create_generator_resume_function<'tcx>(
10801106 ) ;
10811107 }
10821108
1083- if can_unwind ( tcx , body ) {
1109+ if can_unwind {
10841110 cases. insert (
10851111 2 ,
10861112 ( POISONED , insert_panic_block ( tcx, body, ResumedAfterPanic ( generator_kind) ) ) ,
0 commit comments