MCPcopy Index your code
hub / github.com/RustPython/RustPython / compile_for

Method compile_for

crates/codegen/src/compile.rs:5782–5885  ·  view source on GitHub ↗
(
        &mut self,
        target: &ast::Expr,
        iter: &ast::Expr,
        body: &[ast::Stmt],
        orelse: &[ast::Stmt],
        is_async: bool,
    )

Source from the content-addressed store, hash-verified

5780 }
5781
5782 fn compile_for(
5783 &mut self,
5784 target: &ast::Expr,
5785 iter: &ast::Expr,
5786 body: &[ast::Stmt],
5787 orelse: &[ast::Stmt],
5788 is_async: bool,
5789 ) -> CompileResult<()> {
5790 self.enter_conditional_block();
5791
5792 // Start loop
5793 let for_block = self.new_block();
5794 let else_block = self.new_block();
5795 let after_block = self.new_block();
5796 let mut end_async_for_target = BlockIdx::NULL;
5797
5798 // The thing iterated:
5799 // Optimize: `for x in [a, b, c]` → use tuple instead of list
5800 // Skip for async-for (GET_AITER expects the original type)
5801 if !is_async
5802 && let ast::Expr::List(ast::ExprList { elts, .. }) = iter
5803 && !elts.iter().any(|e| matches!(e, ast::Expr::Starred(_)))
5804 {
5805 for elt in elts {
5806 self.compile_expression(elt)?;
5807 }
5808 emit!(
5809 self,
5810 Instruction::BuildTuple {
5811 count: u32::try_from(elts.len()).expect("too many elements"),
5812 }
5813 );
5814 } else {
5815 self.compile_expression(iter)?;
5816 }
5817
5818 if is_async {
5819 if self.ctx.func != FunctionContext::AsyncFunction {
5820 return Err(self.error(CodegenErrorType::InvalidAsyncFor));
5821 }
5822 emit!(self, Instruction::GetAIter);
5823
5824 self.switch_to_block(for_block);
5825
5826 // codegen_async_for: push fblock BEFORE SETUP_FINALLY
5827 self.push_fblock(FBlockType::ForLoop, for_block, after_block)?;
5828
5829 // SETUP_FINALLY to guard the __anext__ call
5830 emit!(self, PseudoInstruction::SetupFinally { delta: else_block });
5831 emit!(self, Instruction::GetANext);
5832 self.emit_load_const(ConstantData::None);
5833 end_async_for_target = self.compile_yield_from_sequence(true)?;
5834 // POP_BLOCK for SETUP_FINALLY - only GetANext/yield_from are protected
5835 emit!(self, PseudoInstruction::PopBlock);
5836 emit!(self, Instruction::NotTaken);
5837
5838 // Success block for __anext__
5839 self.compile_store(target)?;

Callers 1

compile_statementMethod · 0.80

Calls 15

new_blockMethod · 0.80
compile_expressionMethod · 0.80
switch_to_blockMethod · 0.80
push_fblockMethod · 0.80
emit_load_constMethod · 0.80
compile_storeMethod · 0.80
compile_statementsMethod · 0.80
pop_fblockMethod · 0.80
set_source_rangeMethod · 0.80
emit_end_async_forMethod · 0.80

Tested by

no test coverage detected