✅ Hotfix 5: Pre-populate params vector in MirFunction::new()
📦 箱理論: 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先生 <task@anthropic.com>
This commit is contained in:
@ -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());
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user