Skip to content

feat(stdlib): baml.ToString interface + string.from<T> driver - #3792

Merged
codeshaunted merged 7 commits into
canaryfrom
avery/tostring
Jun 18, 2026
Merged

codeshaunted merged 7 commits into
canaryfrom
avery/tostring

Conversation

@codeshaunted

@codeshaunted codeshaunted commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

What

Replaces the implicit to_string path with an opt-in baml.ToString interface and a string.from<T>(value) driver. Strings only — the JSON side (baml.ToJson / json.from) is deferred.

// baml.ToString  (new conversions.baml)
interface ToString {
  function to_string(self) -> string throws never {
    root._to_string_default(self)   // default body == the structural fallback
  }
}

// method on string
function from<T>(value: T) -> string throws never {
  root._to_string_shim(value)
}
  • A type opts in with implements baml.ToString { function to_string ... } to control its rendering. implements baml.ToString {} (no override) renders the same structural default as a non-implementor.
  • string.from(x) renders any value: primitives naturally (42, true), containers/instances structurally ([1, 2], Point { x: 1, y: 2 }), nested strings quoted.

Why dispatch is a runtime shim, not a static match

The natural form match (value) { baml.ToString => value.to_string(), _ => default } can't work inside a stdlib driver: an interface match in the baml package lowers against the per-package implementor table, and baml is a dependency of user code — so it can never see a downstream implements baml.ToString. The arm would compile to an unconditional goto failure and never fire for user types (the VM IsType opcode doesn't consult the global implementor table).

So string.from resolves to_string on the value's runtime class via a native shim (_to_string_shim → make_to_string_callee, looking up {class_fqn}.baml.ToString.to_string in VM globals), falling back to the structural default. This mirrors the existing baml.json.to_json native and Sortable.sort's _compare_shim.

Changes

  • baml_builtins2/baml_std/baml/conversions.baml (new): ToString interface + _to_string_default / _to_string_shim natives; registered in lib.rs.
  • string.baml: string.from<T> static method on String.
  • bex_vm/.../root.rs: structural Display walker + the two natives.
  • bex_vm/.../mod.rs: make_to_string_callee (runtime-class dispatch).

Tests

crates/baml_tests/tests/to_string_interface.rs (7 tests): primitives, containers, instances, user override dispatch, default-body == non-implementor, direct method calls. Full baml_tests suite green; stdlib + bytecode snapshots updated for the added functions.

Follow-ups

  • JSON side: baml.ToJson + json.from (replacing to_json<T>).
  • The literal match (value) { baml.ToString => ... } driver form would need a global runtime interface is-test (a new VM capability over interface_implementors).

Summary by CodeRabbit

  • New Features
    • Added opt-in baml.ToString interface with runtime dispatch for human-readable rendering, plus String.from<T>(value) with structural fallback.
    • Updated core built-ins (e.g., time types, errors stack traces, Uint8Array, TypeValue) to implement baml.ToString.
  • Behavior Changes
    • Refined to_string/to_json error handling for time types to prevent unexpected panics.
  • Compiler Updates
    • Added diagnostic E0140 when to_string is defined outside an implements baml.ToString block.
  • Tests
    • Added compile-time and runtime coverage for dispatch, fallback, and quoting (including Instant).
  • Chores
    • Sanitized emitted Python hard keywords during SDK generation (with tests).

Replace the implicit to_string path with an opt-in `baml.ToString`
interface and a `string.from<T>(value)` driver (strings only; json
deferred).

- `interface ToString` (new conversions.baml) with a default `to_string`
  body, so `implements baml.ToString {}` with no override renders the
  same structural default as a non-implementor.
- `string.from(x)` renders any value: a user `implements baml.ToString`
  override is resolved on the value's runtime class (`_to_string_shim` /
  `make_to_string_callee`); everything else gets a structural,
  human-readable default (`_to_string_default`).

