baml.ops.__union_add

(internal) Runtime double dispatch for `a + b`: picks the `baml.ops.Add` impl from *both* operands' runtime types — `a`'s selects the implementing type, `b`'s the `Rhs` — and tail-calls its `add`.

Reference version

Signature

function baml.ops.__union_add(a: unknown, b: unknown) -> unknown throws never

(internal) Runtime double dispatch for a + b: picks the baml.ops.Add impl from both operands' runtime types — a's selects the implementing type, b's the Rhs — and tail-calls its add.

The compiler emits a __union_<op> call for a binary operator whose operands' static types are erased to an abstract form (a union, an interface-existential, or a type variable), where the implement rule can only be chosen from the operands' runtime types — double dispatch a static call cannot express. Primitive operands keep their fast path and a statically-pinned pair calls the impl directly; only the abstract case lands here.

unknown in and out costs nothing: the type checker has already proved every runtime operand pair is implemented — an unresolved dispatch is an internal error, not a user one — and supplies the real operand types, while the caller re-applies the statically-computed result type to what comes back.

The four drivers below (__union_sub, __union_mul, __union_div, __union_rem) and the unary __union_neg work exactly the same way, each against its own interface.

Panics

  • Whatever the resolved add raises — for an int pair, for instance, baml.panics.IntegerOverflow.

Source:<builtin>/baml/ns_ops/math.bamlbytes 15257–15348