diff --git a/src/mir/builder.rs b/src/mir/builder.rs index 647728c9..103c670d 100644 --- a/src/mir/builder.rs +++ b/src/mir/builder.rs @@ -127,13 +127,6 @@ pub struct MirBuilder { /// Direct field access for backward compatibility (migration in progress). pub(super) comp_ctx: compilation_context::CompilationContext, - /// [DEPRECATED] Variable name to ValueId mapping (for SSA conversion) - /// Phase 136 Step 5/7: Moved to variable_ctx.variable_map (backward compat wrapper) - /// 注意: compilation_contextがSomeの場合は使用されません - /// Phase 25.1: HashMap → BTreeMap(PHI生成の決定性確保) - #[deprecated(note = "Use variable_ctx.variable_map instead")] - pub(super) variable_map: BTreeMap, - /// Pending phi functions to be inserted #[allow(dead_code)] pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>, @@ -300,7 +293,6 @@ impl MirBuilder { variable_ctx: variable_context::VariableContext::new(), // Phase 136 Step 5/7: Variable context metadata_ctx: metadata_context::MetadataContext::new(), // Phase 136 Step 6/7: Metadata context comp_ctx, // Phase 136 Step 7/7: Compilation context - variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat) pending_phis: Vec::new(), user_defined_boxes: HashSet::new(), weak_fields_by_box: HashMap::new(), @@ -342,18 +334,7 @@ impl MirBuilder { } // Phase 2-5: BindingContext sync helpers removed - binding_ctx is now SSOT - - /// Phase 136 Step 5/7: Sync variable_ctx changes back to legacy field (backward compatibility) - #[allow(deprecated)] - fn sync_variable_ctx_to_legacy(&mut self) { - self.variable_map = self.variable_ctx.variable_map.clone(); - } - - /// Phase 136 Step 5/7: Sync legacy field changes to variable_ctx (backward compatibility) - #[allow(deprecated)] - fn sync_legacy_to_variable_ctx(&mut self) { - self.variable_ctx.variable_map = self.variable_map.clone(); - } + // Phase 2-6: VariableContext sync helpers removed - variable_ctx is now SSOT /// Push/pop helpers for If merge context (best-effort; optional usage) pub(super) fn push_if_merge(&mut self, bb: BasicBlockId) { @@ -616,7 +597,7 @@ impl MirBuilder { )); } - if let Some(&value_id) = self.variable_map.get(&name) { + if let Some(&value_id) = self.variable_ctx.variable_map.get(&name) { Ok(value_id) } else { Err(self.undefined_variable_message(&name)) @@ -681,7 +662,7 @@ impl MirBuilder { // Result: VM would try to read undefined ValueIds (e.g., ValueId(270) at bb303). if !var_name.starts_with("__pin$") { // In SSA form, each assignment creates a new value - self.variable_map.insert(var_name.clone(), value_id); + self.variable_ctx.variable_map.insert(var_name.clone(), value_id); } Ok(value_id) @@ -808,7 +789,7 @@ impl MirBuilder { }) = callee { let names: Vec = self - .variable_map + .variable_ctx.variable_map .iter() .filter(|(_, &vid)| vid == *r) .map(|(k, _)| k.clone()) @@ -1148,13 +1129,11 @@ mod binding_id_tests { use super::*; #[test] - #[allow(deprecated)] fn test_binding_map_initialization() { let builder = MirBuilder::new(); assert_eq!(builder.core_ctx.next_binding_id, 0); - // Phase 136 Step 4/7: Check both binding_ctx (SSOT) and legacy field + // Phase 2-6: binding_ctx is now SSOT (legacy field removed) assert!(builder.binding_ctx.is_empty()); - assert!(builder.binding_map.is_empty()); } #[test] @@ -1171,7 +1150,6 @@ mod binding_id_tests { } #[test] - #[allow(deprecated)] fn test_shadowing_binding_restore() { let mut builder = MirBuilder::new(); @@ -1184,11 +1162,9 @@ mod binding_id_tests { builder .declare_local_in_current_scope("x", outer_vid) .unwrap(); - // Phase 136 Step 4/7: Check binding_ctx (SSOT) + // Phase 2-6: Check binding_ctx (SSOT) let outer_bid = builder.binding_ctx.lookup("x").unwrap(); assert_eq!(outer_bid.raw(), 0); - // Also verify legacy field is synced - assert_eq!(*builder.binding_map.get("x").unwrap(), outer_bid); // Enter inner scope and shadow x builder.push_lexical_scope(); @@ -1197,20 +1173,16 @@ mod binding_id_tests { builder .declare_local_in_current_scope("x", inner_vid) .unwrap(); - // Phase 136 Step 4/7: Check binding_ctx (SSOT) + // Phase 2-6: Check binding_ctx (SSOT) let inner_bid = builder.binding_ctx.lookup("x").unwrap(); assert_eq!(inner_bid.raw(), 1); - // Also verify legacy field is synced - assert_eq!(*builder.binding_map.get("x").unwrap(), inner_bid); // Exit inner scope - should restore outer binding builder.pop_lexical_scope(); - // Phase 136 Step 4/7: Check binding_ctx (SSOT) + // Phase 2-6: Check binding_ctx (SSOT) let restored_bid = builder.binding_ctx.lookup("x").unwrap(); assert_eq!(restored_bid, outer_bid); assert_eq!(restored_bid.raw(), 0); - // Also verify legacy field is synced - assert_eq!(*builder.binding_map.get("x").unwrap(), restored_bid); // Cleanup builder.pop_lexical_scope(); diff --git a/src/mir/builder/calls/build.rs b/src/mir/builder/calls/build.rs index 90841636..bd988677 100644 --- a/src/mir/builder/calls/build.rs +++ b/src/mir/builder/calls/build.rs @@ -421,7 +421,7 @@ impl MirBuilder { method: &str, arguments: &[ASTNode], ) -> Result, String> { - let is_local_var = self.variable_map.contains_key(obj_name); + let is_local_var = self.variable_ctx.variable_map.contains_key(obj_name); // Debug trace if std::env::var("NYASH_STATIC_CALL_TRACE").ok().as_deref() == Some("1") { @@ -434,7 +434,7 @@ impl MirBuilder { eprintln!("[DEBUG] variable_map contains '{}' - treating as local variable, will use method call", obj_name); eprintln!( "[DEBUG] variable_map keys: {:?}", - self.variable_map.keys().collect::>() + self.variable_ctx.variable_map.keys().collect::>() ); } else { eprintln!("[DEBUG] '{}' not in variable_map - treating as static box, will use global call", obj_name); @@ -570,7 +570,7 @@ impl MirBuilder { if let Some(origin) = self.type_ctx.value_origin_newbox.get(&object_value) { eprintln!("[DEBUG/param-recv] origin: {}", origin); } - if let Some(&mapped_id) = self.variable_map.get(name) { + if let Some(&mapped_id) = self.variable_ctx.variable_map.get(name) { eprintln!( "[DEBUG/param-recv] variable_map['{}'] = ValueId({})", name, mapped_id.0 diff --git a/src/mir/builder/calls/lowering.rs b/src/mir/builder/calls/lowering.rs index c452cd18..d52f0906 100644 --- a/src/mir/builder/calls/lowering.rs +++ b/src/mir/builder/calls/lowering.rs @@ -37,7 +37,7 @@ impl MirBuilder { // BoxCompilationContext vs saved_var_map モード判定 let context_active = self.compilation_context.is_some(); let saved_var_map = if !context_active { - Some(std::mem::take(&mut self.variable_map)) + Some(std::mem::take(&mut self.variable_ctx.variable_map)) } else { None }; @@ -47,7 +47,7 @@ impl MirBuilder { // BoxCompilationContext mode: clear()で完全独立化 if context_active { - self.variable_map.clear(); + self.variable_ctx.variable_map.clear(); self.type_ctx.value_origin_newbox.clear(); // value_types も static box 単位で独立させる。 // これにより、前の static box で使用された ValueId に紐づく型情報が @@ -139,7 +139,7 @@ impl MirBuilder { f.params.push(new_pid); new_pid }; - self.variable_map.insert(p.clone(), pid); + self.variable_ctx.variable_map.insert(p.clone(), pid); // Phase 136 Step 3/7: Insert into scope_ctx (SSOT) self.scope_ctx.function_param_names.insert(p.clone()); @@ -237,13 +237,13 @@ impl MirBuilder { // モード別にcontext復元 if ctx.context_active { // BoxCompilationContext mode: clear のみ(次回も完全独立) - self.variable_map.clear(); + self.variable_ctx.variable_map.clear(); self.type_ctx.value_origin_newbox.clear(); // static box ごとに型情報も独立させる(前 box の型メタデータを引きずらない) self.type_ctx.value_types.clear(); } else if let Some(saved) = ctx.saved_var_map { // Legacy mode: Main.main 側の variable_map を元に戻す - self.variable_map = saved; + self.variable_ctx.variable_map = saved; } // Static box context復元 @@ -307,7 +307,7 @@ impl MirBuilder { // me let me_id = f.params[0]; - self.variable_map.insert("me".to_string(), me_id); + self.variable_ctx.variable_map.insert("me".to_string(), me_id); self.type_ctx.value_origin_newbox.insert(me_id, box_name.to_string()); slot_regs.push(("me".to_string(), None)); @@ -316,13 +316,13 @@ impl MirBuilder { let param_idx = idx + 1; if param_idx < f.params.len() { let pid = f.params[param_idx]; - self.variable_map.insert(p.clone(), pid); + self.variable_ctx.variable_map.insert(p.clone(), pid); slot_regs.push((p.clone(), None)); } else { // 念のため足りない場合は新規に確保(互換用) let pid = f.next_value_id(); f.params.push(pid); - self.variable_map.insert(p.clone(), pid); + self.variable_ctx.variable_map.insert(p.clone(), pid); slot_regs.push((p.clone(), None)); } } @@ -402,7 +402,7 @@ impl MirBuilder { // Step 1: Context準備(instance methodでは不要だがAPI統一のため) let mut ctx = LoweringContext { context_active: false, - saved_var_map: Some(std::mem::take(&mut self.variable_map)), + saved_var_map: Some(std::mem::take(&mut self.variable_ctx.variable_map)), saved_static_ctx: None, saved_function: None, saved_block: None, @@ -473,7 +473,7 @@ impl MirBuilder { 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; + self.variable_ctx.variable_map = saved; } self.current_slot_registry = ctx.saved_slot_registry; diff --git a/src/mir/builder/calls/utils.rs b/src/mir/builder/calls/utils.rs index 638cb611..76ee8a24 100644 --- a/src/mir/builder/calls/utils.rs +++ b/src/mir/builder/calls/utils.rs @@ -39,7 +39,7 @@ impl MirBuilder { super::method_resolution::resolve_call_target( name, &self.current_static_box, - &self.variable_map, + &self.variable_ctx.variable_map, ) } } diff --git a/src/mir/builder/control_flow/debug.rs b/src/mir/builder/control_flow/debug.rs index 03d5e069..a8100ae6 100644 --- a/src/mir/builder/control_flow/debug.rs +++ b/src/mir/builder/control_flow/debug.rs @@ -25,6 +25,6 @@ impl MirBuilder { /// Enable with NYASH_TRACE_VARMAP=1 #[allow(dead_code)] pub(in crate::mir::builder) fn trace_varmap(&self, context: &str) { - super::joinir::trace::trace().varmap(context, &self.variable_map); + super::joinir::trace::trace().varmap(context, &self.variable_ctx.variable_map); } } diff --git a/src/mir/builder/control_flow/joinir/merge/exit_line/meta_collector.rs b/src/mir/builder/control_flow/joinir/merge/exit_line/meta_collector.rs index 362672c5..8368e078 100644 --- a/src/mir/builder/control_flow/joinir/merge/exit_line/meta_collector.rs +++ b/src/mir/builder/control_flow/joinir/merge/exit_line/meta_collector.rs @@ -3,7 +3,7 @@ //! Modularizes the exit_bindings collection logic from Pattern lowerers //! into a focused, testable Box. //! -//! **Responsibility**: Construct exit_bindings from ExitMeta + variable_map lookup +//! **Responsibility**: Construct exit_bindings from ExitMeta + variable_ctx.variable_map lookup use crate::mir::builder::MirBuilder; use crate::mir::join_ir::lowering::carrier_info::ExitMeta; @@ -16,10 +16,10 @@ use crate::mir::ValueId; // Phase 228-8: For ConditionOnly placeholder /// /// ## Pure Function Philosophy /// ExitMetaCollector::collect() is a **pure function**: -/// - Input: builder (read-only for variable_map lookup) +/// - Input: builder (read-only for variable_ctx.variable_map lookup) /// - Input: exit_meta (data structure) /// - Output: Vec (new data) -/// - No side effects (except reading builder.variable_map) +/// - No side effects (except reading builder.variable_ctx.variable_map) /// /// ## Why Pure Functions? /// - Easy to test (no mocks needed) @@ -40,7 +40,7 @@ use crate::mir::ValueId; // Phase 228-8: For ConditionOnly placeholder /// /// **Input**: /// - ExitMeta with exit_values (carrier_name → join_exit_value mappings) -/// - MirBuilder with variable_map for host ValueId lookup +/// - MirBuilder with variable_ctx.variable_map for host ValueId lookup /// /// **Effect**: /// - Creates LoopExitBinding vector (pure function, no side effects) @@ -50,25 +50,25 @@ use crate::mir::ValueId; // Phase 228-8: For ConditionOnly placeholder pub struct ExitMetaCollector; impl ExitMetaCollector { - /// Build exit_bindings from ExitMeta and variable_map + /// Build exit_bindings from ExitMeta and variable_ctx.variable_map /// /// # Algorithm /// /// For each entry in exit_meta.exit_values: - /// 1. Look up the carrier's host ValueId from builder.variable_map + /// 1. Look up the carrier's host ValueId from builder.variable_ctx.variable_map /// 2. Create LoopExitBinding with carrier_name, join_exit_value, host_slot /// 3. Collect into Vec /// /// # Phase 228-8: ConditionOnly carrier handling /// /// ConditionOnly carriers are included in exit_bindings even if they're not - /// in variable_map, because they need latch incoming values for header PHI. + /// in variable_ctx.variable_map, because they need latch incoming values for header PHI. /// The host_slot is set to ValueId(0) as a placeholder since ConditionOnly /// carriers don't participate in exit PHI. /// /// # Skipped carriers /// - /// Carriers not found in variable_map AND not in carrier_info are silently skipped. + /// Carriers not found in variable_ctx.variable_map AND not in carrier_info are silently skipped. /// This is intentional: some carriers may not be relevant to the current pattern. /// /// # Logging @@ -96,13 +96,13 @@ impl ExitMetaCollector { for (carrier_name, join_exit_value) in &exit_meta.exit_values { if verbose { eprintln!( - "[joinir/exit-line] checking carrier '{}' in variable_map", + "[joinir/exit-line] checking carrier '{}' in variable_ctx.variable_map", carrier_name ); } - // Look up host slot from variable_map - if let Some(&host_slot) = builder.variable_map.get(carrier_name) { + // Look up host slot from variable_ctx.variable_map + if let Some(&host_slot) = builder.variable_ctx.variable_map.get(carrier_name) { use crate::mir::join_ir::lowering::carrier_info::CarrierRole; // Phase 228-8: Look up role from carrier_info if available @@ -157,7 +157,7 @@ impl ExitMetaCollector { if verbose { eprintln!( - "[joinir/exit-line] collected ConditionOnly carrier '{}' JoinIR {:?} (not in variable_map)", + "[joinir/exit-line] collected ConditionOnly carrier '{}' JoinIR {:?} (not in variable_ctx.variable_map)", carrier_name, join_exit_value ); } @@ -166,7 +166,7 @@ impl ExitMetaCollector { } Some((CarrierRole::LoopState, CarrierInit::FromHost)) => { // Phase 247-EX: Include FromHost carrier in exit_bindings - // (needed for latch incoming, not for exit PHI or variable_map) + // (needed for latch incoming, not for exit PHI or variable_ctx.variable_map) let binding = LoopExitBinding { carrier_name: carrier_name.clone(), join_exit_value: *join_exit_value, @@ -176,7 +176,7 @@ impl ExitMetaCollector { if verbose { eprintln!( - "[joinir/exit-line] collected FromHost carrier '{}' JoinIR {:?} (not in variable_map)", + "[joinir/exit-line] collected FromHost carrier '{}' JoinIR {:?} (not in variable_ctx.variable_map)", carrier_name, join_exit_value ); } @@ -203,7 +203,7 @@ impl ExitMetaCollector { } _ => { let msg = format!( - "[joinir/exit-line] carrier '{}' not in variable_map and not ConditionOnly/FromHost (skip)", + "[joinir/exit-line] carrier '{}' not in variable_ctx.variable_map and not ConditionOnly/FromHost (skip)", carrier_name ); if strict { @@ -243,7 +243,7 @@ mod tests { fn test_missing_carrier_in_variable_map() { // This test would require full MirBuilder setup // Placeholder for future detailed testing - // When carrier not in variable_map, should be silently skipped + // When carrier not in variable_ctx.variable_map, should be silently skipped assert!(true); } } diff --git a/src/mir/builder/control_flow/joinir/merge/exit_line/reconnector.rs b/src/mir/builder/control_flow/joinir/merge/exit_line/reconnector.rs index bdb43aab..67b9c308 100644 --- a/src/mir/builder/control_flow/joinir/merge/exit_line/reconnector.rs +++ b/src/mir/builder/control_flow/joinir/merge/exit_line/reconnector.rs @@ -3,7 +3,7 @@ //! Modularizes the exit line reconnection logic (Phase 6 from merge/mod.rs) //! into a focused, testable Box. //! -//! **Responsibility**: Update host variable_map with PHI dst values from exit block +//! **Responsibility**: Update host variable_ctx.variable_map with PHI dst values from exit block //! //! # Phase 33-13 Architecture Change //! @@ -23,15 +23,15 @@ use std::collections::BTreeMap; /// # Design Notes /// /// ## Why Separate Box? -/// - Responsibility: Update host variable_map with PHI dst values +/// - Responsibility: Update host variable_ctx.variable_map with PHI dst values /// - Input: JoinInlineBoundary.exit_bindings + carrier_phis map -/// - Output: Updated MirBuilder.variable_map -/// - No side effects beyond variable_map updates +/// - Output: Updated MirBuilder.variable_ctx.variable_map +/// - No side effects beyond variable_ctx.variable_map updates /// /// ## Phase 33-13 Carrier PHI Integration /// This Box now uses carrier_phis from exit_phi_builder: -/// - Before: `variable_map[carrier] = remapper.get(join_exit)` (SSA-incorrect!) -/// - After: `variable_map[carrier] = carrier_phis[carrier]` (SSA-correct!) +/// - Before: `variable_ctx.variable_map[carrier] = remapper.get(join_exit)` (SSA-incorrect!) +/// - After: `variable_ctx.variable_map[carrier] = carrier_phis[carrier]` (SSA-correct!) /// /// The key insight is that remapped exit values are PHI INPUTS, not OUTPUTS. /// Only the PHI dst ValueId is defined in the exit block. @@ -40,7 +40,7 @@ use std::collections::BTreeMap; /// Can be tested independently: /// 1. Create mock boundary with exit_bindings /// 2. Create mock carrier_phis map -/// 3. Call reconnect() and verify variable_map updates +/// 3. Call reconnect() and verify variable_ctx.variable_map updates /// 4. No need to construct full merge/mod.rs machinery /// /// # Box Contract @@ -50,14 +50,14 @@ use std::collections::BTreeMap; /// - carrier_phis: Map from carrier name to PHI dst ValueId /// /// **Effect**: -/// - Updates builder.variable_map entries for each carrier with PHI dst values +/// - Updates builder.variable_ctx.variable_map entries for each carrier with PHI dst values /// /// **Output**: /// - Result<(), String> (side effect on builder) pub struct ExitLineReconnector; impl ExitLineReconnector { - /// Reconnect exit values to host variable_map using carrier PHI dst values + /// Reconnect exit values to host variable_ctx.variable_map using carrier PHI dst values /// /// # Phase 33-13: Carrier PHI Integration /// @@ -71,7 +71,7 @@ impl ExitLineReconnector { /// /// For each exit_binding: /// 1. Look up the PHI dst for this carrier in carrier_phis - /// 2. Update variable_map[binding.carrier_name] with PHI dst + /// 2. Update variable_ctx.variable_map[binding.carrier_name] with PHI dst /// 3. Log each update (if debug enabled) pub fn reconnect( builder: &mut MirBuilder, @@ -119,12 +119,12 @@ impl ExitLineReconnector { // Process each exit binding for binding in &boundary.exit_bindings { - // Phase 228-8: Skip ConditionOnly carriers (no variable_map update needed) + // Phase 228-8: Skip ConditionOnly carriers (no variable_ctx.variable_map update needed) use crate::mir::join_ir::lowering::carrier_info::CarrierRole; if binding.role == CarrierRole::ConditionOnly { if verbose { eprintln!( - "[joinir/exit-line] skip ConditionOnly carrier '{}' (no variable_map update)", + "[joinir/exit-line] skip ConditionOnly carrier '{}' (no variable_ctx.variable_map update)", binding.carrier_name ); } @@ -141,25 +141,25 @@ impl ExitLineReconnector { ); } - // Update variable_map with PHI dst + // Update variable_ctx.variable_map with PHI dst if let Some(&phi_value) = phi_dst { - if let Some(var_vid) = builder.variable_map.get_mut(&binding.carrier_name) { + if let Some(var_vid) = builder.variable_ctx.variable_map.get_mut(&binding.carrier_name) { // Phase 177-STRUCT: Always log for debugging if verbose { eprintln!( - "[joinir/exit-line] variable_map['{}'] {:?} → {:?}", + "[joinir/exit-line] variable_ctx.variable_map['{}'] {:?} → {:?}", binding.carrier_name, *var_vid, phi_value ); } *var_vid = phi_value; } else if verbose { eprintln!( - "[joinir/exit-line] warning: carrier '{}' not found in variable_map", + "[joinir/exit-line] warning: carrier '{}' not found in variable_ctx.variable_map", binding.carrier_name ); } else if strict { return Err(format!( - "[joinir/exit-line] missing variable_map entry for carrier '{}' (exit reconnection)", + "[joinir/exit-line] missing variable_ctx.variable_map entry for carrier '{}' (exit reconnection)", binding.carrier_name )); } @@ -188,9 +188,9 @@ impl ExitLineReconnector { } // Phase 190-impl-D-3: Contract verification (debug build only) - // Ensures all exit_bindings have corresponding entries in carrier_phis and variable_map + // Ensures all exit_bindings have corresponding entries in carrier_phis and variable_ctx.variable_map #[cfg(debug_assertions)] - Self::verify_exit_line_contract(boundary, carrier_phis, &builder.variable_map); + Self::verify_exit_line_contract(boundary, carrier_phis, &builder.variable_ctx.variable_map); Ok(()) } @@ -200,14 +200,14 @@ impl ExitLineReconnector { /// # Contract Requirements /// /// 1. Every exit_binding must have a corresponding entry in carrier_phis - /// 2. Every exit_binding's carrier must exist in variable_map after reconnect - /// 3. The variable_map entry must point to the PHI dst (not the original host value) + /// 2. Every exit_binding's carrier must exist in variable_ctx.variable_map after reconnect + /// 3. The variable_ctx.variable_map entry must point to the PHI dst (not the original host value) /// /// # Panics /// /// Panics if any contract violation is detected. This helps catch bugs where: /// - PHI is missing for a carrier (Phase 190-impl-D root cause) - /// - variable_map update was skipped + /// - variable_ctx.variable_map update was skipped /// - ValueId collision occurred #[cfg(debug_assertions)] fn verify_exit_line_contract( @@ -218,10 +218,10 @@ impl ExitLineReconnector { use crate::mir::join_ir::lowering::carrier_info::CarrierRole; for binding in &boundary.exit_bindings { - // Phase 228-8: Skip ConditionOnly carriers (not in variable_map by design) + // Phase 228-8: Skip ConditionOnly carriers (not in variable_ctx.variable_map by design) if binding.role == CarrierRole::ConditionOnly { eprintln!( - "[JoinIR/ExitLine/Contract] Phase 228-8: Skipping ConditionOnly carrier '{}' (not in variable_map)", + "[JoinIR/ExitLine/Contract] Phase 228-8: Skipping ConditionOnly carrier '{}' (not in variable_ctx.variable_map)", binding.carrier_name ); continue; @@ -240,20 +240,20 @@ impl ExitLineReconnector { // Future: Distinguish loop_var from carriers in exit_bindings } - // Contract 2: variable_map must contain this carrier after reconnect + // Contract 2: variable_ctx.variable_map must contain this carrier after reconnect let var_value = variable_map.get(&binding.carrier_name); if var_value.is_none() { panic!( - "[JoinIR/ExitLine/Contract] VIOLATION: Carrier '{}' missing from variable_map after reconnect", + "[JoinIR/ExitLine/Contract] VIOLATION: Carrier '{}' missing from variable_ctx.variable_map after reconnect", binding.carrier_name ); } - // Contract 3: variable_map entry should point to PHI dst (if PHI exists) + // Contract 3: variable_ctx.variable_map entry should point to PHI dst (if PHI exists) if let (Some(&phi), Some(&var)) = (phi_dst, var_value) { if phi != var { panic!( - "[JoinIR/ExitLine/Contract] VIOLATION: Carrier '{}' variable_map={:?} but PHI dst={:?} (mismatch!)", + "[JoinIR/ExitLine/Contract] VIOLATION: Carrier '{}' variable_ctx.variable_map={:?} but PHI dst={:?} (mismatch!)", binding.carrier_name, var, phi ); } diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern1_minimal.rs b/src/mir/builder/control_flow/joinir/patterns/pattern1_minimal.rs index 39a14d79..adcf8228 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern1_minimal.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern1_minimal.rs @@ -54,7 +54,7 @@ impl MirBuilder { let ctx = build_pattern_context(self, condition, body, PatternVariant::Pattern1)?; // Phase 195: Use unified trace - trace::trace().varmap("pattern1_start", &self.variable_map); + trace::trace().varmap("pattern1_start", &self.variable_ctx.variable_map); // Phase 202-A: Create JoinValueSpace for unified ValueId allocation // Pattern 1 uses Param region for boundary input slots (loop var) and Local region for temps. diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs b/src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs index 516134c3..98cdd4f4 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs @@ -108,7 +108,7 @@ fn prepare_pattern2_inputs( ConditionEnvBuilder::build_for_break_condition_v2( condition, &loop_var_name, - &builder.variable_map, + &builder.variable_ctx.variable_map, loop_var_id, &mut join_value_space, )?; @@ -140,7 +140,7 @@ fn prepare_pattern2_inputs( // Add captured vars for var in &captured_env.vars { - if let Some(&host_id) = builder.variable_map.get(&var.name) { + if let Some(&host_id) = builder.variable_ctx.variable_map.get(&var.name) { let join_id = join_value_space.alloc_param(); env.insert(var.name.clone(), join_id); condition_bindings.push(ConditionBinding { @@ -676,7 +676,7 @@ pub(crate) fn can_lower(builder: &MirBuilder, ctx: &super::router::LoopPatternCo CommonPatternInitializer::check_carrier_updates_allowed( ctx.body, &loop_var_name, - &builder.variable_map, + &builder.variable_ctx.variable_map, ) } @@ -745,7 +745,7 @@ impl MirBuilder { use super::pattern_pipeline::{build_pattern_context, PatternVariant}; let ctx = build_pattern_context(self, condition, _body, PatternVariant::Pattern2)?; - trace::trace().varmap("pattern2_start", &self.variable_map); + trace::trace().varmap("pattern2_start", &self.variable_ctx.variable_map); let mut inputs = prepare_pattern2_inputs(self, condition, _body, fn_body, &ctx, verbose)?; @@ -977,11 +977,11 @@ mod tests { use crate::mir::ValueId; let mut builder = MirBuilder::new(); - builder.variable_map.insert("i".to_string(), ValueId(1)); - builder.variable_map.insert("len".to_string(), ValueId(2)); - builder.variable_map.insert("s".to_string(), ValueId(3)); - builder.variable_map.insert("digits".to_string(), ValueId(4)); - builder.variable_map.insert("result".to_string(), ValueId(5)); + builder.variable_ctx.variable_map.insert("i".to_string(), ValueId(1)); + builder.variable_ctx.variable_map.insert("len".to_string(), ValueId(2)); + builder.variable_ctx.variable_map.insert("s".to_string(), ValueId(3)); + builder.variable_ctx.variable_map.insert("digits".to_string(), ValueId(4)); + builder.variable_ctx.variable_map.insert("result".to_string(), ValueId(5)); let condition = bin(BinaryOperator::Less, var("i"), var("len")); diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs b/src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs index d2ab80de..896205d5 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern3_with_if_phi.rs @@ -124,7 +124,7 @@ impl MirBuilder { ConditionEnvBuilder::build_for_break_condition_v2( condition, &loop_var_name, - &self.variable_map, + &self.variable_ctx.variable_map, loop_var_id, &mut join_value_space, )?; @@ -183,7 +183,7 @@ impl MirBuilder { // Collect parent-defined variables from function scope // For now, use all variables in variable_map except loop_var let parent_defined: Vec = self - .variable_map + .variable_ctx.variable_map .keys() .filter(|name| *name != &loop_var_name) .cloned() diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs b/src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs index b28c3922..726121cf 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs @@ -81,7 +81,7 @@ pub(crate) fn can_lower(builder: &MirBuilder, ctx: &super::router::LoopPatternCo CommonPatternInitializer::check_carrier_updates_allowed( ctx.body, &loop_var_name, - &builder.variable_map, + &builder.variable_ctx.variable_map, ) } @@ -335,7 +335,7 @@ fn lower_pattern4_joinir( use crate::mir::join_ir::lowering::loop_with_continue_minimal::lower_loop_with_continue_minimal; use crate::mir::join_ir::lowering::JoinInlineBoundaryBuilder; - trace::trace().varmap("pattern4_start", &builder.variable_map); + trace::trace().varmap("pattern4_start", &builder.variable_ctx.variable_map); let mut join_value_space = JoinValueSpace::new(); diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern5_infinite_early_exit.rs b/src/mir/builder/control_flow/joinir/patterns/pattern5_infinite_early_exit.rs index 4ca6bd1d..7cf1eb02 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern5_infinite_early_exit.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern5_infinite_early_exit.rs @@ -316,9 +316,9 @@ pub(crate) fn lower( ); } - // Step 2: Get counter ValueId from variable_map - let counter_id = builder.variable_map.get(&counter_name).copied().ok_or_else(|| { - format!("Counter variable '{}' not found in variable_map", counter_name) + // Step 2: Get counter ValueId from variable_ctx.variable_map + let counter_id = builder.variable_ctx.variable_map.get(&counter_name).copied().ok_or_else(|| { + format!("Counter variable '{}' not found in variable_ctx.variable_map", counter_name) })?; if debug { diff --git a/src/mir/builder/control_flow/joinir/patterns/pattern_pipeline.rs b/src/mir/builder/control_flow/joinir/patterns/pattern_pipeline.rs index f855b0cd..c4434425 100644 --- a/src/mir/builder/control_flow/joinir/patterns/pattern_pipeline.rs +++ b/src/mir/builder/control_flow/joinir/patterns/pattern_pipeline.rs @@ -263,7 +263,7 @@ pub(crate) fn build_pattern_context( let (loop_var_name, loop_var_id, carrier_info) = CommonPatternInitializer::initialize_pattern( builder, condition, - &builder.variable_map, + &builder.variable_ctx.variable_map, None, // No exclusions for now (Pattern 2/4 will filter carriers later) )?; diff --git a/src/mir/builder/control_flow/joinir/patterns/trim_loop_lowering.rs b/src/mir/builder/control_flow/joinir/patterns/trim_loop_lowering.rs index 6c363bbd..ac03762b 100644 --- a/src/mir/builder/control_flow/joinir/patterns/trim_loop_lowering.rs +++ b/src/mir/builder/control_flow/joinir/patterns/trim_loop_lowering.rs @@ -280,7 +280,7 @@ impl TrimLoopLowerer { Self::generate_carrier_initialization(builder, body, trim_helper)?; eprintln!( - "[TrimLoopLowerer] Registered carrier '{}' in variable_map", + "[TrimLoopLowerer] Registered carrier '{}' in variable_ctx.variable_map", trim_helper.carrier_name ); @@ -328,7 +328,7 @@ impl TrimLoopLowerer { /// Generates: /// 1. ch0 = s.substring(start, start+1) /// 2. is_ch_match0 = (ch0 == " " || ch0 == "\t" || ...) - /// 3. Registers carrier in variable_map + /// 3. Registers carrier in variable_ctx.variable_map fn generate_carrier_initialization( builder: &mut MirBuilder, body: &[ASTNode], @@ -353,7 +353,7 @@ impl TrimLoopLowerer { // Get ValueIds for string and start let s_id = - builder.variable_map.get(&s_name).copied().ok_or_else(|| { + builder.variable_ctx.variable_map.get(&s_name).copied().ok_or_else(|| { format!("[TrimLoopLowerer] String variable '{}' not found", s_name) })?; @@ -401,9 +401,9 @@ impl TrimLoopLowerer { is_ch_match0 ); - // Register carrier in variable_map + // Register carrier in variable_ctx.variable_map builder - .variable_map + .variable_ctx.variable_map .insert(trim_helper.carrier_name.clone(), is_ch_match0); Ok(()) @@ -438,7 +438,7 @@ impl TrimLoopLowerer { let mut bindings = Vec::new(); // Add carrier to ConditionEnv - let get_value = |name: &str| builder.variable_map.get(name).copied(); + let get_value = |name: &str| builder.variable_ctx.variable_map.get(name).copied(); let mut env_temp = std::collections::HashMap::new(); // Temporary env for closure let binding = TrimPatternLowerer::add_to_condition_env( diff --git a/src/mir/builder/decls.rs b/src/mir/builder/decls.rs index 821a3577..eb0d4b84 100644 --- a/src/mir/builder/decls.rs +++ b/src/mir/builder/decls.rs @@ -47,7 +47,7 @@ impl super::MirBuilder { ); eprintln!("[DEBUG] params.len() = {}", params.len()); eprintln!("[DEBUG] body.len() = {}", body.len()); - eprintln!("[DEBUG] variable_map = {:?}", self.variable_map); + eprintln!("[DEBUG] variable_map = {:?}", self.variable_ctx.variable_map); // Note: Metadata clearing is now handled by BoxCompilationContext (箱理論) // See lifecycle.rs and builder_calls.rs for context swap implementation let _ = self.lower_static_method_as_function( @@ -58,11 +58,11 @@ impl super::MirBuilder { eprintln!( "[DEBUG] build_static_main_box: After lower_static_method_as_function" ); - eprintln!("[DEBUG] variable_map = {:?}", self.variable_map); + eprintln!("[DEBUG] variable_map = {:?}", self.variable_ctx.variable_map); } // Initialize local variables for Main.main() parameters // Note: These are local variables in the wrapper main() function, NOT parameters - let saved_var_map = std::mem::take(&mut self.variable_map); + let saved_var_map = std::mem::take(&mut self.variable_ctx.variable_map); let script_args = collect_script_args_from_env(); for p in params.iter() { // Allocate a value ID using the current function's value generator @@ -109,7 +109,7 @@ impl super::MirBuilder { self.emit_instruction(MirInstruction::Copy { dst: pid, src: v })?; crate::mir::builder::metadata::propagate::propagate(self, v, pid); } - self.variable_map.insert(p.clone(), pid); + self.variable_ctx.variable_map.insert(p.clone(), pid); // 関数スコープ SlotRegistry にも登録しておくよ(観測専用) if let Some(reg) = self.current_slot_registry.as_mut() { let ty = self.type_ctx.value_types.get(&pid).cloned(); @@ -129,7 +129,7 @@ impl super::MirBuilder { // Phase 200-C: Clear fn_body_ast after main() lowering self.fn_body_ast = None; - self.variable_map = saved_var_map; + self.variable_ctx.variable_map = saved_var_map; lowered } else { Err("main method in static box is not a FunctionDeclaration".to_string()) diff --git a/src/mir/builder/exprs_lambda.rs b/src/mir/builder/exprs_lambda.rs index 76ba82d4..076fe64a 100644 --- a/src/mir/builder/exprs_lambda.rs +++ b/src/mir/builder/exprs_lambda.rs @@ -157,11 +157,11 @@ impl super::MirBuilder { } let mut captures: Vec<(String, ValueId)> = Vec::new(); for name in used.into_iter() { - if let Some(&vid) = self.variable_map.get(&name) { + if let Some(&vid) = self.variable_ctx.variable_map.get(&name) { captures.push((name, vid)); } } - let me = self.variable_map.get("me").copied(); + let me = self.variable_ctx.variable_map.get("me").copied(); let dst = self.next_value_id(); self.emit_instruction(super::MirInstruction::NewClosure { dst, diff --git a/src/mir/builder/if_form.rs b/src/mir/builder/if_form.rs index 1f5977b0..8a3964aa 100644 --- a/src/mir/builder/if_form.rs +++ b/src/mir/builder/if_form.rs @@ -43,7 +43,7 @@ impl<'a> PhiBuilderOps for ToplevelOps<'a> { } fn update_var(&mut self, name: String, value: ValueId) { - self.0.variable_map.insert(name, value); + self.0.variable_ctx.variable_map.insert(name, value); } fn get_block_predecessors(&self, block: BasicBlockId) -> Vec { @@ -113,7 +113,7 @@ impl MirBuilder { )?; // Snapshot variables before entering branches - let pre_if_var_map = self.variable_map.clone(); + let pre_if_var_map = self.variable_ctx.variable_map.clone(); let trace_if = std::env::var("NYASH_IF_TRACE").ok().as_deref() == Some("1"); @@ -124,11 +124,11 @@ impl MirBuilder { // Scope enter for then-branch self.hint_scope_enter(0); let then_ast_for_analysis = then_branch.clone(); - self.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map = pre_if_var_map.clone(); // Materialize all variables at block entry via single-pred Phi (correctness-first) for (name, &pre_v) in pre_if_var_map.iter() { let phi_val = self.insert_phi_single(pre_branch_bb, pre_v)?; - self.variable_map.insert(name.clone(), phi_val); + self.variable_ctx.variable_map.insert(name.clone(), phi_val); if trace_if { eprintln!( "[if-trace] then-entry phi var={} pre={:?} -> dst={:?}", @@ -139,7 +139,7 @@ impl MirBuilder { let then_value_raw = self.build_expression(then_branch)?; let then_exit_block = self.current_block()?; let then_reaches_merge = !self.is_current_block_terminated(); - let then_var_map_end = self.variable_map.clone(); + let then_var_map_end = self.variable_ctx.variable_map.clone(); if then_reaches_merge { // Scope leave for then-branch self.hint_scope_leave(0); @@ -157,11 +157,11 @@ impl MirBuilder { let (else_value_raw, else_ast_for_analysis, else_var_map_end_opt) = if let Some(else_ast) = else_branch { // Reset variable_map BEFORE materializing PHI nodes (same pattern as then-branch) - self.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map = pre_if_var_map.clone(); // Materialize all variables at block entry via single-pred Phi (correctness-first) for (name, &pre_v) in pre_if_var_map.iter() { let phi_val = self.insert_phi_single(pre_branch_bb, pre_v)?; - self.variable_map.insert(name.clone(), phi_val); + self.variable_ctx.variable_map.insert(name.clone(), phi_val); if trace_if { eprintln!( "[if-trace] else-entry phi var={} pre={:?} -> dst={:?}", @@ -170,13 +170,13 @@ impl MirBuilder { } } let val = self.build_expression(else_ast.clone())?; - (val, Some(else_ast), Some(self.variable_map.clone())) + (val, Some(else_ast), Some(self.variable_ctx.variable_map.clone())) } else { // No else branch: materialize PHI nodes for the empty else block - self.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map = pre_if_var_map.clone(); for (name, &pre_v) in pre_if_var_map.iter() { let phi_val = self.insert_phi_single(pre_branch_bb, pre_v)?; - self.variable_map.insert(name.clone(), phi_val); + self.variable_ctx.variable_map.insert(name.clone(), phi_val); if trace_if { eprintln!( "[if-trace] else-entry phi var={} pre={:?} -> dst={:?}", @@ -187,7 +187,7 @@ impl MirBuilder { let void_val = crate::mir::builder::emission::constant::emit_void(self); // Phase 25.1c/k: Pass PHI-renamed variable_map for empty else branch // This ensures merge_modified_vars uses correct ValueIds after PHI renaming - (void_val, None, Some(self.variable_map.clone())) + (void_val, None, Some(self.variable_ctx.variable_map.clone())) }; let else_exit_block = self.current_block()?; let else_reaches_merge = !self.is_current_block_terminated(); diff --git a/src/mir/builder/ops.rs b/src/mir/builder/ops.rs index a9696a81..d6b82175 100644 --- a/src/mir/builder/ops.rs +++ b/src/mir/builder/ops.rs @@ -354,17 +354,17 @@ impl super::MirBuilder { let pre_branch_bb = self.current_block()?; // Snapshot variables before entering branches - let pre_if_var_map = self.variable_map.clone(); + let pre_if_var_map = self.variable_ctx.variable_map.clone(); // ---- THEN branch ---- self.start_new_block(then_block)?; self.hint_scope_enter(0); // Reset scope to pre-if snapshot for clean deltas - self.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map = pre_if_var_map.clone(); // Materialize all variables at entry via single-pred PHI (correctness-first) for (name, &pre_v) in pre_if_var_map.iter() { let phi_val = self.insert_phi_single(pre_branch_bb, pre_v)?; - self.variable_map.insert(name.clone(), phi_val); + self.variable_ctx.variable_map.insert(name.clone(), phi_val); } // AND: then → evaluate RHS and reduce to bool @@ -404,7 +404,7 @@ impl super::MirBuilder { }; let then_exit_block = self.current_block()?; let then_reaches_merge = !self.is_current_block_terminated(); - let then_var_map_end = self.variable_map.clone(); + let then_var_map_end = self.variable_ctx.variable_map.clone(); if then_reaches_merge { self.hint_scope_leave(0); crate::mir::builder::emission::branch::emit_jump(self, merge_block)?; @@ -413,11 +413,11 @@ impl super::MirBuilder { // ---- ELSE branch ---- self.start_new_block(else_block)?; self.hint_scope_enter(0); - self.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map = pre_if_var_map.clone(); // Materialize all variables at entry via single-pred PHI (correctness-first) for (name, &pre_v) in pre_if_var_map.iter() { let phi_val = self.insert_phi_single(pre_branch_bb, pre_v)?; - self.variable_map.insert(name.clone(), phi_val); + self.variable_ctx.variable_map.insert(name.clone(), phi_val); } // AND: else → false // OR: else → evaluate RHS and reduce to bool @@ -455,7 +455,7 @@ impl super::MirBuilder { }; let else_exit_block = self.current_block()?; let else_reaches_merge = !self.is_current_block_terminated(); - let else_var_map_end = self.variable_map.clone(); + let else_var_map_end = self.variable_ctx.variable_map.clone(); if else_reaches_merge { self.hint_scope_leave(0); crate::mir::builder::emission::branch::emit_jump(self, merge_block)?; diff --git a/src/mir/builder/phi.rs b/src/mir/builder/phi.rs index 35d0ef37..749cbc4c 100644 --- a/src/mir/builder/phi.rs +++ b/src/mir/builder/phi.rs @@ -64,7 +64,7 @@ impl MirBuilder { 0 => {} 1 => { let (_pred, v) = inputs[0]; - self.variable_map.insert(pin_name.clone(), v); + self.variable_ctx.variable_map.insert(pin_name.clone(), v); } _ => { if let Some(func) = self.scope_ctx.current_function.as_mut() { @@ -94,7 +94,7 @@ impl MirBuilder { type_hint: None, // Phase 63-6: Legacy path, no type hint })?; } - self.variable_map.insert(pin_name.clone(), merged); + self.variable_ctx.variable_map.insert(pin_name.clone(), merged); } } } @@ -164,8 +164,8 @@ impl MirBuilder { 0 => {} 1 => { // Direct bind (no PHI needed) - self.variable_map = pre_if_var_map.clone(); - self.variable_map.insert(var_name, inputs[0].1); + self.variable_ctx.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map.insert(var_name, inputs[0].1); return Ok(inputs[0].1); } _ => { @@ -181,8 +181,8 @@ impl MirBuilder { self.insert_phi_with_dst(result_val, inputs)?; } } - self.variable_map = pre_if_var_map.clone(); - self.variable_map.insert(var_name, result_val); + self.variable_ctx.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map.insert(var_name, result_val); } else { // No variable assignment pattern detected – just emit Phi for expression result let mut inputs: Vec<(BasicBlockId, ValueId)> = Vec::new(); @@ -215,7 +215,7 @@ impl MirBuilder { } } // Merge variable map conservatively to pre-if snapshot (no new bindings) - self.variable_map = pre_if_var_map.clone(); + self.variable_ctx.variable_map = pre_if_var_map.clone(); } Ok(result_val) diff --git a/src/mir/builder/phi_merge.rs b/src/mir/builder/phi_merge.rs index ab1181d5..1485348b 100644 --- a/src/mir/builder/phi_merge.rs +++ b/src/mir/builder/phi_merge.rs @@ -81,7 +81,7 @@ impl<'a> PhiMergeHelper<'a> { 1 => { // Single predecessor - direct insert (no PHI) let (_pred, v) = inputs[0]; - self.builder.variable_map.insert(name, v); + self.builder.variable_ctx.variable_map.insert(name, v); Ok(()) } _ => { @@ -95,7 +95,7 @@ impl<'a> PhiMergeHelper<'a> { crate::mir::phi_core::common::debug_verify_phi_inputs(func, cur_bb, &inputs); } let merged = self.builder.insert_phi(inputs)?; - self.builder.variable_map.insert(name, merged); + self.builder.variable_ctx.variable_map.insert(name, merged); Ok(()) } } diff --git a/src/mir/builder/receiver.rs b/src/mir/builder/receiver.rs index 33dd822a..c053d79f 100644 --- a/src/mir/builder/receiver.rs +++ b/src/mir/builder/receiver.rs @@ -29,7 +29,7 @@ pub fn finalize_method_receiver(builder: &mut MirBuilder, callee: &mut Callee) { .unwrap_or_else(|| "".to_string()); let bb = builder.current_block; let names: Vec = builder - .variable_map + .variable_ctx.variable_map .iter() .filter(|(_, &vid)| vid == r) .map(|(k, _)| k.clone()) diff --git a/src/mir/builder/ssa/local.rs b/src/mir/builder/ssa/local.rs index 8264c814..22fef79a 100644 --- a/src/mir/builder/ssa/local.rs +++ b/src/mir/builder/ssa/local.rs @@ -54,16 +54,16 @@ pub fn ensure(builder: &mut MirBuilder, v: ValueId, kind: LocalKind) -> ValueId } // CRITICAL FIX: If `v` is from a pinned slot, check if there's a PHI value for that slot - // in the current block's variable_map. If so, use the PHI value directly instead of + // in the current block's variable_ctx.variable_map. If so, use the PHI value directly instead of // emitting a Copy from the old value (which might not be defined in this block). // Try to detect pinned slots for this value and redirect to the latest slot value. - // 1) First, look for "__pin$" entries in variable_map that still point to v. + // 1) First, look for "__pin$" entries in variable_ctx.variable_map that still point to v. // 2) If not found, consult builder.pin_slot_names to recover the slot name // and then look up the current ValueId for that slot. let mut slot_name_opt: Option = None; let names_for_v: Vec = builder - .variable_map + .variable_ctx.variable_map .iter() .filter(|(k, &vid)| vid == v && k.starts_with("__pin$")) .map(|(k, _)| k.clone()) @@ -76,7 +76,7 @@ pub fn ensure(builder: &mut MirBuilder, v: ValueId, kind: LocalKind) -> ValueId } if let Some(slot_name) = slot_name_opt { - if let Some(¤t_val) = builder.variable_map.get(&slot_name) { + if let Some(¤t_val) = builder.variable_ctx.variable_map.get(&slot_name) { if current_val != v { // The slot has been updated (likely by a PHI or header rewrite). // Use the updated value instead of the stale pinned ValueId. diff --git a/src/mir/builder/stmts.rs b/src/mir/builder/stmts.rs index acf42d6c..03885ae0 100644 --- a/src/mir/builder/stmts.rs +++ b/src/mir/builder/stmts.rs @@ -429,7 +429,7 @@ impl super::MirBuilder { // Register at least Future to avoid later fail-fast type inference panics. self.type_ctx.value_types .insert(future_id, MirType::Future(Box::new(MirType::Unknown))); - self.variable_map.insert(variable.clone(), future_id); + self.variable_ctx.variable_map.insert(variable.clone(), future_id); if let Some(reg) = self.current_slot_registry.as_mut() { reg.ensure_slot(&variable, None); } @@ -448,7 +448,7 @@ impl super::MirBuilder { .unwrap_or(MirType::Unknown); self.type_ctx.value_types .insert(future_id, MirType::Future(Box::new(inner))); - self.variable_map.insert(variable.clone(), future_id); + self.variable_ctx.variable_map.insert(variable.clone(), future_id); if let Some(reg) = self.current_slot_registry.as_mut() { reg.ensure_slot(&variable, None); } @@ -478,7 +478,7 @@ impl super::MirBuilder { // me: resolve to param if present; else symbolic const (stable mapping) pub(super) fn build_me_expression(&mut self) -> Result { - if let Some(id) = self.variable_map.get("me").cloned() { + if let Some(id) = self.variable_ctx.variable_map.get("me").cloned() { return Ok(id); } let me_tag = if let Some(ref cls) = self.current_static_box { @@ -487,7 +487,7 @@ impl super::MirBuilder { "__me__".to_string() }; let me_value = crate::mir::builder::emission::constant::emit_string(self, me_tag); - self.variable_map.insert("me".to_string(), me_value); + self.variable_ctx.variable_map.insert("me".to_string(), me_value); if let Some(reg) = self.current_slot_registry.as_mut() { reg.ensure_slot("me", None); } diff --git a/src/mir/builder/utils.rs b/src/mir/builder/utils.rs index 970ad55c..f08e5fce 100644 --- a/src/mir/builder/utils.rs +++ b/src/mir/builder/utils.rs @@ -132,31 +132,31 @@ impl super::MirBuilder { if false && !self.suppress_pin_entry_copy_next { // Keep old code for reference // First pass: copy all pin slots and remember old->new mapping - let names: Vec = self.variable_map.keys().cloned().collect(); + let names: Vec = self.variable_ctx.variable_map.keys().cloned().collect(); let mut pin_renames: Vec<(super::ValueId, super::ValueId)> = Vec::new(); for name in names.iter() { if !name.starts_with("__pin$") { continue; } - if let Some(&src) = self.variable_map.get(name) { + if let Some(&src) = self.variable_ctx.variable_map.get(name) { let dst = self.next_value_id(); self.emit_instruction(super::MirInstruction::Copy { dst, src })?; crate::mir::builder::metadata::propagate::propagate(self, src, dst); - self.variable_map.insert(name.clone(), dst); + self.variable_ctx.variable_map.insert(name.clone(), dst); pin_renames.push((src, dst)); } } // Second pass: update any user variables that pointed to old pin ids to the new ones if !pin_renames.is_empty() { let snapshot: Vec<(String, super::ValueId)> = self - .variable_map + .variable_ctx.variable_map .iter() .filter(|(k, _)| !k.starts_with("__pin$")) .map(|(k, &v)| (k.clone(), v)) .collect(); for (k, v) in snapshot.into_iter() { if let Some((_, newv)) = pin_renames.iter().find(|(oldv, _)| *oldv == v) { - self.variable_map.insert(k, *newv); + self.variable_ctx.variable_map.insert(k, *newv); } } } @@ -460,7 +460,7 @@ impl super::MirBuilder { // LocalSSA uses this to redirect old pinned values to the latest slot value. self.pin_slot_names.insert(v, slot_name.clone()); self.pin_slot_names.insert(dst, slot_name.clone()); - self.variable_map.insert(slot_name, dst); + self.variable_ctx.variable_map.insert(slot_name, dst); Ok(dst) } diff --git a/src/mir/builder/vars/assignment_resolver.rs b/src/mir/builder/vars/assignment_resolver.rs index 7509dc7d..81387d1d 100644 --- a/src/mir/builder/vars/assignment_resolver.rs +++ b/src/mir/builder/vars/assignment_resolver.rs @@ -17,7 +17,7 @@ impl AssignmentResolverBox { return Ok(()); } - if builder.variable_map.contains_key(var_name) { + if builder.variable_ctx.variable_map.contains_key(var_name) { return Ok(()); } diff --git a/src/mir/builder/vars/lexical_scope.rs b/src/mir/builder/vars/lexical_scope.rs index 51bd601d..b20f8ac2 100644 --- a/src/mir/builder/vars/lexical_scope.rs +++ b/src/mir/builder/vars/lexical_scope.rs @@ -51,10 +51,10 @@ impl super::super::MirBuilder { for (name, previous) in frame.restore { match previous { Some(prev_id) => { - self.variable_map.insert(name, prev_id); + self.variable_ctx.variable_map.insert(name, prev_id); } None => { - self.variable_map.remove(&name); + self.variable_ctx.variable_map.remove(&name); } } } @@ -85,7 +85,7 @@ impl super::super::MirBuilder { if frame.declared.insert(name.to_string()) { // Capture previous ValueId for restoration - let previous = self.variable_map.get(name).copied(); + let previous = self.variable_ctx.variable_map.get(name).copied(); frame.restore.insert(name.to_string(), previous); // Phase 74: Capture previous BindingId for parallel restoration @@ -97,7 +97,7 @@ impl super::super::MirBuilder { } // Update both ValueId and BindingId mappings - self.variable_map.insert(name.to_string(), value); + self.variable_ctx.variable_map.insert(name.to_string(), value); // Phase 74: Allocate and register new BindingId for this binding let binding_id = self.allocate_binding_id(); diff --git a/src/mir/region/observer.rs b/src/mir/region/observer.rs index 68b09a6f..8cd9a9bf 100644 --- a/src/mir/region/observer.rs +++ b/src/mir/region/observer.rs @@ -167,7 +167,7 @@ fn classify_slots_from_registry(reg: &mut FunctionSlotRegistry) -> Vec Vec { let mut slots = Vec::new(); - for (name, &vid) in builder.variable_map.iter() { + for (name, &vid) in builder.variable_ctx.variable_map().iter() { let ref_kind = classify_slot(builder, vid, name.as_str()); slots.push(SlotMetadata { name: name.clone(),