feat(mir): Phase 136 P0 - ValueId allocator SSOT 徹底(関数内経路から value_gen.next() 掃討)
## Summary
Eliminates remaining `value_gen.next()` calls from function-context code paths,
unifying all ValueId allocation through `MirBuilder::next_value_id()` SSOT allocator.
## Changes
### 1. Fixed `new_typed_value()` (src/mir/builder.rs:1068)
**Before**: `let id = self.value_gen.next();` (bypasses function context)
**After**: `let id = self.next_value_id();` (respects function context)
This is a public API used in function context, so must use SSOT allocator
to avoid collisions with reserved PHI dsts and function params.
### 2. Fixed test code (src/mir/builder.rs)
**test_shadowing_binding_restore** (lines 1161, 1171):
- Simulates function scope with `push_lexical_scope()`
- Changed to `builder.next_value_id()` for function scope simulation
**test_valueid_binding_parallel_allocation** (lines 1196-1216):
- Tests ValueId/BindingId independence
- Changed to `builder.next_value_id()` with note that Module context fallback preserves test intent
### 3. Verified Module context fallbacks (OK, no change needed)
These already check `current_function.is_some()` and use `value_gen.next()` only as Module context fallback:
- `src/mir/builder/utils.rs:43` - next_value_id() SSOT implementation
- `src/mir/builder/utils.rs:436` - pin_to_slot()
- `src/mir/builder/utils.rs:467` - materialize_local()
- `src/mir/utils/phi_helpers.rs:69` - insert_phi_unified()
## Verification
```bash
rg -n "value_gen\.next\(" src/mir --type rust | grep -v "Module context" | grep -v "//"
# Result: Only comments/docs remain
```
## Acceptance
✅ cargo test --release --lib - 997 passed
✅ phase135_trim_mir_verify.sh - PASS
✅ phase132_exit_phi_parity.sh - 3/3 PASS
✅ All function-context `value_gen.next()` eliminated
## Effect
- **Collision prevention**: No more ValueId collisions between function-level allocations and reserved PHI dsts
- **SSOT compliance**: All ValueId allocation flows through single allocator
- **Contract enforcement**: Phase 135 P1 contract_checks will catch violations immediately
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -1064,8 +1064,9 @@ impl MirBuilder {
|
||||
// ============================================================================
|
||||
|
||||
/// 型付きValueIdを発行(新API)
|
||||
/// Phase 136 P0: Use SSOT allocator (next_value_id) to respect function context
|
||||
pub fn new_typed_value(&mut self, kind: super::MirValueKind) -> super::TypedValueId {
|
||||
let id = self.value_gen.next();
|
||||
let id = self.next_value_id();
|
||||
self.value_kinds.insert(id, kind);
|
||||
super::TypedValueId::new(id, kind)
|
||||
}
|
||||
@ -1156,7 +1157,8 @@ mod binding_id_tests {
|
||||
builder.push_lexical_scope();
|
||||
|
||||
// Declare outer x
|
||||
let outer_vid = builder.value_gen.next();
|
||||
// Phase 136 P0: Use SSOT allocator for function scope simulation
|
||||
let outer_vid = builder.next_value_id();
|
||||
builder
|
||||
.declare_local_in_current_scope("x", outer_vid)
|
||||
.unwrap();
|
||||
@ -1165,7 +1167,8 @@ mod binding_id_tests {
|
||||
|
||||
// Enter inner scope and shadow x
|
||||
builder.push_lexical_scope();
|
||||
let inner_vid = builder.value_gen.next();
|
||||
// Phase 136 P0: Use SSOT allocator for function scope simulation
|
||||
let inner_vid = builder.next_value_id();
|
||||
builder
|
||||
.declare_local_in_current_scope("x", inner_vid)
|
||||
.unwrap();
|
||||
@ -1186,10 +1189,13 @@ mod binding_id_tests {
|
||||
fn test_valueid_binding_parallel_allocation() {
|
||||
let mut builder = MirBuilder::new();
|
||||
|
||||
// Phase 136 P0: Use SSOT allocator (next_value_id)
|
||||
// Note: Without current_function, next_value_id() falls back to value_gen.next()
|
||||
// so this test still validates ValueId/BindingId independence
|
||||
// Allocate ValueIds and BindingIds in parallel
|
||||
let vid0 = builder.value_gen.next();
|
||||
let vid0 = builder.next_value_id();
|
||||
let bid0 = builder.allocate_binding_id();
|
||||
let vid1 = builder.value_gen.next();
|
||||
let vid1 = builder.next_value_id();
|
||||
let bid1 = builder.allocate_binding_id();
|
||||
|
||||
// ValueId and BindingId should be independent
|
||||
@ -1199,15 +1205,15 @@ mod binding_id_tests {
|
||||
assert_eq!(bid1.raw(), 1);
|
||||
|
||||
// Allocating more ValueIds should not affect BindingId counter
|
||||
let _ = builder.value_gen.next();
|
||||
let _ = builder.value_gen.next();
|
||||
let _ = builder.next_value_id();
|
||||
let _ = builder.next_value_id();
|
||||
let bid2 = builder.allocate_binding_id();
|
||||
assert_eq!(bid2.raw(), 2); // Still sequential
|
||||
|
||||
// Allocating more BindingIds should not affect ValueId counter
|
||||
let _ = builder.allocate_binding_id();
|
||||
let _ = builder.allocate_binding_id();
|
||||
let vid2 = builder.value_gen.next();
|
||||
let vid2 = builder.next_value_id();
|
||||
assert_eq!(vid2.0, 4); // Continues from where we left off
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user