@@ -1008,6 +1008,45 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
1008
1008
false
1009
1009
}
1010
1010
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
+
1011
1050
fn create_generator_resume_function < ' tcx > (
1012
1051
tcx : TyCtxt < ' tcx > ,
1013
1052
transform : TransformVisitor < ' tcx > ,
@@ -1041,7 +1080,12 @@ fn create_generator_resume_function<'tcx>(
1041
1080
) ;
1042
1081
}
1043
1082
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
+ }
1045
1089
1046
1090
insert_switch ( body, cases, & transform, TerminatorKind :: Unreachable ) ;
1047
1091
0 commit comments