authorgravatar for mason@anthropicstudios.comMason Remaley <mason@anthropicstudios.com> 2023-05-01 01:03:46-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-01 05:03:46+00:00
loge963793e37f93d84f1e5295d309ebe0c738b663d
tree46eae49bf1a983385eac9eab56b633f33e511099
parent6ae19fa48d7853430ba45f2de90550cd48cf5b4c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Updates std.meta.intToEnum to support non-exhaustive enums (#15491)

This was preventing `std.json` from deserializing non-exhaustive enums.

1 files changed, 16 insertions(+), 1 deletions(-)

lib/std/meta.zig+16-1
......@@ -965,18 +965,33 @@ test "intToEnum with error return" {
965965 A,
966966 B,
967967 };
968 const E3 = enum(i8) { A, _ };
968969
969970 var zero: u8 = 0;
970971 var one: u16 = 1;
971972 try testing.expect(intToEnum(E1, zero) catch unreachable == E1.A);
972973 try testing.expect(intToEnum(E2, one) catch unreachable == E2.B);
974 try testing.expect(intToEnum(E3, zero) catch unreachable == E3.A);
975 try testing.expect(intToEnum(E3, 127) catch unreachable == @intToEnum(E3, 127));
976 try testing.expect(intToEnum(E3, -128) catch unreachable == @intToEnum(E3, -128));
973977 try testing.expectError(error.InvalidEnumTag, intToEnum(E1, one));
978 try testing.expectError(error.InvalidEnumTag, intToEnum(E3, 128));
979 try testing.expectError(error.InvalidEnumTag, intToEnum(E3, -129));
974980}
975981
976982pub const IntToEnumError = error{InvalidEnumTag};
977983
978984pub fn intToEnum(comptime EnumTag: type, tag_int: anytype) IntToEnumError!EnumTag {
979 inline for (@typeInfo(EnumTag).Enum.fields) |f| {
985 const enum_info = @typeInfo(EnumTag).Enum;
986
987 if (!enum_info.is_exhaustive) {
988 if (std.math.cast(enum_info.tag_type, tag_int)) |tag| {
989 return @intToEnum(EnumTag, tag);
990 }
991 return error.InvalidEnumTag;
992 }
993
994 inline for (enum_info.fields) |f| {
980995 const this_tag_value = @field(EnumTag, f.name);
981996 if (tag_int == @enumToInt(this_tag_value)) {
982997 return this_tag_value;