Files
hakorune/docs/development/current/main/phase84-4-implementation-recommendation.md
nyash-codex c5abf62350 docs(phase84): Add Phase 84-3 analysis and Phase 84-4 recommendations
Task agent investigation results after Phase 84-3 completion.

Remaining 4 Case D analysis:
- test_lowering_await_expression: await construct
- mir_lowering_of_qmark_propagate: QMark (?) construct
- mir_stage1_cli_emit_program_min_*: Stage1Cli type inference (2 tests)

Root cause (unified): BoxCall/Await/QMark return types not registered in value_types

Phase 84-4 implementation recommendations:
- Phase 84-4-A: dev fallback (0.5 days) - immediate unblock
- Phase 84-4-B: BoxCall type registration (1-2 days) - solves 3 cases
- Phase 84-4-C: Await type special handling (0.5 days) - solves 1 case

Documents added:
- phase84-3-summary.md: Reduction results and Phase 84-4 recommendations
- phase84-3-remaining-4-analysis.md: Detailed analysis of each test
- phase84-4-implementation-recommendation.md: Implementation guide with code examples
- phase84-index.md: Phase 84 overall index and roadmap
- phase84-3-final-report.md: Complete report with executive summary

Cumulative results:
- Phase 82: 12 cases
- Phase 84-2: 9 cases (25% reduction)
- Phase 84-3: 4 cases (56% reduction)
- Total: 67% reduction achieved (12 → 4)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 20:18:13 +09:00

