✗
Failing This test is currently failing.
Failed: backend-exec
Error Details
output_emitted.zig:44:60: error: remainder division with 'i64' and 'i64': signed integers and floats must use @rem or @mod
Failure Output
🎯 Compiler coordination: Passes: 15 (flow-based: frontend, analysis, emission)
Error: output_emitted.zig:44:60: error: remainder division with 'i64' and 'i64': signed integers and floats must use @rem or @mod
{ const i = __koru_item_0; _ = &i; a.acc = (a.acc + 7) % @as(i64, @intCast(i));
^~~~~~~~~~~
referenced by:
main: output_emitted.zig:505:22
callMain [inlined]: /opt/homebrew/Cellar/zig/0.15.2_1/lib/zig/std/start.zig:618:22
callMainWithArgs [inlined]: /opt/homebrew/Cellar/zig/0.15.2_1/lib/zig/std/start.zig:587:20
main: /opt/homebrew/Cellar/zig/0.15.2_1/lib/zig/std/start.zig:602:28
1 reference(s) hidden; use '-freference-trace=5' to see all references Code
// RED PIN (2026-07-03): the NAIVE Koru `%` operator on signed i64 must compile,
// run, and be C-fast. It currently does NOT: expressions in .k bodies (captured
// fields, if-conditions, args) are passed to Zig as RAW STRINGS, not parsed into a
// Koru AST — so `a % b` reaches Zig verbatim, and Zig REJECTS `%` on signed ints
// ("signed integers and floats must use @rem or @mod"), a hard backend compile
// error. That is why .k authors reach for raw `@mod` (euclidean — and ~1.25x slower
// than @rem's truncated remainder, which is C's `%`; measured 45.9ms vs 36.6ms on
// the josephus hot loop).
//
// THE FIX (endeavor "A"): give .k body-expressions a parse-and-lower layer so the
// `%` operator lowers to @rem (truncated, C/Rust semantics) — and `/` to a
// type-aware @divTrunc/`/`. When that lands, THIS TEST GOES GREEN. Until then the
// compute-kernel ports use raw @rem as a faithful stopgap (endeavor "B", shipped).
// See baton_koru_expression_layer_raw_zig_gap.
//
// Semantics check: for i in [2,5): acc=0 -> (0+7)%2=1 -> (1+7)%3=2 -> (2+7)%4=1.
import std/io
capture { acc: 0[i64] }
! as a |> for(2..5)
! each i |> captured { acc: (a.acc + 7) % @as(i64, @intCast(i)) }
| captured r |> std/io:print.ln("{{ r.acc:d }}")
Expected output
1Flows
flow ~capture click a branch to expand · @labels scroll to their anchor
capture (source: acc: 0[i64])
Test Configuration
MUST_RUN