@@ -891,7 +891,7 @@ fn create_generator_drop_shim<'tcx>(
891
891
892
892
let source_info = source_info ( & body) ;
893
893
894
- let mut cases = create_cases ( & mut body, transform, |point| point . drop ) ;
894
+ let mut cases = create_cases ( & mut body, transform, Operation :: Drop ) ;
895
895
896
896
cases. insert ( 0 , ( UNRESUMED , drop_clean) ) ;
897
897
@@ -1009,7 +1009,7 @@ fn create_generator_resume_function<'tcx>(
1009
1009
}
1010
1010
}
1011
1011
1012
- let mut cases = create_cases ( body, & transform, |point| Some ( point . resume ) ) ;
1012
+ let mut cases = create_cases ( body, & transform, Operation :: Resume ) ;
1013
1013
1014
1014
use rustc:: mir:: interpret:: PanicInfo :: { ResumedAfterPanic , ResumedAfterReturn } ;
1015
1015
@@ -1059,22 +1059,35 @@ fn insert_clean_drop(body: &mut BodyAndCache<'_>) -> BasicBlock {
1059
1059
drop_clean
1060
1060
}
1061
1061
1062
- fn create_cases < ' tcx , F > (
1062
+ /// An operation that can be performed on a generator.
1063
+ #[ derive( PartialEq , Copy , Clone ) ]
1064
+ enum Operation {
1065
+ Resume ,
1066
+ Drop ,
1067
+ }
1068
+
1069
+ impl Operation {
1070
+ fn target_block ( self , point : & SuspensionPoint < ' _ > ) -> Option < BasicBlock > {
1071
+ match self {
1072
+ Operation :: Resume => Some ( point. resume ) ,
1073
+ Operation :: Drop => point. drop ,
1074
+ }
1075
+ }
1076
+ }
1077
+
1078
+ fn create_cases < ' tcx > (
1063
1079
body : & mut BodyAndCache < ' tcx > ,
1064
1080
transform : & TransformVisitor < ' tcx > ,
1065
- target : F ,
1066
- ) -> Vec < ( usize , BasicBlock ) >
1067
- where
1068
- F : Fn ( & SuspensionPoint < ' tcx > ) -> Option < BasicBlock > ,
1069
- {
1081
+ operation : Operation ,
1082
+ ) -> Vec < ( usize , BasicBlock ) > {
1070
1083
let source_info = source_info ( body) ;
1071
1084
1072
1085
transform
1073
1086
. suspension_points
1074
1087
. iter ( )
1075
1088
. filter_map ( |point| {
1076
1089
// Find the target for this suspension point, if applicable
1077
- target ( point) . map ( |target| {
1090
+ operation . target_block ( point) . map ( |target| {
1078
1091
let block = BasicBlock :: new ( body. basic_blocks ( ) . len ( ) ) ;
1079
1092
let mut statements = Vec :: new ( ) ;
1080
1093
@@ -1087,15 +1100,17 @@ where
1087
1100
}
1088
1101
}
1089
1102
1090
- // Move the resume argument to the destination place of the `Yield` terminator
1091
- let resume_arg = Local :: new ( 2 ) ; // 0 = return, 1 = self
1092
- statements. push ( Statement {
1093
- source_info,
1094
- kind : StatementKind :: Assign ( box (
1095
- point. resume_arg ,
1096
- Rvalue :: Use ( Operand :: Move ( resume_arg. into ( ) ) ) ,
1097
- ) ) ,
1098
- } ) ;
1103
+ if operation == Operation :: Resume {
1104
+ // Move the resume argument to the destination place of the `Yield` terminator
1105
+ let resume_arg = Local :: new ( 2 ) ; // 0 = return, 1 = self
1106
+ statements. push ( Statement {
1107
+ source_info,
1108
+ kind : StatementKind :: Assign ( box (
1109
+ point. resume_arg ,
1110
+ Rvalue :: Use ( Operand :: Move ( resume_arg. into ( ) ) ) ,
1111
+ ) ) ,
1112
+ } ) ;
1113
+ }
1099
1114
1100
1115
// Then jump to the real target
1101
1116
body. basic_blocks_mut ( ) . push ( BasicBlockData {
0 commit comments