411 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 84-4: 実装推奨 — BoxCall 型情報登録による根本解決
## 実装優先順位
### 🎯 Phase 84-4-A: dev フォールバック(推奨: 即実装)
**目的**: 開発環境の即座のアンブロック
**実装時間**: 0.5日
**実装箇所**: `src/mir/builder/lifecycle.rs`
```rust
// lifecycle.rs の infer_type_from_phi() の Case D セクション内
// 既存のコード:
// Case D: GenericTypeResolver も失敗 → if_phi フォールバックが必要
eprintln!("[phase82/phi_fallback] Case D triggered for {}", ret_val);
// ↓ 以下を追加 ↓
// Phase 84-4-A: dev 環境専用フォールバック
if should_enable_dev_fallback() {
if is_base_definition_with_missing_type(self.current_function(), ret_val) {
eprintln!(
"[phase84/dev_fallback] {} is base definition with missing type → Unknown (dev only)",
ret_val
);
return Ok(MirType::Unknown);
}
}
// 既存の panic 処理
if std::env::var("NYASH_PHI_FALLBACK_DISABLED").is_ok() {
panic!(...);
}
```
**ヘルパー関数**:
```rust
/// Phase 84-4-A: dev 環境専用フォールバック判定
fn should_enable_dev_fallback() -> bool {
std::env::var("NYASH_PHI_DEV_FALLBACK").ok().as_deref() == Some("1")
}
/// base 定義BoxCall/Await/etcで型が未登録かチェック
fn is_base_definition_with_missing_type(
func: &MirFunction,
val: ValueId,
) -> bool {
// val を定義する命令を探索
for bb in func.blocks.values() {
for inst in bb.instructions.iter().chain(bb.terminator.iter()) {
match inst {
MirInstruction::BoxCall { dst: Some(d), .. }
| MirInstruction::Await { dst: d, .. }
| MirInstruction::PluginInvoke { dst: Some(d), .. }
| MirInstruction::ExternCall { dst: Some(d), .. }
if *d == val =>
{
return true;
}
_ => {}
}
}
}
false
}
```
**使用方法**:
```bash
# dev 環境での作業
NYASH_PHI_DEV_FALLBACK=1 cargo test --release --lib
# production 環境CI
# 環境変数なし → 依然として厳格なエラー
cargo test --release --lib
```
**利点**:
- ✅ 開発者の作業を即座にアンブロック
- ✅ production 環境は依然として厳格CI で検出可能)
- ✅ 警告ログで問題箇所を明示
**欠点**:
- ⚠️ 根本解決ではない(暫定措置)
- ⚠️ dev 環境で型エラーが隠蔽される可能性
---
### 🔥 Phase 84-4-B: BoxCall 型情報登録(推奨: 根本解決)
**目的**: BoxCall 戻り値型の完全追跡
**実装時間**: 1-2日
**実装箇所**: `src/mir/builder/builder_calls.rs`
#### ステップ1: 型情報取得インフラ整備
```rust
// builder_calls.rs に追加
/// BoxCall のメソッド戻り値型を推論Phase 84-4-B
fn infer_boxcall_return_type(
&self,
box_val: ValueId,
method: &str,
_args: &[ValueId],
) -> Option<MirType> {
// 1. box_val の型を取得
let box_ty = self.value_types.get(&box_val)?;
// 2. Box 型名を取得
let box_name = match box_ty {
MirType::Box { name } => name,
_ => return None,
};
// 3. ビルトイン Box の型情報(ハードコード)
match (box_name.as_str(), method) {
// StringBox
("StringBox", "upper") => Some(MirType::Box {
name: "StringBox".to_string(),
}),
("StringBox", "lower") => Some(MirType::Box {
name: "StringBox".to_string(),
}),
("StringBox", "length") => Some(MirType::Box {
name: "IntegerBox".to_string(),
}),
// IntegerBox
("IntegerBox", "abs") => Some(MirType::Box {
name: "IntegerBox".to_string(),
}),
// BoolBox
("BoolBox", "not") => Some(MirType::Box {
name: "BoolBox".to_string(),
}),
// ArrayBox
("ArrayBox", "length") => Some(MirType::Box {
name: "IntegerBox".to_string(),
}),
("ArrayBox", "get") => Some(MirType::Unknown), // 要素型は実行時決定
// Result-like Box (QMark 用)
(_, "isOk") => Some(MirType::Box {
name: "BoolBox".to_string(),
}),
(_, "getValue") => Some(MirType::Unknown), // Result<T> の T
// 未知のメソッド
_ => {
if std::env::var("NYASH_BOXCALL_TYPE_DEBUG").is_ok() {
eprintln!(
"[boxcall_type] unknown method {}.{} → Unknown",
box_name, method
);
}
Some(MirType::Unknown)
}
}
}
```
#### ステップ2: emit_box_call() への統合
```rust
// builder_calls.rs の emit_box_call() を修正
pub fn emit_box_call(
&mut self,
box_val: ValueId,
method: &str,
args: Vec<ValueId>,
) -> Result<ValueId, String> {
let dst = self.next_value_id();
// 既存の BoxCall 命令生成
self.emit_instruction(MirInstruction::BoxCall {
dst: Some(dst),
box_val,
method: method.to_string(),
args: args.clone(),
method_id: None,
effects: EffectMask::UNKNOWN,
})?;
// **Phase 84-4-B 新機能**: 戻り値型を推論して登録
if let Some(ret_ty) = self.infer_boxcall_return_type(box_val, method, &args) {
self.value_types.insert(dst, ret_ty);
if std::env::var("NYASH_BOXCALL_TYPE_TRACE").is_ok() {
eprintln!(
"[boxcall_type] registered {} = BoxCall({}, {}) → {:?}",
dst, box_val, method, ret_ty
);
}
}
Ok(dst)
}
```
#### ステップ3: テスト実行
```bash
# 型推論トレース有効化
NYASH_BOXCALL_TYPE_TRACE=1 cargo test --release --lib mir_lowering_of_qmark_propagate
# 期待される出力:
# [boxcall_type] registered %3 = BoxCall(%1, isOk) → Box(BoolBox)
# [boxcall_type] registered %7 = BoxCall(%1, getValue) → Unknown
# Case D チェック
NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib 2>&1 | grep "Case D" | wc -l
# 期待: 1await のみ残存)
```
**利点**:
- ✅ 3件GroupB 2件 + GroupD 1件を根本解決
- ✅ production 環境でも安全
- ✅ 型情報の追跡可能性向上
**将来の拡張**:
- Phase 26-A で slot_registry から動的に型情報取得
- ユーザー定義 Box のメソッド戻り値型も追跡可能
---
### ⚡ Phase 84-4-C: Await 型情報特殊処理(推奨: 暫定対応)
**目的**: Await 戻り値型の暫定登録
**実装時間**: 0.5日
**実装箇所**: `src/mir/builder/stmts.rs`
```rust
// stmts.rs の build_await_expression() を修正
pub(super) fn build_await_expression(
&mut self,
expression: ASTNode,
) -> Result<ValueId, String> {
let future_value = self.build_expression(expression)?;
self.emit_instruction(MirInstruction::Safepoint)?;
let result_id = self.next_value_id();
// **Phase 84-4-C 新機能**: Future の型から戻り値型を推論
if let Some(future_ty) = self.value_types.get(&future_value) {
match future_ty {
MirType::Box { name } if name.contains("Future") => {
// Future<T> の T を抽出Phase 67+ で完全実装予定)
// 現時点では Unknown として登録
self.value_types.insert(result_id, MirType::Unknown);
if std::env::var("NYASH_AWAIT_TYPE_TRACE").is_ok() {
eprintln!(
"[await_type] registered {} = Await({}) → Unknown (temp)",
result_id, future_value
);
}
}
_ => {
// Future 型でない場合も Unknown で登録(エラー防止)
self.value_types.insert(result_id, MirType::Unknown);
}
}
} else {
// future_value の型が不明でも Unknown で登録
self.value_types.insert(result_id, MirType::Unknown);
}
self.emit_instruction(MirInstruction::Await {
dst: result_id,
future: future_value,
})?;
self.emit_instruction(MirInstruction::Safepoint)?;
Ok(result_id)
}
```
**テスト実行**:
```bash
# 型推論トレース有効化
NYASH_AWAIT_TYPE_TRACE=1 cargo test --release --lib test_lowering_await_expression
# Case D チェック
NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib 2>&1 | grep "Case D" | wc -l
# 期待: 0全件解決
```
**利点**:
- ✅ GroupC1件を暫定解決
- ✅ Phase 67+ 実装までの橋渡し
**長期対応**:
- Phase 67+ で Future<T> の T 型を正確に抽出
- async/await 型システムの完全実装
---
## 実装順序の推奨
### パターン1: 最速アンブロック(推奨: 即実装)
```
Phase 84-4-A (0.5日)
開発作業継続可能
Phase 84-4-B (1-2日) + Phase 84-4-C (0.5日)
Phase 84-5: if_phi.rs 削除
```
**利点**:
- ✅ 即座に開発環境アンブロック
- ✅ 根本解決と並行作業可能
**欠点**:
- ⚠️ dev 環境で型エラーが一時的に隠蔽
### パターン2: 完璧主義(推奨: 時間に余裕がある場合)
```
Phase 84-4-B (1-2日) + Phase 84-4-C (0.5日)
Phase 84-5: if_phi.rs 削除
```
**利点**:
- ✅ dev フォールバック不要
- ✅ 最初から根本解決
**欠点**:
- ⚠️ 実装完了まで開発ブロック1-2日
---
## 完了条件と検証方法
### Phase 84-4-A 完了
```bash
# dev 環境での全テスト通過
NYASH_PHI_DEV_FALLBACK=1 NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib 2>&1 | grep "Case D"
# 期待: 出力なし(全件通過)
# production 環境では依然としてエラー
NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib 2>&1 | grep "Case D" | wc -l
# 期待: 4依然として厳格
```
### Phase 84-4-B 完了
```bash
# BoxCall 型登録の確認
NYASH_BOXCALL_TYPE_TRACE=1 cargo test --release --lib mir_lowering_of_qmark_propagate 2>&1 | grep "boxcall_type"
# 期待: [boxcall_type] registered ... の出力
# Case D 削減確認
NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib 2>&1 | grep "Case D" | wc -l
# 期待: 1await のみ残存)
```
### Phase 84-4-C 完了
```bash
# Await 型登録の確認
NYASH_AWAIT_TYPE_TRACE=1 cargo test --release --lib test_lowering_await_expression 2>&1 | grep "await_type"
# 期待: [await_type] registered ... の出力
# Case D 完全解決確認
NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib 2>&1 | grep "Case D" | wc -l
# 期待: 0全件解決
```
### Phase 84-5 準備完了
```bash
# if_phi.rs 削除前の最終確認
NYASH_PHI_FALLBACK_DISABLED=1 cargo test --release --lib
# 期待: 全テスト通過Case D panic なし)
# レガシーフォールバック使用確認
cargo test --release --lib 2>&1 | grep "infer_type_from_phi_fallback"
# 期待: 出力なし(もう使われていない)
```
---
## まとめ
**推奨実装パス**: Phase 84-4-A → Phase 84-4-B → Phase 84-4-C
**総実装時間**: 2-3日
**期待成果**:
- ✅ Case D 4件 → 0件100%削減)
- ✅ if_phi.rs レガシーフォールバック削除準備完了
- ✅ 型推論システムの完全箱化達成
**次のステップ**: Phase 84-5if_phi.rs 完全削除)