@@ -33,6 +33,7 @@ enum CallType {
3333 Keyword { nargs : u32 } ,
3434 Ex { has_kwargs : bool } ,
3535}
36+
3637impl CallType {
3738 fn normal_call ( self ) -> Instruction {
3839 match self {
@@ -69,6 +70,7 @@ pub struct CompileOpts {
6970 /// not emit assert statements
7071 pub optimize : u8 ,
7172}
73+
7274impl Default for CompileOpts {
7375 fn default ( ) -> Self {
7476 CompileOpts { optimize : 0 }
@@ -1608,7 +1610,7 @@ impl Compiler {
16081610 "starred assignment target must be in a list or tuple" . to_owned ( ) ,
16091611 ) ,
16101612 _ => CompileErrorType :: Assign ( target. node . name ( ) ) ,
1611- } ) )
1613+ } ) ) ;
16121614 }
16131615 }
16141616
@@ -1907,10 +1909,10 @@ impl Compiler {
19071909 YieldFrom { value } => {
19081910 match self . ctx . func {
19091911 FunctionContext :: NoFunction => {
1910- return Err ( self . error ( CompileErrorType :: InvalidYieldFrom ) )
1912+ return Err ( self . error ( CompileErrorType :: InvalidYieldFrom ) ) ;
19111913 }
19121914 FunctionContext :: AsyncFunction => {
1913- return Err ( self . error ( CompileErrorType :: AsyncYieldFrom ) )
1915+ return Err ( self . error ( CompileErrorType :: AsyncYieldFrom ) ) ;
19141916 }
19151917 FunctionContext :: Function => { }
19161918 }
@@ -2295,37 +2297,48 @@ impl Compiler {
22952297 }
22962298
22972299 let mut loop_labels = vec ! [ ] ;
2300+ let mut is_async = false ;
22982301 for generator in generators {
2299- if generator. is_async {
2300- unimplemented ! ( "async for comprehensions" ) ;
2301- }
2302-
23032302 let loop_block = self . new_block ( ) ;
23042303 let after_block = self . new_block ( ) ;
23052304
23062305 // Setup for loop:
2307- self . emit ( Instruction :: SetupLoop {
2308- break_target : after_block,
2309- } ) ;
2306+ if !generator. is_async {
2307+ self . emit ( Instruction :: SetupLoop {
2308+ break_target : after_block,
2309+ } ) ;
2310+ }
23102311
23112312 if loop_labels. is_empty ( ) {
23122313 // Load iterator onto stack (passed as first argument):
23132314 self . emit ( Instruction :: LoadFast ( arg0) ) ;
23142315 } else {
23152316 // Evaluate iterated item:
23162317 self . compile_expression ( & generator. iter ) ?;
2317-
2318- // Get iterator / turn item into an iterator
2319- self . emit ( Instruction :: GetIter ) ;
2318+ if generator. is_async {
2319+ self . emit ( Instruction :: GetAIter ) ;
2320+ } else {
2321+ // Get iterator / turn item into an iterator
2322+ self . emit ( Instruction :: GetIter ) ;
2323+ }
23202324 }
23212325
23222326 loop_labels. push ( ( loop_block, after_block) ) ;
2323-
23242327 self . switch_to_block ( loop_block) ;
2325- self . emit ( Instruction :: ForIter {
2326- target : after_block,
2327- } ) ;
2328-
2328+ if generator. is_async {
2329+ is_async = true ;
2330+ self . emit ( Instruction :: SetupFinally {
2331+ handler : after_block,
2332+ } ) ;
2333+ self . emit ( Instruction :: GetANext ) ;
2334+ self . emit_constant ( ConstantData :: None ) ;
2335+ self . emit ( Instruction :: YieldFrom ) ;
2336+ self . emit ( Instruction :: PopBlock ) ;
2337+ } else {
2338+ self . emit ( Instruction :: ForIter {
2339+ target : after_block,
2340+ } ) ;
2341+ }
23292342 self . compile_store ( & generator. target ) ?;
23302343
23312344 // Now evaluate the ifs:
@@ -2379,10 +2392,19 @@ impl Compiler {
23792392 self . compile_expression ( & generators[ 0 ] . iter ) ?;
23802393
23812394 // Get iterator / turn item into an iterator
2382- self . emit ( Instruction :: GetIter ) ;
2395+ if is_async {
2396+ self . emit ( Instruction :: GetAIter ) ;
2397+ } else {
2398+ self . emit ( Instruction :: GetIter ) ;
2399+ }
23832400
23842401 // Call just created <listcomp> function:
23852402 self . emit ( Instruction :: CallFunctionPositional { nargs : 1 } ) ;
2403+ if is_async {
2404+ self . emit ( Instruction :: GetAwaitable ) ;
2405+ self . emit_constant ( ConstantData :: None ) ;
2406+ self . emit ( Instruction :: YieldFrom ) ;
2407+ }
23862408 Ok ( ( ) )
23872409 }
23882410
@@ -2398,7 +2420,9 @@ impl Compiler {
23982420 // "generator_stop" => {}
23992421 // "annotations" => {}
24002422 other => {
2401- return Err ( self . error ( CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) ) )
2423+ return Err (
2424+ self . error ( CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) )
2425+ ) ;
24022426 }
24032427 }
24042428 }
0 commit comments