Open deanveloper opened 7 months ago
should specify that Discord's Role Tags Structure is incredibly cursed, but alas, I must parse it. And it'd be very convenient to use Omittable(?noreturn)
đŸ˜„
Does Omittable(@TypeOf(null))
not work for this usecase? @TypeOf(null)
gives you a zero sized type that can only be the value null
:
test {
const S = struct {
f: @TypeOf(null),
};
const s = S{ .f = null };
try std.testing.expectEqual(null, s.f);
}
const std = @import("std");
On a sidenote, this is kinda funny:
src/main.zig:7:44: error: no size available for type '@TypeOf(null)'
try std.testing.expectEqual(0, @sizeOf(@TypeOf(null)));
But @sizeOf(S)
return 0
. Seems like a bug. Is there an issue for this?
Aah no, you cannot have fields of type @TypeOf(null)
at runtime. My bad:
test {
const S = struct {
f: @TypeOf(null),
};
var s = S{ .f = null };
try std.testing.expectEqual(0, @sizeOf(@TypeOf(S)));
try std.testing.expectEqual(null, s.f);
s = s;
}
const std = @import("std");
src/main.zig:5:9: error: variable of type 'main.test_0.S' must be const or comptime
var s = S{ .f = null };
^
src/main.zig:3:12: note: struct requires comptime because of this field
f: @TypeOf(null),
Not sure when this changed
@Hejsil I also think of @TypeOf(null)
as a runtime-valid type, but it seems like the opposite was invalidly assumed at some point when stage2 was written.
For arguments and return values this has been reported and fixed before: https://github.com/ziglang/zig/pull/16104.
I haven't found an open issue about using it as struct field, but IMO there shouldn't be any disparity between those usages.
Regarding @sizeOf
on comptime-only types erroring, that's proposal https://github.com/ziglang/zig/issues/4211 ; currently the langref states that 0 is returned (behavior which is imo misleading/ a source for errors).
Correction to my last comment:
I just found out I misread #16104 several times over - the description says "null
and undefined
are [...] comptime-only values.".
The following still fails, seemingly intentionally:
// compile error:
// argument to function being called at comptime must be comptime-known;
// function returns a comptime-only type '@TypeOf(null)'
pub fn foo(value: bool) @TypeOf(null) {
_ = value;
return null;
}
fn exe(a: anytype) void {
@compileLog(foo(a));
}
test exe {
exe(true);
}
I still see no fundamental problem with the idea, and think it would be nicer if this were allowed, i.e. @TypeOf(null)
were a 0-bit runtime type.
EDIT: As a crutch, you can sometimes use an optional with a stub payload type: const Null = ?enum{};
.
Imo this reduces code clarity over @TypeOf(null)
though, and doesn't integrate as nicely (needs separate checking code).
Yup, I've been using Omittable(?enum{})
for now. It's definitely a strange use-case, you can blame discord's wacky API for this issue ahaha.
Zig Version
0.12.0-dev.2928+6fddc9cd3
Steps to Reproduce and Observed Behavior
Minimum reproducible example:
Gives the compile-time error:
Expected Behavior
While
noreturn
on its own can't be parsed into,?noreturn
andfn (T: type) type { return union(enum) { x: SomeType, y: T }}
(where T isnoreturn
) are useful. For instance, see Discord's Role Tags Structure, which with anfn Omittable(T)
helper, can be represented asOmittable(?noreturn)
Workaround for now can be to use
enum{}
instead ofnoreturn
, which both represent a type that has 0 possible values. Another workaround is of course to just make a custom type with its ownjsonParse
andjsonStringify
methods.