From aa3fdf3c18d2f20c1999cc6abdb838398d0da2e7 Mon Sep 17 00:00:00 2001 From: tomoaki Date: Sun, 21 Dec 2025 06:33:11 +0900 Subject: [PATCH] refactor(joinir): Phase 260 P0.1 Step 6b - fix tests and add TODO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix helpers.rs tests to use new MirFunction::new(FunctionSignature, BasicBlockId) API - Update continuation_contract.rs import path to use rewriter::helpers - Add TODO comment for future exit_collection integration - All 6 rewriter tests pass The exit_collection module is complete and tested but full integration with instruction_rewriter.rs deferred (80/20 rule - logging context and flow control require careful refactoring). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../joinir/merge/instruction_rewriter.rs | 8 +++ .../joinir/merge/rewriter/helpers.rs | 55 +++++++++++-------- .../merge/tests/continuation_contract.rs | 2 +- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs index 4bdcdaac..0d9a8fe0 100644 --- a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs +++ b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs @@ -29,6 +29,14 @@ use super::rewriter::helpers::is_skippable_continuation; use super::rewriter::type_propagation::propagate_value_type_for_inst; // Phase 260 P0.1 Step 5: Import from terminator module use super::rewriter::terminator::{apply_remapped_terminator, remap_branch, remap_jump}; +// Phase 260 P0.1 Step 6: exit_collection module available +// TODO: Migrate inline Return→Jump conversion to use exit_collection functions: +// - collect_exit_values_from_legacy_edge_args() +// - add_carrier_values_to_inputs() +// - handle_fallback_exit_collection() +// - collect_k_exit_values() +// The module is ready at super::rewriter::exit_collection but full integration +// requires careful refactoring due to logging context and flow control. /// Phase 4: Merge ALL functions and rewrite instructions /// diff --git a/src/mir/builder/control_flow/joinir/merge/rewriter/helpers.rs b/src/mir/builder/control_flow/joinir/merge/rewriter/helpers.rs index 7c8619b0..ae837742 100644 --- a/src/mir/builder/control_flow/joinir/merge/rewriter/helpers.rs +++ b/src/mir/builder/control_flow/joinir/merge/rewriter/helpers.rs @@ -49,18 +49,28 @@ pub(in crate::mir::builder::control_flow::joinir::merge) fn is_skippable_continu #[cfg(test)] mod tests { use super::*; - use crate::mir::{BasicBlock, BasicBlockId, MirInstruction}; + use crate::mir::{BasicBlock, BasicBlockId, EffectMask, FunctionSignature, MirInstruction, MirType}; + + fn make_test_function(name: &str) -> MirFunction { + let signature = FunctionSignature { + name: name.to_string(), + params: vec![], + return_type: MirType::Void, + effects: EffectMask::PURE, + }; + MirFunction::new(signature, BasicBlockId::new(0)) + } #[test] fn test_is_skippable_continuation_pure_stub() { // Pure exit stub: 1 block, no instructions, return only - let mut func = MirFunction::new("k_exit".to_string(), vec![]); - let entry_block_id = BasicBlockId::new(0); - func.entry_block = entry_block_id; + let mut func = make_test_function("k_exit"); + let entry_block_id = func.entry_block; - let mut block = BasicBlock::new(entry_block_id); - block.set_terminator(MirInstruction::Return { value: None }); - func.add_block(block); + // MirFunction::new already creates entry block, just set terminator + if let Some(block) = func.blocks.get_mut(&entry_block_id) { + block.set_terminator(MirInstruction::Return { value: None }); + } assert!(is_skippable_continuation(&func)); } @@ -68,17 +78,16 @@ mod tests { #[test] fn test_is_skippable_continuation_has_instructions() { // Has instructions: not skippable - let mut func = MirFunction::new("k_exit".to_string(), vec![]); - let entry_block_id = BasicBlockId::new(0); - func.entry_block = entry_block_id; + let mut func = make_test_function("k_exit"); + let entry_block_id = func.entry_block; - let mut block = BasicBlock::new(entry_block_id); - block.instructions.push(MirInstruction::Const { - dst: crate::mir::ValueId::new(1), - value: crate::mir::types::ConstValue::Integer(42), - }); - block.set_terminator(MirInstruction::Return { value: None }); - func.add_block(block); + if let Some(block) = func.blocks.get_mut(&entry_block_id) { + block.instructions.push(MirInstruction::Const { + dst: crate::mir::ValueId::new(1), + value: crate::mir::types::ConstValue::Integer(42), + }); + block.set_terminator(MirInstruction::Return { value: None }); + } assert!(!is_skippable_continuation(&func)); } @@ -86,14 +95,14 @@ mod tests { #[test] fn test_is_skippable_continuation_multiple_blocks() { // Multiple blocks: not skippable - let mut func = MirFunction::new("k_exit".to_string(), vec![]); - let entry_block_id = BasicBlockId::new(0); - func.entry_block = entry_block_id; + let mut func = make_test_function("k_exit"); + let entry_block_id = func.entry_block; - let mut block1 = BasicBlock::new(entry_block_id); - block1.set_terminator(MirInstruction::Return { value: None }); - func.add_block(block1); + if let Some(block) = func.blocks.get_mut(&entry_block_id) { + block.set_terminator(MirInstruction::Return { value: None }); + } + // Add second block let block2 = BasicBlock::new(BasicBlockId::new(1)); func.add_block(block2); diff --git a/src/mir/builder/control_flow/joinir/merge/tests/continuation_contract.rs b/src/mir/builder/control_flow/joinir/merge/tests/continuation_contract.rs index 5ecc659b..da1e722f 100644 --- a/src/mir/builder/control_flow/joinir/merge/tests/continuation_contract.rs +++ b/src/mir/builder/control_flow/joinir/merge/tests/continuation_contract.rs @@ -9,7 +9,7 @@ //! - Skippable continuation: 1 block + empty instructions + Return only //! - Non-skippable continuation: Contains other instructions (e.g., TailCall) -use crate::mir::builder::control_flow::joinir::merge::instruction_rewriter::is_skippable_continuation; +use crate::mir::builder::control_flow::joinir::merge::rewriter::helpers::is_skippable_continuation; use crate::mir::{BasicBlockId, EffectMask, FunctionSignature, MirFunction, MirInstruction, MirType, ValueId}; fn make_function(name: &str) -> MirFunction {