From fa087eeeea9dc7da7665a1ca45d73e40bf3c4945 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Tue, 18 Nov 2025 07:56:47 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20Hotfix=205:=20Pre-populate=20params?= =?UTF-8?q?=20vector=20in=20MirFunction::new()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📦 箱理論: Parameter ValueId完全予約システム確立 ## 🎯 根本原因 Hotfix 4でnext_value_id counterは予約したが、paramsベクトルが空のまま。 setup_function_params()が新規ValueIdをインクリメント済みcounterから割り当て。 結果: シグネチャは%0だが本体は%2を使用するミスマッチ発生。 ## ✅ 修正内容 ### 1. src/mir/function.rs - MirFunction::new() ```rust // 🔥 Hotfix 5: Pre-populate params vector with reserved ValueIds let mut pre_params = Vec::new(); for i in 0..total_value_ids { pre_params.push(ValueId::new(i)); } // ... params: pre_params, // ✅ Pre-populate instead of empty Vec ``` ### 2. src/mir/builder/calls/lowering.rs - setup_function_params() ```rust // 📦 Hotfix 5: Use pre-populated params from MirFunction::new() let receiver_offset = if f.params.is_empty() { 0 } else { if f.params.len() > params.len() { 1 } else { 0 } }; for (idx, p) in params.iter().enumerate() { let param_idx = receiver_offset + idx; let pid = if param_idx < f.params.len() { f.params[param_idx] // Use pre-allocated ValueId } else { let new_pid = f.next_value_id(); f.params.push(new_pid); new_pid }; // ... } ``` ## 📊 テスト結果 - ✅ mir_parserbox_parse_program2_harness_parses_minimal_source: PASS - ✅ mir_stage1_using_resolver_full_collect_entries_verifies: PASS - ⚠️ mir_stage1_using_resolver_min_fragment_verifies: 別問題(dominator violation) ## 🎉 成果 - **Parameter ValueId問題完全解決**: 0/3 → 2/3 tests passing - **Counter予約とVector実体の完全一致**: シグネチャと本体の整合性確保 - **Static method receiver完全対応**: 暗黙receiverも正しく予約 ## 🔧 次のステップ 残り1テストのdominator violation調査(LoopForm Exit PHI生成問題) Co-Authored-By: task先生 --- src/mir/builder/calls/lowering.rs | 21 ++++++++++++++++++--- src/mir/function.rs | 14 +++++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/mir/builder/calls/lowering.rs b/src/mir/builder/calls/lowering.rs index 067bfb20..c0f4cdd7 100644 --- a/src/mir/builder/calls/lowering.rs +++ b/src/mir/builder/calls/lowering.rs @@ -94,9 +94,24 @@ impl MirBuilder { fn setup_function_params(&mut self, params: &[String]) { self.function_param_names.clear(); if let Some(ref mut f) = self.current_function { - for p in params { - let pid = f.next_value_id(); - f.params.push(pid); + // 📦 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() { 0 } else { + // If params already populated (by Hotfix 4+5), use them + if f.params.len() > params.len() { 1 } else { 0 } + }; + + for (idx, p) in params.iter().enumerate() { + let param_idx = receiver_offset + idx; + let pid = if param_idx < f.params.len() { + // Use pre-allocated ValueId from MirFunction::new() + f.params[param_idx] + } else { + // Allocate new ValueId (fallback for non-static methods) + let new_pid = f.next_value_id(); + f.params.push(new_pid); + new_pid + }; self.variable_map.insert(p.clone(), pid); self.function_param_names.insert(p.clone()); } diff --git a/src/mir/function.rs b/src/mir/function.rs index d49160f6..03d10713 100644 --- a/src/mir/function.rs +++ b/src/mir/function.rs @@ -104,9 +104,17 @@ impl MirFunction { let total_value_ids = param_count + receiver_count; let initial_counter = total_value_ids.max(1); // At least 1 to reserve ValueId(0) as sentinel + // 🔥 Hotfix 5: Pre-populate params vector with reserved ValueIds + // Without this, setup_function_params() will allocate NEW ValueIds starting from + // the already-incremented counter, causing signature/body mismatch. + let mut pre_params = Vec::new(); + for i in 0..total_value_ids { + pre_params.push(ValueId::new(i)); + } + if std::env::var("NYASH_LOOPFORM_DEBUG").is_ok() { - eprintln!("[MirFunction::new] fn='{}' params={}, receiver={}, total={}, initial_counter={}", - signature.name, param_count, receiver_count, total_value_ids, initial_counter); + eprintln!("[MirFunction::new] fn='{}' params={}, receiver={}, total={}, initial_counter={}, pre_params={:?}", + signature.name, param_count, receiver_count, total_value_ids, initial_counter, pre_params); } Self { @@ -114,7 +122,7 @@ impl MirFunction { blocks, entry_block, locals: Vec::new(), - params: Vec::new(), + params: pre_params, // ✅ Pre-populate instead of empty Vec next_value_id: initial_counter, metadata: FunctionMetadata::default(), }