From 116ff105ed5f4ffd6dee29d641e649897ca11f73 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Mon, 17 Nov 2025 02:16:59 +0900 Subject: [PATCH] fix(mir/phi): include pinned variables in loop header PHIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Problem**: "use of undefined value ValueId(22)" errors in Stage-B when method receivers were used after loops. **Root cause**: prepare_loop_variables_with() explicitly skipped pinned variables (like __pin$6438$@recv) when creating loop header PHIs. Comment claimed they were "materialized via entry-phi in loop body" but this only happened for the body block, not for loop exit merge points. When receivers were used after loops, there was no PHI to merge values from different control flow paths. **Fix**: Remove the skip logic (lines 174-177) so pinned variables get PHIs at loop headers and exits like any other variable. **Impact**: - ValueId(22) error eliminated in Stage-B selfhost tests - MIR verification passes with NYASH_VM_VERIFY_MIR=1 - Pinned slots now correctly merge across loop boundaries - No more "use of undefined value" for cross-loop receivers **Test case**: /tmp/test_loop_recv.hako demonstrates receiver usage in loop and after loop exit, now works correctly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/mir/phi_core/loop_phi.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mir/phi_core/loop_phi.rs b/src/mir/phi_core/loop_phi.rs index 49087df7..47eca99a 100644 --- a/src/mir/phi_core/loop_phi.rs +++ b/src/mir/phi_core/loop_phi.rs @@ -170,11 +170,10 @@ pub fn prepare_loop_variables_with( let mut incomplete_phis: Vec = Vec::new(); for (var_name, &value_before) in current_vars.iter() { - // Skip pinned variables (internal compiler temporaries) - if var_name.starts_with("__pin$") { - // Pinned variables are materialized via entry-phi in loop body, skip here - continue; - } + // Phase 25.1b fix: Include pinned variables in loop header PHIs + // Previously pinned variables were skipped, causing "use of undefined value" + // errors when receivers were used after loops. Pinned variables need PHIs + // at both header and exit points to properly merge values across control flow. // Materialize the incoming value at preheader to satisfy UseBeforeDef constraints // even when `value_before` was defined in a different block (e.g., previous loop header).