Skip to content
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

Allow explicit null packing optimization in non-exhaustive and sized enums #12524

Closed
sno2 opened this issue Aug 20, 2022 · 4 comments
Closed
Labels
optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@sno2
Copy link
Contributor

sno2 commented Aug 20, 2022

Hello, it would be great if we would allow explicitly setting a value for null on an enum to allow for setting the value of it when the enum is null. The optimization is similar to the nullable pointer optimization which allows null to be coerced to null pointers as 0. The following syntax can be used and is non-breaking as parsing fails on the current version of Zig:

const Person = enum (u8) {
  null = 0,
  John,
  James,
  Jack,
  _,
}:

The null variant must have an explicit initializer so as to not confuse it with a regular variant. I am not sure, but it may also be a good idea to limit this variant to non-exhaustive sized enums because the optimization could technically be possible by default on regular enums as the ABI is unspecified.

When you specify a null variant, it is impossible to construct the null via that enum itself (e.g. through alias):

Person.null; // syntax error anyways
Person.@"null"; // this would actually try to access a variant for the literal string "null" so it may fail or pass but it would never actually mean the null variant

The null variant only has meaning for an optional type which contains the enum. In which case, the option part is packed and any time null is assigned to the optional type it will be set to the value of the null variant. This allows for far more beautiful DX when using the optional enum type.

const Person = enum (u32) {
    null = 0,
    John,
    James,
    Jack,
    _
};

const MaybePerson = ?Person;

const foo: MaybePerson = null;
std.debug.print("{}\n", .{@enumToInt(foo)}); // 0 - the value specified

std.debug.print("{}\n", .{@sizeOf(Person)}); // 1
std.debug.print("{}\n", .{@sizeOf(MaybePerson)}); // 1 - successfully packed using the null variant

A use-case I have for this currently is for packing the optional values of garbage-collected references which are secretly indices using a null tag to stay in u32 even when it's optional. I have been just explicitly naming the tag but this means I cannot use the other amazing syntatic features of optional types such as nullable if expressions and orelse.

@sno2
Copy link
Contributor Author

sno2 commented Aug 20, 2022

I would like to try to implement this if there is not that much opposition.

@sno2 sno2 changed the title Allow null packing in non-exhaustive and sized enums Allow explicit null packing in non-exhaustive and sized enums Aug 20, 2022
@sno2 sno2 changed the title Allow explicit null packing in non-exhaustive and sized enums Allow explicit null packing optimization in non-exhaustive and sized enums Aug 20, 2022
@nektro
Copy link
Contributor

nektro commented Aug 20, 2022

already being discussed in #12186

@sno2
Copy link
Contributor Author

sno2 commented Aug 20, 2022

already being discussed in #12186

I did not see that, thanks. However, that seems to be discussing behind the scenes exhaustive enum optimizations whereas I'm suggesting a manual solution for optimizing non-exhaustive enums.

@Vexu Vexu added optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. labels Aug 21, 2022
@Vexu Vexu added this to the 0.12.0 milestone Aug 21, 2022
@sno2
Copy link
Contributor Author

sno2 commented Aug 13, 2024

I shouldn't have made this proposal.

@sno2 sno2 closed this as not planned Won't fix, can't repro, duplicate, stale Aug 13, 2024
@alexrp alexrp modified the milestones: 0.16.0, 0.14.0 Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

4 participants