Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[workspace]
resolver = "2"
members = ["crates/own-ir", "crates/own-syntax", "crates/own-cfg", "crates/own-diagnostics", "crates/own-analysis", "crates/own-lowered"]
members = ["crates/own-ir", "crates/own-syntax", "crates/own-cfg", "crates/own-diagnostics", "crates/own-analysis", "crates/own-lowered", "crates/own-bridge"]

[workspace.package]
edition = "2021"
Expand Down
20 changes: 20 additions & 0 deletions rust/crates/own-bridge/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The OwnIR -> Layer 2 lowering (P-022 #259 slice 3): a pure transformation
# crate. Production API is `OwnIr -> Result<LoweredDocument, BridgeError>` —
# no filesystem, no CLI, no diagnostics, no analysis side effects; fixture
# I/O lives only in the integration tests.
[package]
name = "own-bridge"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
publish.workspace = true
description = "OwnIR facts -> normalized Layer 2 lowering (Python to_module parity)"

[dependencies]
own-ir = { path = "../own-ir" }
own-lowered = { path = "../own-lowered" }
serde_json.workspace = true

[lints]
workspace = true
52 changes: 52 additions & 0 deletions rust/crates/own-bridge/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! `own-bridge` — the `OwnIR` facts → Layer 2 lowering (P-022 #259 slice 3).
//!
//! The Rust port of `ownlang/ownir.py::to_module` **restricted to the behavior
//! the shared Layer 2 fixtures exercise**: routing R1–R6, global `sub_`/`cap_`
//! and `parg_`/`loc_` handle minting, capture/DI lifetime regions, flow
//! lowering with the local map and kill-on-rebind, branch-local hoisting with
//! its negative gates, `alias_join`, unmapped references, call lowering, the
//! `$consume`/`$borrow`/`$borrow_mut` channels, the precise-overload channel
//! vs the merged-may kill site, in-branch untrack vs top-level kill site,
//! fresh-result minting, and the fail-loud flow-op vocabulary.
//!
//! **Pure transformation**: [`lower`] maps a typed [`own_ir::OwnIr`] document
//! to an [`own_lowered::LoweredDocument`] (or a [`BridgeError`] whose message
//! text is part of the parity surface — Python projects it as the `Rejected`
//! form). No filesystem, no CLI, no diagnostics, no analysis. The tolerant
//! door, `OwnIR` validation parity, MOS contract *changes*, and analysis
//! wiring are all out of scope (#294 stays open; the `tolerant_unknown_kind`
//! fixture stays Python-only).
//!
//! The oracle is byte-exact: for every `rust_replay: true` manifest case,
//! `facts → OwnIr::from_json → lower → own_lowered::to_canonical_json` must
//! equal the committed Python golden (`tests/replay.rs`). The goldens are
//! expected output ONLY — never an input to construction.

mod lower;
mod mos;

use own_ir::OwnIr;
use own_lowered::LoweredDocument;

/// A lowering rejection — the Rust twin of Python's `OwnIRError` from
/// `to_module`. The message TEXT is part of the Layer 2 parity surface
/// (a fail-loud golden pins it byte-for-byte).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BridgeError(pub String);

impl std::fmt::Display for BridgeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}

impl std::error::Error for BridgeError {}

/// Lower one `OwnIR` facts document into the normalized Layer 2 document.
///
/// # Errors
/// [`BridgeError`] on vocabulary skew the reference bridge fails loud on
/// (e.g. an unknown flow op); the message text matches Python's `OwnIRError`.
pub fn lower(facts: &OwnIr) -> Result<LoweredDocument, BridgeError> {
lower::lower(facts)
}
Loading
Loading