@@ -1008,6 +1008,45 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
10081008 false
10091009}
10101010
1011+ fn can_unwind < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > ) -> bool {
1012+ // Nothing can unwind when landing pads are off.
1013+ if tcx. sess . no_landing_pads ( ) {
1014+ return false ;
1015+ }
1016+
1017+ // Unwinds can only start at certain terminators.
1018+ for block in body. basic_blocks ( ) {
1019+ match block. terminator ( ) . kind {
1020+ // These never unwind.
1021+ TerminatorKind :: Goto { .. }
1022+ | TerminatorKind :: SwitchInt { .. }
1023+ | TerminatorKind :: Abort
1024+ | TerminatorKind :: Return
1025+ | TerminatorKind :: Unreachable
1026+ | TerminatorKind :: GeneratorDrop
1027+ | TerminatorKind :: FalseEdges { .. }
1028+ | TerminatorKind :: FalseUnwind { .. } => { }
1029+
1030+ // Resume will *continue* unwinding, but if there's no other unwinding terminator it
1031+ // will never be reached.
1032+ TerminatorKind :: Resume => { }
1033+
1034+ TerminatorKind :: Yield { .. } => {
1035+ unreachable ! ( "`can_unwind` called before generator transform" )
1036+ }
1037+
1038+ // These may unwind.
1039+ TerminatorKind :: Drop { .. }
1040+ | TerminatorKind :: DropAndReplace { .. }
1041+ | TerminatorKind :: Call { .. }
1042+ | TerminatorKind :: Assert { .. } => return true ,
1043+ }
1044+ }
1045+
1046+ // If we didn't find an unwinding terminator, the function cannot unwind.
1047+ false
1048+ }
1049+
10111050fn create_generator_resume_function < ' tcx > (
10121051 tcx : TyCtxt < ' tcx > ,
10131052 transform : TransformVisitor < ' tcx > ,
@@ -1041,7 +1080,12 @@ fn create_generator_resume_function<'tcx>(
10411080 ) ;
10421081 }
10431082
1044- cases. insert ( 2 , ( POISONED , insert_panic_block ( tcx, body, ResumedAfterPanic ( generator_kind) ) ) ) ;
1083+ if can_unwind ( tcx, body) {
1084+ cases. insert (
1085+ 2 ,
1086+ ( POISONED , insert_panic_block ( tcx, body, ResumedAfterPanic ( generator_kind) ) ) ,
1087+ ) ;
1088+ }
10451089
10461090 insert_switch ( body, cases, & transform, TerminatorKind :: Unreachable ) ;
10471091
0 commit comments