A static `match (value) { baml.ToString => value.to_string() }` cannot be
used in the driver: an interface match in the stdlib `baml` package can't
see downstream user implementors, so dispatch resolves on the runtime
class instead — mirroring `baml.json.to_json` and `Sortable.sort`'s
`_compare_shim`.

Tests: crates/baml_tests/tests/to_string_interface.rs. Stdlib snapshots
updated for the added functions.
@vercel

vercel Bot commented Jun 17, 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 18, 2026 1:46am
promptfiddle Ready Ready Preview, Comment Jun 18, 2026 1:46am
promptfiddle2 Ready Ready Preview, Comment Jun 18, 2026 1:46am

Request Review

@vercel
vercel Bot temporarily deployed to Preview – beps June 17, 2026 22:31 Inactive
@coderabbitai

coderabbitai Bot commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (9)
  • baml_language/crates/baml_tests/snapshots/baml_src/class_type_args_at_runtime.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/csv.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/inferred_generic_type_args.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/instantiation_expr.qualified.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/instantiation_expr.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/reflect_type_of.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/reflect_type_of_generic.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/shell.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/baml_src/time.snap is excluded by !**/*.snap

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 95227f84-3be8-4e44-aa23-59b449a5e8e8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds string.from(value) to the BAML standard library backed by a new baml.ToString interface. An opt-in to_string(self) override is dispatched at runtime via make_to_string_callee; values without an override fall back to a total structural renderer (DisplaySnap + to_string_default_recursive) implemented natively in the VM. Compiler diagnostics enforce that to_string methods must be declared inside implements baml.ToString blocks. Eight builtin classes (time, error, type, and binary types) are migrated to implement the interface. Python SDK identifier generation now escapes hard keywords with a trailing underscore.

Changes

string.from and baml.ToString

Layer / File(s) Summary
BAML stdlib contracts: ToString interface and String.from
baml_language/crates/baml_builtins2/baml_std/baml/conversions.baml, baml_language/crates/baml_builtins2/baml_std/baml/string.baml, baml_language/crates/baml_builtins2/src/lib.rs
Defines the ToString interface with default to_string(self) body, internal _to_string_default and _to_string_shim generics, and the public String.from<T> factory; registers conversions.baml in the builtin list.
VM callee resolution: make_to_string_callee
baml_language/crates/bex_vm/src/package_baml/mod.rs
Adds make_to_string_callee to derive a class FQN from a runtime value and resolve {fqn}.baml.ToString.to_string into a bound method pointer, returning None on miss.
VM native entrypoints and structural renderer
baml_language/crates/bex_vm/src/package_baml/root.rs
Implements _to_string_default and _to_string_shim as native VM methods; introduces DisplaySnap heap snapshot enum and to_string_default_recursive for total structural rendering of all value kinds.
Compiler enforcement: ToStringMustImplementInterface diagnostic
baml_language/crates/baml_compiler2_hir/src/builder.rs, baml_language/crates/baml_compiler2_hir/src/diagnostic.rs, baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs
Adds compile-time check during class lowering to reject direct to_string definitions; introduces ToStringMustImplementInterface diagnostic variant (error code E0140) directing users to move methods into implements baml.ToString blocks.
Builtin class integrations
baml_language/crates/baml_builtins2/baml_std/baml/ns_errors/stack_trace.baml, baml_language/crates/baml_builtins2/baml_std/baml/ns_time/*.baml, baml_language/crates/baml_builtins2/baml_std/baml/type_class.baml, baml_language/crates/baml_builtins2/baml_std/baml/uint8array.baml
Migrates eight builtin classes to declare implements baml.ToString; splits to_string implementations into public delegating wrapper (throws never) and private _to_string_impl helper; updates to_json methods to call _to_string_impl directly for proper error surfacing.
VM implementation method renames
baml_language/crates/bex_vm/src/package_baml/stack_trace.rs, baml_language/crates/bex_vm/src/package_baml/time.rs, baml_language/crates/bex_vm/src/package_baml/type_class.rs, baml_language/crates/bex_vm/src/package_baml/uint8array.rs
Updates Rust trait implementations to rename native string conversion entry points from to_string to _to_string_impl for all affected builtins, maintaining method signatures and serialization logic.
Integration tests
baml_language/crates/baml_tests/tests/to_string_interface.rs
Tokio tests covering compile-time enforcement, primitive rendering, unquoted top-level strings, quoted array elements, structural class rendering, custom to_string dispatch, empty-override fallback parity, builtin Instant integration, and direct method invocation.
Snapshot update
baml_language/crates/baml_tests/tests/shell.rs
Updates insta snapshot to reflect new Uint8Array method dispatch path via interface.

Python SDK keyword escaping

Layer / File(s) Summary
Python keyword escape function and usage
baml_language/sdks/python/rust/sdkgen_python_pydantic2/src/emit/mod.rs
Adds escape_python_keyword function that appends _ to identifiers matching Python hard keywords; applies escaping during PyFunction and PyMethodBinding emission; includes unit tests verifying keyword escaping and soft-keyword passthrough.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • BoundaryML/baml#3692: Adds baml.time class implementations (Plain*, ZonedDateTime) whose to_string behavior is directly refactored in this PR to implement baml.ToString via _to_string_impl and runtime dispatch.

Poem

🐇 A string was a mystery, lost in the heap,
Now from(value) wakes what was silently asleep.
The shim checks the class, finds the override if there,
Or snapshots the struct with recursive care.
throws never — I promise, no panic, no fright,
Just bunnies converting your values just right! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing a new baml.ToString interface and string.from driver function for standardized string conversions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch avery/tostring

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 and usage tips.

@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/to_string_interface.rs (1)

24-153: ⚡ Quick win

Add focused VM unit tests alongside these integration tests.

Great e2e coverage; please also add crate-level unit tests for make_to_string_callee and to_string_default_recursive so failures localize faster and align with the repo’s testing preference.
As per coding guidelines, "**/*.rs: Prefer writing Rust unit tests over integration tests where possible."

