Repository navigation
Use RealizedTy in runtime - #3998
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
⏭️ 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):
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (53)
🚧 Files skipped from review as they are similar to previous changes (49)
📝 WalkthroughWalkthroughThis PR makes associated-type projection interfaces mandatory and migrates compiler, VM, heap, serialization, and host-boundary type metadata from ChangesType-system projection invariants
Realized type runtime migration
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Binary size checks passed✅ 7 passed
Generated by |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
baml_language/crates/bex_vm/src/package_baml/resolve.rs (1)
731-738: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant double
try_fromconversion.
<&RealizedTy>::try_from(other)is evaluated once in the match guard and again inside the arm body. Consider binding it once.♻️ Suggested simplification
- other if <&RealizedTy>::try_from(other).is_ok() => { - let realized = <&RealizedTy>::try_from(other) - .unwrap_or_else(|_| unreachable!("guarded by the `is_ok` above")); - let (args, assoc) = pinned_interface_instantiation(vm, rule); - push_unique(&mut out, (realized.clone(), args, assoc)); - } + other if let Ok(realized) = <&RealizedTy>::try_from(other) => { + let (args, assoc) = pinned_interface_instantiation(vm, rule); + push_unique(&mut out, (realized.clone(), args, assoc)); + }Note: match-guard
letbindings require a sufficiently recent Rust edition/feature; verify compatibility with the project's toolchain before applying, or use anif let/matchrestructure instead.🤖 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_vm/src/package_baml/resolve.rs` around lines 731 - 738, Update the concrete-type branch in the surrounding resolver logic to perform the RealizedTy conversion only once, binding and reusing the successful result instead of calling try_from in both the guard and arm body. If match-guard bindings are unsupported by the project toolchain, restructure this branch with if let or match while preserving the existing push_unique behavior.baml_language/crates/bex_engine/src/conversion.rs (1)
189-223: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winHoist the repeated
class_type_args→Vec<RuntimeTy>conversion.The same widening of
instance.class_type_argsis recomputed inside the per-field closure (forfield_type) and again for the outerInstance.type_args, redoing the conversion once per field instead of once per instance.♻️ Suggested refactor
+ let runtime_type_args: Vec<baml_type::RuntimeTy> = instance + .class_type_args + .iter() + .map(baml_type::RuntimeTy::from) + .collect(); let fields: Result<indexmap::IndexMap<String, BexExternalValue>, EngineError> = class .fields .iter() .zip(instance.fields.iter()) .map(|(class_field, slot)| { let value = slot.load(); - let field_type = class_field.field_template.substitute_symbolic( - &instance - .class_type_args - .iter() - .map(baml_type::RuntimeTy::from) - .collect::<Vec<_>>(), - ); + let field_type = class_field + .field_template + .substitute_symbolic(&runtime_type_args); Ok(( class_field.name.clone(), self.convert_vm_value_to_external_with_type( value, &field_type, permit, )?, )) }) .collect(); Ok(BexExternalValue::Instance { class_name: class.name.to_string(), - type_args: instance - .class_type_args - .iter() - .map(baml_type::RuntimeTy::from) - .collect(), + type_args: runtime_type_args, fields: fields?, })🤖 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_engine/src/conversion.rs` around lines 189 - 223, In the instance conversion branch, hoist the conversion of instance.class_type_args to Vec<RuntimeTy> into a local value before the fields iterator. Reuse that value for substitute_symbolic in the per-field closure and for the Instance type_args field, removing both repeated conversions while preserving the existing field and instance output.baml_language/crates/bex_vm_types/src/types/function.rs (1)
337-360: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winStale doc comment:
BoundMethod::type_argscomment still says it staysRuntimeTy.The comment claims "
RuntimeTy(notRealizedTy) ... so all three stayRuntimeTyand narrow toRealizedTytogether once it lands" — but this very diff narrowsClosure::captured_type_args,BoundMethod::type_args, andGenericFunction::type_argstoRealizedTyalready. The comment now directly contradicts the field's declared type just below it.📝 Proposed doc update
- /// `RuntimeTy` (not `RealizedTy`) mirrors [`Closure::captured_type_args`] - /// and [`GenericFunction::type_args`]: these positions should never carry a - /// type variable, but the upstream fix that stops typevars leaking into - /// value positions is still in flight, so all three stay `RuntimeTy` and - /// narrow to `RealizedTy` together once it lands. + /// `RealizedTy` (like [`Closure::captured_type_args`] and + /// [`GenericFunction::type_args`]): these positions never carry a type + /// variable, so they are fully realized by construction. pub type_args: Box<[baml_type::RealizedTy]>,🤖 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_vm_types/src/types/function.rs` around lines 337 - 360, Update the BoundMethod::type_args documentation to reflect that the field and corresponding Closure::captured_type_args and GenericFunction::type_args now use RealizedTy. Remove the stale RuntimeTy explanation and any claim that a future narrowing is still pending.
🤖 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/bex_vm_types/src/types/class.rs`:
- Around line 80-83: The doc comment above Instance::class_type_args references
the obsolete RuntimeTy type; update it to refer to the current
baml_type::RealizedTy element type while preserving the explanation about the
boxed slice and existing convention.
In `@baml_language/crates/bex_vm_types/src/types/object.rs`:
- Around line 124-125: Update the Object::Type payload to preserve the existing
RuntimeTy wire representation instead of baml_type::RealizedTy, matching the
stable serialization used by Program artifacts. If RealizedTy is required
internally, add an explicit versioned conversion or migration path while keeping
legacy bytecode and packed executables deserializable.
In `@baml_language/crates/bex_vm/src/package_baml/ops.rs`:
- Around line 596-604: Update resolve_equals_eq to propagate failures from
resolve::realize_frame instead of calling unwrap_or_else with unreachable!. Use
the function’s existing Option return path so realization errors produce None,
while preserving the successful Some((callee, type_args)) behavior.
In `@baml_language/crates/bex_vm/src/type_context.rs`:
- Around line 116-158: The runtime associated-type reduction path can recurse
indefinitely through RuntimeTypeContext::project and TyTemplate::substitute. Add
and propagate a projection depth or fuel limit across both
baml_language/crates/bex_vm/src/type_context.rs:116-158 and
baml_language/crates/baml_type/src/template.rs:237-258, terminating with an
opaque or otherwise safe result when exhausted, consistent with
PROJECTION_REDUCTION_FUEL.
---
Nitpick comments:
In `@baml_language/crates/bex_engine/src/conversion.rs`:
- Around line 189-223: In the instance conversion branch, hoist the conversion
of instance.class_type_args to Vec<RuntimeTy> into a local value before the
fields iterator. Reuse that value for substitute_symbolic in the per-field
closure and for the Instance type_args field, removing both repeated conversions
while preserving the existing field and instance output.
In `@baml_language/crates/bex_vm_types/src/types/function.rs`:
- Around line 337-360: Update the BoundMethod::type_args documentation to
reflect that the field and corresponding Closure::captured_type_args and
GenericFunction::type_args now use RealizedTy. Remove the stale RuntimeTy
explanation and any claim that a future narrowing is still pending.
In `@baml_language/crates/bex_vm/src/package_baml/resolve.rs`:
- Around line 731-738: Update the concrete-type branch in the surrounding
resolver logic to perform the RealizedTy conversion only once, binding and
reusing the successful result instead of calling try_from in both the guard and
arm body. If match-guard bindings are unsupported by the project toolchain,
restructure this branch with if let or match while preserving the existing
push_unique 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: 3a73d925-7cf2-4d85-8adf-ef303b839053
📒 Files selected for processing (52)
baml_language/crates/baml_builtins2_codegen/src/codegen.rsbaml_language/crates/baml_compiler2_emit/src/lib.rsbaml_language/crates/baml_compiler2_mir/src/ir.rsbaml_language/crates/baml_compiler2_mir/src/lower.rsbaml_language/crates/baml_compiler2_tir/src/builder.rsbaml_language/crates/baml_compiler2_tir/src/builder/associated_projection.rsbaml_language/crates/baml_compiler2_tir/src/exhaustiveness.rsbaml_language/crates/baml_compiler2_tir/src/generics.rsbaml_language/crates/baml_compiler2_tir/src/interfaces.rsbaml_language/crates/baml_compiler2_tir/src/interfaces/coherence.rsbaml_language/crates/baml_compiler2_tir/src/interfaces/impl_rules.rsbaml_language/crates/baml_compiler2_tir/src/lower_type_expr.rsbaml_language/crates/baml_compiler2_tir/src/normalize.rsbaml_language/crates/baml_type/src/family.rsbaml_language/crates/baml_type/src/lib.rsbaml_language/crates/baml_type/src/normalize.rsbaml_language/crates/baml_type/src/normalize/tests.rsbaml_language/crates/baml_type/src/realized_ty.rsbaml_language/crates/baml_type/src/runtime_ty.rsbaml_language/crates/baml_type/src/template.rsbaml_language/crates/bex_engine/src/conversion.rsbaml_language/crates/bex_engine/src/lib.rsbaml_language/crates/bex_engine/src/trace_heap.rsbaml_language/crates/bex_engine/src/trace_value_encode.rsbaml_language/crates/bex_heap/src/accessor.rsbaml_language/crates/bex_heap/src/gc.rsbaml_language/crates/bex_heap/src/tlab.rsbaml_language/crates/bex_heap/tests/generational.rsbaml_language/crates/bex_vm/src/package_baml/array.rsbaml_language/crates/bex_vm/src/package_baml/csv.rsbaml_language/crates/bex_vm/src/package_baml/json.rsbaml_language/crates/bex_vm/src/package_baml/mod.rsbaml_language/crates/bex_vm/src/package_baml/ops.rsbaml_language/crates/bex_vm/src/package_baml/resolve.rsbaml_language/crates/bex_vm/src/package_baml/root.rsbaml_language/crates/bex_vm/src/package_baml/toml.rsbaml_language/crates/bex_vm/src/package_baml/type_class.rsbaml_language/crates/bex_vm/src/package_baml/yaml.rsbaml_language/crates/bex_vm/src/type_context.rsbaml_language/crates/bex_vm/src/type_match.rsbaml_language/crates/bex_vm/src/vm.rsbaml_language/crates/bex_vm/src/watch.rsbaml_language/crates/bex_vm/tests/load_type.rsbaml_language/crates/bex_vm/tests/method_class_type_args.rsbaml_language/crates/bex_vm_types/src/errors.rsbaml_language/crates/bex_vm_types/src/types.rsbaml_language/crates/bex_vm_types/src/types/class.rsbaml_language/crates/bex_vm_types/src/types/containers.rsbaml_language/crates/bex_vm_types/src/types/function.rsbaml_language/crates/bex_vm_types/src/types/object.rsbaml_language/crates/bridge_ctypes/src/ty_decode.rsbaml_language/crates/bridge_ctypes/src/ty_encode.rs
3d3abec to
d6044fa
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
baml_language/crates/baml_builtins2_codegen/src/codegen.rs (1)
1827-1830: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStale doc: the "absent from
generics" case no longer yieldsunknown. The header still saysunknownappears "when a generic name is absent fromgenerics", but theGenericarm now emitscompile_error!for that case (Line 1868); only the "type argument not supplied at the call" case falls back tounknown. Update the sentence to match.🤖 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_builtins2_codegen/src/codegen.rs` around lines 1827 - 1830, Update the documentation comment above the relevant generic type-resolution logic to remove the claim that an absent generic name yields unknown. State that unknown is used only when a generic type argument was not supplied at the call, while the absent-from-generics case emits compile_error! as implemented in the Generic arm.
🤖 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_builtins2_codegen/src/codegen.rs`:
- Around line 1827-1830: Update the documentation comment above the relevant
generic type-resolution logic to remove the claim that an absent generic name
yields unknown. State that unknown is used only when a generic type argument was
not supplied at the call, while the absent-from-generics case emits
compile_error! as implemented in the Generic arm.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 3f92ccff-7d36-4952-87ef-afcab77ae924
⛔ Files ignored due to path filters (1)
baml_language/crates/baml_tests/snapshots/baml_src/inferred_generic_type_args.snapis excluded by!**/*.snap
📒 Files selected for processing (54)
baml_language/crates/baml_builtins2_codegen/src/codegen.rsbaml_language/crates/baml_compiler2_emit/src/lib.rsbaml_language/crates/baml_compiler2_mir/src/ir.rsbaml_language/crates/baml_compiler2_mir/src/lower.rsbaml_language/crates/baml_compiler2_tir/src/builder.rsbaml_language/crates/baml_compiler2_tir/src/builder/associated_projection.rsbaml_language/crates/baml_compiler2_tir/src/exhaustiveness.rsbaml_language/crates/baml_compiler2_tir/src/generics.rsbaml_language/crates/baml_compiler2_tir/src/interfaces.rsbaml_language/crates/baml_compiler2_tir/src/interfaces/coherence.rsbaml_language/crates/baml_compiler2_tir/src/interfaces/impl_rules.rsbaml_language/crates/baml_compiler2_tir/src/lower_type_expr.rsbaml_language/crates/baml_compiler2_tir/src/normalize.rsbaml_language/crates/baml_compiler2_tir/src/type_context.rsbaml_language/crates/baml_type/src/family.rsbaml_language/crates/baml_type/src/lib.rsbaml_language/crates/baml_type/src/normalize.rsbaml_language/crates/baml_type/src/normalize/tests.rsbaml_language/crates/baml_type/src/realized_ty.rsbaml_language/crates/baml_type/src/runtime_ty.rsbaml_language/crates/baml_type/src/template.rsbaml_language/crates/bex_engine/src/conversion.rsbaml_language/crates/bex_engine/src/future.rsbaml_language/crates/bex_engine/src/lib.rsbaml_language/crates/bex_engine/src/trace_heap.rsbaml_language/crates/bex_engine/src/trace_value_encode.rsbaml_language/crates/bex_heap/src/accessor.rsbaml_language/crates/bex_heap/src/gc.rsbaml_language/crates/bex_heap/src/tlab.rsbaml_language/crates/bex_heap/tests/generational.rsbaml_language/crates/bex_vm/src/package_baml/array.rsbaml_language/crates/bex_vm/src/package_baml/csv.rsbaml_language/crates/bex_vm/src/package_baml/json.rsbaml_language/crates/bex_vm/src/package_baml/mod.rsbaml_language/crates/bex_vm/src/package_baml/ops.rsbaml_language/crates/bex_vm/src/package_baml/resolve.rsbaml_language/crates/bex_vm/src/package_baml/root.rsbaml_language/crates/bex_vm/src/package_baml/toml.rsbaml_language/crates/bex_vm/src/package_baml/type_class.rsbaml_language/crates/bex_vm/src/package_baml/yaml.rsbaml_language/crates/bex_vm/src/type_context.rsbaml_language/crates/bex_vm/src/type_match.rsbaml_language/crates/bex_vm/src/vm.rsbaml_language/crates/bex_vm/src/watch.rsbaml_language/crates/bex_vm/tests/load_type.rsbaml_language/crates/bex_vm/tests/method_class_type_args.rsbaml_language/crates/bex_vm_types/src/errors.rsbaml_language/crates/bex_vm_types/src/types.rsbaml_language/crates/bex_vm_types/src/types/class.rsbaml_language/crates/bex_vm_types/src/types/containers.rsbaml_language/crates/bex_vm_types/src/types/function.rsbaml_language/crates/bex_vm_types/src/types/object.rsbaml_language/crates/bridge_ctypes/src/ty_decode.rsbaml_language/crates/bridge_ctypes/src/ty_encode.rs
🚧 Files skipped from review as they are similar to previous changes (48)
- baml_language/crates/bex_vm/src/package_baml/yaml.rs
- baml_language/crates/baml_compiler2_tir/src/builder.rs
- baml_language/crates/baml_compiler2_tir/src/exhaustiveness.rs
- baml_language/crates/bex_vm/src/package_baml/toml.rs
- baml_language/crates/baml_compiler2_mir/src/ir.rs
- baml_language/crates/baml_type/src/family.rs
- baml_language/crates/bex_vm/src/package_baml/root.rs
- baml_language/crates/bex_vm/src/watch.rs
- baml_language/crates/bex_engine/src/trace_value_encode.rs
- baml_language/crates/bex_vm_types/src/types/containers.rs
- baml_language/crates/bex_vm_types/src/types.rs
- baml_language/crates/baml_compiler2_tir/src/interfaces.rs
- baml_language/crates/bridge_ctypes/src/ty_encode.rs
- baml_language/crates/baml_compiler2_emit/src/lib.rs
- baml_language/crates/bex_engine/src/trace_heap.rs
- baml_language/crates/bex_vm_types/src/types/class.rs
- baml_language/crates/bex_vm/src/package_baml/type_class.rs
- baml_language/crates/bex_vm/src/type_context.rs
- baml_language/crates/bridge_ctypes/src/ty_decode.rs
- baml_language/crates/bex_vm/src/type_match.rs
- baml_language/crates/baml_compiler2_tir/src/interfaces/impl_rules.rs
- baml_language/crates/bex_vm_types/src/errors.rs
- baml_language/crates/baml_compiler2_tir/src/builder/associated_projection.rs
- baml_language/crates/bex_vm_types/src/types/object.rs
- baml_language/crates/baml_compiler2_tir/src/generics.rs
- baml_language/crates/baml_type/src/lib.rs
- baml_language/crates/baml_type/src/realized_ty.rs
- baml_language/crates/baml_compiler2_tir/src/interfaces/coherence.rs
- baml_language/crates/baml_compiler2_tir/src/type_context.rs
- baml_language/crates/baml_type/src/runtime_ty.rs
- baml_language/crates/bex_vm/tests/method_class_type_args.rs
- baml_language/crates/bex_heap/src/accessor.rs
- baml_language/crates/bex_vm/src/package_baml/mod.rs
- baml_language/crates/bex_vm_types/src/types/function.rs
- baml_language/crates/baml_compiler2_tir/src/normalize.rs
- baml_language/crates/bex_heap/src/gc.rs
- baml_language/crates/bex_heap/tests/generational.rs
- baml_language/crates/bex_heap/src/tlab.rs
- baml_language/crates/bex_vm/src/package_baml/csv.rs
- baml_language/crates/baml_compiler2_mir/src/lower.rs
- baml_language/crates/bex_vm/tests/load_type.rs
- baml_language/crates/baml_type/src/normalize/tests.rs
- baml_language/crates/baml_type/src/normalize.rs
- baml_language/crates/baml_compiler2_tir/src/lower_type_expr.rs
- baml_language/crates/bex_engine/src/conversion.rs
- baml_language/crates/baml_type/src/template.rs
- baml_language/crates/bex_vm/src/package_baml/ops.rs
- baml_language/crates/bex_vm/src/package_baml/resolve.rs
A thread that terminated with an internal error is now killed instead of hanging forever. Also placed a bandaid on the case that fixed it (broader fix planned for proper dynamic `Self` resolution in default interface method bodies)
d6044fa to
d3c41ae
Compare
Semantic reconcile with canary's #3998 ("Use RealizedTy in runtime"). Canary's change: the runtime narrowed every type-arg storage slot from RuntimeTy to RealizedTy (the typevar-free deep subset of the ty_family) — Instance::class_type_args, Array::element_ty, Map::key_ty/value_ty, Closure::captured_type_args, BoundMethod/GenericFunction::type_args, HostClosure::ret_ty/throws_ty/params, Value::{Type,Array,Map}, plus the VM's BytecodeFrame::type_args / pending_call_type_args and accessors. (It also made AssociatedTypeProjection::interface non-optional, but that surface isn't touched by this branch.) The merge was textually clean; the break was purely a type mismatch at our call sites (Vec<RuntimeTy> vs the new &[RealizedTy]). Our adaptation — mirror the same narrowing at the bytecode-cache/linker sites that shadow GenericFunction::type_args: - GenericFnKey::type_args: Vec<RuntimeTy> -> Vec<RealizedTy> (unit.rs) - linker generic-fn dedup map: HashMap<String, HashMap<Vec<RuntimeTy>, usize>> -> Vec<RealizedTy> (link.rs, both the resolver and the interning pass) - emit's tail_generic_dupes_clean clean_keys: Vec<(String, Vec<RuntimeTy>)> -> Vec<RealizedTy> (lib.rs) This is a pure rename/narrow: the generic-value interning model is unchanged (intern key is still (base_fn, type_args)); only the element type narrows. Borsh wire shape: GenericFnKey::type_args serializes a RealizedTy instead of a RuntimeTy, but ty_family assigns each variant its explicit stable master discriminant (RealizedTy just omits the typevar/projection variants, leaving gaps), so any realized value's on-wire bytes are identical. Even setting that aside, FORMAT_VERSION is 1 and unreleased, so a shape change would be fine. Gate: cargo check --workspace clean (0 warnings); fmt/clippy clean; baml_cli --lib (358), bex_vm_types+bex_cache+bex_project (106), relink_oracle (1), link_units_oracle (5), bytecode_format (7, no snapshot regen needed) all green. BAML_CACHE_VERIFY=1 corpus spot-check (cold + warm + body-edit reuse/relink, "wrote 1, reused 76") zero bails.
… Windows size ceiling Two CI-only failures on non-Linux platforms. 1. diagnostics_cache_oracle: the `unique_root()` helper anchored the project root under `std::env::temp_dir()` verbatim (unlike the already-fixed `bytecode_cache.rs` copy). `ProjectDatabase` canonicalizes the root and source paths only when they exist on disk: db1 is built before the cache dir exists (root canonicalize is a no-op fallback), then `store_with_manifest` materializes the root, so db2's `set_project_root` canonicalizes it — while the in-memory `.baml` files never exist to canonicalize. On macOS the root then resolves `/var` -> `/private/var`, on Windows it gains the `\\?\` prefix; the source paths keep the unresolved form, `strip_prefix` fails, every rel_path comes out absolute, and `plan_reuse` collapses to `None` — so `plan.dirty_files` is empty. `served == honest` still holds (a `None` plan is a full fresh check), but the `dirty.contains(...)` assertions fail (oracle_layout_reorder, oracle_mixed_file_field_reorder, oracle_throws_edit, verify_diagnostics_bails_on_a_stale_cache). `/tmp` on Linux has no symlink so it was silently fine. Canonicalize the temp base up front, matching 4f6df7b. Reproduced on Linux by routing TMPDIR through a symlink (same 4 failures); fixed under the symlink and in a normal run. 2. Size gate: the Windows baml-cli absolute ceiling was miscalibrated at baseline x1.0199 (19_098_870 / 18_726_400) — tighter than the 3% max_delta_pct guard and every other platform's x1.03 ceiling. Post-baseline canary merges (#3998 RealizedTy runtime, #4031 array-rest patterns; no Cargo.lock change) grew the Windows binary +408.6 KB (+2.18%, within the 3% guard) to 19_134_976, tripping only the stale ceiling. Normalize it to baseline x1.03 = 19_288_192, matching the 68f72e2 precedent.
Representation tightening to prevent invariant violations:
Iin(C as I).Assoc) is no longer optional: it must either be written explicitly or inferred by the TIR.RealizedTyanywhere that typevars are invalid, including function call frames and instances' generic params.Summary by CodeRabbit
Bug Fixes
Reliability