//! 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
//!
//! ## Design
//!
//! - Input: `&StepTree` with pre-computed contract
//! - No AST re-analysis (contract-only decisions)
//! - Single responsibility: structure → JoinIR conversion
use crate::mir::control_tree::step_tree::StepTree;
use crate::mir::join_ir::lowering::carrier_info::{ExitMeta, JoinFragmentMeta};
use crate::mir::join_ir::JoinModule;
use super::contracts::{check_if_only, CapabilityCheckResult};
/// Box-First: StepTree → Normalized shadow lowering
pub struct StepTreeNormalizedShadowLowererBox;
impl StepTreeNormalizedShadowLowererBox {
/// Try to lower an if-only StepTree to normalized form
///
/// ## Returns
///
/// - `Ok(None)`: Out of scope (e.g., contains loops)
/// - `Ok(Some(...))`: Shadow generation succeeded
/// - `Err(...)`: Should be supported but conversion failed (internal error)
///
/// ## Contract
///
/// - Only processes if-only patterns (no loops/breaks/continues)
/// - Uses contract information only (no AST re-analysis)
/// - Dev-only: caller must check `joinir_dev_enabled()` before calling
///
/// ## Phase 122 Implementation
///
/// - Generates Normalized JoinIR (env + continuation)
/// - env layout: writes only (SSOT)
/// - merge = join_k(env) tail-call (no PHI)
/// - Minimal node support: If/Return/Assign(Const/Variable/BinOp(Add))
pub fn try_lower_if_only(
step_tree: &StepTree,
) -> Result