You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Agent brief — tier: strong. One PR (Closes #<this>); branch from main. House rules: AGENTS.md.
Goal
Step 4 of the P-022 strangler-fig migration, next after the merged own-cfg (#197/#203): the analysis heart. Port the generic worklist solver and the four analyses (ownership → then lifetime → effect → DI) to rust/crates/own-analysis, plus the minimal own-diagnosticstypes crate it constructs into. Python stays the reference; a divergence is a Rust bug until separately proven otherwise.
Sources of truth
docs/proposals/P-022-rust-core-migration.md — crate DAG (the load-bearing edges: own-analysis → own-diagnostics; own-diagnostics depends ONLY on the own-ir span leaf, never the parser or the solver), the idioms table (bitset lattice over {OWNED,MOVED,RELEASED,ESCAPED}, dense Vec by RID, RPO worklist scheduling, exhaustive match), and the migration order in §strategy step 4: diff diagnostics (line, code) first → then evidence → then SARIF, layer by layer.
ownlang/analysis.py, ownlang/ownership.py, ownlang/lifetimes.py, ownlang/effects.py, ownlang/di.py, ownlang/buffers.py — the reference implementations.
spec/Inference.md (MOS S/R/F/A/M-rules) and spec/OwnCore.md, spec/Diagnostics.md — normative behaviour.
The feat: P-022 step 3 — port own-cfg (AST → CFG lowering) with exact CFG-JSON parity #203 parity pattern: tests/test_cfg_fixtures.py + tests/fixtures/cfg_parity.json + own-cfg/tests/parity.rs — extend the same fixture-freezing approach to the diagnostics layer (Python emits the golden (path, line, code) sets over corpus/ + examples/ + tests/fixtures/ + curated cases; Rust replays and must match exactly, incl. intra-tie ordering).
Deliverable
rust/crates/own-diagnostics (Diagnostic/Evidence data types only — presentation/SARIF is step 5, out of scope).
rust/crates/own-analysis: Lattice/Analysis traits + one generic worklist solver + the four analyses as independent impls (the de-noodling of Python's interleaved _Analyzer).
No behaviour changes; exact parity on (line, code) per input — evidence-slice and SARIF parity are later steps, do not fake them now.
Cargo edge test (cargo metadata) asserting the allowed DAG edges from P-022 §fitness (diagnostics never depends on analysis; codegen untouched).
Workspace lints stand (unsafe_code = "forbid", the pre-resolved indexing_slicing allowance for arena/newtype access only).
Correctness first: no perf micro-опт before parity is green; the P-022 perf doctrine (bitset, RPO, FxHashMap) is the starting shape, not an optimization pass.
If a Python behaviour looks like a bug mid-port — do NOT fix it in Rust; note it in the PR and keep parity (a deliberate divergence is a separate, Python-first change).
Done when
Full-corpus diagnostics parity green in CI (rust job + the new fixture check in run_tests.py), cargo fmt/clippy/test clean, DAG edge test in place, Python side untouched except the parity-fixture generator.
Agent brief — tier: strong. One PR (
Closes #<this>); branch frommain. House rules:AGENTS.md.Goal
Step 4 of the P-022 strangler-fig migration, next after the merged
own-cfg(#197/#203): the analysis heart. Port the generic worklist solver and the four analyses (ownership → then lifetime → effect → DI) torust/crates/own-analysis, plus the minimalown-diagnosticstypes crate it constructs into. Python stays the reference; a divergence is a Rust bug until separately proven otherwise.Sources of truth
docs/proposals/P-022-rust-core-migration.md— crate DAG (the load-bearing edges:own-analysis → own-diagnostics;own-diagnosticsdepends ONLY on theown-irspan leaf, never the parser or the solver), the idioms table (bitset lattice over{OWNED,MOVED,RELEASED,ESCAPED}, denseVecby RID, RPO worklist scheduling, exhaustivematch), and the migration order in §strategy step 4: diff diagnostics (line, code) first → then evidence → then SARIF, layer by layer.ownlang/analysis.py,ownlang/ownership.py,ownlang/lifetimes.py,ownlang/effects.py,ownlang/di.py,ownlang/buffers.py— the reference implementations.spec/Inference.md(MOS S/R/F/A/M-rules) andspec/OwnCore.md,spec/Diagnostics.md— normative behaviour.tests/test_cfg_fixtures.py+tests/fixtures/cfg_parity.json+own-cfg/tests/parity.rs— extend the same fixture-freezing approach to the diagnostics layer (Python emits the golden(path, line, code)sets overcorpus/+examples/+tests/fixtures/+ curated cases; Rust replays and must match exactly, incl. intra-tie ordering).Deliverable
rust/crates/own-diagnostics(Diagnostic/Evidence data types only — presentation/SARIF is step 5, out of scope).rust/crates/own-analysis:Lattice/Analysistraits + one generic worklist solver + the four analyses as independent impls (the de-noodling of Python's interleaved_Analyzer).tests/run_tests.pyand therustCI job, following feat: P-022 step 3 — port own-cfg (AST → CFG lowering) with exact CFG-JSON parity #203's ratchet conventions (regenerate on Python-core or corpus change, steady state runs zero Python).Guardrails
(line, code)per input — evidence-slice and SARIF parity are later steps, do not fake them now.cargo metadata) asserting the allowed DAG edges from P-022 §fitness (diagnostics never depends on analysis; codegen untouched).unsafe_code = "forbid", the pre-resolvedindexing_slicingallowance for arena/newtype access only).Done when
Full-corpus diagnostics parity green in CI (
rustjob + the new fixture check inrun_tests.py),cargo fmt/clippy/testclean, DAG edge test in place, Python side untouched except the parity-fixture generator.