unreachable
In Debug
and ReleaseSafe
mode, and when using zig test, unreachable
emits a call to panic
with the message reached unreachable code
.
In ReleaseFast
mode, the optimizer uses the assumption that unreachable
code will never be hit to perform optimizations. However, zig test even in ReleaseFast
mode still emits unreachable
as calls to panic
.
Basics
test_unreachable.zig
// unreachable is used to assert that control flow will never happen upon 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.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.zig
1/1 test "this will fail"... thread 794145 panic: reached unreachable code
/home/andy/Downloads/zig/docgen_tmp/test.zig:3:14: 0x207f3b in assert (test)
if (!ok) unreachable; // assertion failure
^
/home/andy/Downloads/zig/docgen_tmp/test.zig:8:11: 0x2079ce in test "this will fail" (test)
assert(false);
^
/home/andy/Downloads/zig/lib/std/special/test_runner.zig:80:28: 0x22f423 in std.special.main (test)
} else test_fn.func();
^
/home/andy/Downloads/zig/lib/std/start.zig:543:22: 0x227e1c in std.start.callMain (test)
root.main();
^
/home/andy/Downloads/zig/lib/std/start.zig:495:12: 0x20923e in std.start.callMainWithArgs (test)
return @call(.{ .modifier = .always_inline }, callMain, .{});
^
/home/andy/Downloads/zig/lib/std/start.zig:409:17: 0x2082d6 in std.start.posixCallMainAndExit (test)
std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp }));
^
/home/andy/Downloads/zig/lib/std/start.zig:322:5: 0x2080e2 in std.start._start (test)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
error: the following test command crashed:
docgen_tmp/zig-cache/o/8e4964e05ddaf866e77360a551b3c05b/test /home/andy/Downloads/zig/build-release/zig
At Compile-Time
test.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.zig
docgen_tmp/test.zig:10:16: error: unreachable code
assert(@TypeOf(unreachable) == noreturn);
^
docgen_tmp/test.zig:10:24: note: control flow is diverted here
assert(@TypeOf(unreachable) == noreturn);
^
See also: