diff --git a/src/mir/builder/calls/lowering.rs b/src/mir/builder/calls/lowering.rs index eaab73a3..84cc7f5a 100644 --- a/src/mir/builder/calls/lowering.rs +++ b/src/mir/builder/calls/lowering.rs @@ -203,9 +203,14 @@ impl MirBuilder { if dev { use crate::mir::control_tree::normalized_shadow::StepTreeNormalizedShadowLowererBox; use crate::mir::control_tree::normalized_shadow::parity; + use crate::mir::control_tree::normalized_shadow::available_inputs_collector::AvailableInputsCollectorBox; + + // Phase 126: Collect available_inputs from SSOT sources + // Note: CapturedEnv is None for now (if-only patterns don't use CapturedEnv yet) + let available_inputs = AvailableInputsCollectorBox::collect(self, None); // Try shadow lowering (if-only scope) - let shadow_result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let shadow_result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); match shadow_result { Ok(Some((module, _meta))) => { diff --git a/src/mir/control_tree/normalized_shadow/builder.rs b/src/mir/control_tree/normalized_shadow/builder.rs index 9797aa13..b540b379 100644 --- a/src/mir/control_tree/normalized_shadow/builder.rs +++ b/src/mir/control_tree/normalized_shadow/builder.rs @@ -16,6 +16,8 @@ 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 crate::mir::ValueId; // Phase 126 +use std::collections::BTreeMap; // Phase 126 use super::contracts::{check_if_only, CapabilityCheckResult}; @@ -89,21 +91,27 @@ impl StepTreeNormalizedShadowLowererBox { /// - Uses contract information only (no AST re-analysis) /// - Dev-only: caller must check `joinir_dev_enabled()` before calling /// - /// ## Phase 122 Implementation + /// ## Phase 122-126 Implementation /// /// - Generates Normalized JoinIR (env + continuation) - /// - env layout: writes only (SSOT) + /// - env layout: writes + inputs (Phase 125-126) /// - merge = join_k(env) tail-call (no PHI) /// - Minimal node support: If/Return/Assign(Const/Variable/BinOp(Add)) + /// + /// ## Phase 126: available_inputs + /// + /// - available_inputs: function params + CapturedEnv (SSOT) + /// - inputs = reads ∩ available_inputs (deterministic order) pub fn try_lower_if_only( step_tree: &StepTree, + available_inputs: &BTreeMap, ) -> Result, String> { // Phase 121 P1: Capability check (if-only scope) let capability = check_if_only(step_tree); match capability { CapabilityCheckResult::Supported => { - // Phase 122-123: Generate Normalized JoinModule - Self::lower_if_only_to_normalized(step_tree) + // Phase 122-126: Generate Normalized JoinModule + Self::lower_if_only_to_normalized(step_tree, available_inputs) } CapabilityCheckResult::Unsupported(_reason) => { // Out of scope for Phase 121/122 @@ -112,7 +120,7 @@ impl StepTreeNormalizedShadowLowererBox { } } - /// Lower if-only StepTree to Normalized JoinModule (Phase 122-125) + /// Lower if-only StepTree to Normalized JoinModule (Phase 122-126) /// /// ## Design /// @@ -120,31 +128,33 @@ impl StepTreeNormalizedShadowLowererBox { /// - merge 形式: `join_k(env)` への tail-call(PHI 禁止) /// - 対応ノード: If/Return/Assign(最小セット) /// - /// ## Phase 123-125 Node Support + /// ## Phase 123-126 Node Support /// /// - Return(Integer literal): `Const + Ret(Some(vid))` /// - Return(Variable from writes): Phase 124 - /// - Return(Variable from inputs): Phase 125 (reads-only) + /// - Return(Variable from inputs): Phase 125-126 (reads-only) /// - Return(void): `Ret(None)` /// - If(minimal compare): Compare with Integer literal only /// + /// ## Phase 126: available_inputs + /// + /// - available_inputs: function params + CapturedEnv (SSOT) + /// - inputs = reads ∩ available_inputs (deterministic order) + /// /// ## Returns /// /// - `Ok(Some((module, meta)))`: Normalized JoinModule生成成功 - /// - `Ok(None)`: Out of scope for Phase 123-125 (unsupported patterns) + /// - `Ok(None)`: Out of scope for Phase 123-126 (unsupported patterns) /// - `Err(msg)`: 生成できるはずなのに失敗(内部エラー) fn lower_if_only_to_normalized( step_tree: &StepTree, + available_inputs: &BTreeMap, ) -> Result, String> { use crate::mir::join_ir::{JoinFunction, JoinFuncId, JoinInst}; use crate::mir::ValueId; - use std::collections::BTreeMap; - // Phase 125 P2: available_inputs (P3 で配線、今は空) - let available_inputs: BTreeMap = BTreeMap::new(); - - // Phase 125 P2: EnvLayout 生成 - let env_layout = EnvLayout::from_contract(&step_tree.contract, &available_inputs); + // Phase 126: EnvLayout 生成(available_inputs を使用) + let env_layout = EnvLayout::from_contract(&step_tree.contract, available_inputs); let main_func_id = JoinFuncId::new(0); @@ -679,7 +689,8 @@ mod tests { #[test] fn test_if_only_supported() { let tree = make_if_only_tree(); - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); assert!(result.unwrap().is_some()); } @@ -687,7 +698,8 @@ mod tests { #[test] fn test_loop_rejected() { let tree = make_loop_tree(); - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); assert!(result.unwrap().is_none()); } @@ -728,7 +740,8 @@ mod tests { }; // Lower to JoinModule - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); let (module, _meta) = result.unwrap().expect("Should generate JoinModule"); @@ -772,7 +785,8 @@ mod tests { }; // Lower to JoinModule - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); let (module, _meta) = result.unwrap().expect("Should generate JoinModule"); @@ -818,7 +832,8 @@ mod tests { // Phase 125 P4: Lower to JoinModule - should return Ok(None) // because x is in reads but not in available_inputs (not in env) - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); let option = result.unwrap(); assert!(option.is_none(), "Should return None when variable is in reads but not available as input"); @@ -876,7 +891,8 @@ mod tests { }; // Lower to JoinModule - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); let (module, _meta) = result.unwrap().expect("Should generate JoinModule"); @@ -924,7 +940,8 @@ mod tests { }; // Lower to JoinModule - should succeed - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); let option = result.unwrap(); @@ -980,7 +997,8 @@ mod tests { // Phase 125 P2-P4: Lower to JoinModule // Because available_inputs is empty (P3 not wired), x won't be in inputs // So this should return Ok(None) (out of scope) - let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree); + let available_inputs = BTreeMap::new(); // Phase 126: empty for unit tests + let result = StepTreeNormalizedShadowLowererBox::try_lower_if_only(&tree, &available_inputs); assert!(result.is_ok()); let option = result.unwrap();