`unreachable` can be anything

From: unreachable is a slice, function, and constructor · Issue #22553 · ziglang/zig · GitHub

test {
   unreachable[0..5];
   unreachable[0..5] ** 3;
   unreachable(1, true, "foo");
   unreachable(1, true, "foo")[0..5];
   try unreachable(1, true, "foo");
   unreachable.*;
   unreachable.?;
   !unreachable;
   unreachable.enumField;
   unreachable.method();
   unreachable.field.method();
   for (unreachable) |_| {}
   while (unreachable) {}
   if (unreachable) {}
   switch (unreachable) {}
   defer unreachable;
   unreachable;
}
1 Like

unreachable is of type noreturn so any other value of noreturn type works just as good (except for defer since return cant be in defer).

test {
    (return)[0..5];
    (return)[0..5] ** 3;
    (return)(1, true, "foo");
    (return)(1, true, "foo")[0..5];
    try (return)(1, true, "foo");
    (return).*;
    (return).?;
    !(return);
    (return).enumField;
    (return).method();
    (return).field.method();
    for (return) |_| {}
    while (return) {}
    if (return) {}
    switch (return) {}
    (return);
}
3 Likes

Funny! Correct behavior should be “error: unreachable code” reported by AstGen.zig

Except for this one:

defer unreachable;

Also consider this snippet, which is actually useful:

errdefer comptime unreachable;
8 Likes

Interesting! So that the following code compiles:

const std = @import("std");

fn foo() u8 {
    for (return 1) |_| {
     	(break).foo;
    }
    while (return 2) {
    	(continue).?;
    }
    if (return 3) {
    	try unreachable[0..5];
    }
}

pub fn main() !void {
    std.debug.print("{}\n", . {foo()}); // 1
}

Why return/continue/break are required to be enclosed in (...), but unreachable not?

@andrewrk

Do you mean there is something which needs to be fixed in unreachable is a slice, function, and constructor · Issue #22553 · ziglang/zig · GitHub?

Good point, I didn’t consider that while closing the issue.

I’ve often felt like almost every usage of expr in AstGen ought to be reachableExpr; I guess this confirms that!

I’ll re-open the issue, and put this on my list of things to handle in The Great AstGen Rewrite (yes I’m serious about that).

2 Likes

I guess the line should be understood as “beyond this point failure is no longer an option”. Definitely useful in situations where your code makes irreversible changes (to the file system, for instance).

return/continue/break all can have arguments after them and () required to show what no values will follow. unreachable doesn’t have anything after so () are not needed.

2 Likes