🤖 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/to_string_interface.rs` around lines 24
- 153, Add unit tests at the crate level (in the module where the functions are
defined) for the two core functions make_to_string_callee and
to_string_default_recursive. These unit tests should test the functions in
isolation rather than through the integration test approach shown in this file,
allowing failures to localize faster and aligning with the repository's testing
preference for unit tests over integration tests.

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/to_string_interface.rs`:
- Around line 24-153: Add unit tests at the crate level (in the module where the
functions are defined) for the two core functions make_to_string_callee and
to_string_default_recursive. These unit tests should test the functions in
isolation rather than through the integration test approach shown in this file,
allowing failures to localize faster and aligning with the repository's testing
preference for unit tests over integration tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 345eb03d-adb7-44e2-b433-621f2b69ff83

📥 Commits

Reviewing files that changed from the base of the PR and between 3d0fed5 and 756a045.

⛔ Files ignored due to path filters (7)
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/src/compiler2_tir/snapshots/baml_tests__compiler2_tir__phase5__snapshot_baml_package_items.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded_unoptimized.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • baml_language/crates/baml_builtins2/baml_std/baml/conversions.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/string.baml
  • baml_language/crates/baml_builtins2/src/lib.rs
  • baml_language/crates/baml_tests/tests/to_string_interface.rs
  • baml_language/crates/bex_vm/src/package_baml/mod.rs
  • baml_language/crates/bex_vm/src/package_baml/root.rs

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 17, 2026 22:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 17, 2026 22:49 Inactive
…rface checks

Explain why `string.from` resolves to_string on the runtime class via
`_to_string_shim` instead of the natural `if value is baml.ToString {
value.to_string() } else { ... }`: `is <interface>` and interface
dispatch are resolved at compile time from a per-package implementor set
(dependencies + self, never dependents), so the `baml` stdlib package
can't see a downstream user `implements baml.ToString` and the test folds
to constant false.

