fix(joinir): Phase 82-5 lifecycle.rs return type inference bug fix

**Problem**: lifecycle.rs walked bb.instructions before checking bb.terminator,
causing it to infer types from intermediate values like `%1 = const void` instead
of the actual return value.

**Solution**: Remove instructions walking entirely, only check terminator Returns.
This ensures we infer type from the actual return value (e.g., `ret %3`).

**Impact**:
- Case D failures: 51 → 20 (60% reduction! 31 eliminated)
- Removed ~55 lines of redundant instructions walking
- All remaining 20 Case D are genuine GenericTypeResolver coverage issues

**Files Modified**:
- src/mir/builder/lifecycle.rs: Remove instructions loop, only check terminator

**Test Results**:
- Baseline: 483 passed, 33 failed
- With NYASH_PHI_FALLBACK_DISABLED=1: 463 passed, 53 failed (20 Case D panics)
- All remaining Case D are in `main` functions (genuine, not bugs)

**Related**: Phase 82-if-phi-retire Step 5 (ChatGPT root cause analysis)
This commit is contained in:
nyash-codex
2025-12-02 16:00:50 +09:00
parent b9496000f9
commit be38e4c272
2 changed files with 6 additions and 58 deletions

View File

@ -301,68 +301,16 @@ impl super::MirBuilder {
let mut module = self.current_module.take().unwrap();
let mut function = self.current_function.take().unwrap();
function.metadata.value_types = self.value_types.clone();
// Phase 82-5: lifecycle.rs バグ修正 - terminator の Return のみをチェック
// 問題: instructions を先に走査すると、中間値const void 等)を誤って推論対象にしてしまう
// 解決: terminator の Return のみをチェックし、実際の戻り値を正しく推論する
if matches!(
function.signature.return_type,
super::MirType::Void | super::MirType::Unknown
) {
let mut inferred: Option<super::MirType> = None;
'outer: for (_bid, bb) in function.blocks.iter() {
for inst in bb.instructions.iter() {
if let super::MirInstruction::Return { value: Some(v) } = inst {
if let Some(mt) = self.value_types.get(v).cloned() {
inferred = Some(mt);
break 'outer;
}
// Phase 65.5: TypeHintPolicy 使用(箱化モジュール)
// Phase 67: P3-C 経路を GenericTypeResolver に委譲
let hint = if TypeHintPolicy::is_target(&function.signature.name) {
TypeHintPolicy::extract_phi_type_hint(&function, *v)
} else {
None
};
// Phase 67: P3-C 対象なら GenericTypeResolver を優先使用
if hint.is_none() && TypeHintPolicy::is_p3c_target(&function.signature.name)
{
if let Some(mt) = GenericTypeResolver::resolve_from_phi(
&function,
*v,
&self.value_types,
) {
if std::env::var("NYASH_P3C_DEBUG").is_ok() {
eprintln!(
"[lifecycle/p3c] {} type inferred via GenericTypeResolver: {:?}",
function.signature.name, mt
);
}
inferred = Some(mt);
break 'outer;
}
}
// Phase 82: dev ガード - if_phi フォールバック禁止モード
if crate::config::env::phi_fallback_disabled() {
let case =
classify_phi_fallback_case(hint.as_ref(), &function.signature.name);
panic!(
"[phase82/phi_fallback] disabled but infer_type_from_phi called\n\
Function: {}\n\
ValueId: {:?}\n\
Case: {}",
function.signature.name, v, case
);
}
if let Some(mt) =
crate::mir::phi_core::if_phi::infer_type_from_phi_with_hint(
hint, // Phase 63-6-3: P1 の場合は PHI の type_hint、それ以外は None
&function,
*v,
&self.value_types,
)
{
inferred = Some(mt);
break 'outer;
}
}
}
for (_bid, bb) in function.blocks.iter() {
// Phase 82-5: instructions 走査を削除、terminator の Return のみをチェック
if let Some(super::MirInstruction::Return { value: Some(v) }) = &bb.terminator {
if let Some(mt) = self.value_types.get(v).cloned() {
inferred = Some(mt);