| ... | @@ -2169,6 +2169,9 @@ pub const EnumAuto = struct { | ... | @@ -2169,6 +2169,9 @@ pub const EnumAuto = struct { |
| 2169 | decl: Module.Decl.Index, | 2169 | decl: Module.Decl.Index, |
| 2170 | /// This may be `none` if there are no declarations. | 2170 | /// This may be `none` if there are no declarations. |
| 2171 | namespace: Module.Namespace.OptionalIndex, | 2171 | namespace: Module.Namespace.OptionalIndex, |
| | 2172 | /// An integer type which is used for the numerical value of the enum, which |
| | 2173 | /// was inferred by Zig based on the number of tags. |
| | 2174 | int_tag_type: Index, |
| 2172 | fields_len: u32, | 2175 | fields_len: u32, |
| 2173 | /// Maps field names to declaration index. | 2176 | /// Maps field names to declaration index. |
| 2174 | names_map: MapIndex, | 2177 | names_map: MapIndex, |
| ... | @@ -2553,7 +2556,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -2553,7 +2556,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2553 | return .{ .enum_type = .{ | 2556 | return .{ .enum_type = .{ |
| 2554 | .decl = enum_auto.data.decl, | 2557 | .decl = enum_auto.data.decl, |
| 2555 | .namespace = enum_auto.data.namespace, | 2558 | .namespace = enum_auto.data.namespace, |
| 2556 | .tag_ty = ip.getEnumIntTagType(enum_auto.data.fields_len), | 2559 | .tag_ty = enum_auto.data.int_tag_type, |
| 2557 | .names = names, | 2560 | .names = names, |
| 2558 | .values = &.{}, | 2561 | .values = &.{}, |
| 2559 | .tag_mode = .auto, | 2562 | .tag_mode = .auto, |
| ... | @@ -2928,14 +2931,6 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType { | ... | @@ -2928,14 +2931,6 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType { |
| 2928 | }; | 2931 | }; |
| 2929 | } | 2932 | } |
| 2930 | | 2933 | |
| 2931 | /// Asserts the integer tag type is already present in the InternPool. | | |
| 2932 | fn getEnumIntTagType(ip: InternPool, fields_len: u32) Index { | | |
| 2933 | return ip.getAssumeExists(.{ .int_type = .{ | | |
| 2934 | .bits = if (fields_len == 0) 0 else std.math.log2_int_ceil(u32, fields_len), | | |
| 2935 | .signedness = .unsigned, | | |
| 2936 | } }); | | |
| 2937 | } | | |
| 2938 | | | |
| 2939 | fn indexToKeyEnum(ip: InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key { | 2934 | fn indexToKeyEnum(ip: InternPool, data: u32, tag_mode: Key.EnumType.TagMode) Key { |
| 2940 | const enum_explicit = ip.extraDataTrail(EnumExplicit, data); | 2935 | const enum_explicit = ip.extraDataTrail(EnumExplicit, data); |
| 2941 | const names = @ptrCast( | 2936 | const names = @ptrCast( |
| ... | @@ -3222,6 +3217,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3222,6 +3217,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3222 | .data = ip.addExtraAssumeCapacity(EnumAuto{ | 3217 | .data = ip.addExtraAssumeCapacity(EnumAuto{ |
| 3223 | .decl = enum_type.decl, | 3218 | .decl = enum_type.decl, |
| 3224 | .namespace = enum_type.namespace, | 3219 | .namespace = enum_type.namespace, |
| | 3220 | .int_tag_type = enum_type.tag_ty, |
| 3225 | .names_map = names_map, | 3221 | .names_map = names_map, |
| 3226 | .fields_len = fields_len, | 3222 | .fields_len = fields_len, |
| 3227 | }), | 3223 | }), |
| ... | @@ -4000,18 +3996,18 @@ pub fn getIncompleteEnum( | ... | @@ -4000,18 +3996,18 @@ pub fn getIncompleteEnum( |
| 4000 | } | 3996 | } |
| 4001 | } | 3997 | } |
| 4002 | | 3998 | |
| 4003 | pub fn getIncompleteEnumAuto( | 3999 | fn getIncompleteEnumAuto( |
| 4004 | ip: *InternPool, | 4000 | ip: *InternPool, |
| 4005 | gpa: Allocator, | 4001 | gpa: Allocator, |
| 4006 | enum_type: Key.IncompleteEnumType, | 4002 | enum_type: Key.IncompleteEnumType, |
| 4007 | ) Allocator.Error!IncompleteEnumType { | 4003 | ) Allocator.Error!IncompleteEnumType { |
| 4008 | // Although the integer tag type will not be stored in the `EnumAuto` struct, | 4004 | const int_tag_type = if (enum_type.tag_ty != .none) |
| 4009 | // `InternPool` logic depends on it being present so that `typeOf` can be infallible. | 4005 | enum_type.tag_ty |
| 4010 | // Ensure it is present here: | 4006 | else |
| 4011 | _ = try ip.get(gpa, .{ .int_type = .{ | 4007 | try ip.get(gpa, .{ .int_type = .{ |
| 4012 | .bits = if (enum_type.fields_len == 0) 0 else std.math.log2_int_ceil(u32, enum_type.fields_len), | 4008 | .bits = if (enum_type.fields_len == 0) 0 else std.math.log2_int_ceil(u32, enum_type.fields_len), |
| 4013 | .signedness = .unsigned, | 4009 | .signedness = .unsigned, |
| 4014 | } }); | 4010 | } }); |
| 4015 | | 4011 | |
| 4016 | // We must keep the map in sync with `items`. The hash and equality functions | 4012 | // We must keep the map in sync with `items`. The hash and equality functions |
| 4017 | // for enum types only look at the decl field, which is present even in | 4013 | // for enum types only look at the decl field, which is present even in |
| ... | @@ -4029,6 +4025,7 @@ pub fn getIncompleteEnumAuto( | ... | @@ -4029,6 +4025,7 @@ pub fn getIncompleteEnumAuto( |
| 4029 | const extra_index = ip.addExtraAssumeCapacity(EnumAuto{ | 4025 | const extra_index = ip.addExtraAssumeCapacity(EnumAuto{ |
| 4030 | .decl = enum_type.decl, | 4026 | .decl = enum_type.decl, |
| 4031 | .namespace = enum_type.namespace, | 4027 | .namespace = enum_type.namespace, |
| | 4028 | .int_tag_type = int_tag_type, |
| 4032 | .names_map = names_map, | 4029 | .names_map = names_map, |
| 4033 | .fields_len = enum_type.fields_len, | 4030 | .fields_len = enum_type.fields_len, |
| 4034 | }); | 4031 | }); |
| ... | @@ -4040,7 +4037,7 @@ pub fn getIncompleteEnumAuto( | ... | @@ -4040,7 +4037,7 @@ pub fn getIncompleteEnumAuto( |
| 4040 | ip.extra.appendNTimesAssumeCapacity(@enumToInt(Index.none), enum_type.fields_len); | 4037 | ip.extra.appendNTimesAssumeCapacity(@enumToInt(Index.none), enum_type.fields_len); |
| 4041 | return .{ | 4038 | return .{ |
| 4042 | .index = @intToEnum(Index, ip.items.len - 1), | 4039 | .index = @intToEnum(Index, ip.items.len - 1), |
| 4043 | .tag_ty_index = undefined, | 4040 | .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?, |
| 4044 | .names_map = names_map, | 4041 | .names_map = names_map, |
| 4045 | .names_start = extra_index + extra_fields_len, | 4042 | .names_start = extra_index + extra_fields_len, |
| 4046 | .values_map = .none, | 4043 | .values_map = .none, |