TODO marks both sites to drop the shim and use the literal `is` form once
the TIR rework moves interface conformance checks to runtime.
@vercel
vercel Bot temporarily deployed to Preview – beps June 17, 2026 22:58 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 17, 2026 23:04 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 17, 2026 23:16 Inactive
… to_string

Move every builtin `to_string` onto the `baml.ToString` interface and
forbid declaring `to_string` directly on a class — it is provided by the
interface, not as a magic method.

Stdlib migration (TypeValue, Uint8Array, StackTrace, PlainTime, Instant,
PlainDate, PlainDateTime, ZonedDateTime):
- The native/formatter moves to a private `_to_string_impl`; the public
  `to_string` is an `implements baml.ToString { ... }` block delegating to
  it.
- Infallible formatters delegate directly. The fallible time formatters
  (`Instant`/`PlainDate`/`PlainDateTime`/`ZonedDateTime`, which throw
  `InvalidArgument` for out-of-RFC-3339-range years etc.) keep throwing
  from `_to_string_impl`; the `throws never` interface method catches and
  `panic`s instead. `to_json` is left untouched — it still calls the
  throwing `_to_string_impl` and surfaces a `JsonSerializationError`.

Ban: a `to_string` method declared directly in a class body is now an
error (E0139) pointing the user at `implements baml.ToString { ... }`.
Methods inside `implements` blocks (in `c.implements`, not `c.methods`)
are unaffected.

Tests in to_string_interface.rs cover builtin dispatch via the interface
and both sides of the ban. Stdlib/bytecode snapshots updated.
@vercel
vercel Bot temporarily deployed to Preview – beps June 17, 2026 23:56 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: 1

