**Problem**: is_parameter() was too simple, checking only ValueId which changes
through copies/PHIs. This caused parameters like 'data' to be misclassified as
carriers, leading to incorrect PHI construction.
**Solution**: Track original parameter names at function entry.
**Changes**:
1. **Added function_param_names field** (builder.rs):
- HashSet<String> to track original parameter names
- Populated in lower_static_method_as_function()
- Cleared and repopulated for each new function
2. **Improved is_parameter()** (loop_builder.rs):
- Check name against function_param_names instead of ValueId
- More reliable than checking func.params (ValueIds change)
- __pin$*$@* variables correctly classified as carriers
- Added debug logging with NYASH_LOOPFORM_DEBUG
3. **Enhanced debug output** (loopform_builder.rs):
- Show carrier/pinned classification during prepare_structure()
- Show variable_map state after emit_header_phis()
**Test Results**:
- ✅ 'args' correctly identified as parameter (was working)
- ✅ 'data' now correctly identified as parameter (was broken)
- ✅ __pin variables correctly classified as carriers
- ✅ PHI values allocated and variable_map updated correctly
- ⚠️ ValueId undefined errors persist (separate issue)
**Remaining Issue**:
ValueId(10) undefined error suggests PHI visibility problem or VM verification
issue. Needs further investigation of emit_phi_at_block_start() or VM executor.
**Backward Compatibility**:
- Flag OFF: 100% existing behavior preserved (legacy path unchanged)
- Feature-flagged with NYASH_LOOPFORM_PHI_V2=1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Phase 25.1b: Complete SSA fix - eliminate all global ValueId usage in function contexts.
Root cause: ~75 locations throughout MIR builder were using global value
generator (self.value_gen.next()) instead of function-local allocator
(f.next_value_id()), causing SSA verification failures and runtime
"use of undefined value" errors.
Solution:
- Added next_value_id() helper that automatically chooses correct allocator
- Fixed 19 files with ~75 occurrences of ValueId allocation
- All function-context allocations now use function-local IDs
Files modified:
- src/mir/builder/utils.rs: Added next_value_id() helper, fixed 8 locations
- src/mir/builder/builder_calls.rs: 17 fixes
- src/mir/builder/ops.rs: 8 fixes
- src/mir/builder/stmts.rs: 7 fixes
- src/mir/builder/emission/constant.rs: 6 fixes
- src/mir/builder/rewrite/*.rs: 10 fixes
- + 13 other files
Verification:
- cargo build --release: SUCCESS
- Simple tests with NYASH_VM_VERIFY_MIR=1: Zero undefined errors
- Multi-parameter static methods: All working
Known remaining: ValueId(22) in Stage-B (separate issue to investigate)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>