/// 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 ¤t_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))); }