bridge-cpp: typed literal types - baml::Lit + one polymorphic BAML_LIT macro - #4079
Conversation
…T macro
BAML literal types stop widening: each value is a distinct C++ type
(Lit<'d','r','a','f','t'>, Lit<int64_t{42}>, Lit<true>,
Lit<Sentiment::Positive> for enum-variant types), so literal unions
dispatch and exhaustively match at compile time and misspellings do not
compile. C++17 throughout: strings ride a char-pack via the
Boost.Metaparse constant-indexing technique (64-char cap), scalars and
enums are plain auto NTTPs, and a single BAML_LIT(x) macro classifies
its argument through overloaded constexpr helpers - BAML_LIT("draft"),
BAML_LIT(42) (normalized to int64_t so a bare int cannot mint a twin
type), BAML_LIT(true), BAML_LIT(Sentiment::Positive). Any other shape
lands on a teaching static_assert.
The union decode gains a literal pass before the strict/lenient passes,
so Lit<"auto"> beats a std::string sibling for its exact value. Float
literals stay widened (float NTTPs are C++20; BAML has none in
practice). New shared-fixture coverage: mixed-base literal union
("active" | 1 | true) round trip, python-first.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
⏭️ Performance benchmarks were skippedPerf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to To run them on this PR, do any of the following, then push a commit (or re-run CI):
|
Binary size checks failed❌ 4 violations · ✅ 3 passed
Details & how to fixViolations:
Add/update baselines:
[artifacts.baml-cli]
file_bytes = 19545072
stripped_bytes = 19545120
gzip_bytes = 9329751
[artifacts.bridge_wasm]
file_bytes = 16160508
gzip_bytes = 4402886
[artifacts.baml-cli]
file_bytes = 21070848
stripped_bytes = 21070848
gzip_bytes = 9539693
[artifacts.baml-cli]
file_bytes = 25267920
stripped_bytes = 25267912
gzip_bytes = 10728953Generated by |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/sdks/cpp/bridge_cpp/include/baml/lit.h`:
- Around line 80-86: Update the static_assert diagnostic in the Lit shape
validation to remove the undefined BAML_LIT_INT, BAML_LIT_BOOL, and
BAML_LIT_ENUM macro references. Describe the supported integer, boolean, and
enum forms using the existing baml::IntLit and baml::Lit syntax, while retaining
the BAML_LIT recommendation for strings.
- Around line 163-191: Update LitValueOf(T) to validate unsigned integral values
are representable in int64_t before normalization, using the original type/value
in a compile-time assertion, then perform the cast. Ensure out-of-range values
such as UINT64_MAX are rejected while signed and representable unsigned literals
retain the existing canonical int64_t behavior.
🪄 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: cf6d69a1-dd97-40a8-9746-6fc8bfbf495b
📒 Files selected for processing (11)
baml_language/sdk_tests/crates/cpp/function_calls/customizable/tests/test_main.ccbaml_language/sdk_tests/crates/cpp/type_shapes/customizable/tests/test_complex_models.ccbaml_language/sdk_tests/crates/cpp/type_shapes/customizable/tests/test_enums.ccbaml_language/sdk_tests/crates/cpp/type_shapes/customizable/tests/test_literals.ccbaml_language/sdk_tests/crates/cpp/type_shapes/customizable/tests/unions_static.ccbaml_language/sdk_tests/crates/python_pydantic2/type_shapes/customizable/roundtrip_tests/test_literals.pybaml_language/sdk_tests/fixtures/type_shapes/baml_src/ns_literals/types.bamlbaml_language/sdks/cpp/bridge_cpp/include/baml/baml.hbaml_language/sdks/cpp/bridge_cpp/include/baml/codec.hbaml_language/sdks/cpp/bridge_cpp/include/baml/lit.hbaml_language/sdks/cpp/sdkgen_cpp/src/lib.rs
…iterals The shape static_assert still named the BAML_LIT_INT/_BOOL/_ENUM macros deleted when BAML_LIT became polymorphic. And LitValueOf's int64_t normalization silently wrapped unsigned values above INT64_MAX, so BAML_LIT(UINT64_MAX) aliased BAML_LIT(-1); the constexpr-throw guard now fails constant evaluation with the message in the diagnostic.
Stacked on #4078 (retargets to canary when it merges).
BAML literal types stop widening to their base scalars: each literal value is a distinct C++ type, so literal unions dispatch and exhaustively match at compile time, and misspellings do not compile. Pure C++17.
Surface
One macro classifies its argument via overloaded constexpr helpers (overload resolution is the dispatch):
Every
Litcarries its value statically (::value, plus implicit conversion tostring_view/int64_t/bool/enum). Any non-blessed shape (Lit<1>int-typed, floats, mixed packs, pointers...) lands on a teachingstatic_assert. Generated code never uses the macro - the emitter spells char packs directly.Mechanics
lit.h:template <auto... Vs> struct Litwith LitShape tag-dispatch (no partial-spec ambiguity),TrimNullscanonicalization so every spelling of a string lands on one instantiation,IntLit/BoolLitmacro-free alternates.Lit<"auto">beats astd::stringsibling.Ty::Literal+Ty::EnumVariantemit::baml::Lit<...>(proper char escaping incl.\xNNand thei64::MINspelling trick); float literals stay widened (float NTTPs are C++20; BAML has none in practice).baml::Unionmachinery unchanged.Tests
test_literals.ccrewritten to typed semantics (returns/round-trips/class-of-literals + implicit-conversion ergonomics + type-level static_asserts).type Flag = "active" | 1 | trueround trip (test_round_trip_flag_mixed_literal_unionin python, exact-alternative dispatch + match in C++).test_complex_models.cc/test_enums.ccupdated (Invoice.status literal union, EnumVariant-as-type now a singleton Lit).unions_static.cc: BAML_LIT canonical-identity + int-normalization + Lit-union order-canonicality pins.cpp fixtures 12/12 locally; python + the rest on CI.
Summary by CodeRabbit
New Features
"active",1, andtrue.Bug Fixes