✓
Passing Passing: the compiler rejects this program as expected.
Code
// 520_008: `->` produce of `"lit" ++ field` emits Zig `++` — a comptime-only
// concat — over a runtime operand. The emitted output_emitted.zig fails its
// own build: "unable to resolve comptime value / slice being concatenated
// must be comptime-known".
//
// Latency mechanism: Zig analyzes a function body only when the function is
// reached. greet_event.handler is reached HERE because the registered
// dispatcher calls it — a wire turn via std/bridge:run forces analysis.
// Plain call sites stay silent: `greet(name: "x")` constant-folds through
// the produce (the literal arg makes the whole concat comptime-known), and
// a folded call leaves the handler body unanalyzed — 020_014 passes with
// the identical produce because nothing ever calls its handler.
//
// Deferred by design: the honest fix is a runtime concat, which allocates —
// and ownership is a language-semantics question (produced runtime strings
// should carry string<allocated!> to a disposer), not an emission detail.
// See BUG.md.
import std/io
import std/bridge
import std/runtime
import std/interpreter
pub tor greet { name: string } -> string
greet -> "hello " ++ name
std/runtime:register(scope: "api") {
greet(5)
}
[with]std/bridge:create(id: "repro", scope: "api"): br
|> std/bridge:run(br, source: "greet(name: \"assistant\")")
| result r |> std/interpreter:value.stringify(r.value): j |> std/io:print.ln("said: {{ j:s }}")
| error e |> std/io:print.ln("failed: {{ e.kind:s }}")
Supporting Files
# BUG: `->` produce of `"lit" ++ field` emits comptime-only Zig concat
## Status
**OPEN** — deferred: the fix is a string-allocation/ownership decision,
not an emission detail.
## Symptom
A produce whose body concatenates a literal with a runtime operand emits
Zig `++`, which is comptime-only:
```koru
pub tor greet { name: string } -> string
greet -> "hello " ++ name
```
```zig
// output_emitted.zig
return "hello " ++ name; // error: slice being concatenated must be comptime-known
```
## Why it stayed latent
Zig analyzes a function body only when the function is *reached*. Two
hiding spots kept this invisible:
1. **Uncalled handlers.** `020_014_pure_subflow_impl` has carried the
identical produce (`"Hello, " ++ name ++ "!"`) green for months —
nothing calls `greet_event.handler`, so the broken body is never
sema'd.
2. **Constant folding at call sites.** `greet(name: "x")` folds the whole
concat at comptime; even `echo(s: "lit"): a |> greet(name: a)` folds,
because `a` resolves to a comptime-known string.
The paths that expose it are the ones that matter: `runtime:register`
generates a dispatcher that *calls* the handler — so a wire turn
(`std/cell:run`, `std/bridge:run`) forces analysis and the emitted
program fails its own build. Every `greet -> "hello {{ name:s }}"`
example in the cell suite only ever printed `r.bound`, which is the
interpreter's binding name (`r1`), not the value — so the produce body
was never observed either.
## What the honest fix looks like
Runtime concat allocates. `koru_allocator()` is leak-metered in Debug —
an untracked concat result converts this compile error into a guaranteed
leak-check failure, and `page_allocator` would hide the alloc from the
meter ("a METER, not a mop"). The semantically consistent answer is that
a runtime-concat produce yields `string<allocated!>` — the obligation
rides to the caller and discharges via `std/io:free`, same contract as
`std/fmt:fmt` results. That decision (and `{{ }}` interpolation living at
the fmt/print boundary, not in string literals) is the real work — this
bug is pinned so the seam is named until then.
## Reproduction
`input.kz` — a registered `greet` whose produce is `"hello " ++ name`,
dispatched through `std/bridge:run` so the handler is sema'd. Fails at
`zig build` of `output_emitted.zig`:
`unable to resolve comptime value — slice being concatenated must be
comptime-known`.
Actual compiler output
[REGISTRY] Creating dispatcher for scope 'api'
[REGISTRY] Found 1 events
[REGISTRY] Generated 18901 bytes
Error: install
+- install output
+- compile exe output Debug native 1 errors
output_emitted.zig:134:32: error: unable to resolve comptime value
return "hello " ++ name;
^~~~
output_emitted.zig:134:32: note: slice being concatenated must be comptime-known
referenced by:
dispatch_api_greet: output_emitted.zig:228:52
scope_events_api: output_emitted.zig:325:599
14 reference(s) hidden; use '-freference-trace=16' to see all references
error: the following command failed with 1 compilation errors:
/opt/homebrew/Cellar/zig/0.15.2_1/bin/zig build-exe -ODebug --dep ast --dep koru_parser --dep koru_ast=ast --dep koru_errors=errors --dep flow_parser --dep liquid -Mroot=/Users/larsde/src/koru/tests/regression/500_INTEGRATION_TESTING/520_BUG_REPRODUCTION/520_008_runtime_concat_produce/output_emitted.zig -ODebug --dep errors -Mast=/Users/larsde/src/koru/src/ast.zig -ODebug --dep struct_literal --dep ast --dep ast_mangle --dep lexer --dep errors --dep type_registry --dep expression_parser --dep comptime_eval --dep annotation_parser --dep union_collector --dep module_resolver --dep file_types -Mkoru_parser=/Users/larsde/src/koru/src/parser.zig -ODebug -Merrors=/Users/larsde/src/koru/src/errors.zig -ODebug --dep ast --dep lexer --dep errors --dep expression_parser -Mflow_parser=/Users/larsde/src/koru/src/flow_parser.zig -ODebug -Mliquid=/Users/larsde/src/koru/src/liquid.zig -ODebug --dep liquid -Mstruct_literal=/Users/larsde/src/koru/src/struct_literal.zig -ODebug --dep ast -Mast_mangle=/Users/larsde/src/koru/src/ast_mangle.zig -ODebug -Mlexer=/Users/larsde/src/koru/src/lexer.zig -ODebug --dep ast --dep log -Mtype_registry=/Users/larsde/src/koru/src/type_registry.zig -ODebug --dep lexer --dep ast -Mexpression_parser=/Users/larsde/src/koru/src/expression_parser.zig -ODebug --dep ast --dep expression_parser -Mcomptime_eval=/Users/larsde/src/koru/src/comptime_eval.zig -ODebug -Mannotation_parser=/Users/larsde/src/koru/src/annotation_parser.zig -ODebug --dep ast -Munion_collector=/Users/larsde/src/koru/src/union_collector.zig -ODebug --dep config --dep log --dep file_types -Mmodule_resolver=/Users/larsde/src/koru/src/module_resolver.zig -ODebug -Mfile_types=/Users/larsde/src/koru/src/file_types.zig -ODebug -Mlog=/Users/larsde/src/koru/src/log.zig -ODebug --dep log -Mconfig=/Users/larsde/src/koru/src/config.zig -lc --cache-dir .zig-cache --global-cache-dir /Users/larsde/.cache/zig --name output --zig-lib-dir .zig-cache/koru_lib_overlay/ --listen=-
Build Summary: 0/3 steps succeeded; 1 failed
install transitive failure
+- install output transitive failure
+- compile exe output Debug native 1 errors
error: the following build command failed with exit code 1:
.zig-cache/o/407a46767a24a93214b9f296a57d4142/build /opt/homebrew/Cellar/zig/0.15.2_1/bin/zig .zig-cache/koru_lib_overlay /Users/larsde/src/koru/tests/regression/500_INTEGRATION_TESTING/520_BUG_REPRODUCTION/520_008_runtime_concat_produce .zig-cache /Users/larsde/.cache/zig --seed 0x9e1f6d -Z57d3cfba131c4b88 -Doptimize=DebugMust contain:
slice being concatenated must be comptime-knownFlows
flow ~register click a branch to expand · @labels scroll to their anchor
register (scope: "api", source: greet(5))
flow ~create click a branch to expand · @labels scroll to their anchor
create (id: "repro", scope: "api")
Test Configuration
MUST_ERROR