diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2024-02-17 01:18:54 +0000 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2024-03-06 21:26:37 +0000 |
| commit | 975b859377dee450418ae9ed572ec9d3c0b77312 (patch) | |
| tree | 08a86de7c929deb2a86deb5b587f35bb980ca500 /src/type.zig | |
| parent | a6ca20b9a1dfc7b6e8d004cb166c0714bb8db2db (diff) | |
| download | zig-975b859377dee450418ae9ed572ec9d3c0b77312.tar.gz zig-975b859377dee450418ae9ed572ec9d3c0b77312.zip | |
InternPool: create specialized functions for loading namespace types
Namespace types (`struct`, `enum`, `union`, `opaque`) do not use
structural equality - equivalence is based on their Decl index (and soon
will change to AST node + captures). However, we previously stored all
other information in the corresponding `InternPool.Key` anyway. For
logical consistency, it makes sense to have the key only be the true key
(that is, the Decl index) and to load all other data through another
function. This introduces those functions, by the name of
`loadStructType` etc. It's a big diff, but most of it is no-brainer
changes.
In future, it might be nice to eliminate a bunch of the loaded state in
favour of accessor functions on the `LoadedXyzType` types (like how we
have `LoadedUnionType.size()`), but that can be explored at a later
date.
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 334 |
1 files changed, 178 insertions, 156 deletions
diff --git a/src/type.zig b/src/type.zig index b038d7a021..2021a1aaea 100644 --- a/src/type.zig +++ b/src/type.zig @@ -320,11 +320,12 @@ pub const Type = struct { .generic_poison => unreachable, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); if (struct_type.decl.unwrap()) |decl_index| { const decl = mod.declPtr(decl_index); try decl.renderFullyQualifiedName(mod, writer); - } else if (struct_type.namespace.unwrap()) |namespace_index| { + } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| { const namespace = mod.namespacePtr(namespace_index); try namespace.renderFullyQualifiedName(mod, .empty, writer); } else { @@ -573,7 +574,8 @@ pub const Type = struct { .generic_poison => unreachable, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); if (struct_type.assumeRuntimeBitsIfFieldTypesWip(ip)) { // In this case, we guess that hasRuntimeBits() for this type is true, // and then later if our guess was incorrect, we emit a compile error. @@ -601,7 +603,8 @@ pub const Type = struct { return false; }, - .union_type => |union_type| { + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); switch (union_type.flagsPtr(ip).runtime_tag) { .none => { if (union_type.flagsPtr(ip).status == .field_types_wip) { @@ -628,9 +631,8 @@ pub const Type = struct { .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes()) return error.NeedLazy, } - const union_obj = ip.loadUnionType(union_type); - for (0..union_obj.field_types.len) |field_index| { - const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); + for (0..union_type.field_types.len) |field_index| { + const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]); if (try field_ty.hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true; } else { @@ -639,7 +641,7 @@ pub const Type = struct { }, .opaque_type => true, - .enum_type => |enum_type| Type.fromInterned(enum_type.tag_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), + .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), // values, not types .undef, @@ -736,15 +738,19 @@ pub const Type = struct { .generic_poison, => false, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); // Struct with no fields have a well-defined layout of no bits. return struct_type.layout != .Auto or struct_type.field_types.len == 0; }, - .union_type => |union_type| switch (union_type.flagsPtr(ip).runtime_tag) { - .none, .safety => union_type.flagsPtr(ip).layout != .Auto, - .tagged => false, + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); + return switch (union_type.flagsPtr(ip).runtime_tag) { + .none, .safety => union_type.flagsPtr(ip).layout != .Auto, + .tagged => false, + }; }, - .enum_type => |enum_type| switch (enum_type.tag_mode) { + .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) { .auto => false, .explicit, .nonexhaustive => true, }, @@ -1019,7 +1025,8 @@ pub const Type = struct { .noreturn => unreachable, .generic_poison => unreachable, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); if (struct_type.layout == .Packed) { switch (strat) { .sema => |sema| try sema.resolveTypeLayout(ty), @@ -1066,7 +1073,8 @@ pub const Type = struct { } return .{ .scalar = big_align }; }, - .union_type => |union_type| { + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); const flags = union_type.flagsPtr(ip).*; if (flags.alignment != .none) return .{ .scalar = flags.alignment }; @@ -1082,8 +1090,8 @@ pub const Type = struct { return .{ .scalar = union_type.flagsPtr(ip).alignment }; }, .opaque_type => return .{ .scalar = .@"1" }, - .enum_type => |enum_type| return .{ - .scalar = Type.fromInterned(enum_type.tag_ty).abiAlignment(mod), + .enum_type => return .{ + .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(mod), }, // values, not types @@ -1394,7 +1402,8 @@ pub const Type = struct { .noreturn => unreachable, .generic_poison => unreachable, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); switch (strat) { .sema => |sema| try sema.resolveTypeLayout(ty), .lazy => switch (struct_type.layout) { @@ -1439,7 +1448,8 @@ pub const Type = struct { return AbiSizeAdvanced{ .scalar = ty.structFieldOffset(field_count, mod) }; }, - .union_type => |union_type| { + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); switch (strat) { .sema => |sema| try sema.resolveTypeLayout(ty), .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{ @@ -1455,7 +1465,7 @@ pub const Type = struct { return .{ .scalar = union_type.size(ip).* }; }, .opaque_type => unreachable, // no size available - .enum_type => |enum_type| return AbiSizeAdvanced{ .scalar = Type.fromInterned(enum_type.tag_ty).abiSize(mod) }, + .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(mod) }, // values, not types .undef, @@ -1644,7 +1654,8 @@ pub const Type = struct { .extern_options => unreachable, .type_info => unreachable, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); const is_packed = struct_type.layout == .Packed; if (opt_sema) |sema| { try sema.resolveTypeFields(ty); @@ -1661,7 +1672,8 @@ pub const Type = struct { return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8; }, - .union_type => |union_type| { + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); const is_packed = ty.containerLayout(mod) == .Packed; if (opt_sema) |sema| { try sema.resolveTypeFields(ty); @@ -1670,19 +1682,18 @@ pub const Type = struct { if (!is_packed) { return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8; } - const union_obj = ip.loadUnionType(union_type); - assert(union_obj.flagsPtr(ip).status.haveFieldTypes()); + assert(union_type.flagsPtr(ip).status.haveFieldTypes()); var size: u64 = 0; - for (0..union_obj.field_types.len) |field_index| { - const field_ty = union_obj.field_types.get(ip)[field_index]; + for (0..union_type.field_types.len) |field_index| { + const field_ty = union_type.field_types.get(ip)[field_index]; size = @max(size, try bitSizeAdvanced(Type.fromInterned(field_ty), mod, opt_sema)); } return size; }, .opaque_type => unreachable, - .enum_type => |enum_type| return bitSizeAdvanced(Type.fromInterned(enum_type.tag_ty), mod, opt_sema), + .enum_type => return bitSizeAdvanced(Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), mod, opt_sema), // values, not types .undef, @@ -1713,8 +1724,8 @@ pub const Type = struct { pub fn layoutIsResolved(ty: Type, mod: *Module) bool { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| struct_type.haveLayout(ip), - .union_type => |union_type| union_type.haveLayout(ip), + .struct_type => ip.loadStructType(ty.toIntern()).haveLayout(ip), + .union_type => ip.loadUnionType(ty.toIntern()).haveLayout(ip), .array_type => |array_type| { if ((array_type.len + @intFromBool(array_type.sentinel != .none)) == 0) return true; return Type.fromInterned(array_type.child).layoutIsResolved(mod); @@ -1914,16 +1925,18 @@ pub const Type = struct { /// Otherwise, returns `null`. pub fn unionTagType(ty: Type, mod: *Module) ?Type { const ip = &mod.intern_pool; - return switch (ip.indexToKey(ty.toIntern())) { - .union_type => |union_type| switch (union_type.flagsPtr(ip).runtime_tag) { - .tagged => { - assert(union_type.flagsPtr(ip).status.haveFieldTypes()); - return Type.fromInterned(union_type.enum_tag_ty); - }, - else => null, + switch (ip.indexToKey(ty.toIntern())) { + .union_type => {}, + else => return null, + } + const union_type = ip.loadUnionType(ty.toIntern()); + switch (union_type.flagsPtr(ip).runtime_tag) { + .tagged => { + assert(union_type.flagsPtr(ip).status.haveFieldTypes()); + return Type.fromInterned(union_type.enum_tag_ty); }, - else => null, - }; + else => return null, + } } /// Same as `unionTagType` but includes safety tag. @@ -1931,7 +1944,8 @@ pub const Type = struct { pub fn unionTagTypeSafety(ty: Type, mod: *Module) ?Type { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .union_type => |union_type| { + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); if (!union_type.hasTag(ip)) return null; assert(union_type.haveFieldTypes(ip)); return Type.fromInterned(union_type.enum_tag_ty); @@ -1981,17 +1995,16 @@ pub const Type = struct { pub fn unionGetLayout(ty: Type, mod: *Module) Module.UnionLayout { const ip = &mod.intern_pool; - const union_type = ip.indexToKey(ty.toIntern()).union_type; - const union_obj = ip.loadUnionType(union_type); + const union_obj = ip.loadUnionType(ty.toIntern()); return mod.getUnionLayout(union_obj); } pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| struct_type.layout, + .struct_type => ip.loadStructType(ty.toIntern()).layout, .anon_struct_type => .Auto, - .union_type => |union_type| union_type.flagsPtr(ip).layout, + .union_type => ip.loadUnionType(ty.toIntern()).flagsPtr(ip).layout, else => unreachable, }; } @@ -2095,22 +2108,15 @@ pub const Type = struct { /// Asserts the type is an array or vector or struct. pub fn arrayLen(ty: Type, mod: *const Module) u64 { - return arrayLenIp(ty, &mod.intern_pool); + return ty.arrayLenIp(&mod.intern_pool); } pub fn arrayLenIp(ty: Type, ip: *const InternPool) u64 { - return switch (ip.indexToKey(ty.toIntern())) { - .vector_type => |vector_type| vector_type.len, - .array_type => |array_type| array_type.len, - .struct_type => |struct_type| struct_type.field_types.len, - .anon_struct_type => |tuple| tuple.types.len, - - else => unreachable, - }; + return ip.aggregateTypeLen(ty.toIntern()); } pub fn arrayLenIncludingSentinel(ty: Type, mod: *const Module) u64 { - return ty.arrayLen(mod) + @intFromBool(ty.sentinel(mod) != null); + return mod.intern_pool.aggregateTypeLenIncludingSentinel(ty.toIntern()); } pub fn vectorLen(ty: Type, mod: *const Module) u32 { @@ -2199,8 +2205,8 @@ pub const Type = struct { .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) }, else => switch (ip.indexToKey(ty.toIntern())) { .int_type => |int_type| return int_type, - .struct_type => |t| ty = Type.fromInterned(t.backingIntType(ip).*), - .enum_type => |enum_type| ty = Type.fromInterned(enum_type.tag_ty), + .struct_type => ty = Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntType(ip).*), + .enum_type => ty = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child), .error_set_type, .inferred_error_set_type => { @@ -2463,7 +2469,8 @@ pub const Type = struct { .generic_poison => unreachable, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); assert(struct_type.haveFieldTypes(ip)); if (struct_type.knownNonOpv(ip)) return null; @@ -2505,11 +2512,11 @@ pub const Type = struct { } }))); }, - .union_type => |union_type| { - const union_obj = ip.loadUnionType(union_type); + .union_type => { + const union_obj = ip.loadUnionType(ty.toIntern()); const tag_val = (try Type.fromInterned(union_obj.enum_tag_ty).onePossibleValue(mod)) orelse return null; - if (union_obj.field_names.len == 0) { + if (union_obj.field_types.len == 0) { const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); return Value.fromInterned(only); } @@ -2524,45 +2531,48 @@ pub const Type = struct { return Value.fromInterned(only); }, .opaque_type => return null, - .enum_type => |enum_type| switch (enum_type.tag_mode) { - .nonexhaustive => { - if (enum_type.tag_ty == .comptime_int_type) return null; - - if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(mod)) |int_opv| { - const only = try mod.intern(.{ .enum_tag = .{ - .ty = ty.toIntern(), - .int = int_opv.toIntern(), - } }); - return Value.fromInterned(only); - } + .enum_type => { + const enum_type = ip.loadEnumType(ty.toIntern()); + switch (enum_type.tag_mode) { + .nonexhaustive => { + if (enum_type.tag_ty == .comptime_int_type) return null; + + if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(mod)) |int_opv| { + const only = try mod.intern(.{ .enum_tag = .{ + .ty = ty.toIntern(), + .int = int_opv.toIntern(), + } }); + return Value.fromInterned(only); + } - return null; - }, - .auto, .explicit => { - if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(mod)) return null; + return null; + }, + .auto, .explicit => { + if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(mod)) return null; - switch (enum_type.names.len) { - 0 => { - const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); - return Value.fromInterned(only); - }, - 1 => { - if (enum_type.values.len == 0) { - const only = try mod.intern(.{ .enum_tag = .{ - .ty = ty.toIntern(), - .int = try mod.intern(.{ .int = .{ - .ty = enum_type.tag_ty, - .storage = .{ .u64 = 0 }, - } }), - } }); + switch (enum_type.names.len) { + 0 => { + const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); return Value.fromInterned(only); - } else { - return Value.fromInterned(enum_type.values.get(ip)[0]); - } - }, - else => return null, - } - }, + }, + 1 => { + if (enum_type.values.len == 0) { + const only = try mod.intern(.{ .enum_tag = .{ + .ty = ty.toIntern(), + .int = try mod.intern(.{ .int = .{ + .ty = enum_type.tag_ty, + .storage = .{ .u64 = 0 }, + } }), + } }); + return Value.fromInterned(only); + } else { + return Value.fromInterned(enum_type.values.get(ip)[0]); + } + }, + else => return null, + } + }, + } }, // values, not types @@ -2676,7 +2686,8 @@ pub const Type = struct { .type_info, => true, }, - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); // packed structs cannot be comptime-only because they have a well-defined // memory layout and every field has a well-defined bit pattern. if (struct_type.layout == .Packed) @@ -2726,38 +2737,40 @@ pub const Type = struct { return false; }, - .union_type => |union_type| switch (union_type.flagsPtr(ip).requires_comptime) { - .no, .wip => false, - .yes => true, - .unknown => { - // The type is not resolved; assert that we have a Sema. - const sema = opt_sema.?; + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); + switch (union_type.flagsPtr(ip).requires_comptime) { + .no, .wip => return false, + .yes => return true, + .unknown => { + // The type is not resolved; assert that we have a Sema. + const sema = opt_sema.?; - if (union_type.flagsPtr(ip).status == .field_types_wip) - return false; + if (union_type.flagsPtr(ip).status == .field_types_wip) + return false; - union_type.flagsPtr(ip).requires_comptime = .wip; - errdefer union_type.flagsPtr(ip).requires_comptime = .unknown; + union_type.flagsPtr(ip).requires_comptime = .wip; + errdefer union_type.flagsPtr(ip).requires_comptime = .unknown; - try sema.resolveTypeFieldsUnion(ty, union_type); + try sema.resolveTypeFieldsUnion(ty, union_type); - const union_obj = ip.loadUnionType(union_type); - for (0..union_obj.field_types.len) |field_idx| { - const field_ty = union_obj.field_types.get(ip)[field_idx]; - if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, opt_sema)) { - union_obj.flagsPtr(ip).requires_comptime = .yes; - return true; + for (0..union_type.field_types.len) |field_idx| { + const field_ty = union_type.field_types.get(ip)[field_idx]; + if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, opt_sema)) { + union_type.flagsPtr(ip).requires_comptime = .yes; + return true; + } } - } - union_obj.flagsPtr(ip).requires_comptime = .no; - return false; - }, + union_type.flagsPtr(ip).requires_comptime = .no; + return false; + }, + } }, .opaque_type => false, - .enum_type => |enum_type| return Type.fromInterned(enum_type.tag_ty).comptimeOnlyAdvanced(mod, opt_sema), + .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(mod, opt_sema), // values, not types .undef, @@ -2830,11 +2843,12 @@ pub const Type = struct { /// Returns null if the type has no namespace. pub fn getNamespaceIndex(ty: Type, mod: *Module) InternPool.OptionalNamespaceIndex { - return switch (mod.intern_pool.indexToKey(ty.toIntern())) { - .opaque_type => |opaque_type| opaque_type.namespace.toOptional(), - .struct_type => |struct_type| struct_type.namespace, - .union_type => |union_type| union_type.namespace.toOptional(), - .enum_type => |enum_type| enum_type.namespace, + const ip = &mod.intern_pool; + return switch (ip.indexToKey(ty.toIntern())) { + .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(), + .struct_type => ip.loadStructType(ty.toIntern()).namespace, + .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(), + .enum_type => ip.loadEnumType(ty.toIntern()).namespace, else => .none, }; @@ -2920,16 +2934,18 @@ pub const Type = struct { /// Asserts the type is an enum or a union. pub fn intTagType(ty: Type, mod: *Module) Type { - return switch (mod.intern_pool.indexToKey(ty.toIntern())) { - .union_type => |union_type| Type.fromInterned(union_type.enum_tag_ty).intTagType(mod), - .enum_type => |enum_type| Type.fromInterned(enum_type.tag_ty), + const ip = &mod.intern_pool; + return switch (ip.indexToKey(ty.toIntern())) { + .union_type => Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty).intTagType(mod), + .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), else => unreachable, }; } pub fn isNonexhaustiveEnum(ty: Type, mod: *Module) bool { - return switch (mod.intern_pool.indexToKey(ty.toIntern())) { - .enum_type => |enum_type| switch (enum_type.tag_mode) { + const ip = &mod.intern_pool; + return switch (ip.indexToKey(ty.toIntern())) { + .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) { .nonexhaustive => true, .auto, .explicit => false, }, @@ -2953,21 +2969,21 @@ pub const Type = struct { } pub fn enumFields(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice { - return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names; + return mod.intern_pool.loadEnumType(ty.toIntern()).names; } pub fn enumFieldCount(ty: Type, mod: *Module) usize { - return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names.len; + return mod.intern_pool.loadEnumType(ty.toIntern()).names.len; } pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString { const ip = &mod.intern_pool; - return ip.indexToKey(ty.toIntern()).enum_type.names.get(ip)[field_index]; + return ip.loadEnumType(ty.toIntern()).names.get(ip)[field_index]; } pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, mod: *Module) ?u32 { const ip = &mod.intern_pool; - const enum_type = ip.indexToKey(ty.toIntern()).enum_type; + const enum_type = ip.loadEnumType(ty.toIntern()); return enum_type.nameIndex(ip, field_name); } @@ -2976,7 +2992,7 @@ pub const Type = struct { /// declaration order, or `null` if `enum_tag` does not match any field. pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, mod: *Module) ?u32 { const ip = &mod.intern_pool; - const enum_type = ip.indexToKey(ty.toIntern()).enum_type; + const enum_type = ip.loadEnumType(ty.toIntern()); const int_tag = switch (ip.indexToKey(enum_tag.toIntern())) { .int => enum_tag.toIntern(), .enum_tag => |info| info.int, @@ -2990,7 +3006,7 @@ pub const Type = struct { pub fn structFieldName(ty: Type, field_index: u32, mod: *Module) InternPool.OptionalNullTerminatedString { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| struct_type.fieldName(ip, field_index), + .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, field_index), .anon_struct_type => |anon_struct| anon_struct.fieldName(ip, field_index), else => unreachable, }; @@ -3010,7 +3026,7 @@ pub const Type = struct { pub fn structFieldCount(ty: Type, mod: *Module) u32 { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| struct_type.field_types.len, + .struct_type => ip.loadStructType(ty.toIntern()).field_types.len, .anon_struct_type => |anon_struct| anon_struct.types.len, else => unreachable, }; @@ -3020,9 +3036,9 @@ pub const Type = struct { pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| Type.fromInterned(struct_type.field_types.get(ip)[index]), - .union_type => |union_type| { - const union_obj = ip.loadUnionType(union_type); + .struct_type => Type.fromInterned(ip.loadStructType(ty.toIntern()).field_types.get(ip)[index]), + .union_type => { + const union_obj = ip.loadUnionType(ty.toIntern()); return Type.fromInterned(union_obj.field_types.get(ip)[index]); }, .anon_struct_type => |anon_struct| Type.fromInterned(anon_struct.types.get(ip)[index]), @@ -3033,7 +3049,8 @@ pub const Type = struct { pub fn structFieldAlign(ty: Type, index: usize, mod: *Module) Alignment { const ip = &mod.intern_pool; switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); assert(struct_type.layout != .Packed); const explicit_align = struct_type.fieldAlign(ip, index); const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]); @@ -3042,8 +3059,8 @@ pub const Type = struct { .anon_struct_type => |anon_struct| { return Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignment(mod); }, - .union_type => |union_type| { - const union_obj = ip.loadUnionType(union_type); + .union_type => { + const union_obj = ip.loadUnionType(ty.toIntern()); return mod.unionFieldNormalAlignment(union_obj, @intCast(index)); }, else => unreachable, @@ -3053,7 +3070,8 @@ pub const Type = struct { pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { const ip = &mod.intern_pool; switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); const val = struct_type.fieldInit(ip, index); // TODO: avoid using `unreachable` to indicate this. if (val == .none) return Value.@"unreachable"; @@ -3072,7 +3090,8 @@ pub const Type = struct { pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { const ip = &mod.intern_pool; switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); if (struct_type.fieldIsComptime(ip, index)) { assert(struct_type.haveFieldInits(ip)); return Value.fromInterned(struct_type.field_inits.get(ip)[index]); @@ -3095,7 +3114,7 @@ pub const Type = struct { pub fn structFieldIsComptime(ty: Type, index: usize, mod: *Module) bool { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| struct_type.fieldIsComptime(ip, index), + .struct_type => ip.loadStructType(ty.toIntern()).fieldIsComptime(ip, index), .anon_struct_type => |anon_struct| anon_struct.values.get(ip)[index] != .none, else => unreachable, }; @@ -3110,7 +3129,8 @@ pub const Type = struct { pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 { const ip = &mod.intern_pool; switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); assert(struct_type.haveLayout(ip)); assert(struct_type.layout != .Packed); return struct_type.offsets.get(ip)[index]; @@ -3137,11 +3157,11 @@ pub const Type = struct { return offset; }, - .union_type => |union_type| { + .union_type => { + const union_type = ip.loadUnionType(ty.toIntern()); if (!union_type.hasTag(ip)) return 0; - const union_obj = ip.loadUnionType(union_type); - const layout = mod.getUnionLayout(union_obj); + const layout = mod.getUnionLayout(union_type); if (layout.tag_align.compare(.gte, layout.payload_align)) { // {Tag, Payload} return layout.payload_align.forward(layout.tag_size); @@ -3194,7 +3214,8 @@ pub const Type = struct { pub fn isTuple(ty: Type, mod: *Module) bool { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); if (struct_type.layout == .Packed) return false; if (struct_type.decl == .none) return false; return struct_type.flagsPtr(ip).is_tuple; @@ -3215,7 +3236,8 @@ pub const Type = struct { pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { + .struct_type => { + const struct_type = ip.loadStructType(ty.toIntern()); if (struct_type.layout == .Packed) return false; if (struct_type.decl == .none) return false; return struct_type.flagsPtr(ip).is_tuple; @@ -3262,12 +3284,12 @@ pub const Type = struct { } pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index { - return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { - inline .struct_type, - .union_type, - .enum_type, - .opaque_type, - => |info| info.zir_index.unwrap(), + const ip = &zcu.intern_pool; + return switch (ip.indexToKey(ty.toIntern())) { + .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(), + .union_type => ip.loadUnionType(ty.toIntern()).zir_index.unwrap(), + .enum_type => ip.loadEnumType(ty.toIntern()).zir_index.unwrap(), + .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index.unwrap(), else => null, }; } |
