-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Tuples and structs in Zig support comptime fields, which are effectively declarations with a fancy hat on. These fields have a fixed value which is associated with the type itself.
A slightly weird thing about comptime fields is that they're actually semantically considered mutable: the catch is that the value you store to them must be comptime-known to match the current value. For instance:
const S = struct {
comptime a: [2]u32 = .{ 123, 456 },
};
test "store to comptime field" {
var s: S = .{};
s.a[0] = 123; // this is fine
s.a = .{ 123, 456 }; // this is fine
s.a[0] = 600; // this emits an error
}foo.zig:8:12: error: value stored in comptime field does not match the default value of the field
s.a[0] = 600; // this emits an error
~~~~~~~^~~~~
Because pointers to comptime fields are semantically considered mutable, they unfortunately have the same restrictions as pointers to comptime vars, introduced in #19414. This limits the usefulness of these fields, and can be particularly frustrating since fields of untyped anonymous initializations are implicitly made comptime.
However, there does not appear to be any reason these fields have to be mutable. I would guess that the main reason is for RLS-style initialization: in the example above, perhaps we want s = .{ .a = .{ 123, 456 } } to be valid. I think this makes sense, because of the fact that if no type were given, you would get a type with a comptime field; it would be strange if explicit specification of the struct removed the ability to initialize its comptime field. Thus, I do not propose disallowing comptime fields from appearing in struct iniitalization expressions, although the field initializer must -- like today -- be comptime-known and match the field value. I do, however, propose that "normal" pointers to such fields should always be considered immutable. They should have a const pointer type, and attempting to mutate through them at comptime should raise a compile error. This would remove the restrictions in place on these fields, allowing them to be referenced at runtime just like non-comptime fields. I believe this change would improve "perceived simplicity" of the language, i.e. how difficult it is to learn/understand (and the impact on actual spec simplicity should be fairly neural).