Skip to content

Normalize MIR interface implementors through the canonical TIR registry#4012

Open
aaronvg wants to merge 1 commit into
canaryfrom
agent/b-884-cross-file-interface-match
Open

Normalize MIR interface implementors through the canonical TIR registry#4012
aaronvg wants to merge 1 commit into
canaryfrom
agent/b-884-cross-file-interface-match

Conversation

@aaronvg

@aaronvg aaronvg commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • build MIR runtime interface-implementor tables from TIR's canonical ImplData registry
  • remove the separate MIR walks over in-body class_data.implements and out-of-body free_impls
  • carry normalized generic arguments and associated-type bindings through the interface requires closure
  • add a multi-file runtime regression proving in-body and cross-file out-of-body syntax share the same registry after erasure to a parent interface

Root cause

TIR already normalizes both forms:

class C {
  implements I {}
}

and:

implement I for C {}

into one semantic ImplData shape containing the resolved interface, implementor pattern, generics, associated bindings, methods, and field links. The syntax origin is diagnostic metadata only.

MIR bypassed that invariant. It independently populated runtime interface membership from:

  1. class_data.implements for in-body/same-file declarations
  2. free_impls for generic out-of-body rules

A non-generic cross-file out-of-body implementation therefore existed in the canonical TIR registry—so type checking and reflection returned true—but was absent from MIR's runtime type-tag candidate set. Matching the erased provider against its child capability selected the wildcard arm.

Fix

MIR now enumerates package_impl_locs, reads each normalized impl_data, and derives runtime class candidates from for_ty_pattern. Both source syntaxes therefore take the same path. Blanket bounds are checked from canonical normalized bounds, and the interface closure receives canonical generic and associated-type bindings.

Tracks B-884.

Validation

  • paired in-body/cross-file runtime regression — passed
  • cargo nextest run -p baml_tests --test interfaces --no-fail-fast — 470 passed, 2 skipped
  • cargo nextest run -p baml_compiler2_mir — 5 passed
  • SKIP=no-commit-to-branch prek run --all-files --show-diff-on-failure --hook-stage manual — passed
  • cargo fmt --all -- --check — passed
  • git diff --check — passed

Summary by CodeRabbit

  • Bug Fixes

    • Fixed interface-implementor registration so out-of-body implements I for C rules correctly apply when the target is a concrete class without type arguments.
    • Improved interface narrowing across files so projected calls resolve to the correct implementation, including inherited requirements.
  • Tests

    • Added an async end-to-end runtime test covering cross-file interface implementations and interface narrowing behavior.

@linear

linear Bot commented Jul 14, 2026

Copy link
Copy Markdown

B-884

@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 14, 2026 6:53pm
promptfiddle Ready Ready Preview, Comment Jul 14, 2026 6:53pm
promptfiddle2 Ready Ready Preview, Comment Jul 14, 2026 6:53pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

MIR lowering now consumes canonical TIR implementation data for interface-implementor registration, propagates associated-type bindings during closure computation, and supports concrete out-of-body implementations. A multi-file runtime test verifies interface narrowing and method dispatch.

Changes

Interface implementor registration

Layer / File(s) Summary
Propagate interface closure arguments
baml_language/crates/baml_compiler2_mir/src/lower.rs
Root interface closure registration now uses impl_data.interface_args and associated-type bindings; the redundant target-argument helper was removed.
Populate canonical implementations and validate narrowing
baml_language/crates/baml_compiler2_mir/src/lower.rs, baml_language/crates/baml_tests/tests/interfaces.rs
Package population reads canonical TIR implementation locations, registers concrete and type-variable targets, and validates cross-file narrowing through an async runtime test.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • BoundaryML/baml#3672: Extends interface matching and inference for generic bounds and associated-type bindings.
  • BoundaryML/baml#3705: Updates interface dispatch and implementation resolution in lower.rs.
  • BoundaryML/baml#3896: Refactors emitted interface implementation rules and runtime resolution.

Suggested reviewers: sxlijin, codeshaunted, 2kai2kai2

Poem

A rabbit hops through TIR’s bright trail,
Interface bindings set the sail.
Classes register across the files,
Narrowing answers with runtime smiles.
“search” blooms from the compiler’s tale.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main refactor to use the canonical TIR registry for MIR interface implementor normalization.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/b-884-cross-file-interface-match

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
baml_language/crates/baml_tests/tests/interfaces.rs (1)

5631-5690: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider writing a unit test instead of an integration test.

As per coding guidelines, prefer writing Rust unit tests over integration tests where possible. Given this is a new integration test for cross-file interface matching, please evaluate if this behavior can be adequately validated via a unit test in the baml_compiler2_mir crate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/crates/baml_tests/tests/interfaces.rs` around lines 5631 -
5690, Evaluate whether cross-file interface matching in
cross_file_out_of_body_impl_matches_after_parent_interface_erasure can be
covered at the MIR level, and if so, move the test into a Rust unit-test module
in the baml_compiler2_mir crate using the closest existing MIR test helpers.
Preserve coverage of parent-interface erasure and out-of-body implementations
across files; retain the integration test only if those compiler-engine
behaviors cannot be validated adequately at MIR level.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@baml_language/crates/baml_tests/tests/interfaces.rs`:
- Around line 5631-5690: Evaluate whether cross-file interface matching in
cross_file_out_of_body_impl_matches_after_parent_interface_erasure can be
covered at the MIR level, and if so, move the test into a Rust unit-test module
in the baml_compiler2_mir crate using the closest existing MIR test helpers.
Preserve coverage of parent-interface erasure and out-of-body implementations
across files; retain the integration test only if those compiler-engine
behaviors cannot be validated adequately at MIR level.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: bbc72881-e18f-418b-b350-f51225efd3a2

📥 Commits

Reviewing files that changed from the base of the PR and between 568d4bf and abc28ff.

📒 Files selected for processing (2)
  • baml_language/crates/baml_compiler2_mir/src/lower.rs
  • baml_language/crates/baml_tests/tests/interfaces.rs

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
baml-cli Linux 🔒 22.1 MB 9.4 MB file 22.1 MB -4.1 KB (-0.0%) OK
packed-program Linux 🔒 15.8 MB 6.7 MB file 15.8 MB -8.2 KB (-0.1%) OK
baml-cli macOS 🔒 17.0 MB 8.2 MB file 17.0 MB -16 B (-0.0%) OK
packed-program macOS 🔒 12.2 MB 5.9 MB file 12.2 MB -16.5 KB (-0.1%) OK
baml-cli Windows 🔒 18.5 MB 8.4 MB file 18.5 MB -4.6 KB (-0.0%) OK
packed-program Windows 🔒 13.1 MB 6.0 MB file 13.1 MB -9.2 KB (-0.1%) OK
bridge_wasm WASM 14.6 MB 🔒 4.1 MB gzip 4.1 MB -661 B (-0.0%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

@aaronvg
aaronvg force-pushed the agent/b-884-cross-file-interface-match branch from abc28ff to 2c96901 Compare July 14, 2026 18:30
@aaronvg aaronvg changed the title Fix cross-file out-of-body interface narrowing Normalize MIR interface implementors through the canonical TIR registry Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant