-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Make comptime
struct fields work like comptime
variables
#5675
Comments
This indeed looks clean, and I think I even tried this as a first attempt to basically have instance bases comptime variables, rather than global ones. This seems very intuitive and simple to understand to me :) |
I'm in agreement on this one. This accomplishes a similar feat to the closure-over-comptime-var trick, but is much easier to read and work with. I'm a bit worried about this leading to potential code bloat or compile time bloat, since the type is effectively generic and every call using it ends up generating a new function. But tuples and closure-over-comptime-var have a similar problem, and people seem to be ok with those, so maybe this is ok too. |
Types with comptime fields would have some fundamental limitations, which are essentially the same limitations covering pointers comptime vars. The compiler has to be able to track the instance through its entire lifetime. You can't store it somewhere and retrieve it later, unless the storage location is also a comptime var. Like async, these limitations are viral. A struct containing a struct containing a comptime field inherits all of these limits. |
Why not? The proposed |
#5895 encompasses this. Closing. |
What if the user or a struct method specifies the values of the comptime fields when dereferencing pointers to such structs? |
Here's how this proposal could be implemented in my simple mind:
I think equivalent behavior is already doable with |
I'd like to point out a completely different usecase that this would also allow: comptime default function parameters. A somewhat common pattern is to do something like this: fn foo(args: FooArgs) void {}
const FooArgs = struct {
a: u32 = 1,
b: MyEnum = .bar,
c: u8 = ' ',
}; However, afaik there is no way to do this pattern for comptime arguments. I think this pattern may become ever more common with the addition of decl literals allowing quick shortcuts, and implementing this would allow comptime arguments to participate in this too. |
@TheHonestHare The same is already possible if you separate comptime and runtime arguments into separate types: fn foo(comptime c: FooComptimeArgs, r: FooRuntimeArgs) void {...}
test foo {foo(.{}, .{});} Being able to unify both in a single argument can be helpful, though for more complex uses like generic arguments (dependent fields), reflection on an |
(DRAG IT, DROP IT, FOLD-UNFOLD IT)
#5578 proposes, in my opinion, a very ugly solution to its problem. The same use case could be accomplished by accompanying each value with a comptime
giveToken
, but then there's the problem of encapsulating this functionality. This could be done very cleanly if structs were allowed to exist partly at comptime, partly at runtime, like so:Such fields would of course inherit most of the restrictions of comptime variables -- i.e. no setting in runtime control flow constructs, no setting to runtime values etc., although non-comptime fields would not have these restrictions. Methods would read and write comptime fields but otherwise run at runtime when appropriate. Obviously such a struct cannot be
packed
orextern
, for the same reason that functions with comptime parameters cannot have the C calling convention.The text was updated successfully, but these errors were encountered: