Skip to main content

Crate ridl_diff

Crate ridl_diff 

Source
Expand description

The ridl diff IR-snapshot compare engine.

The engine compares two resolved IR v2 snapshots and classifies every difference as a Change with a Category and a Verdict. It reads only the IR — never source — so the comparison is honest against exactly what a backend sees (ADR-0008 decision 14, concept note §9.1). Placement is deliberate: this crate is an engine surfaced by the ridl facade, never by ridlc, so the compiler stays a pure source→IR function (the ISO 26262 tool-qualification boundary, ADR-0008 decision 9).

The comparison has two halves. The walk ([walk]) says what structurally differs, emitting one Change per difference with a Category; the classifier (classify) says which direction that difference moved in and settles its Verdict. Splitting them is what lets a single structural category — an appended interaction, a changed timing — carry opposite verdicts depending on the direction, without the walk needing both snapshots at every emission site.

This module owns the vocabulary (Verdict, Category, Change, DiffReport), the set-level comparison (diff_sets, and diff_workspaces with the system headings of system), and rendering (render_text, render_json). It re-exports the snapshot loader load_ir_json from ridl-ir, which owns it. The classification table itself is documented per category by explain, which ridl diff --explain prints.

Re-exports§

pub use system::SystemChange;
pub use system::SystemHeading;
pub use system::diff_systems;
pub use unit_verdict::UnitVerdicts;
pub use unit_verdict::unit_verdict;

Modules§

system
ridl diff at the system (rsdl reference §14): the changes to a lowered system that are not contract changes.
unit_verdict
The verdict of a DiffReport restricted to one unit.

Structs§

Change
One difference between two snapshots, with an honest path into the IR and the rendered before/after values where they apply.
ContextError
An explicit podbuf comparison cannot use its own side’s remote evidence.
ContextIssue
Unusable evidence for a consumer-owned podbuf comparison.
DiffReport
The result of a comparison: every change and the report-level verdict (the maximum verdict over the changes; Verdict::Identical when there are none).

Enums§

Category
The kind of a single difference. The walk emits the structural categories; the classifier maps them to directional verdicts.
ContextIssueReason
Why remote evidence cannot establish inline compatibility.
ContextSide
The side whose remote evidence cannot establish inline compatibility.
LoadError
An error loading an .ir.json snapshot with load_ir_json.
Verdict
The compatibility verdict of a change or of a whole report — ordered so Breaking > Compatible > Identical and a report’s verdict is the maximum over its changes.

Constants§

CATEGORIES
Every category, in the order --explain lists them when asked for an unknown one.

Functions§

