refactor(mir): Remove ScopeContext legacy fields (Phase 2-4/7)

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

## Changes
- Migrated all access sites to scope_ctx.*
- Removed 7 deprecated fields:
  - current_function
  - lexical_scope_stack
  - function_param_names
  - loop_header_stack
  - loop_exit_stack
  - if_merge_stack
  - debug_scope_stack
- Removed 2 sync helpers (sync_scope_ctx_to_legacy, sync_legacy_to_scope_ctx)
- Updated 20+ files with direct field access

## Tests
- cargo build --release: PASS 
- Deprecation warnings: 255 → 166 (-89, -35%)

Phase 2 Progress: 4/7 contexts complete (57%)
This commit is contained in:
nyash-codex
2025-12-15 23:41:30 +09:00
parent b92f85f993
commit 7235fe62e9
21 changed files with 78 additions and 158 deletions

View File

@ -78,11 +78,6 @@ pub struct MirBuilder {
/// Current module being built /// Current module being built
pub(super) current_module: Option<MirModule>, pub(super) current_module: Option<MirModule>,
/// [DEPRECATED] Current function being built
/// Phase 136: Moved to scope_ctx.current_function (backward compat wrapper)
#[deprecated(note = "Use scope_ctx.current_function instead")]
pub(super) current_function: Option<MirFunction>,
/// Current basic block being built /// Current basic block being built
pub(super) current_block: Option<BasicBlockId>, pub(super) current_block: Option<BasicBlockId>,
@ -139,11 +134,6 @@ pub struct MirBuilder {
#[deprecated(note = "Use variable_ctx.variable_map instead")] #[deprecated(note = "Use variable_ctx.variable_map instead")]
pub(super) variable_map: BTreeMap<String, ValueId>, pub(super) variable_map: BTreeMap<String, ValueId>,
/// [DEPRECATED] Lexical scope stack for block-scoped `local` declarations.
/// Phase 136: Moved to scope_ctx.lexical_scope_stack (backward compat wrapper)
#[deprecated(note = "Use scope_ctx.lexical_scope_stack instead")]
lexical_scope_stack: Vec<vars::lexical_scope::LexicalScopeFrame>,
/// Pending phi functions to be inserted /// Pending phi functions to be inserted
#[allow(dead_code)] #[allow(dead_code)]
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>, pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
@ -198,11 +188,6 @@ pub struct MirBuilder {
#[deprecated(note = "Use comp_ctx.static_method_index instead")] #[deprecated(note = "Use comp_ctx.static_method_index instead")]
pub(super) static_method_index: std::collections::HashMap<String, Vec<(String, usize)>>, pub(super) static_method_index: std::collections::HashMap<String, Vec<(String, usize)>>,
/// [DEPRECATED] Function parameter names (for LoopForm PHI construction)
/// Phase 136: Moved to scope_ctx.function_param_names (backward compat wrapper)
#[deprecated(note = "Use scope_ctx.function_param_names instead")]
pub(super) function_param_names: HashSet<String>,
/// [DEPRECATED] Fast lookup: method+arity tail → candidate function names (e.g., ".str/0" → ["JsonNode.str/0", ...]) /// [DEPRECATED] Fast lookup: method+arity tail → candidate function names (e.g., ".str/0" → ["JsonNode.str/0", ...])
/// Phase 136 Step 7/7: Moved to comp_ctx.method_tail_index (backward compat wrapper) /// Phase 136 Step 7/7: Moved to comp_ctx.method_tail_index (backward compat wrapper)
#[deprecated(note = "Use comp_ctx.method_tail_index instead")] #[deprecated(note = "Use comp_ctx.method_tail_index instead")]
@ -233,19 +218,6 @@ pub struct MirBuilder {
pub binding_map: BTreeMap<String, super::BindingId>, pub binding_map: BTreeMap<String, super::BindingId>,
// include guards removed // include guards removed
/// [DEPRECATED] Loop context stacks for lowering break/continue inside nested control flow
/// Phase 136: Moved to scope_ctx.loop_header_stack (backward compat wrapper)
#[deprecated(note = "Use scope_ctx.loop_header_stack instead")]
pub(super) loop_header_stack: Vec<BasicBlockId>,
#[allow(dead_code)]
#[deprecated(note = "Use scope_ctx.loop_exit_stack instead")]
pub(super) loop_exit_stack: Vec<BasicBlockId>,
/// [DEPRECATED] If/merge context stack (innermost first)
/// Phase 136: Moved to scope_ctx.if_merge_stack (backward compat wrapper)
#[deprecated(note = "Use scope_ctx.if_merge_stack instead")]
pub(super) if_merge_stack: Vec<BasicBlockId>,
// フェーズM: no_phi_modeフィールド削除常にPHI使用 // フェーズM: no_phi_modeフィールド削除常にPHI使用
// ---- Try/Catch/Cleanup lowering context ---- // ---- Try/Catch/Cleanup lowering context ----
@ -270,10 +242,6 @@ pub struct MirBuilder {
// ---------------------- // ----------------------
// Debug scope context (dev only; zero-cost when unused) // Debug scope context (dev only; zero-cost when unused)
// ---------------------- // ----------------------
/// [DEPRECATED] Stack of region identifiers like "loop#1/header" or "join#3/join".
/// Phase 136: Moved to scope_ctx.debug_scope_stack (backward compat wrapper)
#[deprecated(note = "Use scope_ctx.debug_scope_stack instead")]
debug_scope_stack: Vec<String>,
/// Local SSA cache: ensure per-block materialization for critical operands (e.g., recv) /// Local SSA cache: ensure per-block materialization for critical operands (e.g., recv)
/// Key: (bb, original ValueId, kind) -> local ValueId /// Key: (bb, original ValueId, kind) -> local ValueId
@ -323,7 +291,6 @@ impl MirBuilder {
#[allow(deprecated)] #[allow(deprecated)]
Self { Self {
current_module: None, current_module: None,
current_function: None,
current_block: None, current_block: None,
// Phase 136 Step 2/7: Core context (new SSOT) // Phase 136 Step 2/7: Core context (new SSOT)
@ -337,7 +304,6 @@ impl MirBuilder {
metadata_ctx: metadata_context::MetadataContext::new(), // Phase 136 Step 6/7: Metadata context metadata_ctx: metadata_context::MetadataContext::new(), // Phase 136 Step 6/7: Metadata context
comp_ctx, // Phase 136 Step 7/7: Compilation context comp_ctx, // Phase 136 Step 7/7: Compilation context
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat) variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
lexical_scope_stack: Vec::new(),
pending_phis: Vec::new(), pending_phis: Vec::new(),
user_defined_boxes: HashSet::new(), user_defined_boxes: HashSet::new(),
weak_fields_by_box: HashMap::new(), weak_fields_by_box: HashMap::new(),
@ -349,7 +315,6 @@ impl MirBuilder {
plugin_method_sigs, plugin_method_sigs,
current_static_box: None, current_static_box: None,
static_method_index: std::collections::HashMap::new(), static_method_index: std::collections::HashMap::new(),
function_param_names: HashSet::new(),
method_tail_index: std::collections::HashMap::new(), method_tail_index: std::collections::HashMap::new(),
method_tail_index_source_len: 0, method_tail_index_source_len: 0,
@ -358,9 +323,6 @@ impl MirBuilder {
binding_map: BTreeMap::new(), // Phase 74: Initialize BindingId mapping binding_map: BTreeMap::new(), // Phase 74: Initialize BindingId mapping
loop_header_stack: Vec::new(),
loop_exit_stack: Vec::new(),
if_merge_stack: Vec::new(),
// フェーズM: no_phi_modeフィールド削除 // フェーズM: no_phi_modeフィールド削除
return_defer_active: false, return_defer_active: false,
return_defer_slot: None, return_defer_slot: None,
@ -371,9 +333,6 @@ impl MirBuilder {
cleanup_allow_throw: false, cleanup_allow_throw: false,
suppress_pin_entry_copy_next: false, suppress_pin_entry_copy_next: false,
// Debug scope context
debug_scope_stack: Vec::new(),
local_ssa_map: HashMap::new(), local_ssa_map: HashMap::new(),
schedule_mat_map: HashMap::new(), schedule_mat_map: HashMap::new(),
pin_slot_names: HashMap::new(), pin_slot_names: HashMap::new(),
@ -385,31 +344,6 @@ impl MirBuilder {
} }
} }
// ---- Phase 136 Step 3/7: ScopeContext synchronization helpers ----
/// Sync scope_ctx changes back to legacy fields (backward compatibility)
#[allow(deprecated)]
fn sync_scope_ctx_to_legacy(&mut self) {
self.lexical_scope_stack = self.scope_ctx.lexical_scope_stack.clone();
self.loop_header_stack = self.scope_ctx.loop_header_stack.clone();
self.loop_exit_stack = self.scope_ctx.loop_exit_stack.clone();
self.if_merge_stack = self.scope_ctx.if_merge_stack.clone();
self.current_function = self.scope_ctx.current_function.clone();
self.function_param_names = self.scope_ctx.function_param_names.clone();
self.debug_scope_stack = self.scope_ctx.debug_scope_stack.clone();
}
/// Sync legacy field changes to scope_ctx (backward compatibility)
#[allow(deprecated)]
fn sync_legacy_to_scope_ctx(&mut self) {
self.scope_ctx.lexical_scope_stack = self.lexical_scope_stack.clone();
self.scope_ctx.loop_header_stack = self.loop_header_stack.clone();
self.scope_ctx.loop_exit_stack = self.loop_exit_stack.clone();
self.scope_ctx.if_merge_stack = self.if_merge_stack.clone();
self.scope_ctx.current_function = self.current_function.clone();
self.scope_ctx.function_param_names = self.function_param_names.clone();
self.scope_ctx.debug_scope_stack = self.debug_scope_stack.clone();
}
// ---- Phase 136 Step 4/7: BindingContext synchronization helpers ---- // ---- Phase 136 Step 4/7: BindingContext synchronization helpers ----
/// Sync binding_ctx changes back to legacy fields (backward compatibility) /// Sync binding_ctx changes back to legacy fields (backward compatibility)
#[allow(deprecated)] #[allow(deprecated)]

View File

@ -21,7 +21,7 @@ impl MirBuilder {
// Dev trace // Dev trace
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") { if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
let cur_fun = self let cur_fun = self
.current_function .scope_ctx.current_function
.as_ref() .as_ref()
.map(|f| f.signature.name.clone()) .map(|f| f.signature.name.clone())
.unwrap_or_else(|| "<none>".to_string()); .unwrap_or_else(|| "<none>".to_string());

View File

@ -79,9 +79,8 @@ impl MirBuilder {
let entry = self.next_block_id(); let entry = self.next_block_id();
let function = self.new_function_with_metadata(signature, entry); let function = self.new_function_with_metadata(signature, entry);
// Phase 136 Step 3/7: Save from scope_ctx (SSOT), sync to legacy field // Phase 136 Step 3/7: Save from scope_ctx (SSOT)
ctx.saved_function = self.scope_ctx.current_function.take(); ctx.saved_function = self.scope_ctx.current_function.take();
self.current_function = None;
ctx.saved_block = self.current_block.take(); ctx.saved_block = self.current_block.take();
eprintln!( eprintln!(
@ -90,9 +89,8 @@ impl MirBuilder {
); );
eprintln!("[DEBUG/create_function_skeleton] Entry block: {:?}", entry); eprintln!("[DEBUG/create_function_skeleton] Entry block: {:?}", entry);
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat) // Phase 136 Step 3/7: Use scope_ctx as SSOT
self.scope_ctx.current_function = Some(function.clone()); self.scope_ctx.current_function = Some(function);
self.current_function = Some(function);
self.current_block = Some(entry); self.current_block = Some(entry);
// 新しい関数スコープ用の SlotRegistry を準備するよ(観測専用) // 新しい関数スコープ用の SlotRegistry を準備するよ(観測専用)
self.current_slot_registry = Some(FunctionSlotRegistry::new()); self.current_slot_registry = Some(FunctionSlotRegistry::new());
@ -107,15 +105,14 @@ impl MirBuilder {
/// 🎯 箱理論: Step 3 - パラメータ設定 /// 🎯 箱理論: Step 3 - パラメータ設定
#[allow(deprecated)] #[allow(deprecated)]
fn setup_function_params(&mut self, params: &[String]) { fn setup_function_params(&mut self, params: &[String]) {
// Phase 136 Step 3/7: Clear both scope_ctx (SSOT) and legacy field (backward compat) // Phase 136 Step 3/7: Clear scope_ctx (SSOT)
self.scope_ctx.function_param_names.clear(); self.scope_ctx.function_param_names.clear();
self.function_param_names.clear();
// SlotRegistry 更新は borrow 競合を避けるため、まずローカルに集約してから反映するよ。 // SlotRegistry 更新は borrow 競合を避けるため、まずローカルに集約してから反映するよ。
let mut slot_regs: Vec<(String, Option<MirType>)> = Vec::new(); let mut slot_regs: Vec<(String, Option<MirType>)> = Vec::new();
// Phase 26-A-3: パラメータ型情報も後で一括登録(借用競合回避) // Phase 26-A-3: パラメータ型情報も後で一括登録(借用競合回避)
let mut param_kinds: Vec<(ValueId, u32)> = Vec::new(); let mut param_kinds: Vec<(ValueId, u32)> = Vec::new();
if let Some(ref mut f) = self.current_function { if let Some(ref mut f) = self.scope_ctx.current_function {
// 📦 Hotfix 5: Use pre-populated params from MirFunction::new() // 📦 Hotfix 5: Use pre-populated params from MirFunction::new()
// Static methods have implicit receiver at params[0], so actual parameters start at offset // Static methods have implicit receiver at params[0], so actual parameters start at offset
let receiver_offset = if f.params.is_empty() { let receiver_offset = if f.params.is_empty() {
@ -143,9 +140,8 @@ impl MirBuilder {
new_pid new_pid
}; };
self.variable_map.insert(p.clone(), pid); self.variable_map.insert(p.clone(), pid);
// Phase 136 Step 3/7: Insert into both scope_ctx (SSOT) and legacy field // Phase 136 Step 3/7: Insert into scope_ctx (SSOT)
self.scope_ctx.function_param_names.insert(p.clone()); self.scope_ctx.function_param_names.insert(p.clone());
self.function_param_names.insert(p.clone());
// Phase 26-A-3: パラメータ型情報を収集(後で一括登録) // Phase 26-A-3: パラメータ型情報を収集(後で一括登録)
// param_idx: receiver offset を考慮した実際のパラメータインデックス // param_idx: receiver offset を考慮した実際のパラメータインデックス
@ -183,7 +179,7 @@ impl MirBuilder {
fn finalize_function(&mut self, returns_value: bool) -> Result<(), String> { fn finalize_function(&mut self, returns_value: bool) -> Result<(), String> {
// Void return追加必要な場合 // Void return追加必要な場合
if !returns_value { if !returns_value {
if let Some(ref mut f) = self.current_function { if let Some(ref mut f) = self.scope_ctx.current_function {
if let Some(block) = f.get_block(self.current_block.unwrap()) { if let Some(block) = f.get_block(self.current_block.unwrap()) {
if !block.is_terminated() { if !block.is_terminated() {
let void_val = crate::mir::builder::emission::constant::emit_void(self); let void_val = crate::mir::builder::emission::constant::emit_void(self);
@ -196,7 +192,7 @@ impl MirBuilder {
} }
// 型推論 // 型推論
if let Some(ref mut f) = self.current_function { if let Some(ref mut f) = self.scope_ctx.current_function {
if returns_value && matches!(f.signature.return_type, MirType::Void | MirType::Unknown) if returns_value && matches!(f.signature.return_type, MirType::Void | MirType::Unknown)
{ {
let mut inferred: Option<MirType> = None; let mut inferred: Option<MirType> = None;
@ -223,9 +219,8 @@ impl MirBuilder {
} }
// Moduleに追加 // Moduleに追加
// Phase 136 Step 3/7: Take from legacy field, sync to scope_ctx // Phase 136 Step 3/7: Take from scope_ctx (SSOT)
let finalized = self.current_function.take().unwrap(); let finalized = self.scope_ctx.current_function.take().unwrap();
self.scope_ctx.current_function = None;
if let Some(ref mut module) = self.current_module { if let Some(ref mut module) = self.current_module {
module.add_function(finalized); module.add_function(finalized);
} }
@ -235,9 +230,8 @@ impl MirBuilder {
/// 🎯 箱理論: Step 6 - Context復元 /// 🎯 箱理論: Step 6 - Context復元
fn restore_lowering_context(&mut self, ctx: LoweringContext) { fn restore_lowering_context(&mut self, ctx: LoweringContext) {
// Phase 136 Step 3/7: Restore to scope_ctx (SSOT), sync to legacy field // Phase 136 Step 3/7: Restore to scope_ctx (SSOT)
self.scope_ctx.current_function = ctx.saved_function.clone(); self.scope_ctx.current_function = ctx.saved_function;
self.current_function = ctx.saved_function;
self.current_block = ctx.saved_block; self.current_block = ctx.saved_block;
// モード別にcontext復元 // モード別にcontext復元
@ -272,14 +266,12 @@ impl MirBuilder {
let entry = self.next_block_id(); let entry = self.next_block_id();
let function = self.new_function_with_metadata(signature, entry); let function = self.new_function_with_metadata(signature, entry);
// Phase 136 Step 3/7: Save from scope_ctx (SSOT), sync to legacy field // Phase 136 Step 3/7: Save from scope_ctx (SSOT)
ctx.saved_function = self.scope_ctx.current_function.take(); ctx.saved_function = self.scope_ctx.current_function.take();
self.current_function = None;
ctx.saved_block = self.current_block.take(); ctx.saved_block = self.current_block.take();
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat) // Phase 136 Step 3/7: Use scope_ctx as SSOT
self.scope_ctx.current_function = Some(function.clone()); self.scope_ctx.current_function = Some(function);
self.current_function = Some(function);
self.current_block = Some(entry); self.current_block = Some(entry);
// instance method 用の関数スコープ SlotRegistry もここで用意するよ。 // instance method 用の関数スコープ SlotRegistry もここで用意するよ。
self.current_slot_registry = Some(FunctionSlotRegistry::new()); self.current_slot_registry = Some(FunctionSlotRegistry::new());
@ -296,7 +288,7 @@ impl MirBuilder {
// SlotRegistry 更新はローカルバッファに集約してから反映するよ。 // SlotRegistry 更新はローカルバッファに集約してから反映するよ。
let mut slot_regs: Vec<(String, Option<MirType>)> = Vec::new(); let mut slot_regs: Vec<(String, Option<MirType>)> = Vec::new();
if let Some(ref mut f) = self.current_function { if let Some(ref mut f) = self.scope_ctx.current_function {
// 📦 Hotfix 6 改訂版: // 📦 Hotfix 6 改訂版:
// MirFunction::new() が既に 0..N の ValueId を params 用に予約しているので、 // MirFunction::new() が既に 0..N の ValueId を params 用に予約しているので、
// ここではそれを「上書き使用」するだけにして、push で二重定義しないようにするよ。 // ここではそれを「上書き使用」するだけにして、push で二重定義しないようにするよ。
@ -377,7 +369,7 @@ impl MirBuilder {
self.lower_function_body(body)?; self.lower_function_body(body)?;
// Step 5: 関数finalize // Step 5: 関数finalize
let returns_value = if let Some(ref f) = self.current_function { let returns_value = if let Some(ref f) = self.scope_ctx.current_function {
!matches!(f.signature.return_type, MirType::Void) !matches!(f.signature.return_type, MirType::Void)
} else { } else {
false false
@ -427,7 +419,7 @@ impl MirBuilder {
self.lower_method_body(body)?; self.lower_method_body(body)?;
// Step 5: 関数finalize // Step 5: 関数finalize
let returns_value = if let Some(ref f) = self.current_function { let returns_value = if let Some(ref f) = self.scope_ctx.current_function {
!matches!(f.signature.return_type, MirType::Void) !matches!(f.signature.return_type, MirType::Void)
} else { } else {
false false
@ -442,7 +434,7 @@ impl MirBuilder {
} }
// 型推論Step 5の一部として // 型推論Step 5の一部として
if let Some(ref mut f) = self.current_function { if let Some(ref mut f) = self.scope_ctx.current_function {
if returns_value && matches!(f.signature.return_type, MirType::Void | MirType::Unknown) if returns_value && matches!(f.signature.return_type, MirType::Void | MirType::Unknown)
{ {
let mut inferred: Option<MirType> = None; let mut inferred: Option<MirType> = None;
@ -469,7 +461,7 @@ impl MirBuilder {
} }
// Moduleに追加 // Moduleに追加
let finalized_function = self.current_function.take().unwrap(); let finalized_function = self.scope_ctx.current_function.take().unwrap();
if let Some(ref mut module) = self.current_module { if let Some(ref mut module) = self.current_module {
module.add_function(finalized_function); module.add_function(finalized_function);
} }
@ -477,9 +469,8 @@ impl MirBuilder {
// FunctionRegion を 1 段ポップして元の関数コンテキストに戻るよ。 // FunctionRegion を 1 段ポップして元の関数コンテキストに戻るよ。
crate::mir::region::observer::pop_function_region(self); crate::mir::region::observer::pop_function_region(self);
// Phase 136 Step 3/7: Restore to scope_ctx (SSOT), sync to legacy field // Phase 136 Step 3/7: Restore to scope_ctx (SSOT)
self.scope_ctx.current_function = ctx.saved_function.clone(); self.scope_ctx.current_function = ctx.saved_function;
self.current_function = ctx.saved_function;
self.current_block = ctx.saved_block; self.current_block = ctx.saved_block;
if let Some(saved) = ctx.saved_var_map { if let Some(saved) = ctx.saved_var_map {
self.variable_map = saved; self.variable_map = saved;

View File

@ -26,7 +26,7 @@ pub(super) fn build_exit_phi(
) -> Result<(Option<ValueId>, BTreeMap<String, ValueId>), String> { ) -> Result<(Option<ValueId>, BTreeMap<String, ValueId>), String> {
let mut carrier_phis: BTreeMap<String, ValueId> = BTreeMap::new(); let mut carrier_phis: BTreeMap<String, ValueId> = BTreeMap::new();
let exit_phi_result_id = if let Some(ref mut func) = builder.current_function { let exit_phi_result_id = if let Some(ref mut func) = builder.scope_ctx.current_function {
let mut exit_block = BasicBlock::new(exit_block_id); let mut exit_block = BasicBlock::new(exit_block_id);
// Phase 189-Fix: If we collected return values, create a PHI in exit block // Phase 189-Fix: If we collected return values, create a PHI in exit block

View File

@ -149,7 +149,7 @@ pub(super) fn merge_and_rewrite(
// Phase 195 FIX: Reuse existing block if present (preserves PHI from JoinIR Select lowering) // Phase 195 FIX: Reuse existing block if present (preserves PHI from JoinIR Select lowering)
// ultrathink "finalizer集約案": Don't overwrite blocks with BasicBlock::new() // ultrathink "finalizer集約案": Don't overwrite blocks with BasicBlock::new()
let mut new_block = if let Some(ref mut current_func) = builder.current_function { let mut new_block = if let Some(ref mut current_func) = builder.scope_ctx.current_function {
current_func current_func
.blocks .blocks
.remove(&new_block_id) .remove(&new_block_id)
@ -811,7 +811,7 @@ pub(super) fn merge_and_rewrite(
} }
// Add block to current function // Add block to current function
if let Some(ref mut current_func) = builder.current_function { if let Some(ref mut current_func) = builder.scope_ctx.current_function {
current_func.add_block(new_block); current_func.add_block(new_block);
} }
} }
@ -866,7 +866,7 @@ pub(super) fn merge_and_rewrite(
// Use BoundaryInjector to inject Copy instructions // Use BoundaryInjector to inject Copy instructions
// Phase 177-3 Option B: Returns reallocations map for condition_bindings with PHI collisions // Phase 177-3 Option B: Returns reallocations map for condition_bindings with PHI collisions
if let Some(ref mut current_func) = builder.current_function { if let Some(ref mut current_func) = builder.scope_ctx.current_function {
let _reallocations = BoundaryInjector::inject_boundary_copies( let _reallocations = BoundaryInjector::inject_boundary_copies(
current_func, current_func,
entry_block_remapped, entry_block_remapped,

View File

@ -733,7 +733,7 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
if let Some(boundary) = boundary { if let Some(boundary) = boundary {
if let Some(ref func) = builder.current_function { if let Some(ref func) = builder.scope_ctx.current_function {
verify_joinir_contracts( verify_joinir_contracts(
func, func,
entry_block, entry_block,

View File

@ -115,7 +115,7 @@ impl super::MirBuilder {
"Loop lowering failed: JoinIR does not support this pattern, and LoopBuilder has been removed.\n\ "Loop lowering failed: JoinIR does not support this pattern, and LoopBuilder has been removed.\n\
Function: {}\n\ Function: {}\n\
Hint: This loop pattern is not supported. All loops must use JoinIR lowering.", Hint: This loop pattern is not supported. All loops must use JoinIR lowering.",
self.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("<unknown>") self.scope_ctx.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("<unknown>")
))); )));
} }

View File

@ -10,7 +10,7 @@ pub fn emit_conditional(
then_bb: BasicBlockId, then_bb: BasicBlockId,
else_bb: BasicBlockId, else_bb: BasicBlockId,
) -> Result<(), String> { ) -> Result<(), String> {
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) { if let (Some(func), Some(cur_bb)) = (b.scope_ctx.current_function.as_mut(), b.current_block) {
crate::mir::ssot::cf_common::set_branch(func, cur_bb, cond, then_bb, else_bb); crate::mir::ssot::cf_common::set_branch(func, cur_bb, cond, then_bb, else_bb);
Ok(()) Ok(())
} else { } else {
@ -24,7 +24,7 @@ pub fn emit_conditional(
#[inline] #[inline]
pub fn emit_jump(b: &mut MirBuilder, target: BasicBlockId) -> Result<(), String> { pub fn emit_jump(b: &mut MirBuilder, target: BasicBlockId) -> Result<(), String> {
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) { if let (Some(func), Some(cur_bb)) = (b.scope_ctx.current_function.as_mut(), b.current_block) {
crate::mir::ssot::cf_common::set_jump(func, cur_bb, target); crate::mir::ssot::cf_common::set_jump(func, cur_bb, target);
Ok(()) Ok(())
} else { } else {

View File

@ -11,7 +11,7 @@ pub fn emit_to(
lhs: ValueId, lhs: ValueId,
rhs: ValueId, rhs: ValueId,
) -> Result<(), String> { ) -> Result<(), String> {
if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) { if let (Some(func), Some(cur_bb)) = (b.scope_ctx.current_function.as_mut(), b.current_block) {
crate::mir::ssot::cf_common::emit_compare_func(func, cur_bb, dst, op, lhs, rhs); crate::mir::ssot::cf_common::emit_compare_func(func, cur_bb, dst, op, lhs, rhs);
} else { } else {
b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?; b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?;

View File

@ -22,7 +22,7 @@ impl super::MirBuilder {
// Jump from current block to dispatch (ensure terminator exists) // Jump from current block to dispatch (ensure terminator exists)
let need_jump = { let need_jump = {
let cur = self.current_block; let cur = self.current_block;
if let (Some(cb), Some(ref func)) = (cur, &self.current_function) { if let (Some(cb), Some(ref func)) = (cur, &self.scope_ctx.current_function) {
if let Some(bb) = func.blocks.get(&cb) { if let Some(bb) = func.blocks.get(&cb) {
!bb.is_terminated() !bb.is_terminated()
} else { } else {
@ -118,7 +118,7 @@ impl super::MirBuilder {
// Merge and yield result // Merge and yield result
self.start_new_block(merge_block)?; self.start_new_block(merge_block)?;
// フェーズM: PHI はブロック先頭に配置cf_common 統一) // フェーズM: PHI はブロック先頭に配置cf_common 統一)
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) { if let (Some(func), Some(cur_bb)) = (self.scope_ctx.current_function.as_mut(), self.current_block) {
crate::mir::ssot::cf_common::insert_phi_at_head_spanned( crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
func, func,
cur_bb, cur_bb,

View File

@ -23,7 +23,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
) -> Result<(), String> { ) -> Result<(), String> {
// merge ブロックの先頭に PHI を挿入 // merge ブロックの先頭に PHI を挿入
if let (Some(func), Some(_cur_bb)) = if let (Some(func), Some(_cur_bb)) =
(self.0.current_function.as_mut(), self.0.current_block) (self.0.scope_ctx.current_function.as_mut(), self.0.current_block)
{ {
crate::mir::ssot::cf_common::insert_phi_at_head_spanned( crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
func, func,
@ -47,7 +47,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
} }
fn get_block_predecessors(&self, block: BasicBlockId) -> Vec<BasicBlockId> { fn get_block_predecessors(&self, block: BasicBlockId) -> Vec<BasicBlockId> {
if let Some(ref func) = self.0.current_function { if let Some(ref func) = self.0.scope_ctx.current_function {
func.blocks func.blocks
.get(&block) .get(&block)
.map(|bb| bb.predecessors.iter().copied().collect()) .map(|bb| bb.predecessors.iter().copied().collect())
@ -72,7 +72,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> {
} }
fn block_exists(&self, block: BasicBlockId) -> bool { fn block_exists(&self, block: BasicBlockId) -> bool {
if let Some(ref func) = self.0.current_function { if let Some(ref func) = self.0.scope_ctx.current_function {
func.blocks.contains_key(&block) func.blocks.contains_key(&block)
} else { } else {
false false
@ -239,7 +239,7 @@ impl MirBuilder {
core_mainline || (joinir_enabled && is_target && (joinir_toplevel || joinir_dryrun)); core_mainline || (joinir_enabled && is_target && (joinir_toplevel || joinir_dryrun));
if should_try_joinir { if should_try_joinir {
if let Some(ref func) = self.current_function { if let Some(ref func) = self.scope_ctx.current_function {
let context = let context =
crate::mir::join_ir::lowering::if_phi_context::IfPhiContext::pure_if(); crate::mir::join_ir::lowering::if_phi_context::IfPhiContext::pure_if();

View File

@ -118,9 +118,8 @@ impl super::MirBuilder {
main_function.metadata.is_entry_point = true; main_function.metadata.is_entry_point = true;
self.current_module = Some(module); self.current_module = Some(module);
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat) // Phase 136 Step 3/7: Use scope_ctx as SSOT
self.scope_ctx.current_function = Some(main_function.clone()); self.scope_ctx.current_function = Some(main_function);
self.current_function = Some(main_function);
self.current_block = Some(entry_block); self.current_block = Some(entry_block);
// 関数スコープの SlotRegistry を初期化するよ(観測専用)。 // 関数スコープの SlotRegistry を初期化するよ(観測専用)。
@ -293,7 +292,7 @@ impl super::MirBuilder {
// Hint: scope leave at function end (id=0 for main) // Hint: scope leave at function end (id=0 for main)
self.hint_scope_leave(0); self.hint_scope_leave(0);
if let Some(block_id) = self.current_block { if let Some(block_id) = self.current_block {
if let Some(ref mut function) = self.current_function { if let Some(ref mut function) = self.scope_ctx.current_function {
if let Some(block) = function.get_block_mut(block_id) { if let Some(block) = function.get_block_mut(block_id) {
if !block.is_terminated() { if !block.is_terminated() {
block.add_instruction(MirInstruction::Return { block.add_instruction(MirInstruction::Return {
@ -308,9 +307,8 @@ impl super::MirBuilder {
} }
let mut module = self.current_module.take().unwrap(); let mut module = self.current_module.take().unwrap();
// Phase 136 Step 3/7: Take from legacy field, sync to scope_ctx // Phase 136 Step 3/7: Take from scope_ctx (SSOT)
let mut function = self.current_function.take().unwrap(); let mut function = self.scope_ctx.current_function.take().unwrap();
self.scope_ctx.current_function = None;
// Phase 84-2: Copy命令型伝播return型推論の前に実行 // Phase 84-2: Copy命令型伝播return型推論の前に実行
// //
// Loop exit や If merge の edge copy で発生する型欠如を解消する。 // Loop exit や If merge の edge copy で発生する型欠如を解消する。

View File

@ -8,42 +8,42 @@ pub(crate) fn push_loop_context(
header: BasicBlockId, header: BasicBlockId,
exit: BasicBlockId, exit: BasicBlockId,
) { ) {
builder.loop_header_stack.push(header); builder.scope_ctx.loop_header_stack.push(header);
builder.loop_exit_stack.push(exit); builder.scope_ctx.loop_exit_stack.push(exit);
} }
/// Pop loop context (header/exit) from the MirBuilder stacks. /// Pop loop context (header/exit) from the MirBuilder stacks.
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn pop_loop_context(builder: &mut super::MirBuilder) { pub(crate) fn pop_loop_context(builder: &mut super::MirBuilder) {
let _ = builder.loop_header_stack.pop(); let _ = builder.scope_ctx.loop_header_stack.pop();
let _ = builder.loop_exit_stack.pop(); let _ = builder.scope_ctx.loop_exit_stack.pop();
} }
/// Peek current loop header block id /// Peek current loop header block id
#[allow(dead_code)] #[allow(dead_code)]
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn current_header(builder: &super::MirBuilder) -> Option<BasicBlockId> { pub(crate) fn current_header(builder: &super::MirBuilder) -> Option<BasicBlockId> {
builder.loop_header_stack.last().copied() builder.scope_ctx.loop_header_stack.last().copied()
} }
/// Peek current loop exit block id /// Peek current loop exit block id
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn current_exit(builder: &super::MirBuilder) -> Option<BasicBlockId> { pub(crate) fn current_exit(builder: &super::MirBuilder) -> Option<BasicBlockId> {
builder.loop_exit_stack.last().copied() builder.scope_ctx.loop_exit_stack.last().copied()
} }
/// Returns true if the builder is currently inside at least one loop context. /// Returns true if the builder is currently inside at least one loop context.
#[allow(dead_code)] #[allow(dead_code)]
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn in_loop(builder: &super::MirBuilder) -> bool { pub(crate) fn in_loop(builder: &super::MirBuilder) -> bool {
!builder.loop_header_stack.is_empty() !builder.scope_ctx.loop_header_stack.is_empty()
} }
/// Current loop nesting depth (0 means not in a loop). /// Current loop nesting depth (0 means not in a loop).
#[allow(dead_code)] #[allow(dead_code)]
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn depth(builder: &super::MirBuilder) -> usize { pub(crate) fn depth(builder: &super::MirBuilder) -> usize {
builder.loop_header_stack.len() builder.scope_ctx.loop_header_stack.len()
} }
/// Add predecessor edge metadata to a basic block. /// Add predecessor edge metadata to a basic block.
@ -55,7 +55,7 @@ pub(crate) fn add_predecessor(
block: BasicBlockId, block: BasicBlockId,
pred: BasicBlockId, pred: BasicBlockId,
) -> Result<(), String> { ) -> Result<(), String> {
if let Some(ref mut function) = builder.current_function { if let Some(ref mut function) = builder.scope_ctx.current_function {
// 📦 Hotfix 6: Ensure block exists (same as start_new_block logic) // 📦 Hotfix 6: Ensure block exists (same as start_new_block logic)
// Create block if not present, without changing current_block // Create block if not present, without changing current_block
if !function.blocks.contains_key(&block) { if !function.blocks.contains_key(&block) {

View File

@ -136,7 +136,7 @@ impl super::MirBuilder {
} else { } else {
// guard中は従来のBinOp // guard中は従来のBinOp
if let (Some(func), Some(cur_bb)) = if let (Some(func), Some(cur_bb)) =
(self.current_function.as_mut(), self.current_block) (self.scope_ctx.current_function.as_mut(), self.current_block)
{ {
crate::mir::ssot::binop_lower::emit_binop_to_dst( crate::mir::ssot::binop_lower::emit_binop_to_dst(
func, cur_bb, dst, op, lhs, rhs, func, cur_bb, dst, op, lhs, rhs,
@ -149,7 +149,7 @@ impl super::MirBuilder {
} else { } else {
// 既存の算術経路 // 既存の算術経路
if let (Some(func), Some(cur_bb)) = if let (Some(func), Some(cur_bb)) =
(self.current_function.as_mut(), self.current_block) (self.scope_ctx.current_function.as_mut(), self.current_block)
{ {
crate::mir::ssot::binop_lower::emit_binop_to_dst( crate::mir::ssot::binop_lower::emit_binop_to_dst(
func, cur_bb, dst, op, lhs, rhs, func, cur_bb, dst, op, lhs, rhs,
@ -201,7 +201,7 @@ impl super::MirBuilder {
} else { } else {
// 既存の算術経路 // 既存の算術経路
if let (Some(func), Some(cur_bb)) = if let (Some(func), Some(cur_bb)) =
(self.current_function.as_mut(), self.current_block) (self.scope_ctx.current_function.as_mut(), self.current_block)
{ {
crate::mir::ssot::binop_lower::emit_binop_to_dst( crate::mir::ssot::binop_lower::emit_binop_to_dst(
func, cur_bb, dst, op, lhs, rhs, func, cur_bb, dst, op, lhs, rhs,
@ -392,7 +392,7 @@ impl super::MirBuilder {
let rhs_false_exit = self.current_block()?; let rhs_false_exit = self.current_block()?;
// join rhs result into a single bool // join rhs result into a single bool
self.start_new_block(rhs_join)?; self.start_new_block(rhs_join)?;
if let Some(func) = self.current_function.as_mut() { if let Some(func) = self.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?; let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
@ -446,7 +446,7 @@ impl super::MirBuilder {
let rhs_false_exit = self.current_block()?; let rhs_false_exit = self.current_block()?;
// join rhs result into a single bool // join rhs result into a single bool
self.start_new_block(rhs_join)?; self.start_new_block(rhs_join)?;
if let Some(func) = self.current_function.as_mut() { if let Some(func) = self.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?; let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
@ -476,7 +476,7 @@ impl super::MirBuilder {
inputs.push((else_exit_block, else_value_raw)); inputs.push((else_exit_block, else_value_raw));
} }
let result_val = if inputs.len() >= 2 { let result_val = if inputs.len() >= 2 {
if let Some(func) = self.current_function.as_mut() { if let Some(func) = self.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
let dst = self.insert_phi(inputs)?; let dst = self.insert_phi(inputs)?;

View File

@ -12,7 +12,7 @@ pub(crate) fn annotate_me_origin(builder: &mut MirBuilder, me_id: ValueId) {
} }
} }
if cls.is_none() { if cls.is_none() {
if let Some(ref fun) = builder.current_function { if let Some(ref fun) = builder.scope_ctx.current_function {
if let Some(dot) = fun.signature.name.find('.') { if let Some(dot) = fun.signature.name.find('.') {
let c = fun.signature.name[..dot].to_string(); let c = fun.signature.name[..dot].to_string();
if !c.is_empty() { if !c.is_empty() {

View File

@ -67,10 +67,10 @@ impl MirBuilder {
self.variable_map.insert(pin_name.clone(), v); self.variable_map.insert(pin_name.clone(), v);
} }
_ => { _ => {
if let Some(func) = self.current_function.as_mut() { if let Some(func) = self.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
if let (Some(func), Some(cur_bb)) = (&self.current_function, self.current_block) if let (Some(func), Some(cur_bb)) = (&self.scope_ctx.current_function, self.current_block)
{ {
crate::mir::phi_core::common::debug_verify_phi_inputs( crate::mir::phi_core::common::debug_verify_phi_inputs(
func, cur_bb, &inputs, func, cur_bb, &inputs,
@ -78,7 +78,7 @@ impl MirBuilder {
} }
let merged = self.next_value_id(); let merged = self.next_value_id();
if let (Some(func), Some(cur_bb)) = if let (Some(func), Some(cur_bb)) =
(self.current_function.as_mut(), self.current_block) (self.scope_ctx.current_function.as_mut(), self.current_block)
{ {
crate::mir::ssot::cf_common::insert_phi_at_head_spanned( crate::mir::ssot::cf_common::insert_phi_at_head_spanned(
func, func,
@ -169,10 +169,10 @@ impl MirBuilder {
return Ok(inputs[0].1); return Ok(inputs[0].1);
} }
_ => { _ => {
if let Some(func) = self.current_function.as_mut() { if let Some(func) = self.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
if let (Some(func), Some(cur_bb)) = (&self.current_function, self.current_block) if let (Some(func), Some(cur_bb)) = (&self.scope_ctx.current_function, self.current_block)
{ {
crate::mir::phi_core::common::debug_verify_phi_inputs( crate::mir::phi_core::common::debug_verify_phi_inputs(
func, cur_bb, &inputs, func, cur_bb, &inputs,
@ -202,10 +202,10 @@ impl MirBuilder {
return Ok(inputs[0].1); return Ok(inputs[0].1);
} }
_ => { _ => {
if let Some(func) = self.current_function.as_mut() { if let Some(func) = self.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
if let (Some(func), Some(cur_bb)) = (&self.current_function, self.current_block) if let (Some(func), Some(cur_bb)) = (&self.scope_ctx.current_function, self.current_block)
{ {
crate::mir::phi_core::common::debug_verify_phi_inputs( crate::mir::phi_core::common::debug_verify_phi_inputs(
func, cur_bb, &inputs, func, cur_bb, &inputs,

View File

@ -86,11 +86,11 @@ impl<'a> PhiMergeHelper<'a> {
} }
_ => { _ => {
// Multiple predecessors - insert PHI // Multiple predecessors - insert PHI
if let Some(func) = self.builder.current_function.as_mut() { if let Some(func) = self.builder.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
if let (Some(func), Some(cur_bb)) = if let (Some(func), Some(cur_bb)) =
(&self.builder.current_function, self.builder.current_block) (&self.builder.scope_ctx.current_function, self.builder.current_block)
{ {
crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs); crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs);
} }
@ -132,11 +132,11 @@ impl<'a> PhiMergeHelper<'a> {
} }
_ => { _ => {
// Insert PHI with explicit dst // Insert PHI with explicit dst
if let Some(func) = self.builder.current_function.as_mut() { if let Some(func) = self.builder.scope_ctx.current_function.as_mut() {
func.update_cfg(); func.update_cfg();
} }
if let (Some(func), Some(cur_bb)) = if let (Some(func), Some(cur_bb)) =
(&self.builder.current_function, self.builder.current_block) (&self.builder.scope_ctx.current_function, self.builder.current_block)
{ {
crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs); crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs);
} }

View File

@ -64,7 +64,7 @@ impl BlockScheduleBox {
if std::env::var("NYASH_BLOCK_SCHEDULE_VERIFY").ok().as_deref() != Some("1") { if std::env::var("NYASH_BLOCK_SCHEDULE_VERIFY").ok().as_deref() != Some("1") {
return; return;
} }
let (f_opt, bb_opt) = (builder.current_function.as_ref(), builder.current_block); let (f_opt, bb_opt) = (builder.scope_ctx.current_function.as_ref(), builder.current_block);
let (Some(fun), Some(bb_id)) = (f_opt, bb_opt) else { let (Some(fun), Some(bb_id)) = (f_opt, bb_opt) else {
return; return;
}; };

View File

@ -181,7 +181,7 @@ impl super::MirBuilder {
idx + 1, idx + 1,
total, total,
self.current_block, self.current_block,
self.current_function self.scope_ctx.current_function
.as_ref() .as_ref()
.map(|f| f.signature.name.as_str()) .map(|f| f.signature.name.as_str())
.unwrap_or("none") .unwrap_or("none")

View File

@ -38,7 +38,7 @@ impl super::MirBuilder {
#[allow(deprecated)] #[allow(deprecated)]
pub(crate) fn next_value_id(&mut self) -> super::ValueId { pub(crate) fn next_value_id(&mut self) -> super::ValueId {
loop { loop {
let candidate = if let Some(ref mut f) = self.current_function { let candidate = if let Some(ref mut f) = self.scope_ctx.current_function {
f.next_value_id() // Function context f.next_value_id() // Function context
} else { } else {
// Phase 136 Step 2/7 + Phase 2-2: Use core_ctx as SSOT (no sync needed) // Phase 136 Step 2/7 + Phase 2-2: Use core_ctx as SSOT (no sync needed)
@ -92,7 +92,7 @@ impl super::MirBuilder {
} }
/// Ensure a basic block exists in the current function /// Ensure a basic block exists in the current function
pub(crate) fn ensure_block_exists(&mut self, block_id: BasicBlockId) -> Result<(), String> { pub(crate) fn ensure_block_exists(&mut self, block_id: BasicBlockId) -> Result<(), String> {
if let Some(ref mut function) = self.current_function { if let Some(ref mut function) = self.scope_ctx.current_function {
if !function.blocks.contains_key(&block_id) { if !function.blocks.contains_key(&block_id) {
let block = BasicBlock::new(block_id); let block = BasicBlock::new(block_id);
function.add_block(block); function.add_block(block);
@ -105,7 +105,7 @@ impl super::MirBuilder {
/// Start a new basic block and set as current /// Start a new basic block and set as current
pub(crate) fn start_new_block(&mut self, block_id: BasicBlockId) -> Result<(), String> { pub(crate) fn start_new_block(&mut self, block_id: BasicBlockId) -> Result<(), String> {
if let Some(ref mut function) = self.current_function { if let Some(ref mut function) = self.scope_ctx.current_function {
if !function.blocks.contains_key(&block_id) { if !function.blocks.contains_key(&block_id) {
function.add_block(BasicBlock::new(block_id)); function.add_block(BasicBlock::new(block_id));
} }
@ -440,7 +440,7 @@ impl super::MirBuilder {
let slot_id = self.core_ctx.next_temp_slot(); let slot_id = self.core_ctx.next_temp_slot();
let slot_name = format!("__pin${}${}", slot_id, hint); let slot_name = format!("__pin${}${}", slot_id, hint);
// Phase 25.1b: Use function-local ID allocator to avoid SSA verification failures // Phase 25.1b: Use function-local ID allocator to avoid SSA verification failures
let dst = if let Some(ref mut f) = self.current_function { let dst = if let Some(ref mut f) = self.scope_ctx.current_function {
f.next_value_id() // Function context: use local ID f.next_value_id() // Function context: use local ID
} else { } else {
self.core_ctx.next_value() // Module context: use core_ctx SSOT self.core_ctx.next_value() // Module context: use core_ctx SSOT
@ -471,7 +471,7 @@ impl super::MirBuilder {
v: super::ValueId, v: super::ValueId,
) -> Result<super::ValueId, String> { ) -> Result<super::ValueId, String> {
// Phase 25.1b: Use function-local ID allocator to avoid SSA verification failures // Phase 25.1b: Use function-local ID allocator to avoid SSA verification failures
let dst = if let Some(ref mut f) = self.current_function { let dst = if let Some(ref mut f) = self.scope_ctx.current_function {
f.next_value_id() // Function context: use local ID f.next_value_id() // Function context: use local ID
} else { } else {
self.core_ctx.next_value() // Module context: use core_ctx SSOT self.core_ctx.next_value() // Module context: use core_ctx SSOT
@ -489,7 +489,7 @@ impl super::MirBuilder {
dst: super::ValueId, dst: super::ValueId,
src: super::ValueId, src: super::ValueId,
) -> Result<(), String> { ) -> Result<(), String> {
if let (Some(ref mut function), Some(bb)) = (&mut self.current_function, self.current_block) if let (Some(ref mut function), Some(bb)) = (&mut self.scope_ctx.current_function, self.current_block)
{ {
if std::env::var("NYASH_SCHEDULE_TRACE").ok().as_deref() == Some("1") { if std::env::var("NYASH_SCHEDULE_TRACE").ok().as_deref() == Some("1") {
eprintln!( eprintln!(

View File

@ -116,9 +116,6 @@ impl super::super::MirBuilder {
self.binding_ctx.insert(name.to_string(), binding_id); self.binding_ctx.insert(name.to_string(), binding_id);
self.sync_binding_ctx_to_legacy(); self.sync_binding_ctx_to_legacy();
// Sync to legacy field
self.sync_scope_ctx_to_legacy();
Ok(()) Ok(())
} }
} }