Issue #1108: A sync function that may panic() is refused at build time (NK1152), though Part II 10.2 lets a build-time run stop with panic

Open and answer this issue on GitHub.

ready, wip · opened 2026-10-31 · updated 2026-10-31 · 0 comments

Found by j5 (docs/briefs/tools/j5-1019-comptime-field.md.report.md), tools lane, #1019.

Problem

A sync function that may panic() cannot run at build time: NK1152, “Nothing says what it touches outside the program”. Part II 10.2 says a build-time run may stop with panic() (refused as NK1244 in the program’s words), and the same function runs fine while the program runs.

Probe (target/fast/nikaia at 69ea78d)

fn pick(n: i64) -> i64 sync {
	if n > 10 { panic("too big") }
	return n * 2
}

comptime X: i64 = pick(3)

fn main() {
	print(f"{X}")
}

Wanted: 6. Today: NK1152 at line 6. Calling pick(3) with let prints 6.

Cause (traced, sure)

panic is the language’s own word, in no ledger, so calls::callee_named returns Callee::Opaque("panic"). sync.nika pausing_call skips it through a_stop (Part I 7.2: panic stops, it does not pause), but touch.nika reached_call sets reach.unknown = true for every Callee::Opaque, so touches_known is false and build_eval.nika bt_may_not_run refuses.

To build

  1. touch.nika reached_call: a Callee::Opaque named panic touches nothing, by the same rule as sync.nika a_stop (one shared helper, not a second copy). Test tests/compiler/tests/a_comptime_runs_a_function_that_may_panic.nika + .stdout (the probe), and one whose build-time run takes the panic branch, refused NK1244 with the panic’s words (.stderr).
  2. j5’s way around it goes: comptime_tree.nika comptime_turn_function / comptime_turn_call write __nikaia_comptime_turn[T]() returning the turn’s value with return inside the turn and panic(...) after the loop, instead of a Vec and .remove(0). The a_comptime_* tests keep passing.

Built by the tools lane (brief docs/briefs/tools/j9-1108-panic-at-build-time.md).


Generated by Claude Code

Back to Open Issues