| author | |
| committer | |
| log | cb6201715a7bcae2b278811186afc17a697b25f7 |
| tree | 30db7b0844d0769b87664e83164f734fae1a9627 |
| parent | 7e2b6b0f1bc5877f11c50a217dd88c11481bbad4 |
Instead of using actual slices for InternPool.Key.AnonStructType, this
commit changes to use Slice types instead, which store a
long-lived index rather than a pointer.
This is a follow-up to 7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b.10 files changed, 248 insertions(+), 178 deletions(-)
src/InternPool.zig+116-80| ... | @@ -373,11 +373,11 @@ pub const Key = union(enum) { | ... | @@ -373,11 +373,11 @@ pub const Key = union(enum) { |
| 373 | }; | 373 | }; |
| 374 | 374 | ||
| 375 | pub const AnonStructType = struct { | 375 | pub const AnonStructType = struct { |
| 376 | types: []const Index, | 376 | types: Index.Slice, |
| 377 | /// This may be empty, indicating this is a tuple. | 377 | /// This may be empty, indicating this is a tuple. |
| 378 | names: []const NullTerminatedString, | 378 | names: NullTerminatedString.Slice, |
| 379 | /// These elements may be `none`, indicating runtime-known. | 379 | /// These elements may be `none`, indicating runtime-known. |
| 380 | values: []const Index, | 380 | values: Index.Slice, |
| 381 | 381 | ||
| 382 | pub fn isTuple(self: AnonStructType) bool { | 382 | pub fn isTuple(self: AnonStructType) bool { |
| 383 | return self.names.len == 0; | 383 | return self.names.len == 0; |
| ... | @@ -1020,9 +1020,9 @@ pub const Key = union(enum) { | ... | @@ -1020,9 +1020,9 @@ pub const Key = union(enum) { |
| 1020 | 1020 | ||
| 1021 | .anon_struct_type => |anon_struct_type| { | 1021 | .anon_struct_type => |anon_struct_type| { |
| 1022 | var hasher = Hash.init(seed); | 1022 | var hasher = Hash.init(seed); |
| 1023 | for (anon_struct_type.types) |elem| std.hash.autoHash(&hasher, elem); | 1023 | for (anon_struct_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem); |
| 1024 | for (anon_struct_type.values) |elem| std.hash.autoHash(&hasher, elem); | 1024 | for (anon_struct_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem); |
| 1025 | for (anon_struct_type.names) |elem| std.hash.autoHash(&hasher, elem); | 1025 | for (anon_struct_type.names.get(ip)) |elem| std.hash.autoHash(&hasher, elem); |
| 1026 | return hasher.final(); | 1026 | return hasher.final(); |
| 1027 | }, | 1027 | }, |
| 1028 | 1028 | ||
| ... | @@ -1352,9 +1352,9 @@ pub const Key = union(enum) { | ... | @@ -1352,9 +1352,9 @@ pub const Key = union(enum) { |
| 1352 | }, | 1352 | }, |
| 1353 | .anon_struct_type => |a_info| { | 1353 | .anon_struct_type => |a_info| { |
| 1354 | const b_info = b.anon_struct_type; | 1354 | const b_info = b.anon_struct_type; |
| 1355 | return std.mem.eql(Index, a_info.types, b_info.types) and | 1355 | return std.mem.eql(Index, a_info.types.get(ip), b_info.types.get(ip)) and |
| 1356 | std.mem.eql(Index, a_info.values, b_info.values) and | 1356 | std.mem.eql(Index, a_info.values.get(ip), b_info.values.get(ip)) and |
| 1357 | std.mem.eql(NullTerminatedString, a_info.names, b_info.names); | 1357 | std.mem.eql(NullTerminatedString, a_info.names.get(ip), b_info.names.get(ip)); |
| 1358 | }, | 1358 | }, |
| 1359 | .error_set_type => |a_info| { | 1359 | .error_set_type => |a_info| { |
| 1360 | const b_info = b.error_set_type; | 1360 | const b_info = b.error_set_type; |
| ... | @@ -2113,9 +2113,9 @@ pub const static_keys = [_]Key{ | ... | @@ -2113,9 +2113,9 @@ pub const static_keys = [_]Key{ |
| 2113 | 2113 | ||
| 2114 | // empty_struct_type | 2114 | // empty_struct_type |
| 2115 | .{ .anon_struct_type = .{ | 2115 | .{ .anon_struct_type = .{ |
| 2116 | .types = &.{}, | 2116 | .types = .{ .start = 0, .len = 0 }, |
| 2117 | .names = &.{}, | 2117 | .names = .{ .start = 0, .len = 0 }, |
| 2118 | .values = &.{}, | 2118 | .values = .{ .start = 0, .len = 0 }, |
| 2119 | } }, | 2119 | } }, |
| 2120 | 2120 | ||
| 2121 | .{ .simple_value = .undefined }, | 2121 | .{ .simple_value = .undefined }, |
| ... | @@ -3025,7 +3025,17 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void { | ... | @@ -3025,7 +3025,17 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void { |
| 3025 | 3025 | ||
| 3026 | // This inserts all the statically-known values into the intern pool in the | 3026 | // This inserts all the statically-known values into the intern pool in the |
| 3027 | // order expected. | 3027 | // order expected. |
| 3028 | for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable; | 3028 | for (static_keys[0..@intFromEnum(Index.empty_struct_type)]) |key| { |
| 3029 | _ = ip.get(gpa, key) catch unreachable; | ||
| 3030 | } | ||
| 3031 | _ = ip.getAnonStructType(gpa, .{ | ||
| 3032 | .types = &.{}, | ||
| 3033 | .names = &.{}, | ||
| 3034 | .values = &.{}, | ||
| 3035 | }) catch unreachable; | ||
| 3036 | for (static_keys[@intFromEnum(Index.empty_struct_type) + 1 ..]) |key| { | ||
| 3037 | _ = ip.get(gpa, key) catch unreachable; | ||
| 3038 | } | ||
| 3029 | 3039 | ||
| 3030 | if (std.debug.runtime_safety) { | 3040 | if (std.debug.runtime_safety) { |
| 3031 | // Sanity check. | 3041 | // Sanity check. |
| ... | @@ -3155,30 +3165,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -3155,30 +3165,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 3155 | .namespace = @as(Module.Namespace.Index, @enumFromInt(data)).toOptional(), | 3165 | .namespace = @as(Module.Namespace.Index, @enumFromInt(data)).toOptional(), |
| 3156 | } }, | 3166 | } }, |
| 3157 | 3167 | ||
| 3158 | .type_struct_anon => { | 3168 | .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(ip, data) }, |
| 3159 | const type_struct_anon = ip.extraDataTrail(TypeStructAnon, data); | 3169 | .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(ip, data) }, |
| 3160 | const fields_len = type_struct_anon.data.fields_len; | ||
| 3161 | const types = ip.extra.items[type_struct_anon.end..][0..fields_len]; | ||
| 3162 | const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len]; | ||
| 3163 | const names = ip.extra.items[type_struct_anon.end + 2 * fields_len ..][0..fields_len]; | ||
| 3164 | return .{ .anon_struct_type = .{ | ||
| 3165 | .types = @ptrCast(types), | ||
| 3166 | .values = @ptrCast(values), | ||
| 3167 | .names = @ptrCast(names), | ||
| 3168 | } }; | ||
| 3169 | }, | ||
| 3170 | .type_tuple_anon => { | ||
| 3171 | const type_struct_anon = ip.extraDataTrail(TypeStructAnon, data); | ||
| 3172 | const fields_len = type_struct_anon.data.fields_len; | ||
| 3173 | const types = ip.extra.items[type_struct_anon.end..][0..fields_len]; | ||
| 3174 | const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len]; | ||
| 3175 | return .{ .anon_struct_type = .{ | ||
| 3176 | .types = @ptrCast(types), | ||
| 3177 | .values = @ptrCast(values), | ||
| 3178 | .names = &.{}, | ||
| 3179 | } }; | ||
| 3180 | }, | ||
| 3181 | |||
| 3182 | .type_union => .{ .union_type = extraUnionType(ip, data) }, | 3170 | .type_union => .{ .union_type = extraUnionType(ip, data) }, |
| 3183 | 3171 | ||
| 3184 | .type_enum_auto => { | 3172 | .type_enum_auto => { |
| ... | @@ -3577,6 +3565,44 @@ fn extraUnionType(ip: *const InternPool, extra_index: u32) Key.UnionType { | ... | @@ -3577,6 +3565,44 @@ fn extraUnionType(ip: *const InternPool, extra_index: u32) Key.UnionType { |
| 3577 | }; | 3565 | }; |
| 3578 | } | 3566 | } |
| 3579 | 3567 | ||
| 3568 | fn extraTypeStructAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType { | ||
| 3569 | const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index); | ||
| 3570 | const fields_len = type_struct_anon.data.fields_len; | ||
| 3571 | return .{ | ||
| 3572 | .types = .{ | ||
| 3573 | .start = type_struct_anon.end, | ||
| 3574 | .len = fields_len, | ||
| 3575 | }, | ||
| 3576 | .values = .{ | ||
| 3577 | .start = type_struct_anon.end + fields_len, | ||
| 3578 | .len = fields_len, | ||
| 3579 | }, | ||
| 3580 | .names = .{ | ||
| 3581 | .start = type_struct_anon.end + fields_len + fields_len, | ||
| 3582 | .len = fields_len, | ||
| 3583 | }, | ||
| 3584 | }; | ||
| 3585 | } | ||
| 3586 | |||
| 3587 | fn extraTypeTupleAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType { | ||
| 3588 | const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index); | ||
| 3589 | const fields_len = type_struct_anon.data.fields_len; | ||
| 3590 | return .{ | ||
| 3591 | .types = .{ | ||
| 3592 | .start = type_struct_anon.end, | ||
| 3593 | .len = fields_len, | ||
| 3594 | }, | ||
| 3595 | .values = .{ | ||
| 3596 | .start = type_struct_anon.end + fields_len, | ||
| 3597 | .len = fields_len, | ||
| 3598 | }, | ||
| 3599 | .names = .{ | ||
| 3600 | .start = 0, | ||
| 3601 | .len = 0, | ||
| 3602 | }, | ||
| 3603 | }; | ||
| 3604 | } | ||
| 3605 | |||
| 3580 | fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType { | 3606 | fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType { |
| 3581 | const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index); | 3607 | const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index); |
| 3582 | var index: usize = type_function.end; | 3608 | var index: usize = type_function.end; |
| ... | @@ -3864,44 +3890,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3864,44 +3890,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3864 | }); | 3890 | }); |
| 3865 | }, | 3891 | }, |
| 3866 | 3892 | ||
| 3867 | .anon_struct_type => |anon_struct_type| { | 3893 | .anon_struct_type => unreachable, // use getAnonStructType() instead |
| 3868 | assert(anon_struct_type.types.len == anon_struct_type.values.len); | ||
| 3869 | for (anon_struct_type.types) |elem| assert(elem != .none); | ||
| 3870 | |||
| 3871 | const fields_len: u32 = @intCast(anon_struct_type.types.len); | ||
| 3872 | if (anon_struct_type.names.len == 0) { | ||
| 3873 | try ip.extra.ensureUnusedCapacity( | ||
| 3874 | gpa, | ||
| 3875 | @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 2), | ||
| 3876 | ); | ||
| 3877 | ip.items.appendAssumeCapacity(.{ | ||
| 3878 | .tag = .type_tuple_anon, | ||
| 3879 | .data = ip.addExtraAssumeCapacity(TypeStructAnon{ | ||
| 3880 | .fields_len = fields_len, | ||
| 3881 | }), | ||
| 3882 | }); | ||
| 3883 | ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.types)); | ||
| 3884 | ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.values)); | ||
| 3885 | return @enumFromInt(ip.items.len - 1); | ||
| 3886 | } | ||
| 3887 | |||
| 3888 | assert(anon_struct_type.names.len == anon_struct_type.types.len); | ||
| 3889 | |||
| 3890 | try ip.extra.ensureUnusedCapacity( | ||
| 3891 | gpa, | ||
| 3892 | @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3), | ||
| 3893 | ); | ||
| 3894 | ip.items.appendAssumeCapacity(.{ | ||
| 3895 | .tag = .type_struct_anon, | ||
| 3896 | .data = ip.addExtraAssumeCapacity(TypeStructAnon{ | ||
| 3897 | .fields_len = fields_len, | ||
| 3898 | }), | ||
| 3899 | }); | ||
| 3900 | ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.types)); | ||
| 3901 | ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.values)); | ||
| 3902 | ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.names)); | ||
| 3903 | return @enumFromInt(ip.items.len - 1); | ||
| 3904 | }, | ||
| 3905 | 3894 | ||
| 3906 | .union_type => unreachable, // use getUnionType() instead | 3895 | .union_type => unreachable, // use getUnionType() instead |
| 3907 | 3896 | ||
| ... | @@ -4408,7 +4397,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -4408,7 +4397,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 4408 | } | 4397 | } |
| 4409 | }, | 4398 | }, |
| 4410 | .anon_struct_type => |anon_struct_type| { | 4399 | .anon_struct_type => |anon_struct_type| { |
| 4411 | for (aggregate.storage.values(), anon_struct_type.types) |elem, ty| { | 4400 | for (aggregate.storage.values(), anon_struct_type.types.get(ip)) |elem, ty| { |
| 4412 | assert(ip.typeOf(elem) == ty); | 4401 | assert(ip.typeOf(elem) == ty); |
| 4413 | } | 4402 | } |
| 4414 | }, | 4403 | }, |
| ... | @@ -4426,7 +4415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -4426,7 +4415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 4426 | switch (ty_key) { | 4415 | switch (ty_key) { |
| 4427 | .anon_struct_type => |anon_struct_type| opv: { | 4416 | .anon_struct_type => |anon_struct_type| opv: { |
| 4428 | switch (aggregate.storage) { | 4417 | switch (aggregate.storage) { |
| 4429 | .bytes => |bytes| for (anon_struct_type.values, bytes) |value, byte| { | 4418 | .bytes => |bytes| for (anon_struct_type.values.get(ip), bytes) |value, byte| { |
| 4430 | if (value != ip.getIfExists(.{ .int = .{ | 4419 | if (value != ip.getIfExists(.{ .int = .{ |
| 4431 | .ty = .u8_type, | 4420 | .ty = .u8_type, |
| 4432 | .storage = .{ .u64 = byte }, | 4421 | .storage = .{ .u64 = byte }, |
| ... | @@ -4434,10 +4423,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -4434,10 +4423,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 4434 | }, | 4423 | }, |
| 4435 | .elems => |elems| if (!std.mem.eql( | 4424 | .elems => |elems| if (!std.mem.eql( |
| 4436 | Index, | 4425 | Index, |
| 4437 | anon_struct_type.values, | 4426 | anon_struct_type.values.get(ip), |
| 4438 | elems, | 4427 | elems, |
| 4439 | )) break :opv, | 4428 | )) break :opv, |
| 4440 | .repeated_elem => |elem| for (anon_struct_type.values) |value| { | 4429 | .repeated_elem => |elem| for (anon_struct_type.values.get(ip)) |value| { |
| 4441 | if (value != elem) break :opv; | 4430 | if (value != elem) break :opv; |
| 4442 | }, | 4431 | }, |
| 4443 | } | 4432 | } |
| ... | @@ -4646,6 +4635,53 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat | ... | @@ -4646,6 +4635,53 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat |
| 4646 | return @enumFromInt(ip.items.len - 1); | 4635 | return @enumFromInt(ip.items.len - 1); |
| 4647 | } | 4636 | } |
| 4648 | 4637 | ||
| 4638 | pub const AnonStructTypeInit = struct { | ||
| 4639 | types: []const Index, | ||
| 4640 | /// This may be empty, indicating this is a tuple. | ||
| 4641 | names: []const NullTerminatedString, | ||
| 4642 | /// These elements may be `none`, indicating runtime-known. | ||
| 4643 | values: []const Index, | ||
| 4644 | }; | ||
| 4645 | |||
| 4646 | pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeInit) Allocator.Error!Index { | ||
| 4647 | assert(ini.types.len == ini.values.len); | ||
| 4648 | for (ini.types) |elem| assert(elem != .none); | ||
| 4649 | |||
| 4650 | const prev_extra_len = ip.extra.items.len; | ||
| 4651 | const fields_len: u32 = @intCast(ini.types.len); | ||
| 4652 | |||
| 4653 | try ip.extra.ensureUnusedCapacity( | ||
| 4654 | gpa, | ||
| 4655 | @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3), | ||
| 4656 | ); | ||
| 4657 | try ip.items.ensureUnusedCapacity(gpa, 1); | ||
| 4658 | |||
| 4659 | const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{ | ||
| 4660 | .fields_len = fields_len, | ||
| 4661 | }); | ||
| 4662 | ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.types)); | ||
| 4663 | ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values)); | ||
| 4664 | |||
| 4665 | const adapter: KeyAdapter = .{ .intern_pool = ip }; | ||
| 4666 | const key: Key = .{ | ||
| 4667 | .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(ip, extra_index) else k: { | ||
| 4668 | assert(ini.names.len == ini.types.len); | ||
| 4669 | ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names)); | ||
| 4670 | break :k extraTypeStructAnon(ip, extra_index); | ||
| 4671 | }, | ||
| 4672 | }; | ||
| 4673 | const gop = try ip.map.getOrPutAdapted(gpa, key, adapter); | ||
| 4674 | if (gop.found_existing) { | ||
| 4675 | ip.extra.items.len = prev_extra_len; | ||
| 4676 | return @enumFromInt(gop.index); | ||
| 4677 | } | ||
| 4678 | ip.items.appendAssumeCapacity(.{ | ||
| 4679 | .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon, | ||
| 4680 | .data = extra_index, | ||
| 4681 | }); | ||
| 4682 | return @enumFromInt(ip.items.len - 1); | ||
| 4683 | } | ||
| 4684 | |||
| 4649 | /// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`. | 4685 | /// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`. |
| 4650 | pub const GetFuncTypeKey = struct { | 4686 | pub const GetFuncTypeKey = struct { |
| 4651 | param_types: []Index, | 4687 | param_types: []Index, |
| ... | @@ -6056,7 +6092,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -6056,7 +6092,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 6056 | for (agg_elems, 0..) |*elem, i| { | 6092 | for (agg_elems, 0..) |*elem, i| { |
| 6057 | const new_elem_ty = switch (ip.indexToKey(new_ty)) { | 6093 | const new_elem_ty = switch (ip.indexToKey(new_ty)) { |
| 6058 | inline .array_type, .vector_type => |seq_type| seq_type.child, | 6094 | inline .array_type, .vector_type => |seq_type| seq_type.child, |
| 6059 | .anon_struct_type => |anon_struct_type| anon_struct_type.types[i], | 6095 | .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[i], |
| 6060 | .struct_type => |struct_type| ip.structPtr(struct_type.index.unwrap().?) | 6096 | .struct_type => |struct_type| ip.structPtr(struct_type.index.unwrap().?) |
| 6061 | .fields.values()[i].ty.toIntern(), | 6097 | .fields.values()[i].ty.toIntern(), |
| 6062 | else => unreachable, | 6098 | else => unreachable, |
src/Sema.zig+60-51| ... | @@ -8052,11 +8052,12 @@ fn instantiateGenericCall( | ... | @@ -8052,11 +8052,12 @@ fn instantiateGenericCall( |
| 8052 | 8052 | ||
| 8053 | fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { | 8053 | fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void { |
| 8054 | const mod = sema.mod; | 8054 | const mod = sema.mod; |
| 8055 | const tuple = switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 8055 | const ip = &mod.intern_pool; |
| 8056 | const tuple = switch (ip.indexToKey(ty.toIntern())) { | ||
| 8056 | .anon_struct_type => |tuple| tuple, | 8057 | .anon_struct_type => |tuple| tuple, |
| 8057 | else => return, | 8058 | else => return, |
| 8058 | }; | 8059 | }; |
| 8059 | for (tuple.types, tuple.values) |field_ty, field_val| { | 8060 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 8060 | try sema.resolveTupleLazyValues(block, src, field_ty.toType()); | 8061 | try sema.resolveTupleLazyValues(block, src, field_ty.toType()); |
| 8061 | if (field_val == .none) continue; | 8062 | if (field_val == .none) continue; |
| 8062 | // TODO: mutate in intern pool | 8063 | // TODO: mutate in intern pool |
| ... | @@ -12929,7 +12930,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -12929,7 +12930,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 12929 | }, | 12930 | }, |
| 12930 | .anon_struct_type => |anon_struct| { | 12931 | .anon_struct_type => |anon_struct| { |
| 12931 | if (anon_struct.names.len != 0) { | 12932 | if (anon_struct.names.len != 0) { |
| 12932 | break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null; | 12933 | break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names.get(ip), field_name) != null; |
| 12933 | } else { | 12934 | } else { |
| 12934 | const field_index = field_name.toUnsigned(ip) orelse break :hf false; | 12935 | const field_index = field_name.toUnsigned(ip) orelse break :hf false; |
| 12935 | break :hf field_index < ty.structFieldCount(mod); | 12936 | break :hf field_index < ty.structFieldCount(mod); |
| ... | @@ -13558,11 +13559,11 @@ fn analyzeTupleCat( | ... | @@ -13558,11 +13559,11 @@ fn analyzeTupleCat( |
| 13558 | break :rs runtime_src; | 13559 | break :rs runtime_src; |
| 13559 | }; | 13560 | }; |
| 13560 | 13561 | ||
| 13561 | const tuple_ty = try mod.intern(.{ .anon_struct_type = .{ | 13562 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{ |
| 13562 | .types = types, | 13563 | .types = types, |
| 13563 | .values = values, | 13564 | .values = values, |
| 13564 | .names = &.{}, | 13565 | .names = &.{}, |
| 13565 | } }); | 13566 | }); |
| 13566 | 13567 | ||
| 13567 | const runtime_src = opt_runtime_src orelse { | 13568 | const runtime_src = opt_runtime_src orelse { |
| 13568 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 13569 | const tuple_val = try mod.intern(.{ .aggregate = .{ |
| ... | @@ -13889,11 +13890,11 @@ fn analyzeTupleMul( | ... | @@ -13889,11 +13890,11 @@ fn analyzeTupleMul( |
| 13889 | break :rs runtime_src; | 13890 | break :rs runtime_src; |
| 13890 | }; | 13891 | }; |
| 13891 | 13892 | ||
| 13892 | const tuple_ty = try mod.intern(.{ .anon_struct_type = .{ | 13893 | const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{ |
| 13893 | .types = types, | 13894 | .types = types, |
| 13894 | .values = values, | 13895 | .values = values, |
| 13895 | .names = &.{}, | 13896 | .names = &.{}, |
| 13896 | } }); | 13897 | }); |
| 13897 | 13898 | ||
| 13898 | const runtime_src = opt_runtime_src orelse { | 13899 | const runtime_src = opt_runtime_src orelse { |
| 13899 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 13900 | const tuple_val = try mod.intern(.{ .aggregate = .{ |
| ... | @@ -15217,6 +15218,7 @@ fn zirOverflowArithmetic( | ... | @@ -15217,6 +15218,7 @@ fn zirOverflowArithmetic( |
| 15217 | const lhs_ty = sema.typeOf(uncasted_lhs); | 15218 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 15218 | const rhs_ty = sema.typeOf(uncasted_rhs); | 15219 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 15219 | const mod = sema.mod; | 15220 | const mod = sema.mod; |
| 15221 | const ip = &mod.intern_pool; | ||
| 15220 | 15222 | ||
| 15221 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); | 15223 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 15222 | 15224 | ||
| ... | @@ -15244,7 +15246,7 @@ fn zirOverflowArithmetic( | ... | @@ -15244,7 +15246,7 @@ fn zirOverflowArithmetic( |
| 15244 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs); | 15246 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs); |
| 15245 | 15247 | ||
| 15246 | const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); | 15248 | const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); |
| 15247 | const overflow_ty = mod.intern_pool.indexToKey(tuple_ty.toIntern()).anon_struct_type.types[1].toType(); | 15249 | const overflow_ty = ip.indexToKey(tuple_ty.toIntern()).anon_struct_type.types.get(ip)[1].toType(); |
| 15248 | 15250 | ||
| 15249 | var result: struct { | 15251 | var result: struct { |
| 15250 | inst: Air.Inst.Ref = .none, | 15252 | inst: Air.Inst.Ref = .none, |
| ... | @@ -15418,6 +15420,7 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { | ... | @@ -15418,6 +15420,7 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value { |
| 15418 | 15420 | ||
| 15419 | fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { | 15421 | fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { |
| 15420 | const mod = sema.mod; | 15422 | const mod = sema.mod; |
| 15423 | const ip = &mod.intern_pool; | ||
| 15421 | const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{ | 15424 | const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{ |
| 15422 | .len = ty.vectorLen(mod), | 15425 | .len = ty.vectorLen(mod), |
| 15423 | .child = .u1_type, | 15426 | .child = .u1_type, |
| ... | @@ -15425,11 +15428,11 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { | ... | @@ -15425,11 +15428,11 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { |
| 15425 | 15428 | ||
| 15426 | const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() }; | 15429 | const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() }; |
| 15427 | const values = [2]InternPool.Index{ .none, .none }; | 15430 | const values = [2]InternPool.Index{ .none, .none }; |
| 15428 | const tuple_ty = try mod.intern(.{ .anon_struct_type = .{ | 15431 | const tuple_ty = try ip.getAnonStructType(mod.gpa, .{ |
| 15429 | .types = &types, | 15432 | .types = &types, |
| 15430 | .values = &values, | 15433 | .values = &values, |
| 15431 | .names = &.{}, | 15434 | .names = &.{}, |
| 15432 | } }); | 15435 | }); |
| 15433 | return tuple_ty.toType(); | 15436 | return tuple_ty.toType(); |
| 15434 | } | 15437 | } |
| 15435 | 15438 | ||
| ... | @@ -17578,15 +17581,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17578,15 +17581,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17578 | struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len); | 17581 | struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len); |
| 17579 | for (struct_field_vals, 0..) |*struct_field_val, i| { | 17582 | for (struct_field_vals, 0..) |*struct_field_val, i| { |
| 17580 | const anon_struct_type = ip.indexToKey(ty.toIntern()).anon_struct_type; | 17583 | const anon_struct_type = ip.indexToKey(ty.toIntern()).anon_struct_type; |
| 17581 | const field_ty = anon_struct_type.types[i]; | 17584 | const field_ty = anon_struct_type.types.get(ip)[i]; |
| 17582 | const field_val = anon_struct_type.values[i]; | 17585 | const field_val = anon_struct_type.values.get(ip)[i]; |
| 17583 | const name_val = v: { | 17586 | const name_val = v: { |
| 17584 | var anon_decl = try block.startAnonDecl(); | 17587 | var anon_decl = try block.startAnonDecl(); |
| 17585 | defer anon_decl.deinit(); | 17588 | defer anon_decl.deinit(); |
| 17586 | // TODO: write something like getCoercedInts to avoid needing to dupe | 17589 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 17587 | const bytes = if (tuple.names.len != 0) | 17590 | const bytes = if (tuple.names.len != 0) |
| 17588 | // https://github.com/ziglang/zig/issues/15709 | 17591 | // https://github.com/ziglang/zig/issues/15709 |
| 17589 | try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names[i])) | 17592 | try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip)[i])) |
| 17590 | else | 17593 | else |
| 17591 | try std.fmt.allocPrint(sema.arena, "{d}", .{i}); | 17594 | try std.fmt.allocPrint(sema.arena, "{d}", .{i}); |
| 17592 | const new_decl_ty = try mod.arrayType(.{ | 17595 | const new_decl_ty = try mod.arrayType(.{ |
| ... | @@ -19254,7 +19257,7 @@ fn finishStructInit( | ... | @@ -19254,7 +19257,7 @@ fn finishStructInit( |
| 19254 | 19257 | ||
| 19255 | switch (ip.indexToKey(struct_ty.toIntern())) { | 19258 | switch (ip.indexToKey(struct_ty.toIntern())) { |
| 19256 | .anon_struct_type => |anon_struct| { | 19259 | .anon_struct_type => |anon_struct| { |
| 19257 | for (anon_struct.values, 0..) |default_val, i| { | 19260 | for (anon_struct.values.get(ip), 0..) |default_val, i| { |
| 19258 | if (field_inits[i] != .none) continue; | 19261 | if (field_inits[i] != .none) continue; |
| 19259 | 19262 | ||
| 19260 | if (default_val == .none) { | 19263 | if (default_val == .none) { |
| ... | @@ -19266,7 +19269,7 @@ fn finishStructInit( | ... | @@ -19266,7 +19269,7 @@ fn finishStructInit( |
| 19266 | root_msg = try sema.errMsg(block, init_src, template, .{i}); | 19269 | root_msg = try sema.errMsg(block, init_src, template, .{i}); |
| 19267 | } | 19270 | } |
| 19268 | } else { | 19271 | } else { |
| 19269 | const field_name = anon_struct.names[i]; | 19272 | const field_name = anon_struct.names.get(ip)[i]; |
| 19270 | const template = "missing struct field: {}"; | 19273 | const template = "missing struct field: {}"; |
| 19271 | const args = .{field_name.fmt(ip)}; | 19274 | const args = .{field_name.fmt(ip)}; |
| 19272 | if (root_msg) |msg| { | 19275 | if (root_msg) |msg| { |
| ... | @@ -19395,6 +19398,7 @@ fn structInitAnon( | ... | @@ -19395,6 +19398,7 @@ fn structInitAnon( |
| 19395 | ) CompileError!Air.Inst.Ref { | 19398 | ) CompileError!Air.Inst.Ref { |
| 19396 | const mod = sema.mod; | 19399 | const mod = sema.mod; |
| 19397 | const gpa = sema.gpa; | 19400 | const gpa = sema.gpa; |
| 19401 | const ip = &mod.intern_pool; | ||
| 19398 | const zir_datas = sema.code.instructions.items(.data); | 19402 | const zir_datas = sema.code.instructions.items(.data); |
| 19399 | 19403 | ||
| 19400 | const types = try sema.arena.alloc(InternPool.Index, extra_data.fields_len); | 19404 | const types = try sema.arena.alloc(InternPool.Index, extra_data.fields_len); |
| ... | @@ -19465,11 +19469,11 @@ fn structInitAnon( | ... | @@ -19465,11 +19469,11 @@ fn structInitAnon( |
| 19465 | break :rs runtime_index; | 19469 | break :rs runtime_index; |
| 19466 | }; | 19470 | }; |
| 19467 | 19471 | ||
| 19468 | const tuple_ty = try mod.intern(.{ .anon_struct_type = .{ | 19472 | const tuple_ty = try ip.getAnonStructType(gpa, .{ |
| 19469 | .names = fields.keys(), | 19473 | .names = fields.keys(), |
| 19470 | .types = types, | 19474 | .types = types, |
| 19471 | .values = values, | 19475 | .values = values, |
| 19472 | } }); | 19476 | }); |
| 19473 | 19477 | ||
| 19474 | const runtime_index = opt_runtime_index orelse { | 19478 | const runtime_index = opt_runtime_index orelse { |
| 19475 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 19479 | const tuple_val = try mod.intern(.{ .aggregate = .{ |
| ... | @@ -19688,6 +19692,8 @@ fn arrayInitAnon( | ... | @@ -19688,6 +19692,8 @@ fn arrayInitAnon( |
| 19688 | is_ref: bool, | 19692 | is_ref: bool, |
| 19689 | ) CompileError!Air.Inst.Ref { | 19693 | ) CompileError!Air.Inst.Ref { |
| 19690 | const mod = sema.mod; | 19694 | const mod = sema.mod; |
| 19695 | const gpa = sema.gpa; | ||
| 19696 | const ip = &mod.intern_pool; | ||
| 19691 | 19697 | ||
| 19692 | const types = try sema.arena.alloc(InternPool.Index, operands.len); | 19698 | const types = try sema.arena.alloc(InternPool.Index, operands.len); |
| 19693 | const values = try sema.arena.alloc(InternPool.Index, operands.len); | 19699 | const values = try sema.arena.alloc(InternPool.Index, operands.len); |
| ... | @@ -19701,7 +19707,7 @@ fn arrayInitAnon( | ... | @@ -19701,7 +19707,7 @@ fn arrayInitAnon( |
| 19701 | if (types[i].toType().zigTypeTag(mod) == .Opaque) { | 19707 | if (types[i].toType().zigTypeTag(mod) == .Opaque) { |
| 19702 | const msg = msg: { | 19708 | const msg = msg: { |
| 19703 | const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); | 19709 | const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 19704 | errdefer msg.destroy(sema.gpa); | 19710 | errdefer msg.destroy(gpa); |
| 19705 | 19711 | ||
| 19706 | try sema.addDeclaredHereNote(msg, types[i].toType()); | 19712 | try sema.addDeclaredHereNote(msg, types[i].toType()); |
| 19707 | break :msg msg; | 19713 | break :msg msg; |
| ... | @@ -19718,11 +19724,11 @@ fn arrayInitAnon( | ... | @@ -19718,11 +19724,11 @@ fn arrayInitAnon( |
| 19718 | break :rs runtime_src; | 19724 | break :rs runtime_src; |
| 19719 | }; | 19725 | }; |
| 19720 | 19726 | ||
| 19721 | const tuple_ty = try mod.intern(.{ .anon_struct_type = .{ | 19727 | const tuple_ty = try ip.getAnonStructType(gpa, .{ |
| 19722 | .types = types, | 19728 | .types = types, |
| 19723 | .values = values, | 19729 | .values = values, |
| 19724 | .names = &.{}, | 19730 | .names = &.{}, |
| 19725 | } }); | 19731 | }); |
| 19726 | 19732 | ||
| 19727 | const runtime_src = opt_runtime_src orelse { | 19733 | const runtime_src = opt_runtime_src orelse { |
| 19728 | const tuple_val = try mod.intern(.{ .aggregate = .{ | 19734 | const tuple_val = try mod.intern(.{ .aggregate = .{ |
| ... | @@ -19832,7 +19838,7 @@ fn fieldType( | ... | @@ -19832,7 +19838,7 @@ fn fieldType( |
| 19832 | .Struct => switch (ip.indexToKey(cur_ty.toIntern())) { | 19838 | .Struct => switch (ip.indexToKey(cur_ty.toIntern())) { |
| 19833 | .anon_struct_type => |anon_struct| { | 19839 | .anon_struct_type => |anon_struct| { |
| 19834 | const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src); | 19840 | const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src); |
| 19835 | return Air.internedToRef(anon_struct.types[field_index]); | 19841 | return Air.internedToRef(anon_struct.types.get(ip)[field_index]); |
| 19836 | }, | 19842 | }, |
| 19837 | .struct_type => |struct_type| { | 19843 | .struct_type => |struct_type| { |
| 19838 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 19844 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| ... | @@ -30574,13 +30580,14 @@ fn coerceAnonStructToUnion( | ... | @@ -30574,13 +30580,14 @@ fn coerceAnonStructToUnion( |
| 30574 | inst_src: LazySrcLoc, | 30580 | inst_src: LazySrcLoc, |
| 30575 | ) !Air.Inst.Ref { | 30581 | ) !Air.Inst.Ref { |
| 30576 | const mod = sema.mod; | 30582 | const mod = sema.mod; |
| 30583 | const ip = &mod.intern_pool; | ||
| 30577 | const inst_ty = sema.typeOf(inst); | 30584 | const inst_ty = sema.typeOf(inst); |
| 30578 | const field_info: union(enum) { | 30585 | const field_info: union(enum) { |
| 30579 | name: InternPool.NullTerminatedString, | 30586 | name: InternPool.NullTerminatedString, |
| 30580 | count: usize, | 30587 | count: usize, |
| 30581 | } = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) { | 30588 | } = switch (ip.indexToKey(inst_ty.toIntern())) { |
| 30582 | .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1) | 30589 | .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1) |
| 30583 | .{ .name = anon_struct_type.names[0] } | 30590 | .{ .name = anon_struct_type.names.get(ip)[0] } |
| 30584 | else | 30591 | else |
| 30585 | .{ .count = anon_struct_type.names.len }, | 30592 | .{ .count = anon_struct_type.names.len }, |
| 30586 | .struct_type => |struct_type| name: { | 30593 | .struct_type => |struct_type| name: { |
| ... | @@ -30876,7 +30883,7 @@ fn coerceTupleToStruct( | ... | @@ -30876,7 +30883,7 @@ fn coerceTupleToStruct( |
| 30876 | // https://github.com/ziglang/zig/issues/15709 | 30883 | // https://github.com/ziglang/zig/issues/15709 |
| 30877 | const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) { | 30884 | const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) { |
| 30878 | .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0) | 30885 | .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0) |
| 30879 | anon_struct_type.names[field_i] | 30886 | anon_struct_type.names.get(ip)[field_i] |
| 30880 | else | 30887 | else |
| 30881 | try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}), | 30888 | try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}), |
| 30882 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i], | 30889 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i], |
| ... | @@ -30994,7 +31001,7 @@ fn coerceTupleToTuple( | ... | @@ -30994,7 +31001,7 @@ fn coerceTupleToTuple( |
| 30994 | // https://github.com/ziglang/zig/issues/15709 | 31001 | // https://github.com/ziglang/zig/issues/15709 |
| 30995 | const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) { | 31002 | const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) { |
| 30996 | .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0) | 31003 | .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0) |
| 30997 | anon_struct_type.names[field_i] | 31004 | anon_struct_type.names.get(ip)[field_i] |
| 30998 | else | 31005 | else |
| 30999 | try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}), | 31006 | try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}), |
| 31000 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i], | 31007 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i], |
| ... | @@ -31005,12 +31012,12 @@ fn coerceTupleToTuple( | ... | @@ -31005,12 +31012,12 @@ fn coerceTupleToTuple( |
| 31005 | return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{}); | 31012 | return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{}); |
| 31006 | 31013 | ||
| 31007 | const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) { | 31014 | const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) { |
| 31008 | .anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(), | 31015 | .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[field_index_usize].toType(), |
| 31009 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty, | 31016 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty, |
| 31010 | else => unreachable, | 31017 | else => unreachable, |
| 31011 | }; | 31018 | }; |
| 31012 | const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) { | 31019 | const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) { |
| 31013 | .anon_struct_type => |anon_struct_type| anon_struct_type.values[field_index_usize], | 31020 | .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[field_index_usize], |
| 31014 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val, | 31021 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val, |
| 31015 | else => unreachable, | 31022 | else => unreachable, |
| 31016 | }; | 31023 | }; |
| ... | @@ -31048,7 +31055,7 @@ fn coerceTupleToTuple( | ... | @@ -31048,7 +31055,7 @@ fn coerceTupleToTuple( |
| 31048 | if (field_ref.* != .none) continue; | 31055 | if (field_ref.* != .none) continue; |
| 31049 | 31056 | ||
| 31050 | const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) { | 31057 | const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) { |
| 31051 | .anon_struct_type => |anon_struct_type| anon_struct_type.values[i], | 31058 | .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[i], |
| 31052 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val, | 31059 | .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val, |
| 31053 | else => unreachable, | 31060 | else => unreachable, |
| 31054 | }; | 31061 | }; |
| ... | @@ -32855,6 +32862,7 @@ fn resolvePeerTypesInner( | ... | @@ -32855,6 +32862,7 @@ fn resolvePeerTypesInner( |
| 32855 | peer_vals: []?Value, | 32862 | peer_vals: []?Value, |
| 32856 | ) !PeerResolveResult { | 32863 | ) !PeerResolveResult { |
| 32857 | const mod = sema.mod; | 32864 | const mod = sema.mod; |
| 32865 | const ip = &mod.intern_pool; | ||
| 32858 | 32866 | ||
| 32859 | var strat_reason: usize = 0; | 32867 | var strat_reason: usize = 0; |
| 32860 | var s: PeerResolveStrategy = .unknown; | 32868 | var s: PeerResolveStrategy = .unknown; |
| ... | @@ -32912,7 +32920,7 @@ fn resolvePeerTypesInner( | ... | @@ -32912,7 +32920,7 @@ fn resolvePeerTypesInner( |
| 32912 | .ErrorUnion => blk: { | 32920 | .ErrorUnion => blk: { |
| 32913 | const set_ty = ty.errorUnionSet(mod); | 32921 | const set_ty = ty.errorUnionSet(mod); |
| 32914 | ty_ptr.* = ty.errorUnionPayload(mod); | 32922 | ty_ptr.* = ty.errorUnionPayload(mod); |
| 32915 | if (val_ptr.*) |eu_val| switch (mod.intern_pool.indexToKey(eu_val.toIntern())) { | 32923 | if (val_ptr.*) |eu_val| switch (ip.indexToKey(eu_val.toIntern())) { |
| 32916 | .error_union => |eu| switch (eu.val) { | 32924 | .error_union => |eu| switch (eu.val) { |
| 32917 | .payload => |payload_ip| val_ptr.* = payload_ip.toValue(), | 32925 | .payload => |payload_ip| val_ptr.* = payload_ip.toValue(), |
| 32918 | .err_name => val_ptr.* = null, | 32926 | .err_name => val_ptr.* = null, |
| ... | @@ -33166,8 +33174,8 @@ fn resolvePeerTypesInner( | ... | @@ -33166,8 +33174,8 @@ fn resolvePeerTypesInner( |
| 33166 | }).toIntern(); | 33174 | }).toIntern(); |
| 33167 | 33175 | ||
| 33168 | if (ptr_info.sentinel != .none and peer_info.sentinel != .none) { | 33176 | if (ptr_info.sentinel != .none and peer_info.sentinel != .none) { |
| 33169 | const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child); | 33177 | const peer_sent = try ip.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child); |
| 33170 | const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child); | 33178 | const ptr_sent = try ip.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child); |
| 33171 | if (ptr_sent == peer_sent) { | 33179 | if (ptr_sent == peer_sent) { |
| 33172 | ptr_info.sentinel = ptr_sent; | 33180 | ptr_info.sentinel = ptr_sent; |
| 33173 | } else { | 33181 | } else { |
| ... | @@ -33278,7 +33286,7 @@ fn resolvePeerTypesInner( | ... | @@ -33278,7 +33286,7 @@ fn resolvePeerTypesInner( |
| 33278 | ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile; | 33286 | ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile; |
| 33279 | 33287 | ||
| 33280 | const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) { | 33288 | const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) { |
| 33281 | .One => switch (mod.intern_pool.indexToKey(peer_info.child)) { | 33289 | .One => switch (ip.indexToKey(peer_info.child)) { |
| 33282 | .array_type => |array_type| array_type.sentinel, | 33290 | .array_type => |array_type| array_type.sentinel, |
| 33283 | else => .none, | 33291 | else => .none, |
| 33284 | }, | 33292 | }, |
| ... | @@ -33287,7 +33295,7 @@ fn resolvePeerTypesInner( | ... | @@ -33287,7 +33295,7 @@ fn resolvePeerTypesInner( |
| 33287 | }; | 33295 | }; |
| 33288 | 33296 | ||
| 33289 | const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) { | 33297 | const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) { |
| 33290 | .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) { | 33298 | .One => switch (ip.indexToKey(ptr_info.child)) { |
| 33291 | .array_type => |array_type| array_type.sentinel, | 33299 | .array_type => |array_type| array_type.sentinel, |
| 33292 | else => .none, | 33300 | else => .none, |
| 33293 | }, | 33301 | }, |
| ... | @@ -33449,7 +33457,7 @@ fn resolvePeerTypesInner( | ... | @@ -33449,7 +33457,7 @@ fn resolvePeerTypesInner( |
| 33449 | } | 33457 | } |
| 33450 | 33458 | ||
| 33451 | const sentinel_ty = switch (ptr_info.flags.size) { | 33459 | const sentinel_ty = switch (ptr_info.flags.size) { |
| 33452 | .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) { | 33460 | .One => switch (ip.indexToKey(ptr_info.child)) { |
| 33453 | .array_type => |array_type| array_type.child, | 33461 | .array_type => |array_type| array_type.child, |
| 33454 | else => ptr_info.child, | 33462 | else => ptr_info.child, |
| 33455 | }, | 33463 | }, |
| ... | @@ -33460,11 +33468,11 @@ fn resolvePeerTypesInner( | ... | @@ -33460,11 +33468,11 @@ fn resolvePeerTypesInner( |
| 33460 | no_sentinel: { | 33468 | no_sentinel: { |
| 33461 | if (peer_sentinel == .none) break :no_sentinel; | 33469 | if (peer_sentinel == .none) break :no_sentinel; |
| 33462 | if (cur_sentinel == .none) break :no_sentinel; | 33470 | if (cur_sentinel == .none) break :no_sentinel; |
| 33463 | const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty); | 33471 | const peer_sent_coerced = try ip.getCoerced(sema.gpa, peer_sentinel, sentinel_ty); |
| 33464 | const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty); | 33472 | const cur_sent_coerced = try ip.getCoerced(sema.gpa, cur_sentinel, sentinel_ty); |
| 33465 | if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel; | 33473 | if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel; |
| 33466 | // Sentinels match | 33474 | // Sentinels match |
| 33467 | if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) { | 33475 | if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) { |
| 33468 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ | 33476 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ |
| 33469 | .len = array_type.len, | 33477 | .len = array_type.len, |
| 33470 | .child = array_type.child, | 33478 | .child = array_type.child, |
| ... | @@ -33478,7 +33486,7 @@ fn resolvePeerTypesInner( | ... | @@ -33478,7 +33486,7 @@ fn resolvePeerTypesInner( |
| 33478 | } | 33486 | } |
| 33479 | // Clear existing sentinel | 33487 | // Clear existing sentinel |
| 33480 | ptr_info.sentinel = .none; | 33488 | ptr_info.sentinel = .none; |
| 33481 | switch (mod.intern_pool.indexToKey(ptr_info.child)) { | 33489 | switch (ip.indexToKey(ptr_info.child)) { |
| 33482 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ | 33490 | .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{ |
| 33483 | .len = array_type.len, | 33491 | .len = array_type.len, |
| 33484 | .child = array_type.child, | 33492 | .child = array_type.child, |
| ... | @@ -33501,7 +33509,7 @@ fn resolvePeerTypesInner( | ... | @@ -33501,7 +33509,7 @@ fn resolvePeerTypesInner( |
| 33501 | .peer_idx_a = first_idx, | 33509 | .peer_idx_a = first_idx, |
| 33502 | .peer_idx_b = other_idx, | 33510 | .peer_idx_b = other_idx, |
| 33503 | } }, | 33511 | } }, |
| 33504 | else => switch (mod.intern_pool.indexToKey(pointee)) { | 33512 | else => switch (ip.indexToKey(pointee)) { |
| 33505 | .array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{ | 33513 | .array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{ |
| 33506 | .peer_idx_a = first_idx, | 33514 | .peer_idx_a = first_idx, |
| 33507 | .peer_idx_b = other_idx, | 33515 | .peer_idx_b = other_idx, |
| ... | @@ -33785,7 +33793,7 @@ fn resolvePeerTypesInner( | ... | @@ -33785,7 +33793,7 @@ fn resolvePeerTypesInner( |
| 33785 | is_tuple = ty.isTuple(mod); | 33793 | is_tuple = ty.isTuple(mod); |
| 33786 | field_count = ty.structFieldCount(mod); | 33794 | field_count = ty.structFieldCount(mod); |
| 33787 | if (!is_tuple) { | 33795 | if (!is_tuple) { |
| 33788 | const names = mod.intern_pool.indexToKey(ty.toIntern()).anon_struct_type.names; | 33796 | const names = ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip); |
| 33789 | field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names); | 33797 | field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names); |
| 33790 | } | 33798 | } |
| 33791 | continue; | 33799 | continue; |
| ... | @@ -33839,7 +33847,7 @@ fn resolvePeerTypesInner( | ... | @@ -33839,7 +33847,7 @@ fn resolvePeerTypesInner( |
| 33839 | result_buf.* = result; | 33847 | result_buf.* = result; |
| 33840 | const field_name = if (is_tuple) name: { | 33848 | const field_name = if (is_tuple) name: { |
| 33841 | break :name try std.fmt.allocPrint(sema.arena, "{d}", .{field_idx}); | 33849 | break :name try std.fmt.allocPrint(sema.arena, "{d}", .{field_idx}); |
| 33842 | } else try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(field_names[field_idx])); | 33850 | } else try sema.arena.dupe(u8, ip.stringToSlice(field_names[field_idx])); |
| 33843 | 33851 | ||
| 33844 | // The error info needs the field types, but we can't reuse sub_peer_tys | 33852 | // The error info needs the field types, but we can't reuse sub_peer_tys |
| 33845 | // since the recursive call may have clobbered it. | 33853 | // since the recursive call may have clobbered it. |
| ... | @@ -33892,11 +33900,11 @@ fn resolvePeerTypesInner( | ... | @@ -33892,11 +33900,11 @@ fn resolvePeerTypesInner( |
| 33892 | field_val.* = if (comptime_val) |v| v.toIntern() else .none; | 33900 | field_val.* = if (comptime_val) |v| v.toIntern() else .none; |
| 33893 | } | 33901 | } |
| 33894 | 33902 | ||
| 33895 | const final_ty = try mod.intern(.{ .anon_struct_type = .{ | 33903 | const final_ty = try ip.getAnonStructType(mod.gpa, .{ |
| 33896 | .types = field_types, | 33904 | .types = field_types, |
| 33897 | .names = if (is_tuple) &.{} else field_names, | 33905 | .names = if (is_tuple) &.{} else field_names, |
| 33898 | .values = field_vals, | 33906 | .values = field_vals, |
| 33899 | } }); | 33907 | }); |
| 33900 | 33908 | ||
| 33901 | return .{ .success = final_ty.toType() }; | 33909 | return .{ .success = final_ty.toType() }; |
| 33902 | }, | 33910 | }, |
| ... | @@ -34491,6 +34499,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { | ... | @@ -34491,6 +34499,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { |
| 34491 | /// be resolved. | 34499 | /// be resolved. |
| 34492 | pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { | 34500 | pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { |
| 34493 | const mod = sema.mod; | 34501 | const mod = sema.mod; |
| 34502 | const ip = &mod.intern_pool; | ||
| 34494 | switch (ty.zigTypeTag(mod)) { | 34503 | switch (ty.zigTypeTag(mod)) { |
| 34495 | .Pointer => { | 34504 | .Pointer => { |
| 34496 | return sema.resolveTypeFully(ty.childType(mod)); | 34505 | return sema.resolveTypeFully(ty.childType(mod)); |
| ... | @@ -34498,7 +34507,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { | ... | @@ -34498,7 +34507,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { |
| 34498 | .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 34507 | .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 34499 | .struct_type => return sema.resolveStructFully(ty), | 34508 | .struct_type => return sema.resolveStructFully(ty), |
| 34500 | .anon_struct_type => |tuple| { | 34509 | .anon_struct_type => |tuple| { |
| 34501 | for (tuple.types) |field_ty| { | 34510 | for (tuple.types.get(ip)) |field_ty| { |
| 34502 | try sema.resolveTypeFully(field_ty.toType()); | 34511 | try sema.resolveTypeFully(field_ty.toType()); |
| 34503 | } | 34512 | } |
| 34504 | }, | 34513 | }, |
| ... | @@ -34518,7 +34527,6 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { | ... | @@ -34518,7 +34527,6 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { |
| 34518 | // the function is instantiated. | 34527 | // the function is instantiated. |
| 34519 | return; | 34528 | return; |
| 34520 | } | 34529 | } |
| 34521 | const ip = &mod.intern_pool; | ||
| 34522 | for (0..info.param_types.len) |i| { | 34530 | for (0..info.param_types.len) |i| { |
| 34523 | const param_ty = info.param_types.get(ip)[i]; | 34531 | const param_ty = info.param_types.get(ip)[i]; |
| 34524 | try sema.resolveTypeFully(param_ty.toType()); | 34532 | try sema.resolveTypeFully(param_ty.toType()); |
| ... | @@ -36133,7 +36141,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36133,7 +36141,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36133 | }, | 36141 | }, |
| 36134 | 36142 | ||
| 36135 | .anon_struct_type => |tuple| { | 36143 | .anon_struct_type => |tuple| { |
| 36136 | for (tuple.values) |val| { | 36144 | for (tuple.values.get(ip)) |val| { |
| 36137 | if (val == .none) return null; | 36145 | if (val == .none) return null; |
| 36138 | } | 36146 | } |
| 36139 | // In this case the struct has all comptime-known fields and | 36147 | // In this case the struct has all comptime-known fields and |
| ... | @@ -36141,7 +36149,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36141,7 +36149,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36141 | // TODO: write something like getCoercedInts to avoid needing to dupe | 36149 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 36142 | return (try mod.intern(.{ .aggregate = .{ | 36150 | return (try mod.intern(.{ .aggregate = .{ |
| 36143 | .ty = ty.toIntern(), | 36151 | .ty = ty.toIntern(), |
| 36144 | .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) }, | 36152 | .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) }, |
| 36145 | } })).toValue(); | 36153 | } })).toValue(); |
| 36146 | }, | 36154 | }, |
| 36147 | 36155 | ||
| ... | @@ -36611,7 +36619,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -36611,7 +36619,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 36611 | } | 36619 | } |
| 36612 | }, | 36620 | }, |
| 36613 | .anon_struct_type => |tuple| { | 36621 | .anon_struct_type => |tuple| { |
| 36614 | for (tuple.types, tuple.values) |field_ty, val| { | 36622 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 36615 | const have_comptime_val = val != .none; | 36623 | const have_comptime_val = val != .none; |
| 36616 | if (!have_comptime_val and try sema.typeRequiresComptime(field_ty.toType())) { | 36624 | if (!have_comptime_val and try sema.typeRequiresComptime(field_ty.toType())) { |
| 36617 | return true; | 36625 | return true; |
| ... | @@ -36784,8 +36792,9 @@ fn anonStructFieldIndex( | ... | @@ -36784,8 +36792,9 @@ fn anonStructFieldIndex( |
| 36784 | field_src: LazySrcLoc, | 36792 | field_src: LazySrcLoc, |
| 36785 | ) !u32 { | 36793 | ) !u32 { |
| 36786 | const mod = sema.mod; | 36794 | const mod = sema.mod; |
| 36787 | switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) { | 36795 | const ip = &mod.intern_pool; |
| 36788 | .anon_struct_type => |anon_struct_type| for (anon_struct_type.names, 0..) |name, i| { | 36796 | switch (ip.indexToKey(struct_ty.toIntern())) { |
| 36797 | .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| { | ||
| 36789 | if (name == field_name) return @intCast(i); | 36798 | if (name == field_name) return @intCast(i); |
| 36790 | }, | 36799 | }, |
| 36791 | .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| { | 36800 | .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| { |
| ... | @@ -36798,7 +36807,7 @@ fn anonStructFieldIndex( | ... | @@ -36798,7 +36807,7 @@ fn anonStructFieldIndex( |
| 36798 | else => unreachable, | 36807 | else => unreachable, |
| 36799 | } | 36808 | } |
| 36800 | return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{ | 36809 | return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{ |
| 36801 | field_name.fmt(&mod.intern_pool), struct_ty.fmt(sema.mod), | 36810 | field_name.fmt(ip), struct_ty.fmt(sema.mod), |
| 36802 | }); | 36811 | }); |
| 36803 | } | 36812 | } |
| 36804 | 36813 |
src/TypedValue.zig+4-3| ... | @@ -423,6 +423,7 @@ fn printAggregate( | ... | @@ -423,6 +423,7 @@ fn printAggregate( |
| 423 | if (level == 0) { | 423 | if (level == 0) { |
| 424 | return writer.writeAll(".{ ... }"); | 424 | return writer.writeAll(".{ ... }"); |
| 425 | } | 425 | } |
| 426 | const ip = &mod.intern_pool; | ||
| 426 | if (ty.zigTypeTag(mod) == .Struct) { | 427 | if (ty.zigTypeTag(mod) == .Struct) { |
| 427 | try writer.writeAll(".{"); | 428 | try writer.writeAll(".{"); |
| 428 | const max_len = @min(ty.structFieldCount(mod), max_aggregate_items); | 429 | const max_len = @min(ty.structFieldCount(mod), max_aggregate_items); |
| ... | @@ -430,13 +431,13 @@ fn printAggregate( | ... | @@ -430,13 +431,13 @@ fn printAggregate( |
| 430 | for (0..max_len) |i| { | 431 | for (0..max_len) |i| { |
| 431 | if (i != 0) try writer.writeAll(", "); | 432 | if (i != 0) try writer.writeAll(", "); |
| 432 | 433 | ||
| 433 | const field_name = switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 434 | const field_name = switch (ip.indexToKey(ty.toIntern())) { |
| 434 | .struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(), | 435 | .struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(), |
| 435 | .anon_struct_type => |x| if (x.isTuple()) .none else x.names[i].toOptional(), | 436 | .anon_struct_type => |x| if (x.isTuple()) .none else x.names.get(ip)[i].toOptional(), |
| 436 | else => unreachable, | 437 | else => unreachable, |
| 437 | }; | 438 | }; |
| 438 | 439 | ||
| 439 | if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(&mod.intern_pool)}); | 440 | if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(ip)}); |
| 440 | try print(.{ | 441 | try print(.{ |
| 441 | .ty = ty.structFieldType(i, mod), | 442 | .ty = ty.structFieldType(i, mod), |
| 442 | .val = try val.fieldValue(mod, i), | 443 | .val = try val.fieldValue(mod, i), |
src/codegen.zig+5-1| ... | @@ -438,7 +438,11 @@ pub fn generateSymbol( | ... | @@ -438,7 +438,11 @@ pub fn generateSymbol( |
| 438 | }, | 438 | }, |
| 439 | .anon_struct_type => |tuple| { | 439 | .anon_struct_type => |tuple| { |
| 440 | const struct_begin = code.items.len; | 440 | const struct_begin = code.items.len; |
| 441 | for (tuple.types, tuple.values, 0..) |field_ty, comptime_val, index| { | 441 | for ( |
| 442 | tuple.types.get(ip), | ||
| 443 | tuple.values.get(ip), | ||
| 444 | 0.., | ||
| 445 | ) |field_ty, comptime_val, index| { | ||
| 442 | if (comptime_val != .none) continue; | 446 | if (comptime_val != .none) continue; |
| 443 | if (!field_ty.toType().hasRuntimeBits(mod)) continue; | 447 | if (!field_ty.toType().hasRuntimeBits(mod)) continue; |
| 444 | 448 |
src/codegen/c.zig+10-4| ... | @@ -1275,7 +1275,11 @@ pub const DeclGen = struct { | ... | @@ -1275,7 +1275,11 @@ pub const DeclGen = struct { |
| 1275 | 1275 | ||
| 1276 | try writer.writeByte('{'); | 1276 | try writer.writeByte('{'); |
| 1277 | var empty = true; | 1277 | var empty = true; |
| 1278 | for (tuple.types, tuple.values, 0..) |field_ty, comptime_ty, field_i| { | 1278 | for ( |
| 1279 | tuple.types.get(ip), | ||
| 1280 | tuple.values.get(ip), | ||
| 1281 | 0.., | ||
| 1282 | ) |field_ty, comptime_ty, field_i| { | ||
| 1279 | if (comptime_ty != .none) continue; | 1283 | if (comptime_ty != .none) continue; |
| 1280 | if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; | 1284 | if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; |
| 1281 | 1285 | ||
| ... | @@ -7745,16 +7749,18 @@ fn lowerFnRetTy(ret_ty: Type, mod: *Module) !Type { | ... | @@ -7745,16 +7749,18 @@ fn lowerFnRetTy(ret_ty: Type, mod: *Module) !Type { |
| 7745 | if (ret_ty.ip_index == .noreturn_type) return Type.noreturn; | 7749 | if (ret_ty.ip_index == .noreturn_type) return Type.noreturn; |
| 7746 | 7750 | ||
| 7747 | if (lowersToArray(ret_ty, mod)) { | 7751 | if (lowersToArray(ret_ty, mod)) { |
| 7752 | const gpa = mod.gpa; | ||
| 7753 | const ip = &mod.intern_pool; | ||
| 7748 | const names = [1]InternPool.NullTerminatedString{ | 7754 | const names = [1]InternPool.NullTerminatedString{ |
| 7749 | try mod.intern_pool.getOrPutString(mod.gpa, "array"), | 7755 | try ip.getOrPutString(gpa, "array"), |
| 7750 | }; | 7756 | }; |
| 7751 | const types = [1]InternPool.Index{ret_ty.ip_index}; | 7757 | const types = [1]InternPool.Index{ret_ty.ip_index}; |
| 7752 | const values = [1]InternPool.Index{.none}; | 7758 | const values = [1]InternPool.Index{.none}; |
| 7753 | const interned = try mod.intern(.{ .anon_struct_type = .{ | 7759 | const interned = try ip.getAnonStructType(gpa, .{ |
| 7754 | .names = &names, | 7760 | .names = &names, |
| 7755 | .types = &types, | 7761 | .types = &types, |
| 7756 | .values = &values, | 7762 | .values = &values, |
| 7757 | } }); | 7763 | }); |
| 7758 | return interned.toType(); | 7764 | return interned.toType(); |
| 7759 | } | 7765 | } |
| 7760 | 7766 |
src/codegen/llvm.zig+17-8| ... | @@ -2392,7 +2392,7 @@ pub const Object = struct { | ... | @@ -2392,7 +2392,7 @@ pub const Object = struct { |
| 2392 | comptime assert(struct_layout_version == 2); | 2392 | comptime assert(struct_layout_version == 2); |
| 2393 | var offset: u64 = 0; | 2393 | var offset: u64 = 0; |
| 2394 | 2394 | ||
| 2395 | for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| { | 2395 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 2396 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; | 2396 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; |
| 2397 | 2397 | ||
| 2398 | const field_size = field_ty.toType().abiSize(mod); | 2398 | const field_size = field_ty.toType().abiSize(mod); |
| ... | @@ -2401,7 +2401,7 @@ pub const Object = struct { | ... | @@ -2401,7 +2401,7 @@ pub const Object = struct { |
| 2401 | offset = field_offset + field_size; | 2401 | offset = field_offset + field_size; |
| 2402 | 2402 | ||
| 2403 | const field_name = if (tuple.names.len != 0) | 2403 | const field_name = if (tuple.names.len != 0) |
| 2404 | ip.stringToSlice(tuple.names[i]) | 2404 | ip.stringToSlice(tuple.names.get(ip)[i]) |
| 2405 | else | 2405 | else |
| 2406 | try std.fmt.allocPrintZ(gpa, "{d}", .{i}); | 2406 | try std.fmt.allocPrintZ(gpa, "{d}", .{i}); |
| 2407 | defer if (tuple.names.len == 0) gpa.free(field_name); | 2407 | defer if (tuple.names.len == 0) gpa.free(field_name); |
| ... | @@ -3325,7 +3325,10 @@ pub const Object = struct { | ... | @@ -3325,7 +3325,10 @@ pub const Object = struct { |
| 3325 | var offset: u64 = 0; | 3325 | var offset: u64 = 0; |
| 3326 | var big_align: u32 = 0; | 3326 | var big_align: u32 = 0; |
| 3327 | 3327 | ||
| 3328 | for (anon_struct_type.types, anon_struct_type.values) |field_ty, field_val| { | 3328 | for ( |
| 3329 | anon_struct_type.types.get(ip), | ||
| 3330 | anon_struct_type.values.get(ip), | ||
| 3331 | ) |field_ty, field_val| { | ||
| 3329 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; | 3332 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; |
| 3330 | 3333 | ||
| 3331 | const field_align = field_ty.toType().abiAlignment(mod); | 3334 | const field_align = field_ty.toType().abiAlignment(mod); |
| ... | @@ -3874,7 +3877,11 @@ pub const Object = struct { | ... | @@ -3874,7 +3877,11 @@ pub const Object = struct { |
| 3874 | var offset: u64 = 0; | 3877 | var offset: u64 = 0; |
| 3875 | var big_align: u32 = 0; | 3878 | var big_align: u32 = 0; |
| 3876 | var need_unnamed = false; | 3879 | var need_unnamed = false; |
| 3877 | for (tuple.types, tuple.values, 0..) |field_ty, field_val, field_index| { | 3880 | for ( |
| 3881 | tuple.types.get(ip), | ||
| 3882 | tuple.values.get(ip), | ||
| 3883 | 0.., | ||
| 3884 | ) |field_ty, field_val, field_index| { | ||
| 3878 | if (field_val != .none) continue; | 3885 | if (field_val != .none) continue; |
| 3879 | if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; | 3886 | if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue; |
| 3880 | 3887 | ||
| ... | @@ -10537,10 +10544,11 @@ fn llvmField(ty: Type, field_index: usize, mod: *Module) ?LlvmField { | ... | @@ -10537,10 +10544,11 @@ fn llvmField(ty: Type, field_index: usize, mod: *Module) ?LlvmField { |
| 10537 | var offset: u64 = 0; | 10544 | var offset: u64 = 0; |
| 10538 | var big_align: u32 = 0; | 10545 | var big_align: u32 = 0; |
| 10539 | 10546 | ||
| 10540 | const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 10547 | const ip = &mod.intern_pool; |
| 10548 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { | ||
| 10541 | .anon_struct_type => |tuple| { | 10549 | .anon_struct_type => |tuple| { |
| 10542 | var llvm_field_index: c_uint = 0; | 10550 | var llvm_field_index: c_uint = 0; |
| 10543 | for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| { | 10551 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 10544 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; | 10552 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; |
| 10545 | 10553 | ||
| 10546 | const field_align = field_ty.toType().abiAlignment(mod); | 10554 | const field_align = field_ty.toType().abiAlignment(mod); |
| ... | @@ -11118,6 +11126,7 @@ fn isByRef(ty: Type, mod: *Module) bool { | ... | @@ -11118,6 +11126,7 @@ fn isByRef(ty: Type, mod: *Module) bool { |
| 11118 | // For tuples and structs, if there are more than this many non-void | 11126 | // For tuples and structs, if there are more than this many non-void |
| 11119 | // fields, then we make it byref, otherwise byval. | 11127 | // fields, then we make it byref, otherwise byval. |
| 11120 | const max_fields_byval = 0; | 11128 | const max_fields_byval = 0; |
| 11129 | const ip = &mod.intern_pool; | ||
| 11121 | 11130 | ||
| 11122 | switch (ty.zigTypeTag(mod)) { | 11131 | switch (ty.zigTypeTag(mod)) { |
| 11123 | .Type, | 11132 | .Type, |
| ... | @@ -11146,10 +11155,10 @@ fn isByRef(ty: Type, mod: *Module) bool { | ... | @@ -11146,10 +11155,10 @@ fn isByRef(ty: Type, mod: *Module) bool { |
| 11146 | .Struct => { | 11155 | .Struct => { |
| 11147 | // Packed structs are represented to LLVM as integers. | 11156 | // Packed structs are represented to LLVM as integers. |
| 11148 | if (ty.containerLayout(mod) == .Packed) return false; | 11157 | if (ty.containerLayout(mod) == .Packed) return false; |
| 11149 | const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 11158 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { |
| 11150 | .anon_struct_type => |tuple| { | 11159 | .anon_struct_type => |tuple| { |
| 11151 | var count: usize = 0; | 11160 | var count: usize = 0; |
| 11152 | for (tuple.types, tuple.values) |field_ty, field_val| { | 11161 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 11153 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; | 11162 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; |
| 11154 | 11163 | ||
| 11155 | count += 1; | 11164 | count += 1; |
src/codegen/spirv.zig+5-5| ... | @@ -1227,6 +1227,7 @@ pub const DeclGen = struct { | ... | @@ -1227,6 +1227,7 @@ pub const DeclGen = struct { |
| 1227 | /// Turn a Zig type into a SPIR-V Type, and return a reference to it. | 1227 | /// Turn a Zig type into a SPIR-V Type, and return a reference to it. |
| 1228 | fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef { | 1228 | fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef { |
| 1229 | const mod = self.module; | 1229 | const mod = self.module; |
| 1230 | const ip = &mod.intern_pool; | ||
| 1230 | log.debug("resolveType: ty = {}", .{ty.fmt(self.module)}); | 1231 | log.debug("resolveType: ty = {}", .{ty.fmt(self.module)}); |
| 1231 | const target = self.getTarget(); | 1232 | const target = self.getTarget(); |
| 1232 | switch (ty.zigTypeTag(mod)) { | 1233 | switch (ty.zigTypeTag(mod)) { |
| ... | @@ -1271,7 +1272,6 @@ pub const DeclGen = struct { | ... | @@ -1271,7 +1272,6 @@ pub const DeclGen = struct { |
| 1271 | }, | 1272 | }, |
| 1272 | .Fn => switch (repr) { | 1273 | .Fn => switch (repr) { |
| 1273 | .direct => { | 1274 | .direct => { |
| 1274 | const ip = &mod.intern_pool; | ||
| 1275 | const fn_info = mod.typeToFunc(ty).?; | 1275 | const fn_info = mod.typeToFunc(ty).?; |
| 1276 | // TODO: Put this somewhere in Sema.zig | 1276 | // TODO: Put this somewhere in Sema.zig |
| 1277 | if (fn_info.is_var_args) | 1277 | if (fn_info.is_var_args) |
| ... | @@ -1333,13 +1333,13 @@ pub const DeclGen = struct { | ... | @@ -1333,13 +1333,13 @@ pub const DeclGen = struct { |
| 1333 | } }); | 1333 | } }); |
| 1334 | }, | 1334 | }, |
| 1335 | .Struct => { | 1335 | .Struct => { |
| 1336 | const struct_ty = switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1336 | const struct_ty = switch (ip.indexToKey(ty.toIntern())) { |
| 1337 | .anon_struct_type => |tuple| { | 1337 | .anon_struct_type => |tuple| { |
| 1338 | const member_types = try self.gpa.alloc(CacheRef, tuple.values.len); | 1338 | const member_types = try self.gpa.alloc(CacheRef, tuple.values.len); |
| 1339 | defer self.gpa.free(member_types); | 1339 | defer self.gpa.free(member_types); |
| 1340 | 1340 | ||
| 1341 | var member_index: usize = 0; | 1341 | var member_index: usize = 0; |
| 1342 | for (tuple.types, tuple.values) |field_ty, field_val| { | 1342 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| { |
| 1343 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; | 1343 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue; |
| 1344 | 1344 | ||
| 1345 | member_types[member_index] = try self.resolveType(field_ty.toType(), .indirect); | 1345 | member_types[member_index] = try self.resolveType(field_ty.toType(), .indirect); |
| ... | @@ -1369,12 +1369,12 @@ pub const DeclGen = struct { | ... | @@ -1369,12 +1369,12 @@ pub const DeclGen = struct { |
| 1369 | while (it.next()) |field_and_index| { | 1369 | while (it.next()) |field_and_index| { |
| 1370 | const field = field_and_index.field; | 1370 | const field = field_and_index.field; |
| 1371 | const index = field_and_index.index; | 1371 | const index = field_and_index.index; |
| 1372 | const field_name = mod.intern_pool.stringToSlice(struct_obj.fields.keys()[index]); | 1372 | const field_name = ip.stringToSlice(struct_obj.fields.keys()[index]); |
| 1373 | try member_types.append(try self.resolveType(field.ty, .indirect)); | 1373 | try member_types.append(try self.resolveType(field.ty, .indirect)); |
| 1374 | try member_names.append(try self.spv.resolveString(field_name)); | 1374 | try member_names.append(try self.spv.resolveString(field_name)); |
| 1375 | } | 1375 | } |
| 1376 | 1376 | ||
| 1377 | const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(self.module)); | 1377 | const name = ip.stringToSlice(try struct_obj.getFullyQualifiedName(self.module)); |
| 1378 | 1378 | ||
| 1379 | return try self.spv.resolve(.{ .struct_type = .{ | 1379 | return try self.spv.resolve(.{ .struct_type = .{ |
| 1380 | .name = try self.spv.resolveString(name), | 1380 | .name = try self.spv.resolveString(name), |
src/link/Dwarf.zig+1-1| ... | @@ -327,7 +327,7 @@ pub const DeclState = struct { | ... | @@ -327,7 +327,7 @@ pub const DeclState = struct { |
| 327 | // DW.AT.name, DW.FORM.string | 327 | // DW.AT.name, DW.FORM.string |
| 328 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); | 328 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); |
| 329 | 329 | ||
| 330 | for (fields.types, 0..) |field_ty, field_index| { | 330 | for (fields.types.get(ip), 0..) |field_ty, field_index| { |
| 331 | // DW.AT.member | 331 | // DW.AT.member |
| 332 | try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member)); | 332 | try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member)); |
| 333 | // DW.AT.name, DW.FORM.string | 333 | // DW.AT.name, DW.FORM.string |
src/type.zig+26-22| ... | @@ -170,7 +170,8 @@ pub const Type = struct { | ... | @@ -170,7 +170,8 @@ pub const Type = struct { |
| 170 | 170 | ||
| 171 | /// Prints a name suitable for `@typeName`. | 171 | /// Prints a name suitable for `@typeName`. |
| 172 | pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void { | 172 | pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void { |
| 173 | switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 173 | const ip = &mod.intern_pool; |
| 174 | switch (ip.indexToKey(ty.toIntern())) { | ||
| 174 | .int_type => |int_type| { | 175 | .int_type => |int_type| { |
| 175 | const sign_char: u8 = switch (int_type.signedness) { | 176 | const sign_char: u8 = switch (int_type.signedness) { |
| 176 | .signed => 'i', | 177 | .signed => 'i', |
| ... | @@ -257,7 +258,6 @@ pub const Type = struct { | ... | @@ -257,7 +258,6 @@ pub const Type = struct { |
| 257 | try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set"); | 258 | try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set"); |
| 258 | }, | 259 | }, |
| 259 | .error_set_type => |error_set_type| { | 260 | .error_set_type => |error_set_type| { |
| 260 | const ip = &mod.intern_pool; | ||
| 261 | const names = error_set_type.names; | 261 | const names = error_set_type.names; |
| 262 | try writer.writeAll("error{"); | 262 | try writer.writeAll("error{"); |
| 263 | for (names.get(ip), 0..) |name, i| { | 263 | for (names.get(ip), 0..) |name, i| { |
| ... | @@ -330,13 +330,13 @@ pub const Type = struct { | ... | @@ -330,13 +330,13 @@ pub const Type = struct { |
| 330 | return writer.writeAll("@TypeOf(.{})"); | 330 | return writer.writeAll("@TypeOf(.{})"); |
| 331 | } | 331 | } |
| 332 | try writer.writeAll("struct{"); | 332 | try writer.writeAll("struct{"); |
| 333 | for (anon_struct.types, anon_struct.values, 0..) |field_ty, val, i| { | 333 | for (anon_struct.types.get(ip), anon_struct.values.get(ip), 0..) |field_ty, val, i| { |
| 334 | if (i != 0) try writer.writeAll(", "); | 334 | if (i != 0) try writer.writeAll(", "); |
| 335 | if (val != .none) { | 335 | if (val != .none) { |
| 336 | try writer.writeAll("comptime "); | 336 | try writer.writeAll("comptime "); |
| 337 | } | 337 | } |
| 338 | if (anon_struct.names.len != 0) { | 338 | if (anon_struct.names.len != 0) { |
| 339 | try writer.print("{}: ", .{anon_struct.names[i].fmt(&mod.intern_pool)}); | 339 | try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)}); |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | try print(field_ty.toType(), writer, mod); | 342 | try print(field_ty.toType(), writer, mod); |
| ... | @@ -587,7 +587,7 @@ pub const Type = struct { | ... | @@ -587,7 +587,7 @@ pub const Type = struct { |
| 587 | } | 587 | } |
| 588 | }, | 588 | }, |
| 589 | .anon_struct_type => |tuple| { | 589 | .anon_struct_type => |tuple| { |
| 590 | for (tuple.types, tuple.values) |field_ty, val| { | 590 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 591 | if (val != .none) continue; // comptime field | 591 | if (val != .none) continue; // comptime field |
| 592 | if (try field_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true; | 592 | if (try field_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true; |
| 593 | } | 593 | } |
| ... | @@ -1055,7 +1055,7 @@ pub const Type = struct { | ... | @@ -1055,7 +1055,7 @@ pub const Type = struct { |
| 1055 | }, | 1055 | }, |
| 1056 | .anon_struct_type => |tuple| { | 1056 | .anon_struct_type => |tuple| { |
| 1057 | var big_align: u32 = 0; | 1057 | var big_align: u32 = 0; |
| 1058 | for (tuple.types, tuple.values) |field_ty, val| { | 1058 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 1059 | if (val != .none) continue; // comptime field | 1059 | if (val != .none) continue; // comptime field |
| 1060 | if (!(field_ty.toType().hasRuntimeBits(mod))) continue; | 1060 | if (!(field_ty.toType().hasRuntimeBits(mod))) continue; |
| 1061 | 1061 | ||
| ... | @@ -2155,7 +2155,7 @@ pub const Type = struct { | ... | @@ -2155,7 +2155,7 @@ pub const Type = struct { |
| 2155 | pub fn vectorLen(ty: Type, mod: *const Module) u32 { | 2155 | pub fn vectorLen(ty: Type, mod: *const Module) u32 { |
| 2156 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 2156 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 2157 | .vector_type => |vector_type| vector_type.len, | 2157 | .vector_type => |vector_type| vector_type.len, |
| 2158 | .anon_struct_type => |tuple| @as(u32, @intCast(tuple.types.len)), | 2158 | .anon_struct_type => |tuple| @intCast(tuple.types.len), |
| 2159 | else => unreachable, | 2159 | else => unreachable, |
| 2160 | }; | 2160 | }; |
| 2161 | } | 2161 | } |
| ... | @@ -2536,13 +2536,13 @@ pub const Type = struct { | ... | @@ -2536,13 +2536,13 @@ pub const Type = struct { |
| 2536 | }, | 2536 | }, |
| 2537 | 2537 | ||
| 2538 | .anon_struct_type => |tuple| { | 2538 | .anon_struct_type => |tuple| { |
| 2539 | for (tuple.values) |val| { | 2539 | for (tuple.values.get(ip)) |val| { |
| 2540 | if (val == .none) return null; | 2540 | if (val == .none) return null; |
| 2541 | } | 2541 | } |
| 2542 | // In this case the struct has all comptime-known fields and | 2542 | // In this case the struct has all comptime-known fields and |
| 2543 | // therefore has one possible value. | 2543 | // therefore has one possible value. |
| 2544 | // TODO: write something like getCoercedInts to avoid needing to dupe | 2544 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 2545 | const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values); | 2545 | const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip)); |
| 2546 | defer mod.gpa.free(duped_values); | 2546 | defer mod.gpa.free(duped_values); |
| 2547 | return (try mod.intern(.{ .aggregate = .{ | 2547 | return (try mod.intern(.{ .aggregate = .{ |
| 2548 | .ty = ty.toIntern(), | 2548 | .ty = ty.toIntern(), |
| ... | @@ -2732,7 +2732,7 @@ pub const Type = struct { | ... | @@ -2732,7 +2732,7 @@ pub const Type = struct { |
| 2732 | }, | 2732 | }, |
| 2733 | 2733 | ||
| 2734 | .anon_struct_type => |tuple| { | 2734 | .anon_struct_type => |tuple| { |
| 2735 | for (tuple.types, tuple.values) |field_ty, val| { | 2735 | for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| { |
| 2736 | const have_comptime_val = val != .none; | 2736 | const have_comptime_val = val != .none; |
| 2737 | if (!have_comptime_val and field_ty.toType().comptimeOnly(mod)) return true; | 2737 | if (!have_comptime_val and field_ty.toType().comptimeOnly(mod)) return true; |
| 2738 | } | 2738 | } |
| ... | @@ -2996,13 +2996,14 @@ pub const Type = struct { | ... | @@ -2996,13 +2996,14 @@ pub const Type = struct { |
| 2996 | } | 2996 | } |
| 2997 | 2997 | ||
| 2998 | pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString { | 2998 | pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString { |
| 2999 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 2999 | const ip = &mod.intern_pool; |
| 3000 | return switch (ip.indexToKey(ty.toIntern())) { | ||
| 3000 | .struct_type => |struct_type| { | 3001 | .struct_type => |struct_type| { |
| 3001 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 3002 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| 3002 | assert(struct_obj.haveFieldTypes()); | 3003 | assert(struct_obj.haveFieldTypes()); |
| 3003 | return struct_obj.fields.keys()[field_index]; | 3004 | return struct_obj.fields.keys()[field_index]; |
| 3004 | }, | 3005 | }, |
| 3005 | .anon_struct_type => |anon_struct| anon_struct.names[field_index], | 3006 | .anon_struct_type => |anon_struct| anon_struct.names.get(ip)[field_index], |
| 3006 | else => unreachable, | 3007 | else => unreachable, |
| 3007 | }; | 3008 | }; |
| 3008 | } | 3009 | } |
| ... | @@ -3032,7 +3033,7 @@ pub const Type = struct { | ... | @@ -3032,7 +3033,7 @@ pub const Type = struct { |
| 3032 | const union_obj = ip.loadUnionType(union_type); | 3033 | const union_obj = ip.loadUnionType(union_type); |
| 3033 | return union_obj.field_types.get(ip)[index].toType(); | 3034 | return union_obj.field_types.get(ip)[index].toType(); |
| 3034 | }, | 3035 | }, |
| 3035 | .anon_struct_type => |anon_struct| anon_struct.types[index].toType(), | 3036 | .anon_struct_type => |anon_struct| anon_struct.types.get(ip)[index].toType(), |
| 3036 | else => unreachable, | 3037 | else => unreachable, |
| 3037 | }; | 3038 | }; |
| 3038 | } | 3039 | } |
| ... | @@ -3046,7 +3047,7 @@ pub const Type = struct { | ... | @@ -3046,7 +3047,7 @@ pub const Type = struct { |
| 3046 | return struct_obj.fields.values()[index].alignment(mod, struct_obj.layout); | 3047 | return struct_obj.fields.values()[index].alignment(mod, struct_obj.layout); |
| 3047 | }, | 3048 | }, |
| 3048 | .anon_struct_type => |anon_struct| { | 3049 | .anon_struct_type => |anon_struct| { |
| 3049 | return anon_struct.types[index].toType().abiAlignment(mod); | 3050 | return anon_struct.types.get(ip)[index].toType().abiAlignment(mod); |
| 3050 | }, | 3051 | }, |
| 3051 | .union_type => |union_type| { | 3052 | .union_type => |union_type| { |
| 3052 | const union_obj = ip.loadUnionType(union_type); | 3053 | const union_obj = ip.loadUnionType(union_type); |
| ... | @@ -3057,7 +3058,8 @@ pub const Type = struct { | ... | @@ -3057,7 +3058,8 @@ pub const Type = struct { |
| 3057 | } | 3058 | } |
| 3058 | 3059 | ||
| 3059 | pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { | 3060 | pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value { |
| 3060 | switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 3061 | const ip = &mod.intern_pool; |
| 3062 | switch (ip.indexToKey(ty.toIntern())) { | ||
| 3061 | .struct_type => |struct_type| { | 3063 | .struct_type => |struct_type| { |
| 3062 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 3064 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| 3063 | const val = struct_obj.fields.values()[index].default_val; | 3065 | const val = struct_obj.fields.values()[index].default_val; |
| ... | @@ -3066,7 +3068,7 @@ pub const Type = struct { | ... | @@ -3066,7 +3068,7 @@ pub const Type = struct { |
| 3066 | return val.toValue(); | 3068 | return val.toValue(); |
| 3067 | }, | 3069 | }, |
| 3068 | .anon_struct_type => |anon_struct| { | 3070 | .anon_struct_type => |anon_struct| { |
| 3069 | const val = anon_struct.values[index]; | 3071 | const val = anon_struct.values.get(ip)[index]; |
| 3070 | // TODO: avoid using `unreachable` to indicate this. | 3072 | // TODO: avoid using `unreachable` to indicate this. |
| 3071 | if (val == .none) return Value.@"unreachable"; | 3073 | if (val == .none) return Value.@"unreachable"; |
| 3072 | return val.toValue(); | 3074 | return val.toValue(); |
| ... | @@ -3076,7 +3078,8 @@ pub const Type = struct { | ... | @@ -3076,7 +3078,8 @@ pub const Type = struct { |
| 3076 | } | 3078 | } |
| 3077 | 3079 | ||
| 3078 | pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { | 3080 | pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { |
| 3079 | switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 3081 | const ip = &mod.intern_pool; |
| 3082 | switch (ip.indexToKey(ty.toIntern())) { | ||
| 3080 | .struct_type => |struct_type| { | 3083 | .struct_type => |struct_type| { |
| 3081 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 3084 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| 3082 | const field = struct_obj.fields.values()[index]; | 3085 | const field = struct_obj.fields.values()[index]; |
| ... | @@ -3087,9 +3090,9 @@ pub const Type = struct { | ... | @@ -3087,9 +3090,9 @@ pub const Type = struct { |
| 3087 | } | 3090 | } |
| 3088 | }, | 3091 | }, |
| 3089 | .anon_struct_type => |tuple| { | 3092 | .anon_struct_type => |tuple| { |
| 3090 | const val = tuple.values[index]; | 3093 | const val = tuple.values.get(ip)[index]; |
| 3091 | if (val == .none) { | 3094 | if (val == .none) { |
| 3092 | return tuple.types[index].toType().onePossibleValue(mod); | 3095 | return tuple.types.get(ip)[index].toType().onePossibleValue(mod); |
| 3093 | } else { | 3096 | } else { |
| 3094 | return val.toValue(); | 3097 | return val.toValue(); |
| 3095 | } | 3098 | } |
| ... | @@ -3099,14 +3102,15 @@ pub const Type = struct { | ... | @@ -3099,14 +3102,15 @@ pub const Type = struct { |
| 3099 | } | 3102 | } |
| 3100 | 3103 | ||
| 3101 | pub fn structFieldIsComptime(ty: Type, index: usize, mod: *Module) bool { | 3104 | pub fn structFieldIsComptime(ty: Type, index: usize, mod: *Module) bool { |
| 3102 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 3105 | const ip = &mod.intern_pool; |
| 3106 | return switch (ip.indexToKey(ty.toIntern())) { | ||
| 3103 | .struct_type => |struct_type| { | 3107 | .struct_type => |struct_type| { |
| 3104 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; | 3108 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| 3105 | if (struct_obj.layout == .Packed) return false; | 3109 | if (struct_obj.layout == .Packed) return false; |
| 3106 | const field = struct_obj.fields.values()[index]; | 3110 | const field = struct_obj.fields.values()[index]; |
| 3107 | return field.is_comptime; | 3111 | return field.is_comptime; |
| 3108 | }, | 3112 | }, |
| 3109 | .anon_struct_type => |anon_struct| anon_struct.values[index] != .none, | 3113 | .anon_struct_type => |anon_struct| anon_struct.values.get(ip)[index] != .none, |
| 3110 | else => unreachable, | 3114 | else => unreachable, |
| 3111 | }; | 3115 | }; |
| 3112 | } | 3116 | } |
| ... | @@ -3202,7 +3206,7 @@ pub const Type = struct { | ... | @@ -3202,7 +3206,7 @@ pub const Type = struct { |
| 3202 | var offset: u64 = 0; | 3206 | var offset: u64 = 0; |
| 3203 | var big_align: u32 = 0; | 3207 | var big_align: u32 = 0; |
| 3204 | 3208 | ||
| 3205 | for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| { | 3209 | for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { |
| 3206 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) { | 3210 | if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) { |
| 3207 | // comptime field | 3211 | // comptime field |
| 3208 | if (i == index) return offset; | 3212 | if (i == index) return offset; |
src/value.zig+4-3| ... | @@ -268,6 +268,7 @@ pub const Value = struct { | ... | @@ -268,6 +268,7 @@ pub const Value = struct { |
| 268 | 268 | ||
| 269 | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { | 269 | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { |
| 270 | if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern(); | 270 | if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern(); |
| 271 | const ip = &mod.intern_pool; | ||
| 271 | switch (val.tag()) { | 272 | switch (val.tag()) { |
| 272 | .eu_payload => { | 273 | .eu_payload => { |
| 273 | const pl = val.castTag(.eu_payload).?.data; | 274 | const pl = val.castTag(.eu_payload).?.data; |
| ... | @@ -286,7 +287,7 @@ pub const Value = struct { | ... | @@ -286,7 +287,7 @@ pub const Value = struct { |
| 286 | .slice => { | 287 | .slice => { |
| 287 | const pl = val.castTag(.slice).?.data; | 288 | const pl = val.castTag(.slice).?.data; |
| 288 | const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod); | 289 | const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod); |
| 289 | var ptr_key = mod.intern_pool.indexToKey(ptr).ptr; | 290 | var ptr_key = ip.indexToKey(ptr).ptr; |
| 290 | assert(ptr_key.len == .none); | 291 | assert(ptr_key.len == .none); |
| 291 | ptr_key.ty = ty.toIntern(); | 292 | ptr_key.ty = ty.toIntern(); |
| 292 | ptr_key.len = try pl.len.intern(Type.usize, mod); | 293 | ptr_key.len = try pl.len.intern(Type.usize, mod); |
| ... | @@ -311,11 +312,11 @@ pub const Value = struct { | ... | @@ -311,11 +312,11 @@ pub const Value = struct { |
| 311 | const old_elems = val.castTag(.aggregate).?.data[0..len]; | 312 | const old_elems = val.castTag(.aggregate).?.data[0..len]; |
| 312 | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); | 313 | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); |
| 313 | defer mod.gpa.free(new_elems); | 314 | defer mod.gpa.free(new_elems); |
| 314 | const ty_key = mod.intern_pool.indexToKey(ty.toIntern()); | 315 | const ty_key = ip.indexToKey(ty.toIntern()); |
| 315 | for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i| | 316 | for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i| |
| 316 | new_elem.* = try old_elem.intern(switch (ty_key) { | 317 | new_elem.* = try old_elem.intern(switch (ty_key) { |
| 317 | .struct_type => ty.structFieldType(field_i, mod), | 318 | .struct_type => ty.structFieldType(field_i, mod), |
| 318 | .anon_struct_type => |info| info.types[field_i].toType(), | 319 | .anon_struct_type => |info| info.types.get(ip)[field_i].toType(), |
| 319 | inline .array_type, .vector_type => |info| info.child.toType(), | 320 | inline .array_type, .vector_type => |info| info.child.toType(), |
| 320 | else => unreachable, | 321 | else => unreachable, |
| 321 | }, mod); | 322 | }, mod); |