phase29ao(p51): unify split-scan v0/v1 value-join path

This commit is contained in:
2025-12-30 21:01:12 +09:00
parent 85103dd40c
commit d5eccc23e2
5 changed files with 49 additions and 3 deletions

View File

@ -3,7 +3,7 @@
## Current Focus
- Phase: `docs/development/current/main/phases/phase-29ao/README.md`
- Next: TBD (P50 done; see `docs/development/current/main/phases/phase-29ao/README.md`)
- Next: TBD (P51 done; see `docs/development/current/main/phases/phase-29ao/README.md`)
## Gate (SSOT)

View File

@ -5,7 +5,7 @@ Scope: 「次にやる候補」を短く列挙するメモ。入口は `docs/dev
## Active
- CorePlan migration: `docs/development/current/main/phases/phase-29ao/README.md`Next: TBD, P50 done
- CorePlan migration: `docs/development/current/main/phases/phase-29ao/README.md`Next: TBD, P51 done
## Near-Term Candidates

View File

@ -34,7 +34,7 @@ Related:
## 1.1 Current (active)
- Active phase: `docs/development/current/main/phases/phase-29ao/README.md`
- Next step: TBD (P50 done)
- Next step: TBD (P51 done)
## 2. すでに固めた SSOT再発防止の土台

View File

@ -276,6 +276,11 @@ GateSSOT:
- 指示書: `docs/development/current/main/phases/phase-29ao/P50-CORELOOPCOMPOSER-V1-PATTERN3-IFPHI-VALUEJOIN-INSTRUCTIONS.md`
- ねらい: Pattern3 join を v1 で受理し、block_params/EdgeArgs 経由の PHI 一本化を維持(仕様不変)
## P51: CoreLoopComposer v1 — Pattern7 value-join path unification ✅
- 指示書: `docs/development/current/main/phases/phase-29ao/P51-CORELOOPCOMPOSER-V1-PATTERN7-VALUEJOIN-UNIFY-INSTRUCTIONS.md`
- ねらい: Pattern7 の value-join を v1 に統一し、v0 は no-join 専用に固定(仕様不変)
## Nextplanned
- Next: TBD

View File

@ -255,6 +255,47 @@ mod tests {
assert!(matches!(composed, Some(crate::mir::builder::control_flow::plan::CorePlan::Loop(_))));
}
#[test]
fn coreloop_v1_rejects_split_scan_without_value_join() {
let condition = ASTNode::Literal {
value: LiteralValue::Bool(true),
span: Span::unknown(),
};
let facts = LoopFacts {
condition_shape: ConditionShape::Unknown,
step_shape: StepShape::Unknown,
skeleton: SkeletonFacts {
kind: SkeletonKind::Loop,
},
features: LoopFeatureFacts::default(),
scan_with_init: None,
split_scan: Some(crate::mir::builder::control_flow::plan::facts::loop_facts::SplitScanFacts {
s_var: "s".to_string(),
sep_var: "sep".to_string(),
result_var: "result".to_string(),
i_var: "i".to_string(),
start_var: "start".to_string(),
shape: SplitScanShape::Minimal,
}),
pattern1_simplewhile: None,
pattern3_ifphi: None,
pattern4_continue: None,
pattern5_infinite_early_exit: None,
pattern8_bool_predicate_scan: None,
pattern9_accum_const_loop: None,
pattern2_break: None,
pattern2_loopbodylocal: None,
};
let canonical = canonicalize_loop_facts(facts);
let mut builder = MirBuilder::new();
builder.enter_function_for_test("coreloop_v1_split_scan_no_join".to_string());
let ctx =
LoopPatternContext::new(&condition, &[], "coreloop_v1_split_scan_no_join", false, false);
let composed =
try_compose_core_loop_v1(&mut builder, &canonical, &ctx).expect("Ok");
assert!(composed.is_none());
}
#[test]
fn coreloop_v1_rejects_split_scan_with_disallowed_exitmap() {
let condition = ASTNode::Literal {