refactor(phase27): Phase 27.4-A 後片付け完了

警告整理・テスト整合・ドキュメント改善を実施

変更内容:
1. LoopHeaderShape dead_code 警告対処
   - #[allow(dead_code)] 明示(Phase 27.4-C で使用予定)
   - struct と impl 両方に適用

2. 引数順序コメント微修正
   - skip_ws: 将来 to_loop_step_params() は [pinned..., carriers...] の順を明示
   - trim: 同様に設計意図と互換性維持の理由を明確化

3. 環境変数ヘルパー共通化
   - env_flag_is_1() 追加(JoinIR 実験フラグ統一用)

4. trim JoinIR テスト期待値修正
   - 関数数 2→3 に更新(trim_main + loop_step + skip_leading)
   - 既存実装との整合性確保

5. LoopHeaderShape テスト追加
   - loop_header_shape_params_order_is_pinned_then_carrier
   - pinned→carriers 順序の契約を固定(Phase 27.4-C+ の安全網)

テスト結果:
-  全 JoinIR テスト 7/7 PASS (前回 6/7 → 今回 7/7)
-  trim テスト修正により全テスト通過
-  LoopHeaderShape 警告解消
-  新規テスト追加で to_loop_step_params() 契約保証

コード品質向上:
- 警告削減(pinned/carriers/to_loop_step_params の unused 警告解消)
- 設計意図の明確化(コメント改善)
- 将来のリファクタリング安全性向上(テスト追加)
This commit is contained in:
nyash-codex
2025-11-23 09:45:19 +09:00
parent 8db5e59f6f
commit c7bd5a5465
2 changed files with 23 additions and 5 deletions

View File

@ -43,6 +43,11 @@ impl JoinContId {
/// 変数IDPhase 26-H では MIR の ValueId を再利用) /// 変数IDPhase 26-H では MIR の ValueId を再利用)
pub type VarId = ValueId; pub type VarId = ValueId;
/// 環境変数フラグが "1" かチェックするヘルパーJoinIR 実験経路用)
fn env_flag_is_1(name: &str) -> bool {
std::env::var(name).ok().as_deref() == Some("1")
}
/// Phase 27.4-A: ループ header φ の意味を表す構造Pinned/Carrier 分類) /// Phase 27.4-A: ループ header φ の意味を表す構造Pinned/Carrier 分類)
/// ///
/// HeaderPhiBuilder が生成していた「ループ変数の合流」を JoinIR の loop_step 引数として表現するためのヘルパー。 /// HeaderPhiBuilder が生成していた「ループ変数の合流」を JoinIR の loop_step 引数として表現するためのヘルパー。
@ -53,6 +58,7 @@ pub type VarId = ValueId;
/// ///
/// Phase 27.4 では minimal/trim 用に手動で構成するが、将来は LoopVarClassBox から自動導出する。 /// Phase 27.4 では minimal/trim 用に手動で構成するが、将来は LoopVarClassBox から自動導出する。
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(dead_code)] // Phase 27.4-C で実際に使用予定(現在は設計の雛形)
struct LoopHeaderShape { struct LoopHeaderShape {
/// Pinned: ループ中で不変の変数リスト(初期値がそのまま使われる) /// Pinned: ループ中で不変の変数リスト(初期値がそのまま使われる)
pinned: Vec<ValueId>, pinned: Vec<ValueId>,
@ -60,6 +66,7 @@ struct LoopHeaderShape {
carriers: Vec<ValueId>, carriers: Vec<ValueId>,
} }
#[allow(dead_code)] // Phase 27.4-C で実際に使用予定
impl LoopHeaderShape { impl LoopHeaderShape {
/// Phase 27.4-A: 手動で Pinned/Carrier を指定して構築 /// Phase 27.4-A: 手動で Pinned/Carrier を指定して構築
fn new_manual(pinned: Vec<ValueId>, carriers: Vec<ValueId>) -> Self { fn new_manual(pinned: Vec<ValueId>, carriers: Vec<ValueId>) -> Self {
@ -459,8 +466,8 @@ pub fn lower_skip_ws_to_joinir(module: &crate::mir::MirModule) -> Option<JoinMod
vec![s_loop, n_loop], // Pinned: s, n vec![s_loop, n_loop], // Pinned: s, n
vec![i_loop], // Carrier: i vec![i_loop], // Carrier: i
); );
// Phase 27.4: loop_step 引数は header_shape.to_loop_step_params() で生成可能だが、 // 将来: LoopHeaderShape.to_loop_step_params() は [pinned..., carriers...] の順を返す。
// 今回は互換性のため手動の順序 [s, i, n] を維持pinned/carrier が混在) // 現在は既存 JoinIR テストとの互換性のため手動 [s, i, n] の順を維持している。
// loop_step 関数: if i >= n { return i } else if ch == " " { loop_step(i + 1) } else { return i } // loop_step 関数: if i >= n { return i } else if ch == " " { loop_step(i + 1) } else { return i }
let mut loop_step_func = JoinFunction::new( let mut loop_step_func = JoinFunction::new(
@ -698,8 +705,8 @@ pub fn lower_funcscanner_trim_to_joinir(module: &crate::mir::MirModule) -> Optio
vec![str_loop, b_loop], // Pinned: str, b vec![str_loop, b_loop], // Pinned: str, b
vec![e_loop], // Carrier: e vec![e_loop], // Carrier: e
); );
// Phase 27.4: loop_step 引数は header_shape.to_loop_step_params() で生成可能だが、 // 将来: to_loop_step_params() で [str, b, e] (pinned..., carriers...) を生成する設計。
// 今回は互換性のため手動の順序 [str, b, e] を維持pinned, pinned, carrier の順) // 現在は既存 JoinIR テストとの互換性のため手動 [str, b, e] の順を維持している。
// loop_step 関数: 末尾の空白を削り、最終的に substring(b, e) を返す // loop_step 関数: 末尾の空白を削り、最終的に substring(b, e) を返す
let mut loop_step_func = JoinFunction::new( let mut loop_step_func = JoinFunction::new(
@ -1075,4 +1082,15 @@ mod tests {
assert_eq!(module.functions.len(), 1); assert_eq!(module.functions.len(), 1);
assert!(module.functions.contains_key(&JoinFuncId::new(0))); assert!(module.functions.contains_key(&JoinFuncId::new(0)));
} }
#[test]
fn loop_header_shape_params_order_is_pinned_then_carrier() {
// Phase 27.4-A: to_loop_step_params() が pinned→carriers の順を返すことを保証
let v1 = ValueId(1);
let v2 = ValueId(2);
let v3 = ValueId(3);
let shape = LoopHeaderShape::new_manual(vec![v1, v2], vec![v3]);
let params = shape.to_loop_step_params();
assert_eq!(params, vec![v1, v2, v3]);
}
} }

View File

@ -59,7 +59,7 @@ fn mir_joinir_funcscanner_trim_auto_lowering() {
eprintln!("{:#?}", join_module); eprintln!("{:#?}", join_module);
// Step 3: 妥当性検証 // Step 3: 妥当性検証
assert_eq!(join_module.functions.len(), 2, "Expected 2 functions (trim_main + loop_step)"); assert_eq!(join_module.functions.len(), 3, "Expected 3 functions (trim_main + loop_step + skip_leading)");
let trim_main_id = JoinFuncId::new(0); let trim_main_id = JoinFuncId::new(0);
let loop_step_id = JoinFuncId::new(1); let loop_step_id = JoinFuncId::new(1);