test "" {
// error: unreachable code
@import("std").debug.assert(@typeOf(unreachable) == noreturn);
}
This might actually be working as intended. The sizeof argument is being evaluated at comptime, and comptime code hit unreachable, right? That's supposed to be a compile error.
@thejoshwolfe
@andrewrk and I had a back and forth about this before I posted this issue
<andrewrk> that's right - @typeOf() takes an expression
<andrewrk> and evaluating an expression can't hit unreachable at compile-time
<Hejsil> Well, @typeOf doesn't evaluate the expression though
<Hejsil> And isn't unreachable of type noreturn?
<andrewrk> it does evaluate the expression
<Hejsil> How does that work for runtime values?
<Hejsil> var a: usize = 0; @typeOf(a); works
<Hejsil> but a can't be comptime evaluated
<andrewrk> hm I think "evaluation" is an ambiguous term in zig
<andrewrk> I'm thinking
<Hejsil> Well, Zig can clearly typecheck unreachable, so it's kinda weird that @typeOf doesn't work
<andrewrk> hmm I think you're right
TLDR: @typeOf shouldn't need to evaluate the expression to figure out its type. You can @typeOf runtime variables, and that works fine, so why shouldn't unreachable.
@typeOf(if (isWindows()) handle else if (isLinux()) fd else unreachable)
Well, shouldn't that work? If we are not windows or linux, then @typeOf should return noreturn as that is the type of unreachable. If you want the code to be comptime executed, then store it in a const global first.
const Handel = if (isWindows()) handle else if (isLinux()) fd else unreachable;
@typeOf(Handle);
Hmmm, actually, I kinda see the problem. We basicly have to special case unreachable for @typeOf for this to work. Still, it's kinda weird not being able to do @typeOf(unreachable), but I don't have a real usecase other than example code.
// This is some documentation:
// As we can see, unreachable is also of type noreturn, which allows it to be part of
// any expression without effect the resulting type of that expression
@import("std").debug.assert(@typeOf(unreachable) == noreturn);
I'm not able to test this right now, but I would expect a "branch quota exceeded" compile error for @typeOf(while (true) {}).
If @typeOf(expr) is equivalent to @typeOf(comptime expr), which i think is the case, then it should be impossible to get noreturn out of @typeOf().
@typeOf(while(true) {} ) hangs the compiler, so there's a bug.
It's correct that @typeOf(x) is equivalent to @typeOf(comptime x) currently. I'm not sure that's the best behavior though. For example, this asks the question, "why does @typeOf(variable) work?"
To which the answer is, another bug:
test "@typeOf" {
var a: i32 = undefined;
@compileLog(comptime a);
}
prints
| (runtime value)
what a mess!
This is probably intended behavior, but the expr passed to @typeOf is emitted into the binary. @typeOf(while(true) {}) doesn't hang the compiler, but runs an inf loop at runtime.
const std = @import("std");
pub fn main() void {
var a = true;
const A = @typeOf(if (a) unreachable else std.os.exit(0));
std.debug.warn("{}\n", @typeName(A));
}
reached unreachable code
testing.zig:5:30: 0x223924 in ??? (testing)
const A = @typeOf(if (a) unreachable else std.os.exit(0));
^
zig/std/special/bootstrap.zig:112:22: 0x2234ab in ??? (testing)
root.main();
^
zig/std/special/bootstrap.zig:43:5: 0x2232b0 in ??? (testing)
@noInlineCall(posixCallMainAndExit);
Most helpful comment
@typeOf(while(true) {} )hangs the compiler, so there's a bug.It's correct that
@typeOf(x)is equivalent to@typeOf(comptime x)currently. I'm not sure that's the best behavior though. For example, this asks the question, "why does@typeOf(variable)work?"To which the answer is, another bug:
prints
what a mess!