fix(mir): fix else block scope bug - PHI materialization order
Root Cause: - Else blocks were not propagating variable assignments to outer scope - Bug 1 (if_form.rs): PHI materialization happened before variable_map reset, causing PHI nodes to be lost - Bug 2 (phi.rs): Variable merge didn't check if else branch modified variables Changes: - src/mir/builder/if_form.rs:93-127 - Reordered: reset variable_map BEFORE materializing PHI nodes - Now matches then-branch pattern (reset → materialize → execute) - Applied to both "else" and "no else" branches for consistency - src/mir/builder/phi.rs:137-154 - Added else_modified_var check to detect variable modifications - Use modified value from else_var_map_end_opt when available - Fall back to pre-if value only when truly not modified Test Results: ✅ Simple block: { x=42 } → 42 ✅ If block: if 1 { x=42 } → 42 ✅ Else block: if 0 { x=99 } else { x=42 } → 42 (FIXED!) ✅ Stage-B body extraction: "return 42" correctly extracted (was null) Impact: - Else block variable assignments now work correctly - Stage-B compiler body extraction restored - Selfhost builder path can now function - Foundation for Phase 21.x progress 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -137,13 +137,20 @@ impl MirBuilder {
|
||||
.get(&var_name)
|
||||
.copied()
|
||||
.unwrap_or(then_value_raw);
|
||||
// Check if else branch actually modified the variable (even if not as last expression)
|
||||
let else_modified_var = else_var_map_end_opt
|
||||
.as_ref()
|
||||
.and_then(|m| m.get(&var_name).copied());
|
||||
let else_value_for_var = if else_assigns_same {
|
||||
else_var_map_end_opt
|
||||
.as_ref()
|
||||
.and_then(|m| m.get(&var_name).copied())
|
||||
.unwrap_or(else_value_raw)
|
||||
} else if let Some(else_modified) = else_modified_var {
|
||||
// Else modifies the variable (even if not as the last expression)
|
||||
else_modified
|
||||
} else {
|
||||
// Else doesn't assign: use pre-if value if available
|
||||
// Else doesn't modify the variable: use pre-if value if available
|
||||
pre_then_var_value.unwrap_or(else_value_raw)
|
||||
};
|
||||
// Build inputs from reachable predecessors only
|
||||
|
||||
Reference in New Issue
Block a user