diff --git a/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs b/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs index 608344e5..45f9a2d2 100644 --- a/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs +++ b/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs @@ -32,8 +32,10 @@ pub(super) fn build_exit_phi( // Phase 189-Fix: If we collected return values, create a PHI in exit block // This merges all return values from JoinIR functions into a single value let phi_result = if !exit_phi_inputs.is_empty() { - // Allocate a new ValueId for the PHI result - let phi_dst = builder.value_gen.next(); + // Phase 132-P2: Use function-level next_value_id() to allocate + // Previously used builder.value_gen.next() which is module-level, causing ValueId collisions + // Note: We use func.next_value_id() directly since builder.current_function is already borrowed + let phi_dst = func.next_value_id(); exit_block.instructions.push(MirInstruction::Phi { dst: phi_dst, inputs: exit_phi_inputs.to_vec(), @@ -61,8 +63,10 @@ pub(super) fn build_exit_phi( continue; } - // Allocate a new ValueId for this carrier's PHI - let phi_dst = builder.value_gen.next(); + // Phase 132-P2: Use function-level next_value_id() to allocate + // Previously used builder.value_gen.next() which is module-level, causing ValueId collisions + // Note: We use func.next_value_id() directly since builder.current_function is already borrowed + let phi_dst = func.next_value_id(); exit_block.instructions.push(MirInstruction::Phi { dst: phi_dst, inputs: inputs.clone(),