Enable PEP 709 inlined comprehensions by youknowone · Pull Request #7412 · RustPython/RustPython
bot reviewed Mar 12, 2026
Activate the existing compile_inlined_comprehension() implementation by fixing 6 bugs that prevented it from working: - LoadFastAndClear: push NULL (not None) when slot is empty so StoreFast can restore empty state after comprehension - StoreFast: accept NULL from stack for the restore path - sub_tables.remove(0) replaced with next_sub_table cursor to match the pattern used elsewhere in the compiler - in_inlined_comp flag moved from non-inlined to inlined path - is_inlined_comprehension_context() now checks comp_inlined flag and restricts inlining to function-like scopes - comp_inlined set only when parent scope uses fastlocals Symbol table analysis handles conflict detection: - Nested scopes in comprehension → skip inlining - Bound name conflicts with parent symbol → skip inlining - Cross-comprehension reference conflicts → skip inlining - Splice comprehension sub_tables into parent for nested scope tracking
Replace conservative bail-out approach with CPython-matching strategy: Symbol table (symboltable.rs): - Remove conflict-based bail-out checks (bound conflict, ref conflict, nested scopes) - Implement inline_comprehension() matching CPython's symtable.c: track inlined_cells, handle __class__ in ClassBlock, merge symbols with proper is_free_in_any_child check - Promote LOCAL to CELL for inlined_cells, set COMP_CELL flag - Splice inlined comp children into parent's sub_tables - Add can_see_class_scope check to inlining decision Compiler (compile.rs): - Implement TweakInlinedComprehensionScopes: temporarily swap symbol scopes during comprehension body compilation - Implement RevertInlinedComprehensionScopes: restore original scopes - Push ALL locally-bound names (not just iteration targets) for save/restore, excluding walrus operator targets - Emit MakeCell/RestoreCell for CELL variables in comprehensions - Re-enable async comprehension inlining with proper SetupFinally/EndAsyncFor handling - Include COMP_CELL symbols in cellvars VM (frame.rs, instruction.rs): - Add RestoreCell instruction for proper cell save/restore - MakeCell now saves old cell to stack and creates new empty cell
…ension cells Register RESTORE_CELL (opcode 121) in _opcode_metadata.py so test__opcode's stack_effect check passes. In locals(), skip cell values when the same name has a set fastlocal value. This fixes test_closure_with_inline_comprehension where a cell variable used as an inlined comprehension iteration target should show the comprehension's value, not the outer cell value.
- Add CO_FAST_LOCAL/CELL/FREE/HIDDEN constants and localspluskinds field to CodeObject for per-slot metadata - Change DEREF instruction opargs from cell-relative indices (NameIdx) to localsplus absolute indices (oparg::VarNum) - Add fixup_deref_opargs pass in ir.rs to convert cell-relative indices to localsplus indices after finalization - Replace get_cell_name with get_localsplus_name in InstrDisplayContext trait - Update VM cell_ref/get_cell_contents/set_cell_contents to use localsplus indices directly (no nlocals offset) - Update function.rs cell2arg, super.rs __class__ lookup with explicit nlocals offsets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters