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
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
pub(super) current_block: Option<BasicBlockId>,
@ -139,11 +134,6 @@ pub struct MirBuilder {
#[deprecated(note = "Use variable_ctx.variable_map instead")]
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
#[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<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", ...])
/// 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<String, super::BindingId>,
// 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使用
// ---- 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<String>,
/// 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)]

View File

@ -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(|| "<none>".to_string());

View File

@ -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<MirType>)> = 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<MirType> = 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<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 改訂版:
// 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<MirType> = 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;

View File

@ -26,7 +26,7 @@ pub(super) fn build_exit_phi(
) -> Result<(Option<ValueId>, BTreeMap<String, ValueId>), String> {
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);
// 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)
// 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,

View File

@ -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,

View File

@ -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("<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,
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 {

View File

@ -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 })?;

View File

@ -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,

View File

@ -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<BasicBlockId> {
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();

View File

@ -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 で発生する型欠如を解消する。

View File

@ -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<BasicBlockId> {
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<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.
#[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) {

View File

@ -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)?;

View File

@ -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() {

View File

@ -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,

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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")

View File

@ -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<super::ValueId, String> {
// 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!(

View File

@ -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(())
}
}