fix(joinir): Phase 283 P0 - Pattern3 Undefined ValueId Bug Fix
- Fix: extract_if_condition() moved after local_cond_env construction (loop_with_if_phi_if_sum.rs:175) - Root cause: condition extraction before i_param/sum_param creation - Result: i % 2 referenced caller's ConditionEnv with unmapped ValueId - Fail-Fast: Add condition_bindings validation in merge (mod.rs) - Fixture: Update loop_if_phi.hako for C2 compatibility (sum.toString()) - Verified: VM execution outputs sum=9 ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -239,7 +239,24 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
||||
.flat_map(|params| params.iter().copied())
|
||||
.collect();
|
||||
|
||||
// Phase 283 P0 DEBUG: Log condition_bindings count
|
||||
trace.stderr_if(
|
||||
&format!(
|
||||
"[cf_loop/joinir] Phase 283 P0 DEBUG: Processing {} condition_bindings",
|
||||
boundary.condition_bindings.len()
|
||||
),
|
||||
debug,
|
||||
);
|
||||
|
||||
for binding in &boundary.condition_bindings {
|
||||
trace.stderr_if(
|
||||
&format!(
|
||||
"[cf_loop/joinir] Phase 283 P0 DEBUG: Checking binding '{}' join={:?}",
|
||||
binding.name, binding.join_value
|
||||
),
|
||||
debug,
|
||||
);
|
||||
|
||||
if all_params.contains(&binding.join_value) {
|
||||
trace.stderr_if(
|
||||
&format!(
|
||||
@ -249,14 +266,27 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
|
||||
debug,
|
||||
);
|
||||
} else {
|
||||
trace.stderr_if(
|
||||
&format!(
|
||||
"[cf_loop/joinir] Phase 171-fix: Adding condition binding '{}' JoinIR {:?} to used_values",
|
||||
// Phase 283 P0 FIX: Ensure remapper has valid mapping (Fail-Fast)
|
||||
if let Some(host_id) = builder.variable_ctx.variable_map.get(&binding.name) {
|
||||
// Variable exists in host context - map join_value to existing host_id
|
||||
trace.stderr_if(
|
||||
&format!(
|
||||
"[cf_loop/joinir] Phase 283 P0: ✅ Condition binding '{}' JoinIR {:?} → host {:?}",
|
||||
binding.name, binding.join_value, host_id
|
||||
),
|
||||
debug,
|
||||
);
|
||||
remapper.set_value(binding.join_value, *host_id);
|
||||
used_values.insert(binding.join_value);
|
||||
} else {
|
||||
// Fail-Fast: No host ValueId found → surface root cause immediately
|
||||
return Err(format!(
|
||||
"[merge/phase2.1] Condition variable '{}' (join={:?}) has no host ValueId in variable_map. \
|
||||
This indicates the value was not properly supplied by boundary builder or cond_env. \
|
||||
Check: (1) boundary builder supplies all condition vars, (2) cond_env correctly tracks host ValueIds.",
|
||||
binding.name, binding.join_value
|
||||
),
|
||||
debug,
|
||||
);
|
||||
used_values.insert(binding.join_value);
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -102,16 +102,6 @@ pub fn lower_if_sum_pattern(
|
||||
&format!("{} {:?} ValueId({})", loop_var, loop_op, loop_limit_val.0)
|
||||
);
|
||||
|
||||
// Step 2: Extract if condition info (e.g., i > 0 → var="i", op=Gt, value=ValueId)
|
||||
// Phase 220-D: Now returns ValueId and instructions
|
||||
// Phase 242-EX-A: Now supports complex LHS
|
||||
let (if_var, if_op, if_lhs_val, if_value_val, if_value_insts) =
|
||||
extract_if_condition(if_stmt, &mut alloc_value, cond_env)?;
|
||||
trace.log(
|
||||
"if-cond",
|
||||
&format!("{} {:?} ValueId({})", if_var, if_op, if_value_val.0)
|
||||
);
|
||||
|
||||
// Step 3: Extract then-branch update (e.g., sum = sum + 1 → var="sum", addend=<expr>)
|
||||
// Phase 256.7: update_addend is now ASTNode (supports variables like separator)
|
||||
let (update_var, update_addend_ast) = extract_then_update(if_stmt)?;
|
||||
@ -182,6 +172,21 @@ pub fn lower_if_sum_pattern(
|
||||
}
|
||||
let cond_env = &local_cond_env; // Shadow the original cond_env
|
||||
|
||||
// Step 2: Extract if condition info (e.g., i > 0 → var="i", op=Gt, value=ValueId)
|
||||
//
|
||||
// IMPORTANT (Phase 283 P0): Extract using the local_cond_env.
|
||||
// The pre-loop extraction phase runs before `i_param`/`sum_param` exist, so
|
||||
// `i % 2 == 1` would resolve `i` via the caller's ConditionEnv and produce
|
||||
// JoinIR ValueIds that the boundary cannot remap → undefined ValueId in MIR.
|
||||
//
|
||||
// By extracting here, Variable("i") resolves to `i_param` and remains remappable.
|
||||
let (if_var, if_op, if_lhs_val, if_value_val, if_value_insts) =
|
||||
extract_if_condition(if_stmt, &mut alloc_value, cond_env)?;
|
||||
trace.log(
|
||||
"if-cond",
|
||||
&format!("{} {:?} ValueId({})", if_var, if_op, if_value_val.0)
|
||||
);
|
||||
|
||||
// === main() function ===
|
||||
let mut main_func = JoinFunction::new(main_id, "main".to_string(), main_params.clone());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user