unreachable
In Debug and ReleaseSafe mode unreachable
emits a call to panic
with the message reached unreachable code
.
In ReleaseFast and ReleaseSmall mode, the optimizer uses the assumption that unreachable
code will never be hit to perform optimizations.
Basics
test_unreachable.zig
// unreachable is used to assert that control flow will never reach a
// particular location:
test "basic math" {
const x = 1;
const y = 2;
if (x + y != 3) {
unreachable;
}
}
Shell
$ zig test test_unreachable.zig
1/1 test.basic math... OK
All 1 tests passed.
In fact, this is how std.debug.assert
is implemented:
test_assertion_failure.zig
// This is how std.debug.assert is implemented
fn assert(ok: bool) void {
if (!ok) unreachable; // assertion failure
}
// This test will fail because we hit unreachable.
test "this will fail" {
assert(false);
}
Shell
$ zig test test_assertion_failure.zig
1/1 test.this will fail... thread 2453337 panic: reached unreachable code
/home/ci/actions-runner/_work/zig-bootstrap/zig/docgen_tmp/test_assertion_failure.zig:3:14: 0x2241e2 in assert (test)
if (!ok) unreachable; // assertion failure
^
/home/ci/actions-runner/_work/zig-bootstrap/zig/docgen_tmp/test_assertion_failure.zig:8:11: 0x22419a in test.this will fail (test)
assert(false);
^
/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/test_runner.zig:176:28: 0x22ceb9 in mainTerminal (test)
} else test_fn.func();
^
/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/test_runner.zig:36:28: 0x22503a in main (test)
return mainTerminal();
^
/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:564:22: 0x2246b2 in posixCallMainAndExit (test)
root.main();
^
/home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:243:5: 0x224201 in _start (test)
asm volatile (switch (native_arch) {
^
???:?:?: 0x0 in ??? (???)
error: the following test command crashed:
/home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/3f6575b81fc83074e649e9b167fa28e1/test
At Compile-Time
test_comptime_unreachable.zig
const assert = @import("std").debug.assert;
test "type of unreachable" {
comptime {
// The type of unreachable is noreturn.
// However this assertion will still fail to compile because
// unreachable expressions are compile errors.
assert(@TypeOf(unreachable) == noreturn);
}
}
Shell
$ zig test test_comptime_unreachable.zig
docgen_tmp/test_comptime_unreachable.zig:10:16: error: unreachable code
assert(@TypeOf(unreachable) == noreturn);
^~~~~~~~~~~~~~~~~~~~
docgen_tmp/test_comptime_unreachable.zig:10:24: note: control flow is diverted here
assert(@TypeOf(unreachable) == noreturn);
^~~~~~~~~~~
See also: