Skip to content

Unify TIR Ty into baml_type::Ty - #3722

Merged
2kai2kai2 merged 10 commits into
canaryfrom
kai/tir-cleanup
Jun 9, 2026
Merged

2kai2kai2 merged 10 commits into
canaryfrom
kai/tir-cleanup

Conversation

@2kai2kai2

@2kai2kai2 2kai2kai2 commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor

Type representations for both the compiler and VM are now unified into a single location. We also use the subenum crate to represent subsets of the type system, so we can make invalid states unrepresentable in various contexts.

Rollout of the runtime/subenum types will come in a followup PR.

Summary by CodeRabbit

  • Refactor
    • Overhauled the internal type representation to richer, dedicated variants and runtime-safe mirrors.
    • Centralized and modernized type naming and rendering for consistent canonical and user-facing formats.
  • Bug Fixes / UX
    • Improved diagnostic and display strings for types (more readable, deterministic names).
    • Media and literal types now render and match more reliably across tooling (CLI, LSP, serialization).

@vercel

vercel Bot commented Jun 9, 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 Jun 9, 2026 8:44pm
promptfiddle Ready Ready Preview, Comment Jun 9, 2026 8:44pm
promptfiddle2 Ready Ready Preview, Comment Jun 9, 2026 8:44pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Introduce a shared type/name crate (qualified names, fresh literals, function-param metadata, runtime-subset conversion, and rendering strategies) and update compiler lowering, MIR/emit, runtime/VM/FFI, tooling, serialization, and tests to use the new APIs and Ty variant shapes.

Changes

Shared type and rendering

Layer / File(s) Summary
Core baml_type crate and names
baml_language/crates/baml_type/src/*, baml_language/crates/baml_type/Cargo.toml
Adds QualifiedTypeName/Package, PrimitiveType, Freshness, FunctionParamTy, RuntimeTy conversion, new Ty layout (literals carry Freshness; functions include generics and FunctionParamTy; runtime leaf variants added), rendering strategy (CanonicalTyRender), and unit-tests. subenum workspace dependency added.
baml_base small change
baml_language/crates/baml_base/src/core_types.rs
MediaKind derives PartialOrd and Ord.

Compiler & TIR

Layer / File(s) Summary
TIR lowering & inference
baml_language/crates/baml_compiler2_tir/*
Lowering, inference, narrowing, normalization, exhaustiveness, generics, throw-inference, interfaces, and package-interface updated for new Ty shapes (Int/Bigint/Float/String/Bool/Null/Uint8Array), Ty::Map { key, value, .. } struct form, Ty::optional(...), and QualifiedTypeName usage. Tests updated.
MIR / emitter
baml_language/crates/baml_compiler2_mir/*, baml_language/crates/baml_compiler2_emit/*
Replace local qtn->TypeName conversions with QualifiedTypeName usage, update literal pattern arity, use render_dotted(false)/display_name() accessors, and adapt interface implementor keys/sorting and class-name lookups.
Compiler shim
baml_language/crates/baml_compiler2_tir/src/ty.rs
Module converted to a thin re-export shim to baml_type and baml_base names/attributes.

Runtime, VM, FFI, tooling

Layer / File(s) Summary
Runtime / VM / bridges
baml_language/crates/bex_*, baml_language/crates/bridge_ctypes/*, baml_language/crates/bex_vm/*
Adopt new Ty shapes and QualifiedTypeName accessors for display/rendering/serialization; update heap accessors to return owned Strings; tighten serialize/deserialize guards against compiler-only Ty variants.
LSP, CLI, project codegen
baml_language/crates/baml_lsp2_actions/*, baml_language/crates/baml_exec/*, baml_language/crates/baml_project/*
Completion, type-info, auto-CLI, and client codegen updated to use new Ty/layout and QualifiedTypeName helpers for media/primitive handling.
Tools and output formats
baml_language/crates/sys_llm/*, baml_language/crates/tools_sap_visualizer/*
Output-format and SAP visualizer updated to use display_name()/render_dotted(false) keys and new literal shapes; hoisting/alias logic adapted.

Tests, snapshots, and wiring

Layer / File(s) Summary
Tests & snapshots
baml_language/crates/baml_tests/*, baml_language/crates/baml_type/tests/*
Unit tests and snapshot renderers updated to build new Ty variants (Freshness::Regular for literals, FunctionParamTy, optional API) and to use render_canonical() for consistent canonical rendering.
Workspace Cargo
baml_language/Cargo.toml, baml_language/crates/baml_type/Cargo.toml
Added subenum dependency in workspace and baml_type crate (workspace = true).

Estimated code review effort:
🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs:

  • BoundaryML/baml#3124: Overlap on Ty::Type / Type reflection and runtime Type handling across compiler and VM surfaces.
  • BoundaryML/baml#3125: Related migration that removed Ty::Opaque and introduced concrete runtime leaf variants (Resource/PromptAst/Type).
  • BoundaryML/baml#3383: Related work on function throws shape and typed throws surfaces that interact with the new function-type layout.

"I hopped through names and types today,
With dotted paths to guide the way.
Fresh literals blink, maps learned to bend,
And canonical strings now round the bend. 🥕"

✨ 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 kai/tir-cleanup

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 9, 2026 19:01 Inactive
@2kai2kai2
2kai2kai2 marked this pull request as ready for review June 9, 2026 19:38
@vercel
vercel Bot temporarily deployed to Preview – beps June 9, 2026 19:39 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 9, 2026 19:45 Inactive
@github-actions

github-actions Bot commented Jun 9, 2026 •

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.

@2kai2kai2
2kai2kai2 enabled auto-merge June 9, 2026 19:51
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

No description provided.

@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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
baml_language/crates/baml_tests/src/compiler2_tir/mod.rs (1)

7-27: ⚠️ Potential issue | 🟠 Major

Run and share successful cargo test --lib results for the Rust change set
The cargo test --lib run did not complete successfully here due to rustup/toolchain download/recovery failures (rename errors) and a subsequent could not find Cargo.toml error (wrong working directory). Re-run cargo test --lib from the repo root and share the output.

🤖 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/src/compiler2_tir/mod.rs` around lines 7 -
27, Re-run the test suite from the repository root by running cargo test --lib
and capture the full successful output; the failures reported were due to
toolchain/download and wrong-working-directory issues rather than code, so
ensure you run from the repo root (not inside crates/baml_tests) and that rustup
is healthy, then paste the complete passing test log; refer to the test modules
listed in mod.rs (explicit_type_args, inference, phase3a, phase5, phase6,
phase7, phase8_exceptions, stream_expansion and the support module) to confirm
those tests ran.

Source: Coding guidelines

baml_language/crates/bex_external_types/src/host_return.rs (1)

134-143: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle Literal::Bigint in host-return validation.

Line 134 currently omits bigint literal equality, so a declared bigint literal return type cannot validate successfully.

💡 Proposed fix
         Ty::Literal(lit, _, _) => match (lit, value) {
             (Literal::Bool(b), BexExternalValue::Bool(v)) => b == v,
             (Literal::Int(i), BexExternalValue::Int(v)) => i == v,
+            (Literal::Bigint(i), BexExternalValue::Bigint(v)) => i == v,
             (Literal::String(s), BexExternalValue::String(v)) => s == v,
             // `Literal::Float` stores the literal as a string for precision;
             // match by tag (any float), mirroring
             // `bex_engine::conversion::value_matches_type`.
             (Literal::Float(_), BexExternalValue::Float(_)) => true,
             _ => false,
         },
🤖 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/bex_external_types/src/host_return.rs` around lines 134
- 143, The Ty::Literal match arm in host_return.rs currently ignores bigint
literals; add a branch to compare bigint literals by value so declared bigint
literal return types validate: in the Ty::Literal(...) => match (lit, value)
arm, handle (Literal::Bigint(b), BexExternalValue::Bigint(v)) => b == v (mirror
the existing Bool/Int/String patterns), ensuring the Literal::Bigint and
BexExternalValue::Bigint symbols are used for the comparison.
baml_language/crates/baml_compiler2_mir/src/lower.rs (1)

200-225: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Account for Tir2Ty::Function generics in dispatch matching.

These helpers still treat two function types as equivalent whenever params/ret/throws line up, but this PR makes function types carry generic_params and generic_param_bounds. That means a generic function type can now satisfy, rewrite into, or bind against a monomorphic request (and vice versa), which can select the wrong dispatch candidate or synthesize the wrong guard. Please include the generic head in the match criteria and keep all three helpers aligned.

Also applies to: 332-367, 432-457

🤖 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_compiler2_mir/src/lower.rs` around lines 200 - 225,
The function-type comparisons in the three dispatch helpers need to include the
function generic head: update the Tir2Ty::Function match arms in
tir_type_satisfies_dispatch_request and the two sibling helpers
(tir_type_rewrites_dispatch_request and tir_type_binds_dispatch_request) to also
check generic_params and generic_param_bounds (e.g., compare lengths and
elementwise equality/compatibility of generic params and bounds) as part of the
match guard and any subsequent checks; make the generic-head comparison part of
the same conjunction that currently checks params.len() and param modes so all
three helpers remain aligned when deciding satisfy/rewrites/bind relationships.
🤖 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.

Inline comments:
In `@baml_language/crates/baml_compiler2_tir/src/package_interface.rs`:
- Around line 525-537: build_self_type_for_class currently constructs the
receiver QualifiedTypeName with a hardcoded Name::new("baml"), causing exported
implicit self types to have the wrong package for non-baml packages; update the
construction in build_self_type_for_class to use the actual package identifier
(the package/name value available on the surrounding context or class_data)
instead of the literal "baml" so QualifiedTypeName::new receives the real
package Name, leaving the rest (ns_path, class_data.name, generic args)
unchanged.
- Around line 181-194: The current mismatch comes from ExportedType::Class being
converted to Ty::Class including TypeVar entries while
PackageResolutionContext::resolve_type() (via def_to_ty()) emits own-package
generic classes with an empty vec, causing asymmetric Ty shapes; update
def_to_ty() (or have resolve_type call the same conversion path) to include the
declaring type's generic parameters as Ty::TypeVar entries (using the same
TyAttr::default() pattern) so that both dependency and own-package generic
classes produce Ty::Class(qtn, vec![Ty::TypeVar(...) ...], TyAttr::default())
consistently; ensure you reference ExportedType::Class, Ty::Class,
PackageResolutionContext::resolve_type(), and def_to_ty() when making the
change.

In `@baml_language/crates/bex_vm/src/package_baml/json.rs`:
- Around line 559-574: The comment and error classification are wrong:
Ty::RustType and Ty::Type are runtime leaf types per Ty::validate_runtime() and
should not be described as “compiler-only”; update the serialize and deserialize
match arms in the JSON handling to either move Ty::RustType and Ty::Type out of
the “TIR-internal compiler-only types” group or split them into their own arm,
and change the raise_serialize/raise_deserialize messages to indicate “not
JSON-representable” (or similar) instead of “compiler_only”; refer to the Ty
enum variants Ty::RustType and Ty::Type, the validate_runtime() caller for
intended semantics, and the raise_serialize call sites in the
serialize/deserialize blocks to make the error text and grouping accurate.

---

Outside diff comments:
In `@baml_language/crates/baml_compiler2_mir/src/lower.rs`:
- Around line 200-225: The function-type comparisons in the three dispatch
helpers need to include the function generic head: update the Tir2Ty::Function
match arms in tir_type_satisfies_dispatch_request and the two sibling helpers
(tir_type_rewrites_dispatch_request and tir_type_binds_dispatch_request) to also
check generic_params and generic_param_bounds (e.g., compare lengths and
elementwise equality/compatibility of generic params and bounds) as part of the
match guard and any subsequent checks; make the generic-head comparison part of
the same conjunction that currently checks params.len() and param modes so all
three helpers remain aligned when deciding satisfy/rewrites/bind relationships.

In `@baml_language/crates/baml_tests/src/compiler2_tir/mod.rs`:
- Around line 7-27: Re-run the test suite from the repository root by running
cargo test --lib and capture the full successful output; the failures reported
were due to toolchain/download and wrong-working-directory issues rather than
code, so ensure you run from the repo root (not inside crates/baml_tests) and
that rustup is healthy, then paste the complete passing test log; refer to the
test modules listed in mod.rs (explicit_type_args, inference, phase3a, phase5,
phase6, phase7, phase8_exceptions, stream_expansion and the support module) to
confirm those tests ran.

In `@baml_language/crates/bex_external_types/src/host_return.rs`:
- Around line 134-143: The Ty::Literal match arm in host_return.rs currently
ignores bigint literals; add a branch to compare bigint literals by value so
declared bigint literal return types validate: in the Ty::Literal(...) => match
(lit, value) arm, handle (Literal::Bigint(b), BexExternalValue::Bigint(v)) => b
== v (mirror the existing Bool/Int/String patterns), ensuring the
Literal::Bigint and BexExternalValue::Bigint symbols are used for the
comparison.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3b8c1877-0318-4b4d-b3d0-be947ae7cdba

📥 Commits

Reviewing files that changed from the base of the PR and between 78f9131 and 854698e.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (54)
  • baml_language/Cargo.toml
  • baml_language/crates/baml_base/src/core_types.rs
  • baml_language/crates/baml_compiler2_emit/src/emit.rs
  • baml_language/crates/baml_compiler2_emit/src/lib.rs
  • baml_language/crates/baml_compiler2_emit/src/stack_carry.rs
  • baml_language/crates/baml_compiler2_mir/src/lib.rs
  • baml_language/crates/baml_compiler2_mir/src/lower.rs
  • baml_language/crates/baml_compiler2_tir/src/associated_projection.rs
  • baml_language/crates/baml_compiler2_tir/src/builder.rs
  • baml_language/crates/baml_compiler2_tir/src/exhaustiveness.rs
  • baml_language/crates/baml_compiler2_tir/src/generics.rs
  • baml_language/crates/baml_compiler2_tir/src/infer_context.rs
  • baml_language/crates/baml_compiler2_tir/src/interfaces.rs
  • baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs
  • baml_language/crates/baml_compiler2_tir/src/narrowing.rs
  • baml_language/crates/baml_compiler2_tir/src/normalize.rs
  • baml_language/crates/baml_compiler2_tir/src/package_interface.rs
  • baml_language/crates/baml_compiler2_tir/src/throw_inference.rs
  • baml_language/crates/baml_compiler2_tir/src/throws_analysis.rs
  • baml_language/crates/baml_compiler2_tir/src/ty.rs
  • baml_language/crates/baml_exec/src/auto_cli.rs
  • baml_language/crates/baml_exec/src/clap_target.rs
  • baml_language/crates/baml_lsp2_actions/src/completions.rs
  • baml_language/crates/baml_lsp2_actions/src/describe.rs
  • baml_language/crates/baml_lsp2_actions/src/type_info.rs
  • baml_language/crates/baml_lsp2_actions/src/utils.rs
  • baml_language/crates/baml_project/src/client_codegen.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/inference.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/mod.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase6.rs
  • baml_language/crates/baml_tests/tests/exceptions.rs
  • baml_language/crates/baml_type/Cargo.toml
  • baml_language/crates/baml_type/src/lib.rs
  • baml_language/crates/baml_type/src/names.rs
  • baml_language/crates/baml_type/src/primitive.rs
  • baml_language/crates/baml_type/src/runtime_ty.rs
  • baml_language/crates/baml_type/src/simplify_sap.rs
  • baml_language/crates/baml_type/src/template.rs
  • baml_language/crates/baml_type/tests/simplify_sap_tests.rs
  • baml_language/crates/bex_engine/src/conversion.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/bex_external_types/src/host_return.rs
  • baml_language/crates/bex_heap/src/accessor.rs
  • baml_language/crates/bex_heap/src/gc.rs
  • baml_language/crates/bex_sap/src/sap_model/convert.rs
  • baml_language/crates/bex_sap/src/to_external.rs
  • baml_language/crates/bex_vm/src/package_baml/json.rs
  • baml_language/crates/bex_vm/src/package_baml/mod.rs
  • baml_language/crates/bex_vm/src/package_baml/type_class.rs
  • baml_language/crates/bex_vm/src/package_baml/unstable.rs
  • baml_language/crates/bridge_ctypes/src/value_encode.rs
  • baml_language/crates/sys_llm/src/lib.rs
  • baml_language/crates/sys_llm/src/types/output_format.rs
  • baml_language/crates/tools_sap_visualizer/src/compile.rs

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 9, 2026 19:57 Inactive
2kai2kai2 added 9 commits June 9, 2026 13:21
This is in preparation for larger changes. Also adds `subenum` for
`baml_type::Ty` (will be extended by further changes)
Unifies a lot of behavior.
It is not a part of the name and was only used in a few places. We
should just use the type itself to get generic params, not the QTE.
For eventually using it in TIR
- Clean up `qtn_to_type_name` now that they are unified
- Replace `Ty::Opaque` with real variants
We actually need them to be separate so that `RuntimeTy` can be deeply
`RuntimeTy`. We still use `subenum` on `RuntimeTy`.
@vercel
vercel Bot temporarily deployed to Preview – beps June 9, 2026 20:22 Inactive
@vercel
vercel Bot temporarily deployed to Preview – beps June 9, 2026 20:27 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 9, 2026 20:33 Inactive

@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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
baml_language/crates/baml_compiler2_mir/src/lower.rs (1)

1836-1843: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't hardcode baml.iter in the generic registry lookup path.

Line 1841 now forces package discovery to use baml.iter.<name>, but interface_view_from_registry is still used for arbitrary target_tns via interface_view_for_tir_ty. That can make blanket-impl lookup miss the real interface package for non-baml.iter interfaces and fail to resolve the interface view.

Suggested fix
-        let target_qtn = Self::baml_iter_qtn(target_tn.name().as_str());
+        let target_qtn = target_tn.clone();
🤖 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_compiler2_mir/src/lower.rs` around lines 1836 -
1843, The code currently forces discovery to use baml.iter by calling
Self::baml_iter_qtn(...) inside interface_view_from_registry; change it to use
the actual target type name instead of hardcoding baml.iter. Specifically, stop
calling baml_iter_qtn and pass the real qualified type name for target_tn into
registry_package_ids_for_interface_lookup (or derive the qtn from target_tn
directly) so package lookup for interface_view_from_registry and
interface_view_for_tir_ty can find non-baml.iter interface packages; update
references around interface_view_from_registry, target_tn, and
registry_package_ids_for_interface_lookup accordingly.
baml_language/crates/baml_compiler2_tir/src/package_interface.rs (2)

237-249: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve class generics when rewriting Self.

substitute_self_in() is fed a bare Path(Foo) here, so an explicit Self inside class Box<T> lowers to Ty::Class(..., []), while the implicit self parameter now comes from build_self_type_for_class() as Ty::Class(..., [TypeVar(T)]). That gives the same receiver type two different Ty shapes inside one method signature and will break equality/rendering for generic methods. Please carry class_data.generic_params through the Self replacement path too.

Also applies to: 257-261

🤖 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_compiler2_tir/src/package_interface.rs` around
lines 237 - 249, The Self substitution currently uses a bare path via
type_expr_for_name(class_data.name) which loses class generic parameters; change
the self_replacement passed to substitute_self_in to include the class's generic
params (mirror what build_self_type_for_class produces) by constructing a
TypeExpr/Path for the enclosing class that carries class_data.generic_params as
type arguments (or corresponding TypeVar expressions) before calling
substitute_self_in in the lower_with_self closure, and make the same change at
the other substitute_self_in call around lines 257-261 so explicit Self and the
implicit receiver share the same Ty shape for generics.

922-927: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Own-package generic interfaces still erase their type variables.

Definition::Interface(_) still constructs Ty::Interface(..., vec![], ...), even though this PR moved unspecialized generic classes to TypeVar args. A same-package generic interface resolved through PackageResolutionContext::resolve_type() will therefore still come back as Iface instead of Iface<T>, keeping interface resolution inconsistent with the new Ty contract.

🤖 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_compiler2_tir/src/package_interface.rs` around
lines 922 - 927, The Interface arm in the Definition::Interface match currently
constructs Ty::Interface with an empty type-arg vector, which erases
same-package generic type parameters; update that construction in
package_interface.rs (the Definition::Interface(_) match) to populate the type
argument vector from the interface's generic/type parameters (mapping each
parameter to an unspecialized Ty::TypeVar or whatever the project uses for
unspecialized generics) so that Ty::Interface(qualify_def(db, def, &name),
vec_of_typevars, ...) preserves the interface's type variables and stays
consistent with PackageResolutionContext::resolve_type and the new Ty contract.
🤖 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.

Inline comments:
In `@baml_language/crates/baml_type/src/lib.rs`:
- Around line 154-157: validate_runtime() currently allows Ty::Literal(_,
Freshness::Fresh, _) through, which leaks the compiler-only Freshness into
runtime equality/hashing/serialization; change validate_runtime() to normalize
any Ty::Literal to use Freshness::Regular (erase Freshness) before
accepting/returning it so runtime representations always use Regular. Locate the
handling of the Ty::Literal variant in validate_runtime() and replace/augment
that branch to construct/return a Literal with Freshness::Regular (or otherwise
map Freshness::Fresh -> Freshness::Regular) so runtime checks and Borsh
serialization cannot observe Freshness.
- Around line 903-910: render_user_facing currently bypasses two user-facing
policies when calling render_with with CanonicalTyRender: it prints raw generic
parameter names instead of using the serializer's user-facing alias and it
renders the no-throws sentinel as "void" instead of the user-facing "never".
Update the CanonicalTyRender path used by render_user_facing (and the code paths
around the generic param and effect rendering) to call the same user-facing
helpers as canonical rendering: use s.type_var(...) (or the equivalent
user-facing serializer method) to render generic/type variables and map the
no-throws sentinel to "never" in the effect-rendering logic so user-facing
strings never expose __effect_param_N or produce "throws void"; keep the caller
as render_user_facing -> render_with(&CanonicalTyRender { user_facing: true })
but ensure the internals honor user_facing when choosing s.type_var and the
no-throws representation.
- Around line 173-179: The runtime validator is currently skipping
Function.generic_param_bounds so compiler-only sentinels (Unknown, Error,
Evolving*, etc.) can leak into runtime metadata; update the runtime validation
to walk and validate each entry in generic_param_bounds (in addition to
generic_params and params) — either by calling a new metadata-aware validator
(e.g., validate_runtime_metadata_ty) or by extending validate_runtime() with a
flag to allow/handle reflective-only forms like TypeVar and
AssociatedTypeProjection, and ensure Function, generic_param_bounds, TypeVar,
and AssociatedTypeProjection are explicitly handled so sentinel types are
rejected or normalized before emitting reflective payloads.

In `@baml_language/crates/baml_type/src/primitive.rs`:
- Around line 7-20: Ty::is_primitive currently omits the new media variants so
Image/Audio/Video/Pdf are misclassified; update the is_primitive matcher in the
Ty impl (function Ty::is_primitive) to include the media branch (e.g., add |
Ty::Media(..) | to the matches list) and likewise update any other similar
primitive-check helpers (the other is_primitive-like match blocks referenced in
the comment) so media types are treated as primitives.

---

Outside diff comments:
In `@baml_language/crates/baml_compiler2_mir/src/lower.rs`:
- Around line 1836-1843: The code currently forces discovery to use baml.iter by
calling Self::baml_iter_qtn(...) inside interface_view_from_registry; change it
to use the actual target type name instead of hardcoding baml.iter.
Specifically, stop calling baml_iter_qtn and pass the real qualified type name
for target_tn into registry_package_ids_for_interface_lookup (or derive the qtn
from target_tn directly) so package lookup for interface_view_from_registry and
interface_view_for_tir_ty can find non-baml.iter interface packages; update
references around interface_view_from_registry, target_tn, and
registry_package_ids_for_interface_lookup accordingly.

In `@baml_language/crates/baml_compiler2_tir/src/package_interface.rs`:
- Around line 237-249: The Self substitution currently uses a bare path via
type_expr_for_name(class_data.name) which loses class generic parameters; change
the self_replacement passed to substitute_self_in to include the class's generic
params (mirror what build_self_type_for_class produces) by constructing a
TypeExpr/Path for the enclosing class that carries class_data.generic_params as
type arguments (or corresponding TypeVar expressions) before calling
substitute_self_in in the lower_with_self closure, and make the same change at
the other substitute_self_in call around lines 257-261 so explicit Self and the
implicit receiver share the same Ty shape for generics.
- Around line 922-927: The Interface arm in the Definition::Interface match
currently constructs Ty::Interface with an empty type-arg vector, which erases
same-package generic type parameters; update that construction in
package_interface.rs (the Definition::Interface(_) match) to populate the type
argument vector from the interface's generic/type parameters (mapping each
parameter to an unspecialized Ty::TypeVar or whatever the project uses for
unspecialized generics) so that Ty::Interface(qualify_def(db, def, &name),
vec_of_typevars, ...) preserves the interface's type variables and stays
consistent with PackageResolutionContext::resolve_type and the new Ty contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 24a0cdf1-f5dd-48b1-ad27-d21730062c74

📥 Commits

Reviewing files that changed from the base of the PR and between 854698e and 89b1f6d.

⛔ Files ignored due to path filters (5)
  • baml_language/Cargo.lock is excluded by !**/*.lock
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/generic_class_destructure_no_type_args/baml_tests__diagnostic_errors__generic_class_destructure_no_type_args__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/generic_class_destructure_no_type_args/baml_tests__diagnostic_errors__generic_class_destructure_no_type_args__05_diagnostics.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/diagnostic_errors/patterns_class_destructure/baml_tests__diagnostic_errors__patterns_class_destructure__05_diagnostics.snap is excluded by !**/*.snap
📒 Files selected for processing (54)
  • baml_language/Cargo.toml
  • baml_language/crates/baml_base/src/core_types.rs
  • baml_language/crates/baml_compiler2_emit/src/emit.rs
  • baml_language/crates/baml_compiler2_emit/src/lib.rs
  • baml_language/crates/baml_compiler2_emit/src/stack_carry.rs
  • baml_language/crates/baml_compiler2_mir/src/lib.rs
  • baml_language/crates/baml_compiler2_mir/src/lower.rs
  • baml_language/crates/baml_compiler2_tir/src/associated_projection.rs
  • baml_language/crates/baml_compiler2_tir/src/builder.rs
  • baml_language/crates/baml_compiler2_tir/src/exhaustiveness.rs
  • baml_language/crates/baml_compiler2_tir/src/generics.rs
  • baml_language/crates/baml_compiler2_tir/src/infer_context.rs
  • baml_language/crates/baml_compiler2_tir/src/interfaces.rs
  • baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs
  • baml_language/crates/baml_compiler2_tir/src/narrowing.rs
  • baml_language/crates/baml_compiler2_tir/src/normalize.rs
  • baml_language/crates/baml_compiler2_tir/src/package_interface.rs
  • baml_language/crates/baml_compiler2_tir/src/throw_inference.rs
  • baml_language/crates/baml_compiler2_tir/src/throws_analysis.rs
  • baml_language/crates/baml_compiler2_tir/src/ty.rs
  • baml_language/crates/baml_exec/src/auto_cli.rs
  • baml_language/crates/baml_exec/src/clap_target.rs
  • baml_language/crates/baml_lsp2_actions/src/completions.rs
  • baml_language/crates/baml_lsp2_actions/src/describe.rs
  • baml_language/crates/baml_lsp2_actions/src/type_info.rs
  • baml_language/crates/baml_lsp2_actions/src/utils.rs
  • baml_language/crates/baml_project/src/client_codegen.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/inference.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/mod.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase6.rs
  • baml_language/crates/baml_tests/tests/exceptions.rs
  • baml_language/crates/baml_type/Cargo.toml
  • baml_language/crates/baml_type/src/lib.rs
  • baml_language/crates/baml_type/src/names.rs
  • baml_language/crates/baml_type/src/primitive.rs
  • baml_language/crates/baml_type/src/runtime_ty.rs
  • baml_language/crates/baml_type/src/simplify_sap.rs
  • baml_language/crates/baml_type/src/template.rs
  • baml_language/crates/baml_type/tests/simplify_sap_tests.rs
  • baml_language/crates/bex_engine/src/conversion.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/bex_external_types/src/host_return.rs
  • baml_language/crates/bex_heap/src/accessor.rs
  • baml_language/crates/bex_heap/src/gc.rs
  • baml_language/crates/bex_sap/src/sap_model/convert.rs
  • baml_language/crates/bex_sap/src/to_external.rs
  • baml_language/crates/bex_vm/src/package_baml/json.rs
  • baml_language/crates/bex_vm/src/package_baml/mod.rs
  • baml_language/crates/bex_vm/src/package_baml/type_class.rs
  • baml_language/crates/bex_vm/src/package_baml/unstable.rs
  • baml_language/crates/bridge_ctypes/src/value_encode.rs
  • baml_language/crates/sys_llm/src/lib.rs
  • baml_language/crates/sys_llm/src/types/output_format.rs
  • baml_language/crates/tools_sap_visualizer/src/compile.rs
✅ Files skipped from review due to trivial changes (7)
  • baml_language/crates/baml_compiler2_tir/src/infer_context.rs
  • baml_language/crates/baml_exec/src/clap_target.rs
  • baml_language/crates/baml_compiler2_mir/src/lib.rs
  • baml_language/crates/baml_lsp2_actions/src/describe.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/phase6.rs
  • baml_language/crates/baml_compiler2_tir/src/associated_projection.rs
  • baml_language/crates/bex_heap/src/gc.rs
🚧 Files skipped from review as they are similar to previous changes (39)
  • baml_language/Cargo.toml
  • baml_language/crates/baml_type/Cargo.toml
  • baml_language/crates/bex_vm/src/package_baml/mod.rs
  • baml_language/crates/baml_tests/tests/exceptions.rs
  • baml_language/crates/baml_base/src/core_types.rs
  • baml_language/crates/bex_sap/src/to_external.rs
  • baml_language/crates/baml_compiler2_tir/src/throws_analysis.rs
  • baml_language/crates/bex_engine/src/lib.rs
  • baml_language/crates/baml_type/tests/simplify_sap_tests.rs
  • baml_language/crates/baml_project/src/client_codegen.rs
  • baml_language/crates/baml_lsp2_actions/src/type_info.rs
  • baml_language/crates/tools_sap_visualizer/src/compile.rs
  • baml_language/crates/baml_type/src/simplify_sap.rs
  • baml_language/crates/baml_type/src/template.rs
  • baml_language/crates/baml_compiler2_emit/src/stack_carry.rs
  • baml_language/crates/baml_lsp2_actions/src/utils.rs
  • baml_language/crates/bex_heap/src/accessor.rs
  • baml_language/crates/bex_vm/src/package_baml/type_class.rs
  • baml_language/crates/baml_compiler2_tir/src/throw_inference.rs
  • baml_language/crates/baml_compiler2_emit/src/emit.rs
  • baml_language/crates/baml_compiler2_tir/src/ty.rs
  • baml_language/crates/baml_tests/src/compiler2_tir/mod.rs
  • baml_language/crates/baml_lsp2_actions/src/completions.rs
  • baml_language/crates/bridge_ctypes/src/value_encode.rs
  • baml_language/crates/baml_compiler2_tir/src/generics.rs
  • baml_language/crates/baml_type/src/runtime_ty.rs
  • baml_language/crates/bex_engine/src/conversion.rs
  • baml_language/crates/baml_compiler2_emit/src/lib.rs
  • baml_language/crates/sys_llm/src/lib.rs
  • baml_language/crates/bex_external_types/src/host_return.rs
  • baml_language/crates/baml_compiler2_tir/src/interfaces.rs
  • baml_language/crates/baml_type/src/names.rs
  • baml_language/crates/bex_sap/src/sap_model/convert.rs
  • baml_language/crates/baml_compiler2_tir/src/exhaustiveness.rs
  • baml_language/crates/bex_vm/src/package_baml/json.rs
  • baml_language/crates/sys_llm/src/types/output_format.rs
  • baml_language/crates/baml_compiler2_tir/src/narrowing.rs
  • baml_language/crates/baml_compiler2_tir/src/normalize.rs
  • baml_language/crates/baml_compiler2_tir/src/builder.rs

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 9, 2026 20:44 Inactive
@2kai2kai2
2kai2kai2 added this pull request to the merge queue Jun 9, 2026
Merged via the queue into canary with commit e93d579 Jun 9, 2026
84 of 86 checks passed
@2kai2kai2
2kai2kai2 deleted the kai/tir-cleanup branch June 9, 2026 21:01

This branch was previously deployed

3 inactive deployments
Preview – promptfiddle — 89b1f6d6 Deployed Jun 9, 2026 by vercel[bot]
Preview – promptfiddle2 — 89b1f6d6 Deployed Jun 9, 2026 by vercel[bot]
Preview – beps — 89b1f6d6 Deployed Jun 9, 2026 by vercel[bot]
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