Files
hakorune/src/tests/mir_value_kind.rs
nyash-codex f9d100ce01 chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果:
-  LoopForm v2 テスト・ドキュメント・コメント完備
  - 4ケース(A/B/C/D)完全テストカバレッジ
  - 最小再現ケース作成(SSAバグ調査用)
  - SSOT文書作成(loopform_ssot.md)
  - 全ソースに [LoopForm] コメントタグ追加

-  Stage-1 CLI デバッグ環境構築
  - stage1_cli.hako 実装
  - stage1_bridge.rs ブリッジ実装
  - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh)
  - アーキテクチャ改善提案文書

-  環境変数削減計画策定
  - 25変数の完全調査・分類
  - 6段階削減ロードマップ(25→5、80%削減)
  - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG)

Phase 26-D からの累積変更:
- PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等)
- MIRビルダーリファクタリング
- 型伝播・最適化パス改善
- その他約300ファイルの累積変更

🎯 技術的成果:
- SSAバグ根本原因特定(条件分岐内loop変数変更)
- Region+next_iパターン適用完了(UsingCollectorBox等)
- LoopFormパターン文書化・テスト化完了
- セルフホスティング基盤強化

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <noreply@openai.com>
Co-Authored-By: Task Assistant <task@anthropic.com>
2025-11-21 06:25:17 +09:00

164 lines
5.5 KiB
Rust
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 26-A-5: 統合テスト - ValueId型安全化の完全動作確認
///
/// GUARDバグ再現防止の完全検証:
/// - パラメータ型自動登録Phase 26-A-3
/// - is_parameter型安全判定Phase 26-A-4
/// - 実際のMIRビルド環境での動作確認
use crate::mir::{MirBuilder, MirValueKind, ValueId};
/// GUARD checkバグ完全再現防止テスト
///
/// ## 背景
///
/// loop_builder.rs で以下のバグがあった:
/// ```rust
/// // ❌ ValueId(0) を「常に未初期化」と誤判定
/// for (name, value) in &current_vars {
/// if value.0 == 0 { // ← Parameter s=ValueId(0) も弾く!
/// return Ok(ValueId(0));
/// }
/// }
/// ```
///
/// ## 検証内容
///
/// Phase 26-A実装により、ValueId(0)でも正しくパラメータと判定できるようになった
#[test]
fn test_guard_bug_prevention_full_flow() {
// MirBuilder作成
let mut builder = MirBuilder::new();
// Phase 26-A-3: パラメータ型を手動登録(実際は setup_function_params() で自動登録)
// skip_whitespace(s, idx) を想定
let s_value_id = ValueId(0);
let idx_value_id = ValueId(1);
builder.register_value_kind(s_value_id, MirValueKind::Parameter(0));
builder.register_value_kind(idx_value_id, MirValueKind::Parameter(1));
// ローカル変数Temporary
let local_value_id = ValueId(2); // 未登録 → デフォルトTemporary扱い
// Phase 26-A-2: get_value_kind() で型情報を取得可能
let s_kind = builder.get_value_kind(s_value_id);
let idx_kind = builder.get_value_kind(idx_value_id);
// Phase 26-A-4: is_value_parameter() で型安全判定
// ✅ GUARD checkバグ修正: ValueId(0) でも正しくパラメータ判定!
assert!(
builder.is_value_parameter(s_value_id),
"ValueId(0) はパラメータ s であり、未初期化ではない!"
);
assert!(
builder.is_value_parameter(idx_value_id),
"ValueId(1) はパラメータ idx"
);
assert!(
!builder.is_value_parameter(local_value_id),
"ValueId(2) はパラメータではない"
);
// 型情報の詳細検証
assert_eq!(
s_kind,
Some(MirValueKind::Parameter(0)),
"s は Parameter(0) として登録されている"
);
assert_eq!(
idx_kind,
Some(MirValueKind::Parameter(1)),
"idx は Parameter(1) として登録されている"
);
}
/// 複雑なパラメータパターンのテスト
///
/// インスタンスメソッドの暗黙的 receiver (me) も含む
#[test]
fn test_instance_method_parameters() {
let mut builder = MirBuilder::new();
// インスタンスメソッド: Box.process(arg1, arg2)
// → 実際のパラメータ: (me, arg1, arg2)
builder.register_value_kind(ValueId(0), MirValueKind::Parameter(0)); // me
builder.register_value_kind(ValueId(1), MirValueKind::Parameter(1)); // arg1
builder.register_value_kind(ValueId(2), MirValueKind::Parameter(2)); // arg2
// receiver (me) = ValueId(0)
// arg1 = ValueId(1)
// arg2 = ValueId(2)
assert!(builder.is_value_parameter(ValueId(0)), "receiver me");
assert!(builder.is_value_parameter(ValueId(1)), "arg1");
assert!(builder.is_value_parameter(ValueId(2)), "arg2");
assert!(!builder.is_value_parameter(ValueId(3)), "not parameter");
// 型情報確認
assert_eq!(
builder.get_value_kind(ValueId(0)),
Some(MirValueKind::Parameter(0))
);
assert_eq!(
builder.get_value_kind(ValueId(1)),
Some(MirValueKind::Parameter(1))
);
assert_eq!(
builder.get_value_kind(ValueId(2)),
Some(MirValueKind::Parameter(2))
);
}
/// ループ内でのパラメータ/ローカル変数の区別テスト
///
/// loop_builder.rs の実際のユースケース
#[test]
fn test_loop_parameter_vs_local_distinction() {
let mut builder = MirBuilder::new();
// Phase 26-A-2: new_typed_value() で各種ValueId作成
let limit = builder.new_typed_value(MirValueKind::Parameter(0)); // パラメータ
let i = builder.new_typed_value(MirValueKind::Local(0)); // ローカル変数
let sum = builder.new_typed_value(MirValueKind::Local(1)); // ローカル変数
let carrier = builder.new_typed_value(MirValueKind::LoopCarrier); // ループキャリア
// パラメータ判定
assert!(
builder.is_value_parameter(limit.value_id()),
"limit はパラメータ"
);
assert!(
!builder.is_value_parameter(i.value_id()),
"i はローカル変数"
);
assert!(
!builder.is_value_parameter(sum.value_id()),
"sum はローカル変数"
);
assert!(
!builder.is_value_parameter(carrier.value_id()),
"carrier はループキャリア"
);
// 型情報確認
assert_eq!(
builder.get_value_kind(limit.value_id()),
Some(MirValueKind::Parameter(0))
);
assert!(builder.get_value_kind(i.value_id()).unwrap().is_local());
assert!(builder
.get_value_kind(carrier.value_id())
.unwrap()
.is_loop_carrier());
}
/// パラメータなし関数のテスト
#[test]
fn test_no_parameters_function() {
let builder = MirBuilder::new();
// 関数: main() - パラメータなし
// ValueId(0) からすべて未登録デフォルトTemporary扱い
assert!(!builder.is_value_parameter(ValueId(0)));
assert!(!builder.is_value_parameter(ValueId(1)));
assert!(!builder.is_value_parameter(ValueId(2)));
}