From 7235fe62e9e543cca5213b8276165ab890dfe8ba Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Mon, 15 Dec 2025 23:41:30 +0900 Subject: [PATCH] refactor(mir): Remove ScopeContext legacy fields (Phase 2-4/7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完全移行→削除の安全順序(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%) --- src/mir/builder.rs | 66 ------------------- src/mir/builder/calls/build.rs | 2 +- src/mir/builder/calls/lowering.rs | 53 +++++++-------- .../joinir/merge/exit_phi_builder.rs | 2 +- .../joinir/merge/instruction_rewriter.rs | 6 +- .../builder/control_flow/joinir/merge/mod.rs | 2 +- src/mir/builder/control_flow/mod.rs | 2 +- src/mir/builder/emission/branch.rs | 4 +- src/mir/builder/emission/compare.rs | 2 +- src/mir/builder/exprs_peek.rs | 4 +- src/mir/builder/if_form.rs | 8 +-- src/mir/builder/lifecycle.rs | 12 ++-- src/mir/builder/loops.rs | 18 ++--- src/mir/builder/ops.rs | 12 ++-- src/mir/builder/origin/infer.rs | 2 +- src/mir/builder/phi.rs | 14 ++-- src/mir/builder/phi_merge.rs | 8 +-- src/mir/builder/schedule/block.rs | 2 +- src/mir/builder/stmts.rs | 2 +- src/mir/builder/utils.rs | 12 ++-- src/mir/builder/vars/lexical_scope.rs | 3 - 21 files changed, 78 insertions(+), 158 deletions(-) diff --git a/src/mir/builder.rs b/src/mir/builder.rs index 58977555..817130fb 100644 --- a/src/mir/builder.rs +++ b/src/mir/builder.rs @@ -78,11 +78,6 @@ pub struct MirBuilder { /// Current module being built pub(super) current_module: Option, - /// [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, - /// Current basic block being built pub(super) current_block: Option, @@ -139,11 +134,6 @@ pub struct MirBuilder { #[deprecated(note = "Use variable_ctx.variable_map instead")] pub(super) variable_map: BTreeMap, - /// [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, - /// Pending phi functions to be inserted #[allow(dead_code)] pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>, @@ -198,11 +188,6 @@ pub struct MirBuilder { #[deprecated(note = "Use comp_ctx.static_method_index instead")] pub(super) static_method_index: std::collections::HashMap>, - /// [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, - /// [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) #[deprecated(note = "Use comp_ctx.method_tail_index instead")] @@ -233,19 +218,6 @@ pub struct MirBuilder { pub binding_map: BTreeMap, // 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, - #[allow(dead_code)] - #[deprecated(note = "Use scope_ctx.loop_exit_stack instead")] - pub(super) loop_exit_stack: Vec, - - /// [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, - // フェーズM: no_phi_modeフィールド削除(常にPHI使用) // ---- Try/Catch/Cleanup lowering context ---- @@ -270,10 +242,6 @@ pub struct MirBuilder { // ---------------------- // 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, /// Local SSA cache: ensure per-block materialization for critical operands (e.g., recv) /// Key: (bb, original ValueId, kind) -> local ValueId @@ -323,7 +291,6 @@ impl MirBuilder { #[allow(deprecated)] Self { current_module: None, - current_function: None, current_block: None, // 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 comp_ctx, // Phase 136 Step 7/7: Compilation context variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat) - lexical_scope_stack: Vec::new(), pending_phis: Vec::new(), user_defined_boxes: HashSet::new(), weak_fields_by_box: HashMap::new(), @@ -349,7 +315,6 @@ impl MirBuilder { plugin_method_sigs, current_static_box: None, static_method_index: std::collections::HashMap::new(), - function_param_names: HashSet::new(), method_tail_index: std::collections::HashMap::new(), method_tail_index_source_len: 0, @@ -358,9 +323,6 @@ impl MirBuilder { 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フィールド削除 return_defer_active: false, return_defer_slot: None, @@ -371,9 +333,6 @@ impl MirBuilder { cleanup_allow_throw: false, suppress_pin_entry_copy_next: false, - // Debug scope context - debug_scope_stack: Vec::new(), - local_ssa_map: HashMap::new(), schedule_mat_map: 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 ---- /// Sync binding_ctx changes back to legacy fields (backward compatibility) #[allow(deprecated)] diff --git a/src/mir/builder/calls/build.rs b/src/mir/builder/calls/build.rs index 42a3405f..90841636 100644 --- a/src/mir/builder/calls/build.rs +++ b/src/mir/builder/calls/build.rs @@ -21,7 +21,7 @@ impl MirBuilder { // Dev trace if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") { let cur_fun = self - .current_function + .scope_ctx.current_function .as_ref() .map(|f| f.signature.name.clone()) .unwrap_or_else(|| "".to_string()); diff --git a/src/mir/builder/calls/lowering.rs b/src/mir/builder/calls/lowering.rs index ec927d8b..c452cd18 100644 --- a/src/mir/builder/calls/lowering.rs +++ b/src/mir/builder/calls/lowering.rs @@ -79,9 +79,8 @@ impl MirBuilder { let entry = self.next_block_id(); 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(); - self.current_function = None; ctx.saved_block = self.current_block.take(); eprintln!( @@ -90,9 +89,8 @@ impl MirBuilder { ); eprintln!("[DEBUG/create_function_skeleton] Entry block: {:?}", entry); - // Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat) - self.scope_ctx.current_function = Some(function.clone()); - self.current_function = Some(function); + // Phase 136 Step 3/7: Use scope_ctx as SSOT + self.scope_ctx.current_function = Some(function); self.current_block = Some(entry); // 新しい関数スコープ用の SlotRegistry を準備するよ(観測専用) self.current_slot_registry = Some(FunctionSlotRegistry::new()); @@ -107,15 +105,14 @@ impl MirBuilder { /// 🎯 箱理論: Step 3 - パラメータ設定 #[allow(deprecated)] 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.function_param_names.clear(); // SlotRegistry 更新は borrow 競合を避けるため、まずローカルに集約してから反映するよ。 let mut slot_regs: Vec<(String, Option)> = Vec::new(); // Phase 26-A-3: パラメータ型情報も後で一括登録(借用競合回避) 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() // Static methods have implicit receiver at params[0], so actual parameters start at offset let receiver_offset = if f.params.is_empty() { @@ -143,9 +140,8 @@ impl MirBuilder { new_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.function_param_names.insert(p.clone()); // Phase 26-A-3: パラメータ型情報を収集(後で一括登録) // param_idx: receiver offset を考慮した実際のパラメータインデックス @@ -183,7 +179,7 @@ impl MirBuilder { fn finalize_function(&mut self, returns_value: bool) -> Result<(), String> { // Void return追加(必要な場合) 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 !block.is_terminated() { 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) { let mut inferred: Option = None; @@ -223,9 +219,8 @@ impl MirBuilder { } // Moduleに追加 - // Phase 136 Step 3/7: Take from legacy field, sync to scope_ctx - let finalized = self.current_function.take().unwrap(); - self.scope_ctx.current_function = None; + // Phase 136 Step 3/7: Take from scope_ctx (SSOT) + let finalized = self.scope_ctx.current_function.take().unwrap(); if let Some(ref mut module) = self.current_module { module.add_function(finalized); } @@ -235,9 +230,8 @@ impl MirBuilder { /// 🎯 箱理論: Step 6 - Context復元 fn restore_lowering_context(&mut self, ctx: LoweringContext) { - // Phase 136 Step 3/7: Restore to scope_ctx (SSOT), sync to legacy field - self.scope_ctx.current_function = ctx.saved_function.clone(); - self.current_function = ctx.saved_function; + // Phase 136 Step 3/7: Restore to scope_ctx (SSOT) + self.scope_ctx.current_function = ctx.saved_function; self.current_block = ctx.saved_block; // モード別にcontext復元 @@ -272,14 +266,12 @@ impl MirBuilder { let entry = self.next_block_id(); 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(); - self.current_function = None; ctx.saved_block = self.current_block.take(); - // Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat) - self.scope_ctx.current_function = Some(function.clone()); - self.current_function = Some(function); + // Phase 136 Step 3/7: Use scope_ctx as SSOT + self.scope_ctx.current_function = Some(function); self.current_block = Some(entry); // instance method 用の関数スコープ SlotRegistry もここで用意するよ。 self.current_slot_registry = Some(FunctionSlotRegistry::new()); @@ -296,7 +288,7 @@ impl MirBuilder { // SlotRegistry 更新はローカルバッファに集約してから反映するよ。 let mut slot_regs: Vec<(String, Option)> = Vec::new(); - if let Some(ref mut f) = self.current_function { + if let Some(ref mut f) = self.scope_ctx.current_function { // 📦 Hotfix 6 改訂版: // MirFunction::new() が既に 0..N の ValueId を params 用に予約しているので、 // ここではそれを「上書き使用」するだけにして、push で二重定義しないようにするよ。 @@ -377,7 +369,7 @@ impl MirBuilder { self.lower_function_body(body)?; // 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) } else { false @@ -427,7 +419,7 @@ impl MirBuilder { self.lower_method_body(body)?; // 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) } else { false @@ -442,7 +434,7 @@ impl MirBuilder { } // 型推論(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) { let mut inferred: Option = None; @@ -469,7 +461,7 @@ impl MirBuilder { } // 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 { module.add_function(finalized_function); } @@ -477,9 +469,8 @@ impl MirBuilder { // FunctionRegion を 1 段ポップして元の関数コンテキストに戻るよ。 crate::mir::region::observer::pop_function_region(self); - // Phase 136 Step 3/7: Restore to scope_ctx (SSOT), sync to legacy field - self.scope_ctx.current_function = ctx.saved_function.clone(); - self.current_function = ctx.saved_function; + // Phase 136 Step 3/7: Restore to scope_ctx (SSOT) + self.scope_ctx.current_function = ctx.saved_function; self.current_block = ctx.saved_block; if let Some(saved) = ctx.saved_var_map { self.variable_map = saved; diff --git a/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs b/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs index 45f9a2d2..b647953b 100644 --- a/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs +++ b/src/mir/builder/control_flow/joinir/merge/exit_phi_builder.rs @@ -26,7 +26,7 @@ pub(super) fn build_exit_phi( ) -> Result<(Option, BTreeMap), String> { let mut carrier_phis: BTreeMap = 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); // Phase 189-Fix: If we collected return values, create a PHI in exit block diff --git a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs index df0f4fb8..ac9ea9ec 100644 --- a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs +++ b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs @@ -149,7 +149,7 @@ pub(super) fn merge_and_rewrite( // Phase 195 FIX: Reuse existing block if present (preserves PHI from JoinIR Select lowering) // 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 .blocks .remove(&new_block_id) @@ -811,7 +811,7 @@ pub(super) fn merge_and_rewrite( } // 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); } } @@ -866,7 +866,7 @@ pub(super) fn merge_and_rewrite( // Use BoundaryInjector to inject Copy instructions // 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( current_func, entry_block_remapped, diff --git a/src/mir/builder/control_flow/joinir/merge/mod.rs b/src/mir/builder/control_flow/joinir/merge/mod.rs index dd227c31..68dc3e15 100644 --- a/src/mir/builder/control_flow/joinir/merge/mod.rs +++ b/src/mir/builder/control_flow/joinir/merge/mod.rs @@ -733,7 +733,7 @@ pub(in crate::mir::builder) fn merge_joinir_mir_blocks( #[cfg(debug_assertions)] { 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( func, entry_block, diff --git a/src/mir/builder/control_flow/mod.rs b/src/mir/builder/control_flow/mod.rs index 4aa94b30..ce6ca768 100644 --- a/src/mir/builder/control_flow/mod.rs +++ b/src/mir/builder/control_flow/mod.rs @@ -115,7 +115,7 @@ impl super::MirBuilder { "Loop lowering failed: JoinIR does not support this pattern, and LoopBuilder has been removed.\n\ Function: {}\n\ 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("") + self.scope_ctx.current_function.as_ref().map(|f| f.signature.name.as_str()).unwrap_or("") ))); } diff --git a/src/mir/builder/emission/branch.rs b/src/mir/builder/emission/branch.rs index 5948653b..7351b015 100644 --- a/src/mir/builder/emission/branch.rs +++ b/src/mir/builder/emission/branch.rs @@ -10,7 +10,7 @@ pub fn emit_conditional( then_bb: BasicBlockId, else_bb: 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_branch(func, cur_bb, cond, then_bb, else_bb); Ok(()) } else { @@ -24,7 +24,7 @@ pub fn emit_conditional( #[inline] 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); Ok(()) } else { diff --git a/src/mir/builder/emission/compare.rs b/src/mir/builder/emission/compare.rs index d5a9516d..718bf248 100644 --- a/src/mir/builder/emission/compare.rs +++ b/src/mir/builder/emission/compare.rs @@ -11,7 +11,7 @@ pub fn emit_to( lhs: ValueId, rhs: ValueId, ) -> 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); } else { b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?; diff --git a/src/mir/builder/exprs_peek.rs b/src/mir/builder/exprs_peek.rs index 14de952e..1457debf 100644 --- a/src/mir/builder/exprs_peek.rs +++ b/src/mir/builder/exprs_peek.rs @@ -22,7 +22,7 @@ impl super::MirBuilder { // Jump from current block to dispatch (ensure terminator exists) let need_jump = { 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) { !bb.is_terminated() } else { @@ -118,7 +118,7 @@ impl super::MirBuilder { // Merge and yield result self.start_new_block(merge_block)?; // フェーズ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( func, cur_bb, diff --git a/src/mir/builder/if_form.rs b/src/mir/builder/if_form.rs index bdcc8093..6a4084a8 100644 --- a/src/mir/builder/if_form.rs +++ b/src/mir/builder/if_form.rs @@ -23,7 +23,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> { ) -> Result<(), String> { // merge ブロックの先頭に PHI を挿入 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( func, @@ -47,7 +47,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> { } fn get_block_predecessors(&self, block: BasicBlockId) -> Vec { - if let Some(ref func) = self.0.current_function { + if let Some(ref func) = self.0.scope_ctx.current_function { func.blocks .get(&block) .map(|bb| bb.predecessors.iter().copied().collect()) @@ -72,7 +72,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> { } 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) } else { false @@ -239,7 +239,7 @@ impl MirBuilder { core_mainline || (joinir_enabled && is_target && (joinir_toplevel || joinir_dryrun)); if should_try_joinir { - if let Some(ref func) = self.current_function { + if let Some(ref func) = self.scope_ctx.current_function { let context = crate::mir::join_ir::lowering::if_phi_context::IfPhiContext::pure_if(); diff --git a/src/mir/builder/lifecycle.rs b/src/mir/builder/lifecycle.rs index 6896de4a..d174a3f8 100644 --- a/src/mir/builder/lifecycle.rs +++ b/src/mir/builder/lifecycle.rs @@ -118,9 +118,8 @@ impl super::MirBuilder { main_function.metadata.is_entry_point = true; self.current_module = Some(module); - // Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat) - self.scope_ctx.current_function = Some(main_function.clone()); - self.current_function = Some(main_function); + // Phase 136 Step 3/7: Use scope_ctx as SSOT + self.scope_ctx.current_function = Some(main_function); self.current_block = Some(entry_block); // 関数スコープの SlotRegistry を初期化するよ(観測専用)。 @@ -293,7 +292,7 @@ impl super::MirBuilder { // Hint: scope leave at function end (id=0 for main) self.hint_scope_leave(0); 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 !block.is_terminated() { block.add_instruction(MirInstruction::Return { @@ -308,9 +307,8 @@ impl super::MirBuilder { } let mut module = self.current_module.take().unwrap(); - // Phase 136 Step 3/7: Take from legacy field, sync to scope_ctx - let mut function = self.current_function.take().unwrap(); - self.scope_ctx.current_function = None; + // Phase 136 Step 3/7: Take from scope_ctx (SSOT) + let mut function = self.scope_ctx.current_function.take().unwrap(); // Phase 84-2: Copy命令型伝播(return型推論の前に実行) // // Loop exit や If merge の edge copy で発生する型欠如を解消する。 diff --git a/src/mir/builder/loops.rs b/src/mir/builder/loops.rs index dc66cb64..fddd472c 100644 --- a/src/mir/builder/loops.rs +++ b/src/mir/builder/loops.rs @@ -8,42 +8,42 @@ pub(crate) fn push_loop_context( header: BasicBlockId, exit: BasicBlockId, ) { - builder.loop_header_stack.push(header); - builder.loop_exit_stack.push(exit); + builder.scope_ctx.loop_header_stack.push(header); + builder.scope_ctx.loop_exit_stack.push(exit); } /// Pop loop context (header/exit) from the MirBuilder stacks. #[allow(dead_code)] pub(crate) fn pop_loop_context(builder: &mut super::MirBuilder) { - let _ = builder.loop_header_stack.pop(); - let _ = builder.loop_exit_stack.pop(); + let _ = builder.scope_ctx.loop_header_stack.pop(); + let _ = builder.scope_ctx.loop_exit_stack.pop(); } /// Peek current loop header block id #[allow(dead_code)] #[allow(dead_code)] pub(crate) fn current_header(builder: &super::MirBuilder) -> Option { - builder.loop_header_stack.last().copied() + builder.scope_ctx.loop_header_stack.last().copied() } /// Peek current loop exit block id #[allow(dead_code)] pub(crate) fn current_exit(builder: &super::MirBuilder) -> Option { - 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. #[allow(dead_code)] #[allow(dead_code)] 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). #[allow(dead_code)] #[allow(dead_code)] 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. @@ -55,7 +55,7 @@ pub(crate) fn add_predecessor( block: BasicBlockId, pred: BasicBlockId, ) -> 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) // Create block if not present, without changing current_block if !function.blocks.contains_key(&block) { diff --git a/src/mir/builder/ops.rs b/src/mir/builder/ops.rs index 01839f67..1211f81b 100644 --- a/src/mir/builder/ops.rs +++ b/src/mir/builder/ops.rs @@ -136,7 +136,7 @@ impl super::MirBuilder { } else { // guard中は従来のBinOp 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( func, cur_bb, dst, op, lhs, rhs, @@ -149,7 +149,7 @@ impl super::MirBuilder { } else { // 既存の算術経路 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( func, cur_bb, dst, op, lhs, rhs, @@ -201,7 +201,7 @@ impl super::MirBuilder { } else { // 既存の算術経路 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( func, cur_bb, dst, op, lhs, rhs, @@ -392,7 +392,7 @@ impl super::MirBuilder { let rhs_false_exit = self.current_block()?; // join rhs result into a single bool 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(); } 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()?; // join rhs result into a single bool 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(); } 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)); } 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(); } let dst = self.insert_phi(inputs)?; diff --git a/src/mir/builder/origin/infer.rs b/src/mir/builder/origin/infer.rs index 6a2e1fb2..49645bf9 100644 --- a/src/mir/builder/origin/infer.rs +++ b/src/mir/builder/origin/infer.rs @@ -12,7 +12,7 @@ pub(crate) fn annotate_me_origin(builder: &mut MirBuilder, me_id: ValueId) { } } 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('.') { let c = fun.signature.name[..dot].to_string(); if !c.is_empty() { diff --git a/src/mir/builder/phi.rs b/src/mir/builder/phi.rs index cdda9c9b..35d0ef37 100644 --- a/src/mir/builder/phi.rs +++ b/src/mir/builder/phi.rs @@ -67,10 +67,10 @@ impl MirBuilder { 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(); } - 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( func, cur_bb, &inputs, @@ -78,7 +78,7 @@ impl MirBuilder { } let merged = self.next_value_id(); 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( func, @@ -169,10 +169,10 @@ impl MirBuilder { 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(); } - 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( func, cur_bb, &inputs, @@ -202,10 +202,10 @@ impl MirBuilder { 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(); } - 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( func, cur_bb, &inputs, diff --git a/src/mir/builder/phi_merge.rs b/src/mir/builder/phi_merge.rs index 0e05484e..ab1181d5 100644 --- a/src/mir/builder/phi_merge.rs +++ b/src/mir/builder/phi_merge.rs @@ -86,11 +86,11 @@ impl<'a> PhiMergeHelper<'a> { } _ => { // 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(); } 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); } @@ -132,11 +132,11 @@ impl<'a> PhiMergeHelper<'a> { } _ => { // 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(); } 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); } diff --git a/src/mir/builder/schedule/block.rs b/src/mir/builder/schedule/block.rs index 71f87855..2ec30c8d 100644 --- a/src/mir/builder/schedule/block.rs +++ b/src/mir/builder/schedule/block.rs @@ -64,7 +64,7 @@ impl BlockScheduleBox { if std::env::var("NYASH_BLOCK_SCHEDULE_VERIFY").ok().as_deref() != Some("1") { 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 { return; }; diff --git a/src/mir/builder/stmts.rs b/src/mir/builder/stmts.rs index fe98a9b5..acf42d6c 100644 --- a/src/mir/builder/stmts.rs +++ b/src/mir/builder/stmts.rs @@ -181,7 +181,7 @@ impl super::MirBuilder { idx + 1, total, self.current_block, - self.current_function + self.scope_ctx.current_function .as_ref() .map(|f| f.signature.name.as_str()) .unwrap_or("none") diff --git a/src/mir/builder/utils.rs b/src/mir/builder/utils.rs index a116e9fc..970ad55c 100644 --- a/src/mir/builder/utils.rs +++ b/src/mir/builder/utils.rs @@ -38,7 +38,7 @@ impl super::MirBuilder { #[allow(deprecated)] pub(crate) fn next_value_id(&mut self) -> super::ValueId { 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 } else { // 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 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) { let block = BasicBlock::new(block_id); function.add_block(block); @@ -105,7 +105,7 @@ impl super::MirBuilder { /// Start a new basic block and set as current 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) { 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_name = format!("__pin${}${}", slot_id, hint); // 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 } else { self.core_ctx.next_value() // Module context: use core_ctx SSOT @@ -471,7 +471,7 @@ impl super::MirBuilder { v: super::ValueId, ) -> Result { // 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 } else { self.core_ctx.next_value() // Module context: use core_ctx SSOT @@ -489,7 +489,7 @@ impl super::MirBuilder { dst: super::ValueId, src: super::ValueId, ) -> 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") { eprintln!( diff --git a/src/mir/builder/vars/lexical_scope.rs b/src/mir/builder/vars/lexical_scope.rs index 424edfcb..fb61ac38 100644 --- a/src/mir/builder/vars/lexical_scope.rs +++ b/src/mir/builder/vars/lexical_scope.rs @@ -116,9 +116,6 @@ impl super::super::MirBuilder { self.binding_ctx.insert(name.to_string(), binding_id); self.sync_binding_ctx_to_legacy(); - // Sync to legacy field - self.sync_scope_ctx_to_legacy(); - Ok(()) } }