143 signed runtime division

○ Planned This feature is planned but not yet implemented.

OWED: signed runtime `/` emits Zig `@divTrunc` (or equivalent), not bare `/`.

Error Details

output_emitted.zig:84:22: error: division with 'i64' and 'comptime_int': signed integers must use @divTrunc, @divFloor, or @divExact

Failure Output

🎯 Compiler coordination: Passes: 20 (flow-based: elaborate, analysis, emission)
Error: output_emitted.zig:84:22: error: division with 'i64' and 'comptime_int': signed integers must use @divTrunc, @divFloor, or @divExact
            return n / 2;
                   ~~^~~
referenced by:
    handler [inlined]: output_emitted.zig:78:39
    __koru_handler_impl: output_emitted.zig:101:55
    5 reference(s) hidden; use '-freference-trace=7' to see all references

Code

input.k

Expected output

half=5

Flows

subflow ~go click a branch to expand · @labels scroll to their anchor
f (n)
flow ~go click a branch to expand · @labels scroll to their anchor
go (n: 10)

Test Configuration

MUST_RUN NEEDS_RULING

Awaiting ruling:

Signed runtime `/`: lower it to `@divTrunc`, or refuse it with a Koru diagnostic that names the operand's signedness? Both beat what happens today, which is Zig's own error reaching the user verbatim — "signed integers must use @divTrunc, @divFloor, or @divExact" — a raw host error with Zig's builtin list in it. The asymmetry that makes this a decision and not a bug report: koru's COMPTIME evaluator already answers it one way. src/comptime_eval.zig uses `@divTrunc` for `.divide` and its own comment calls that "the C-parity choice". The runtime emitter has no matching lowering, so comptime and runtime disagree about the same operator. Characterised 2026-07-25: signed `/` fails, unsigned `/` works, signed `*` works. The `%` half of this pin is SETTLED and landed 2026-09-17: `%` lowers to `@rem` in the Zig spelling of the expression text (codegen_utils.rewriteZigExpr), which is decidable without a type oracle because `@rem` is the same operator for an unsigned operand and the only Zig accepts for a signed one. `/` is not decidable that way — `@divTrunc` is truncating division and `/` is exact division, so which one is right depends on whether the operand is an integer or a float, and the rewrite site carries text, not types. That type oracle is the whole of what is owed here. Options: - lower it, matching comptime_eval's C-parity choice — needs the operand type at the site (the emitter's parsed `.binary` nodes have no types today either); - refuse it in Koru, naming the signedness — this pin flips to MUST_ERROR with that diagnostic as its expectation. Blocks: this test, and the class it stands for. The corpus has zero other tests dividing a signed runtime value — everything divides literals (const-folded) or divides usize — which is how it survived. Found from outside, in a koru-examples ledger app where `cents / 100` compiled until a second module passed the value at runtime.