refactor(joinir): Phase 260 P0.1 Step 6b - fix tests and add TODO

- 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 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 06:33:11 +09:00
parent cbed040a74
commit aa3fdf3c18
3 changed files with 41 additions and 24 deletions

View File

@ -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
///

View File

@ -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);

View File

@ -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 {