feat(joinir): Phase 64-1/2 P2型ヒント実装 & 削減条件準備

Phase 64-1: P2/P3 対象関数分類完了
- P2 対象リスト作成: read_quoted_from, IfMerge Simple/Multiple
- P3 将来拡張: MethodCall戻り値型, Box コンストラクタ
- 実装戦略確立: P2から1関数ずつ段階的拡大

Phase 64-2: P2 型ヒント供給実装完了
- read_quoted.rs: ループカウンタ i (Integer), 文字列 ch (String) 型確定
- if_merge.rs: infer_type_from_mir_pattern() 追加 (Const命令から型推論)
- A/B テスト追加: test_p2_if_merge_type_hint() で型ヒント伝播検証 

技術的成果:
- JoinIR MergePair の type_hint 自動推論システム完成
- Phase 63 P1実装パターンを P2 に拡大適用
- 次ステップ: Phase 64-3 lifecycle.rs で P2 hint経路統合

修正ファイル:
- phase-63-joinir-type-info/README.md: Phase 64-1/2 セクション追加
- read_quoted.rs: MergePair 型ヒント追加 (Integer/String)
- if_merge.rs: infer_type_from_mir_pattern() + 型ヒント推論
- mir_joinir_if_select.rs: test_p2_if_merge_type_hint() 追加

🎯 削除条件 4/5 維持 (P1完了), Phase 64-3で P2拡大へ

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-30 05:12:59 +09:00
parent dc70d0de1b
commit e669f124d2
4 changed files with 123 additions and 14 deletions

View File

@ -401,15 +401,15 @@ impl AstToJoinIrLowerer {
merges: vec![
MergePair {
dst: i_after_esc,
then_val: i_esc,
else_val: step_i,
type_hint: None, // Phase 63-3
then_val: i_esc, // i + 1 (BinOp::Add, Integer)
else_val: step_i, // i (Integer param)
type_hint: Some(crate::mir::MirType::Integer), // Phase 64-2: ループカウンタ型確定
},
MergePair {
dst: ch_merged,
then_val: ch_esc,
else_val: step_ch,
type_hint: None, // Phase 63-3
then_val: ch_esc, // substring 結果 (String)
else_val: step_ch, // substring 結果 (String)
type_hint: Some(crate::mir::MirType::String), // Phase 64-2: 文字列型確定
},
],
k_next: None,

View File

@ -15,7 +15,7 @@
//! - Loop の PHI には触らないLoop lowering の責務)
use crate::mir::join_ir::{JoinInst, MergePair};
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, ValueId};
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, MirType, ValueId};
use std::collections::HashSet;
// Phase 61-1: If-in-loop context support
@ -198,11 +198,15 @@ impl IfMergeLowerer {
// else ブロックで dst に書き込まれる値を探す
let else_val = self.find_written_value(&else_block.instructions, dst)?;
// Phase 64-2: then_val / else_val から型ヒント推論
let type_hint = infer_type_from_mir_pattern(func, then_val)
.or_else(|| infer_type_from_mir_pattern(func, else_val));
merge_pairs.push(MergePair {
dst,
then_val,
else_val,
type_hint: None, // Phase 63-3: 現時点では型ヒントなし
type_hint, // Phase 64-2: Const 命令から型推論
});
}
@ -272,6 +276,34 @@ impl IfMergeLowerer {
}
}
/// Phase 64-2: MIR から ValueId の型を推論
///
/// Const 命令を探して、ValueId に対応する MirType を返す。
/// IfMerge の then_val / else_val から型ヒントを埋めるために使用。
fn infer_type_from_mir_pattern(func: &MirFunction, val_id: ValueId) -> Option<MirType> {
use crate::mir::{ConstValue, MirInstruction, MirType};
// 全ブロックの全命令を走査して Const 命令を探す
for block in func.blocks.values() {
for inst in &block.instructions {
if let MirInstruction::Const { dst, value } = inst {
if *dst == val_id {
return Some(match value {
ConstValue::Integer(_) => MirType::Integer,
ConstValue::Bool(_) => MirType::Bool,
ConstValue::String(_) => MirType::String,
ConstValue::Void => MirType::Void,
ConstValue::Null => MirType::Unknown, // Null は Unknown として扱う
// Float は現状未サポート
_ => return None,
});
}
}
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;