fix(joinir): collect carrier_inputs for skippable ExitJump (Phase 286C-4.1)
After the Phase 286C-4 refactoring, carrier_inputs was not being collected when a tail call's TailCallKind is ExitJump and the target is a skippable continuation. This caused json_lint_vm to fail with: [joinir/phase118/exit_phi/missing_carrier_phi] exit_bindings carrier 'i' is missing from exit_carrier_phis Root cause: The 3-stage pipeline refactoring separated Return→Jump conversion (which collected carrier_inputs) from tail call handling. When found_tail_call=true, the Return processing was skipped entirely, but tail call handling didn't collect carrier_inputs. Fix: Add carrier_inputs collection in the ExitJump (skippable) path at lines 901-934. This mirrors the fallback logic from the Return processing path. Test results: 45/46 PASS (same as before refactoring) - json_lint_vm: PASS (was FAIL) - core_direct_array_oob_set_rc_vm: FAIL (unchanged, known issue) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -872,6 +872,42 @@ fn plan_rewrites(
|
||||
"[plan_rewrites] ExitJump (skippable): redirecting from {:?} to exit_block_id {:?}",
|
||||
target_block, ctx.exit_block_id
|
||||
);
|
||||
|
||||
// Phase 286C-4.1: Collect carrier_inputs for skippable exit jump
|
||||
// This was missing in the refactored code
|
||||
if let Some(b) = boundary {
|
||||
for binding in &b.exit_bindings {
|
||||
// Skip ConditionOnly carriers
|
||||
if binding.role == crate::mir::join_ir::lowering::carrier_info::CarrierRole::ConditionOnly {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to get carrier value from header PHI
|
||||
if let Some(phi_dst) = loop_header_phi_info.get_carrier_phi(&binding.carrier_name) {
|
||||
result.carrier_inputs
|
||||
.entry(binding.carrier_name.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.push((new_block_id, phi_dst));
|
||||
log!(
|
||||
verbose,
|
||||
"[plan_rewrites] ExitJump carrier '{}': from {:?} value {:?}",
|
||||
binding.carrier_name, new_block_id, phi_dst
|
||||
);
|
||||
} else if b.exit_reconnect_mode == crate::mir::join_ir::lowering::carrier_info::ExitReconnectMode::DirectValue {
|
||||
// DirectValue fallback: use host_slot
|
||||
result.carrier_inputs
|
||||
.entry(binding.carrier_name.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.push((new_block_id, binding.host_slot));
|
||||
log!(
|
||||
verbose,
|
||||
"[plan_rewrites] ExitJump DirectValue fallback for '{}': host_slot {:?}",
|
||||
binding.carrier_name, binding.host_slot
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.exit_block_id
|
||||
} else {
|
||||
log!(
|
||||
|
||||
Reference in New Issue
Block a user