feat(mir): Phase 136 Step 3/7 - ScopeContext extraction
## Summary Extract scope and control flow management into ScopeContext for better organization. ## Changes - **New file**: src/mir/builder/scope_context.rs (264 lines) - Lexical scope stack management - Control flow stacks (loop/if) - Function context tracking - Debug scope helpers - **Updated**: src/mir/builder.rs - Add scope_ctx field - Mark legacy fields as deprecated - Add sync helpers (sync_scope_ctx_to_legacy, sync_legacy_to_scope_ctx) - **Updated**: src/mir/builder/vars/lexical_scope.rs - Use scope_ctx as SSOT - Sync to legacy fields for backward compat - **Updated**: src/mir/builder/lifecycle.rs - Sync current_function via scope_ctx - **Updated**: src/mir/builder/calls/lowering.rs - Sync function context in lowering flow ## Extracted Fields (7) 1. lexical_scope_stack - Block-scoped locals 2. loop_header_stack - Loop headers for break/continue 3. loop_exit_stack - Loop exit blocks 4. if_merge_stack - If merge blocks 5. current_function - Currently building function 6. function_param_names - Function parameters (for LoopForm) 7. debug_scope_stack - Debug region identifiers ## Test Results - ✅ cargo build --release (291 warnings - deprecated usage) - ✅ cargo test --release --lib - 1005/1009 PASS - ✅ phase135_trim_mir_verify.sh - PASS - ⚠️ phase132_exit_phi_parity.sh - Error (pre-existing issue) ## Progress Phase 136: 3/7 Contexts complete (TypeContext, CoreContext, ScopeContext) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -53,6 +53,7 @@ mod router; // RouterPolicyBox(Unified vs BoxCall)
|
||||
mod schedule; // BlockScheduleBox(物理順序: PHI→materialize→body)
|
||||
mod ssa; // LocalSSA helpers (in-block materialization)
|
||||
mod stmts;
|
||||
mod scope_context; // Phase 136 follow-up (Step 3/7): ScopeContext extraction
|
||||
mod type_context; // Phase 136 follow-up: TypeContext extraction
|
||||
mod type_facts; // Phase 136 follow-up: Type inference facts box
|
||||
pub(crate) mod type_registry;
|
||||
@ -73,7 +74,9 @@ pub struct MirBuilder {
|
||||
/// Current module being built
|
||||
pub(super) current_module: Option<MirModule>,
|
||||
|
||||
/// Current function being built
|
||||
/// [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
|
||||
@ -104,15 +107,20 @@ pub struct MirBuilder {
|
||||
/// Direct field access for backward compatibility (migration in progress).
|
||||
pub(super) type_ctx: type_context::TypeContext,
|
||||
|
||||
/// Phase 136 follow-up (Step 3/7): Scope and control flow context
|
||||
/// Consolidates lexical_scope_stack, loop stacks, if_merge_stack, current_function,
|
||||
/// function_param_names, debug_scope_stack for better organization.
|
||||
/// Direct field access for backward compatibility (migration in progress).
|
||||
pub(super) scope_ctx: scope_context::ScopeContext,
|
||||
|
||||
/// Variable name to ValueId mapping (for SSA conversion)
|
||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
||||
/// Phase 25.1: HashMap → BTreeMap(PHI生成の決定性確保)
|
||||
pub(super) variable_map: BTreeMap<String, ValueId>,
|
||||
|
||||
/// Lexical scope stack for block-scoped `local` declarations.
|
||||
///
|
||||
/// This tracks per-block shadowing so `local x` inside `{...}` restores the
|
||||
/// outer binding when the block ends.
|
||||
/// [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
|
||||
@ -172,8 +180,9 @@ pub struct MirBuilder {
|
||||
/// Index of static methods seen during lowering: name -> [(BoxName, arity)]
|
||||
pub(super) static_method_index: std::collections::HashMap<String, Vec<(String, usize)>>,
|
||||
|
||||
/// Function parameter names (for LoopForm PHI construction)
|
||||
/// Tracks the original parameter names at function entry
|
||||
/// [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>,
|
||||
|
||||
/// Fast lookup: method+arity tail → candidate function names (e.g., ".str/0" → ["JsonNode.str/0", ...])
|
||||
@ -209,14 +218,17 @@ pub struct MirBuilder {
|
||||
pub binding_map: BTreeMap<String, super::BindingId>,
|
||||
|
||||
// include guards removed
|
||||
/// Loop context stacks for lowering break/continue inside nested control flow
|
||||
/// Top of stack corresponds to the innermost active loop
|
||||
/// [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>,
|
||||
|
||||
/// If/merge context stack (innermost first). Used to make merge targets explicit
|
||||
/// when lowering nested conditionals and to simplify jump generation.
|
||||
/// [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使用)
|
||||
@ -250,7 +262,9 @@ pub struct MirBuilder {
|
||||
// ----------------------
|
||||
// Debug scope context (dev only; zero-cost when unused)
|
||||
// ----------------------
|
||||
/// Stack of region identifiers like "loop#1/header" or "join#3/join".
|
||||
/// [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>,
|
||||
/// [DEPRECATED] Monotonic counter for region IDs (deterministic across a run).
|
||||
/// Phase 136: Moved to core_ctx.debug_join_counter (backward compat wrapper)
|
||||
@ -320,6 +334,7 @@ impl MirBuilder {
|
||||
|
||||
compilation_context: None, // 箱理論: デフォルトは従来モード
|
||||
type_ctx: type_context::TypeContext::new(), // Phase 136: Type context
|
||||
scope_ctx: scope_context::ScopeContext::new(), // Phase 136 Step 3/7: Scope context
|
||||
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保
|
||||
lexical_scope_stack: Vec::new(),
|
||||
pending_phis: Vec::new(),
|
||||
@ -396,11 +411,42 @@ impl MirBuilder {
|
||||
self.type_ctx.value_origin_newbox = self.value_origin_newbox.clone();
|
||||
}
|
||||
|
||||
// ---- 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();
|
||||
}
|
||||
|
||||
/// Push/pop helpers for If merge context (best-effort; optional usage)
|
||||
#[allow(deprecated)]
|
||||
pub(super) fn push_if_merge(&mut self, bb: BasicBlockId) {
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
self.scope_ctx.push_if_merge(bb);
|
||||
self.if_merge_stack.push(bb);
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
pub(super) fn pop_if_merge(&mut self) {
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
let _ = self.scope_ctx.pop_if_merge();
|
||||
let _ = self.if_merge_stack.pop();
|
||||
}
|
||||
|
||||
@ -467,18 +513,27 @@ impl MirBuilder {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub(crate) fn debug_push_region<S: Into<String>>(&mut self, region: S) {
|
||||
self.debug_scope_stack.push(region.into());
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
let region = region.into();
|
||||
self.scope_ctx.debug_push_region(region.clone());
|
||||
self.debug_scope_stack.push(region);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub(crate) fn debug_pop_region(&mut self) {
|
||||
// Phase 136 Step 3/7: Update both scope_ctx (SSOT) and legacy field (backward compat)
|
||||
self.scope_ctx.debug_pop_region();
|
||||
let _ = self.debug_scope_stack.pop();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub(crate) fn debug_current_region_id(&self) -> Option<String> {
|
||||
self.debug_scope_stack.last().cloned()
|
||||
// Phase 136 Step 3/7: Read from scope_ctx (SSOT)
|
||||
self.scope_ctx.debug_current_region_id()
|
||||
}
|
||||
|
||||
/// Hint for downstream metadata: set the logical source file name/path for the next build.
|
||||
|
||||
Reference in New Issue
Block a user