@@ -7656,15 +7656,15 @@ impl Compiler {
76567656 // We must have at least one generator:
76577657 assert ! ( !generators. is_empty( ) ) ;
76587658
7659- if is_inlined {
7659+ if is_inlined && !has_an_async_gen && !element_contains_await {
76607660 // PEP 709: Inlined comprehension - compile inline without new scope
7661+ // Async comprehensions are not inlined due to complex exception handling
76617662 let was_in_inlined_comp = self . current_code_info ( ) . in_inlined_comp ;
76627663 self . current_code_info ( ) . in_inlined_comp = true ;
76637664 let result = self . compile_inlined_comprehension (
76647665 init_collection,
76657666 generators,
76667667 compile_element,
7667- has_an_async_gen,
76687668 ) ;
76697669 self . current_code_info ( ) . in_inlined_comp = was_in_inlined_comp;
76707670 return result;
@@ -7854,7 +7854,6 @@ impl Compiler {
78547854 init_collection : Option < AnyInstruction > ,
78557855 generators : & [ ast:: Comprehension ] ,
78567856 compile_element : & dyn Fn ( & mut Self ) -> CompileResult < ( ) > ,
7857- _has_an_async_gen : bool ,
78587857 ) -> CompileResult < ( ) > {
78597858 // PEP 709: Consume the comprehension's sub_table (but we won't use it as a separate scope).
78607859 // The symbols are already merged into parent scope by analyze_symbol_table.
@@ -7882,13 +7881,9 @@ impl Compiler {
78827881 }
78837882
78847883 // Step 1: Compile the outermost iterator
7884+ // Async comprehensions are never inlined, so only sync iteration here
78857885 self . compile_expression ( & generators[ 0 ] . iter ) ?;
7886- // Use is_async from the first generator, not has_an_async_gen which covers ALL generators
7887- if generators[ 0 ] . is_async {
7888- emit ! ( self , Instruction :: GetAIter ) ;
7889- } else {
7890- emit ! ( self , Instruction :: GetIter ) ;
7891- }
7886+ emit ! ( self , Instruction :: GetIter ) ;
78927887
78937888 // Step 2: Save local variables that will be shadowed by the comprehension
78947889 for name in & pushed_locals {
@@ -7938,32 +7933,15 @@ impl Compiler {
79387933 if i > 0 {
79397934 // For nested loops, compile the iterator expression
79407935 self . compile_expression ( & generator. iter ) ?;
7941- if generator. is_async {
7942- emit ! ( self , Instruction :: GetAIter ) ;
7943- } else {
7944- emit ! ( self , Instruction :: GetIter ) ;
7945- }
7936+ emit ! ( self , Instruction :: GetIter ) ;
79467937 }
79477938
79487939 self . switch_to_block ( loop_block) ;
7949- let mut end_async_for_target = BlockIdx :: NULL ;
79507940
7951- if generator. is_async {
7952- emit ! ( self , Instruction :: GetANext ) ;
7953- self . emit_load_const ( ConstantData :: None ) ;
7954- end_async_for_target = self . compile_yield_from_sequence ( true ) ?;
7955- self . compile_store ( & generator. target ) ?;
7956- } else {
7957- emit ! ( self , Instruction :: ForIter { delta: after_block } ) ;
7958- self . compile_store ( & generator. target ) ?;
7959- }
7960- loop_labels. push ( (
7961- loop_block,
7962- if_cleanup_block,
7963- after_block,
7964- generator. is_async ,
7965- end_async_for_target,
7966- ) ) ;
7941+ emit ! ( self , Instruction :: ForIter { delta: after_block } ) ;
7942+ self . compile_store ( & generator. target ) ?;
7943+
7944+ loop_labels. push ( ( loop_block, if_cleanup_block, after_block) ) ;
79677945
79687946 // Evaluate the if conditions
79697947 for if_condition in & generator. ifs {
@@ -7974,8 +7952,8 @@ impl Compiler {
79747952 // Step 6: Compile the element expression and append to collection
79757953 compile_element ( self ) ?;
79767954
7977- // Step 7: Close all loops
7978- for ( loop_block, if_cleanup_block, after_block, is_async , end_async_for_target ) in
7955+ // Step 7: Close all loops (sync only - async comprehensions are never inlined)
7956+ for ( loop_block, if_cleanup_block, after_block) in
79797957 loop_labels. iter ( ) . rev ( ) . copied ( )
79807958 {
79817959 emit ! ( self , PseudoInstruction :: Jump { delta: loop_block } ) ;
@@ -7984,15 +7962,8 @@ impl Compiler {
79847962 emit ! ( self , PseudoInstruction :: Jump { delta: loop_block } ) ;
79857963
79867964 self . switch_to_block ( after_block) ;
7987- if is_async {
7988- self . emit_end_async_for ( end_async_for_target) ;
7989- // Pop the iterator
7990- emit ! ( self , Instruction :: PopTop ) ;
7991- } else {
7992- // END_FOR + POP_ITER pattern (CPython 3.14)
7993- emit ! ( self , Instruction :: EndFor ) ;
7994- emit ! ( self , Instruction :: PopIter ) ;
7995- }
7965+ emit ! ( self , Instruction :: EndFor ) ;
7966+ emit ! ( self , Instruction :: PopIter ) ;
79967967 }
79977968
79987969 // Step 8: Clean up - restore saved locals
0 commit comments