Skip to content

Proposal: remove implicit @intCast behavior from @enumFromInt #22712

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

Open
mlugg opened this issue Feb 1, 2025 · 1 comment
Open

Proposal: remove implicit @intCast behavior from @enumFromInt #22712

mlugg opened this issue Feb 1, 2025 · 1 comment
Labels
breaking Implementing this issue could cause existing code to no longer compile or have different behavior. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@mlugg
Copy link
Member

mlugg commented Feb 1, 2025

Background

The @enumToInt builtin does not currently require its operand to be of the enum's integer tag type. Rather, it can be of any integer type, and the value is first converted to the tag type with the same semantics as @intCast. The casted integer is then converted to the enum type.

This behavior was implemented in Zig 0.9.0 by bb38931, and the release notes give a hint as to why:

In summary, you can change this:

return @intToEnum(Tag, @intCast(@typeInfo(Tag).Enum.tag_type, number));

...into this:

return @intToEnum(Tag, number);

That definitely looks like it used to be quite annoying! I can see why the unnecessary friction in the first snippet would have motivated this change.

However, that isn't how casting works anymore! Because casting builtins use RLS, the first snippet would actually now look like this if @enumFromInt did not include an implicit @intCast:

return @enumFromInt(@intCast(number));

This seems like the best of both worlds: it's nice and concise, but it makes it clear what's going on. It also makes it easy to do other operations, such as truncation or bitcast:

return @enumFromInt(@truncate(number));
// or
return @enumFromInt(@bitCast(number));

That is, this proposal is equivalent to #20375.

Proposal

Revert the change implemented by bb38931, and bring @enumFromInt in line with modern casting semantics: the operand is given a result type of the enum's integer tag type.

@mlugg mlugg added breaking Implementing this issue could cause existing code to no longer compile or have different behavior. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. labels Feb 1, 2025
@mlugg mlugg marked this as a duplicate of #20375 Feb 1, 2025
@mlugg mlugg modified the milestones: 0.16.0, 0.15.0 Feb 1, 2025
@paperclover
Copy link
Contributor

In code i've written using enums as typed indices, this implicit intCast is the reason i stopped using the builtins and in favor of two one line functions that just call the builtin, forcing the caller to add @intCast.

With this and either ranged int (#3806) or illegal enum ranges (#21870), the code i linked can be removed, instead being represented by language intrinsics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Implementing this issue could cause existing code to no longer compile or have different behavior. 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

2 participants