| ... | ... | @@ -901,11 +901,20 @@ pub fn intToEnum(comptime EnumTag: type, tag_int: anytype) IntToEnumError!EnumTa |
| 901 | 901 | return error.InvalidEnumTag; |
| 902 | 902 | } |
| 903 | 903 | |
| 904 | | inline for (enum_info.fields) |f| { |
| 905 | | const this_tag_value = @field(EnumTag, f.name); |
| 906 | | if (tag_int == @intFromEnum(this_tag_value)) { |
| 907 | | return this_tag_value; |
| 904 | // We don't direcly iterate over the fields of EnumTag, as that |
| 905 | // would require an inline loop. Instead, we create an array of |
| 906 | // values that is comptime-know, but can be iterated at runtime |
| 907 | // without requiring an inline loop. This generates better |
| 908 | // machine code. |
| 909 | const values = comptime blk: { |
| 910 | var result: [enum_info.fields.len]enum_info.tag_type = undefined; |
| 911 | for (&result, enum_info.fields) |*dst, src| { |
| 912 | dst.* = src.value; |
| 908 | 913 | } |
| 914 | break :blk result; |
| 915 | }; |
| 916 | for (values) |v| { |
| 917 | if (v == tag_int) return @enumFromInt(tag_int); |
| 909 | 918 | } |
| 910 | 919 | return error.InvalidEnumTag; |
| 911 | 920 | } |