absence_refused
Whether a reader built against new_set refuses a payload in which the field member of struct container, in package package, is absent — the rule that makes an appended field breaking for its type (driftsys/ridl#598). context holds packages that references resolve against without being compared, such as ridl.std. false when container is not a struct of that package. The ridl check desk check reads it to say so in its RIDL-407 message for an append that also sits beside a moved sibling.
category_from_word
Parses the snake_case word a report prints back into its category, so ridl diff --explain <category> takes exactly what the report shows.
category_word
The stable snake_case word for a category — the single source of truth for both renderers and for ridl diff --explain, which takes a category exactly as the report prints it.
classify
Classifies one change against the two snapshots it was drawn from.
diff_packages
Compares two resolved packages. Matched packages share a name; the new package’s name is used as the path prefix.
diff_refs_in
diff_sets_in over borrowed packages, for a caller that holds the packages by reference and would otherwise clone them. The comparison is judged for no encoding: diff_refs_with with an empty list.
diff_refs_with
diff_refs_in, judged for encodings: the names a [backend.<name>] encodings list writes (flatbuffers, proto3, podbuf). A snapshot does not carry the encodings a workspace builds, so the caller names them.
diff_refs_with_contexts
Compares packages using independent source-side resolution scopes. Missing remote evidence prevents only an explicit podbuf judgment. Context packages resolve references without being compared themselves. Local packages take precedence over context packages with the same name. Growth is reported once per old consumer path and remote declaration; issues are sorted by consumer path, declaration, then side.
diff_refs_with_contexts_partial
Compares complete scopes while retaining independent missing-evidence issues. The report is not an affirmative compatibility judgment for any unit that owns or reaches an issue’s consumer declaration. Such units require recovery; callers may use the report’s proved verdicts for unaffected units. Remote FlatBuffers and proto3 widths are reported once per consumer path and remote declaration reached by a surviving old consumer use, at the consumer path, with <remote declaration>: <integer> values. Only the per-side context entry points report remote widths; a side without remote context draws no such line.
diff_sets
Compares two sets of resolved packages, matching by package name, and interface numbers within each unit ([walk::Matching]). A package present only on the new side is a Category::DeclAdded; matched packages are walked pairwise. A package present only on the old side is a Category::DeclRemoved when its whole unit is gone from the new side, and is walked declaration by declaration when the unit is still there, so that an interface whose number moved to another package of the unit is Category::InterfaceRenamed and one the unit retired is Category::InterfaceRetired.
diff_sets_in
diff_sets, with context: packages that a type reference resolves against without being compared. This entry point shares one context. ridl diff and the MCP server use per-side contexts through diff_workspaces_with_contexts: the built-in ridl.std plus each side’s own remote packages, compiled from source or retained in a snapshot directory, so historical layouts never borrow current remote definitions. ridl check’s baseline desk check passes one shared context and judges no encoding.
diff_workspaces
Compares two workspaces at the system (rsdl reference §14): the packages by the ridl categories, exactly as diff_sets does, and — when both sides carry a lowered system — the system’s placement and composition changes, which carry no verdict, and its instance number changes, which make the report breaking. A system on one side only is not compared: there is nothing to compare it against.
diff_workspaces_with
diff_workspaces, judged for encodings (diff_refs_with).
diff_workspaces_with_contexts
Compares workspace packages with independent side contexts and, when both sides carry a system, lists the system changes, of which only an instance number change enters the verdict, as breaking (diff_workspaces_with). Missing remote evidence is an error for an explicit podbuf comparison.
explain
The rule row for a category: the classification table of ADR-0008 decision 14 as text. This is the CI-facing documentation of record until the E4 error index publishes it.
heading
The heading a category’s changes are grouped under in the text report, or None for a category listed plainly. Five headings exist. “compatible on the wire, visible in source” is for a change that exits 0 but that a consumer sees in its source — an interface renamed on its number changes the generated identity-table names in both wire backends, and an interface leaving a service’s set stops the service.member addresses of that interface resolving under the service. “compatible on the wire, may change the catalog hash” is for a change that exits 0 but can change the catalog hash, which a generated face compares with its peer’s — a number ridl lock froze in place, which always changes it, and an enum or enum-set body reordered, which changes it when an interface reaches the enum or enum set (the hash covers only the declarations an interface reaches). “breaking under podbuf” is for a change whose verdict depends on the encodings the comparison is judged for (diff_refs_with): it exits 0 unless podbuf is among them. “breaking under flatbuffers” follows the same rule for flatbuffers, and “breaking under proto3” for proto3. Each such category’s --explain text states its own consequence; the JSON report carries the category word and no heading field.
is_above_high_water
Whether slot is above every slot in held, which is the append rule for one new member: the member keeps every existing ordinal or value, and it does not reuse a retired one (typl §7.4).
load_ir_json
Loads an .ir.json snapshot written by ridl build --emit ir-json — canonical protobuf JSON, read through from_json, the one reader every surface shares (ADR-0014 decision 1).
render_json
Renders a report as machine-readable JSON with the stable schema {"verdict", "changes": [{"path", "category", "verdict", "before", "after"}]}.
render_text
Renders a report as a human-readable summary: the report verdict on the first line, then one indented line per change. A change whose category has no heading is listed first, in report order; then each heading is printed once, as its own line ending in a colon, followed by the changes under it, in report order. Headings come in CATEGORIES order.