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

  1. // unreachable is used to assert that control flow will never reach a
  2. // particular location:
  3. test "basic math" {
  4. const x = 1;
  5. const y = 2;
  6. if (x + y != 3) {
  7. unreachable;
  8. }
  9. }

Shell

  1. $ zig test test_unreachable.zig
  2. 1/1 test_unreachable.test.basic math... OK
  3. All 1 tests passed.

In fact, this is how std.debug.assert is implemented:

test_assertion_failure.zig

  1. // This is how std.debug.assert is implemented
  2. fn assert(ok: bool) void {
  3. if (!ok) unreachable; // assertion failure
  4. }
  5. // This test will fail because we hit unreachable.
  6. test "this will fail" {
  7. assert(false);
  8. }

Shell

  1. $ zig test test_assertion_failure.zig
  2. 1/1 test_assertion_failure.test.this will fail... thread 988108 panic: reached unreachable code
  3. /home/ci/actions-runner/_work/zig-bootstrap/zig/docgen_tmp/test_assertion_failure.zig:3:14: 0x1038e6d in assert (test)
  4. if (!ok) unreachable; // assertion failure
  5. ^
  6. /home/ci/actions-runner/_work/zig-bootstrap/zig/docgen_tmp/test_assertion_failure.zig:8:11: 0x1038e2a in test.this will fail (test)
  7. assert(false);
  8. ^
  9. /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:158:25: 0x1043a32 in mainTerminal (test)
  10. if (test_fn.func()) |_| {
  11. ^
  12. /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:35:28: 0x1039c8b in main (test)
  13. return mainTerminal();
  14. ^
  15. /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:501:22: 0x1039319 in posixCallMainAndExit (test)
  16. root.main();
  17. ^
  18. /home/ci/actions-runner/_work/zig-bootstrap/out/host/lib/zig/std/start.zig:253:5: 0x1038e81 in _start (test)
  19. asm volatile (switch (native_arch) {
  20. ^
  21. ???:?:?: 0x0 in ??? (???)
  22. error: the following test command crashed:
  23. /home/ci/actions-runner/_work/zig-bootstrap/out/zig-local-cache/o/c95e7748bd467945dbe9cc12e10f552c/test

At Compile-Time

test_comptime_unreachable.zig

  1. const assert = @import("std").debug.assert;
  2. test "type of unreachable" {
  3. comptime {
  4. // The type of unreachable is noreturn.
  5. // However this assertion will still fail to compile because
  6. // unreachable expressions are compile errors.
  7. assert(@TypeOf(unreachable) == noreturn);
  8. }
  9. }

Shell

  1. $ zig test test_comptime_unreachable.zig
  2. docgen_tmp/test_comptime_unreachable.zig:10:16: error: unreachable code
  3. assert(@TypeOf(unreachable) == noreturn);
  4. ^~~~~~~~~~~~~~~~~~~~
  5. docgen_tmp/test_comptime_unreachable.zig:10:24: note: control flow is diverted here
  6. assert(@TypeOf(unreachable) == noreturn);
  7. ^~~~~~~~~~~

See also: