//! Phase 121: StepTree → JoinModule shadow lowering (if-only) //! //! ## Responsibility //! //! - Convert StepTree to JoinModule (Normalized dialect) //! - Only for if-only patterns (no loops) //! - Returns None for out-of-scope patterns //! - Returns Err for patterns that should be supported but conversion failed use crate::mir::control_tree::normalized_shadow::env_layout::{ expected_env_field_count as calc_expected_env_fields, EnvLayout, }; use crate::mir::control_tree::normalized_shadow::if_as_last_join_k::IfAsLastJoinKLowererBox; use crate::mir::control_tree::normalized_shadow::legacy::LegacyLowerer; use crate::mir::control_tree::step_tree::StepTree; use crate::mir::join_ir::lowering::carrier_info::JoinFragmentMeta; use crate::mir::join_ir::JoinModule; use crate::mir::ValueId; // Phase 126 use std::collections::BTreeMap; // Phase 126 use super::contracts::{check_if_only, CapabilityCheckResult}; /// Box-First: StepTree → Normalized shadow lowering pub struct StepTreeNormalizedShadowLowererBox; impl StepTreeNormalizedShadowLowererBox { /// Phase 129-B: Expected env field count (writes + inputs) pub fn expected_env_field_count( step_tree: &StepTree, available_inputs: &BTreeMap, ) -> usize { calc_expected_env_fields(step_tree, available_inputs) } /// Phase 129-B: If-as-last shape detection (no post-if) pub fn expects_join_k_as_last(step_tree: &StepTree) -> bool { IfAsLastJoinKLowererBox::expects_join_k_as_last(step_tree) } /// Try to lower an if-only StepTree to normalized form /// /// - `Ok(None)`: Out of scope (e.g., contains loops) /// - `Ok(Some(...))`: Shadow generation succeeded /// - `Err(...)`: Should be supported but conversion failed (internal error) pub fn try_lower_if_only( step_tree: &StepTree, available_inputs: &BTreeMap, ) -> Result, String> { let capability = check_if_only(step_tree); match capability { CapabilityCheckResult::Supported => { Self::lower_if_only_to_normalized(step_tree, available_inputs) } CapabilityCheckResult::Unsupported(_reason) => Ok(None), } } /// Lower if-only StepTree to Normalized JoinModule (Phase 122-126) fn lower_if_only_to_normalized( step_tree: &StepTree, available_inputs: &BTreeMap, ) -> Result, String> { // Phase 126: EnvLayout 生成(available_inputs を使用) let env_layout = EnvLayout::from_contract(&step_tree.contract, available_inputs); // Phase 129-B: If-as-last join_k lowering (dev-only) if let Some((module, meta)) = IfAsLastJoinKLowererBox::lower(step_tree, &env_layout)? { return Ok(Some((module, meta))); } // Legacy path (Phase 123-128 scope) LegacyLowerer::lower_if_only_to_normalized(step_tree, &env_layout) } /// Dev log helper for out-of-scope cases pub fn get_status_string(step_tree: &StepTree) -> String { format!( "shadow=skipped signature_basis={}", step_tree.signature_basis_string() ) } }