🤖 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_tests/tests/to_string_interface.rs`:
- Around line 49-67: The assertion in the to_string_via_interface_is_allowed
test function only verifies that no errors contain "to_string", which allows
unrelated compiler errors to slip through. Replace the current assertion that
checks !errors.iter().any(|e| e.contains("to_string")) with a simpler and
stricter check using errors.is_empty() to ensure that the compilation produces
no errors at all, not just no to_string-related errors.
🪄 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: c9eebd8b-fe66-404f-910e-c08bafefa7a0

📥 Commits

Reviewing files that changed from the base of the PR and between add95a1 and 5e3e2d4.

⛔ Files ignored due to path filters (7)
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____03_hir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_5_mir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____04_tir.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/snapshots/compiles/__baml_std__/baml_tests__compiles____baml_std____06_codegen.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/src/compiler2_tir/snapshots/baml_tests__compiler2_tir__phase5__snapshot_baml_package_items.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded.snap is excluded by !**/*.snap
  • baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded_unoptimized.snap is excluded by !**/*.snap
📒 Files selected for processing (17)
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_errors/stack_trace.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_time/instant.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_time/plaindate.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_time/plaindatetime.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_time/plaintime.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/ns_time/zoneddatetime.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/type_class.baml
  • baml_language/crates/baml_builtins2/baml_std/baml/uint8array.baml
  • baml_language/crates/baml_compiler2_hir/src/builder.rs
  • baml_language/crates/baml_compiler2_hir/src/diagnostic.rs
  • baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs
  • baml_language/crates/baml_tests/tests/shell.rs
  • baml_language/crates/baml_tests/tests/to_string_interface.rs
  • baml_language/crates/bex_vm/src/package_baml/stack_trace.rs
  • baml_language/crates/bex_vm/src/package_baml/time.rs
  • baml_language/crates/bex_vm/src/package_baml/type_class.rs
  • baml_language/crates/bex_vm/src/package_baml/uint8array.rs
✅ Files skipped from review due to trivial changes (1)
  • baml_language/crates/baml_tests/tests/shell.rs

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 18, 2026 00:01 Inactive
# Conflicts:
#	baml_language/crates/baml_compiler_diagnostics/src/diagnostic.rs
#	baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded.snap
#	baml_language/crates/baml_tests/tests/bytecode_format/snapshots/bytecode_format__bytecode_display_expanded_unoptimized.snap
@github-actions

github-actions Bot commented Jun 18, 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.

@vercel
vercel Bot temporarily deployed to Preview – beps June 18, 2026 00:11 Inactive
@blacksmith-sh

This comment has been minimized.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 18, 2026 00:17 Inactive
@github-actions

github-actions Bot commented Jun 18, 2026 •

Copy link
Copy Markdown

No description provided.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 18, 2026 00:29 Inactive
…cribe snapshots

- sdkgen_python_pydantic2: `from` is a Python hard keyword, so `string.from`
  generated `def from(...)` — a syntax error that broke ruff/pyright/pytest.
  Escape Python keywords on the rendered identifier (`from` -> `from_`),
  generalizing the existing `assert` -> `assert_` package rule. The BAML
  dispatch FQN is built from the raw name, so calls still target `from`.
  TypeScript is unaffected (`from` is legal there).
- root.rs: the `_to_string_shim` doc linked the `pub(super)` `make_to_string_callee`
  via an intra-doc link, which `-D rustdoc::private-intra-doc-links` rejects;
  demote to a plain code span.
- Refresh the `describe` snapshots (baml_cli + baml_lsp2_actions): the builtin
  `string` listing shifted with the added `from` method / `ToString` impl and
  the merged `Equals`/`Compare` impls.
@vercel
vercel Bot temporarily deployed to Preview – beps June 18, 2026 00:40 Inactive
@vercel
vercel Bot temporarily deployed to Preview – beps June 18, 2026 00:42 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 18, 2026 00:47 Inactive
@codeshaunted
codeshaunted enabled auto-merge June 18, 2026 00:52
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 18, 2026 00:59 Inactive
…spatch

The per-namespace bytecode snapshots embed builtin call FQNs, which shifted
from `baml.X.to_string` to `baml.X.baml.ToString.to_string` when to_string
moved onto the interface (plus the merged ops impls). Snapshot-only.
@vercel
vercel Bot temporarily deployed to Preview – beps June 18, 2026 01:29 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 June 18, 2026 01:34 Inactive
@codeshaunted
codeshaunted added this pull request to the merge queue Jun 18, 2026
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle June 18, 2026 01:46 Inactive
Merged via the queue into canary with commit 2f72dba Jun 18, 2026
51 of 52 checks passed
@codeshaunted
codeshaunted deleted the avery/tostring branch June 18, 2026 01:50
codeshaunted added a commit that referenced this pull request Jun 18, 2026
…olation

Canary #3792 replaced magic/implicit `to_string` with the opt-in `baml.ToString`
interface + a `string.from<T>(value)` universal renderer, and added an HIR rule
forbidding a direct `to_string` method on a class. This branch's string
interpolation was built on the now-removed magic to_string, so the merge adopts
canary's design:

- Untagged `${expr}` now elaborates to `string.from(expr)` (the universal
  renderer) instead of `expr.to_string()`. Removed the magic to_string
  auto-derive and the obsolete `to_string`-stringability TIR check (the
  null guard stays). `string.from` is total, so every value interpolates
  without the type needing a `to_string` method.
- Took canary's primitive companions (Int/Float/Bool/String no longer declare
  a direct `to_string`) and removed the now-orphaned Rust `fn to_string` impls.
- Removed the dead MIR primitive-union `to_string` dispatch (interpolation no
  longer emits `union.to_string()`); kept the union member-resolution arm,
  which is load-bearing for BEP-044 union field access.
- Updated tests for the new model: a user class customises rendering via
  `implements baml.ToString`; a class without it renders structurally
  (`Point { x: 1, y: 2 }`); the tagged-template counter uses `string.from(i)`.
- Regenerated snapshots (the per-class auto-derived `to_string` is gone from
  the rendered IR).

Full suite green: 6275 passed, 0 snapshot drift.

This branch was previously deployed

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