refactor(mir): Remove VariableContext legacy fields (Phase 2-6/7)

完全移行→削除の安全順序(Option C)に従い、VariableContext の
deprecated フィールドと sync helpers を完全削除。

## Changes
- Migrated all 66+ access sites to variable_ctx.variable_map
- Removed 1 deprecated field (variable_map) from MirBuilder
- Removed 2 sync helpers (sync_variable_ctx_to_legacy, sync_legacy_to_variable_ctx)
- Fixed BoxCompilationContext.variable_map references (kept as-is, different scope)
- Fixed ExitBindingBuilder.variable_map references (kept as-is, local field)
- Updated observer.rs to use variable_map() accessor method

## JoinIR Integration Verified
- CarrierInfo::from_variable_map() works correctly
- ExitLine contract maintained (Phase 132-135)
- NYASH_TRACE_VARMAP debug support preserved
- Pattern 1-5 lowering all functional

## Tests
- cargo test --release --lib: 1033 passed, 0 failed
- phase135_trim_mir_verify.sh: PASS (MIR SSA/ValueId OK)
- cargo build --release: SUCCESS
- Deprecation warnings: reduced (86 remaining, from other contexts)

## Statistics
- 27 files changed
- 146 insertions(+), 174 deletions(-)
- Net: -28 lines

Phase 2 Progress: 6/7 contexts complete (86%)
-  MetadataContext
-  CoreContext
-  TypeContext
-  ScopeContext
-  BindingContext
-  VariableContext (this commit)
-  CompilationContext (Phase 2-7 next)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-16 03:48:44 +09:00
parent 44b20bfe28
commit 9170f0a85d
27 changed files with 146 additions and 174 deletions

View File

@ -127,13 +127,6 @@ pub struct MirBuilder {
/// Direct field access for backward compatibility (migration in progress).
pub(super) comp_ctx: compilation_context::CompilationContext,
/// [DEPRECATED] Variable name to ValueId mapping (for SSA conversion)
/// Phase 136 Step 5/7: Moved to variable_ctx.variable_map (backward compat wrapper)
/// 注意: compilation_contextがSomeの場合は使用されません
/// Phase 25.1: HashMap → BTreeMapPHI生成の決定性確保
#[deprecated(note = "Use variable_ctx.variable_map instead")]
pub(super) variable_map: BTreeMap<String, ValueId>,
/// Pending phi functions to be inserted
#[allow(dead_code)]
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
@ -300,7 +293,6 @@ impl MirBuilder {
variable_ctx: variable_context::VariableContext::new(), // Phase 136 Step 5/7: Variable context
metadata_ctx: metadata_context::MetadataContext::new(), // Phase 136 Step 6/7: Metadata context
comp_ctx, // Phase 136 Step 7/7: Compilation context
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
pending_phis: Vec::new(),
user_defined_boxes: HashSet::new(),
weak_fields_by_box: HashMap::new(),
@ -342,18 +334,7 @@ impl MirBuilder {
}
// Phase 2-5: BindingContext sync helpers removed - binding_ctx is now SSOT
/// Phase 136 Step 5/7: Sync variable_ctx changes back to legacy field (backward compatibility)
#[allow(deprecated)]
fn sync_variable_ctx_to_legacy(&mut self) {
self.variable_map = self.variable_ctx.variable_map.clone();
}
/// Phase 136 Step 5/7: Sync legacy field changes to variable_ctx (backward compatibility)
#[allow(deprecated)]
fn sync_legacy_to_variable_ctx(&mut self) {
self.variable_ctx.variable_map = self.variable_map.clone();
}
// Phase 2-6: VariableContext sync helpers removed - variable_ctx is now SSOT
/// Push/pop helpers for If merge context (best-effort; optional usage)
pub(super) fn push_if_merge(&mut self, bb: BasicBlockId) {
@ -616,7 +597,7 @@ impl MirBuilder {
));
}
if let Some(&value_id) = self.variable_map.get(&name) {
if let Some(&value_id) = self.variable_ctx.variable_map.get(&name) {
Ok(value_id)
} else {
Err(self.undefined_variable_message(&name))
@ -681,7 +662,7 @@ impl MirBuilder {
// Result: VM would try to read undefined ValueIds (e.g., ValueId(270) at bb303).
if !var_name.starts_with("__pin$") {
// In SSA form, each assignment creates a new value
self.variable_map.insert(var_name.clone(), value_id);
self.variable_ctx.variable_map.insert(var_name.clone(), value_id);
}
Ok(value_id)
@ -808,7 +789,7 @@ impl MirBuilder {
}) = callee
{
let names: Vec<String> = self
.variable_map
.variable_ctx.variable_map
.iter()
.filter(|(_, &vid)| vid == *r)
.map(|(k, _)| k.clone())
@ -1148,13 +1129,11 @@ mod binding_id_tests {
use super::*;
#[test]
#[allow(deprecated)]
fn test_binding_map_initialization() {
let builder = MirBuilder::new();
assert_eq!(builder.core_ctx.next_binding_id, 0);
// Phase 136 Step 4/7: Check both binding_ctx (SSOT) and legacy field
// Phase 2-6: binding_ctx is now SSOT (legacy field removed)
assert!(builder.binding_ctx.is_empty());
assert!(builder.binding_map.is_empty());
}
#[test]
@ -1171,7 +1150,6 @@ mod binding_id_tests {
}
#[test]
#[allow(deprecated)]
fn test_shadowing_binding_restore() {
let mut builder = MirBuilder::new();
@ -1184,11 +1162,9 @@ mod binding_id_tests {
builder
.declare_local_in_current_scope("x", outer_vid)
.unwrap();
// Phase 136 Step 4/7: Check binding_ctx (SSOT)
// Phase 2-6: Check binding_ctx (SSOT)
let outer_bid = builder.binding_ctx.lookup("x").unwrap();
assert_eq!(outer_bid.raw(), 0);
// Also verify legacy field is synced
assert_eq!(*builder.binding_map.get("x").unwrap(), outer_bid);
// Enter inner scope and shadow x
builder.push_lexical_scope();
@ -1197,20 +1173,16 @@ mod binding_id_tests {
builder
.declare_local_in_current_scope("x", inner_vid)
.unwrap();
// Phase 136 Step 4/7: Check binding_ctx (SSOT)
// Phase 2-6: Check binding_ctx (SSOT)
let inner_bid = builder.binding_ctx.lookup("x").unwrap();
assert_eq!(inner_bid.raw(), 1);
// Also verify legacy field is synced
assert_eq!(*builder.binding_map.get("x").unwrap(), inner_bid);
// Exit inner scope - should restore outer binding
builder.pop_lexical_scope();
// Phase 136 Step 4/7: Check binding_ctx (SSOT)
// Phase 2-6: Check binding_ctx (SSOT)
let restored_bid = builder.binding_ctx.lookup("x").unwrap();
assert_eq!(restored_bid, outer_bid);
assert_eq!(restored_bid.raw(), 0);
// Also verify legacy field is synced
assert_eq!(*builder.binding_map.get("x").unwrap(), restored_bid);
// Cleanup
builder.pop_lexical_scope();