authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-11-01 01:43:08+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-01 01:43:08+00:00
log3f7fac5fff9beed535a7674679a5e2c1f3cd74d2
treec5f7affd52d47632874da1f533c888ef648e8304
parenta916bc7fdd3975a9e2ef13c44f814c71ce017193
parent24babde746621492c5111ffcd8edf575cb176d65
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21817 from mlugg/no-anon-structs

compiler: remove anonymous struct types, unify all tuples

63 files changed, 1069 insertions(+), 1314 deletions(-)

lib/compiler/aro/aro/Builtins.zig+1-1
...@@ -157,7 +157,7 @@ fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *c...@@ -157,7 +157,7 @@ fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *c
157 .len = element_count,157 .len = element_count,
158 .elem = child_ty,158 .elem = child_ty,
159 };159 };
160 const vector_ty = .{ .specifier = .vector, .data = .{ .array = arr_ty } };160 const vector_ty: Type = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
161 builder.specifier = Type.Builder.fromType(vector_ty);161 builder.specifier = Type.Builder.fromType(vector_ty);
162 },162 },
163 .q => {163 .q => {
lib/compiler/aro/aro/Parser.zig+1-1
...@@ -8095,7 +8095,7 @@ fn primaryExpr(p: *Parser) Error!Result {...@@ -8095,7 +8095,7 @@ fn primaryExpr(p: *Parser) Error!Result {
80958095
8096fn makePredefinedIdentifier(p: *Parser, strings_top: usize) !Result {8096fn makePredefinedIdentifier(p: *Parser, strings_top: usize) !Result {
8097 const end: u32 = @intCast(p.strings.items.len);8097 const end: u32 = @intCast(p.strings.items.len);
8098 const elem_ty = .{ .specifier = .char, .qual = .{ .@"const" = true } };8098 const elem_ty: Type = .{ .specifier = .char, .qual = .{ .@"const" = true } };
8099 const arr_ty = try p.arena.create(Type.Array);8099 const arr_ty = try p.arena.create(Type.Array);
8100 arr_ty.* = .{ .elem = elem_ty, .len = end - strings_top };8100 arr_ty.* = .{ .elem = elem_ty, .len = end - strings_top };
8101 const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } };8101 const ty: Type = .{ .specifier = .array, .data = .{ .array = arr_ty } };
lib/compiler/aro/aro/text_literal.zig+1-1
...@@ -188,7 +188,7 @@ pub const Parser = struct {...@@ -188,7 +188,7 @@ pub const Parser = struct {
188 pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {188 pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {
189 if (self.errored) return;189 if (self.errored) return;
190 self.errored = true;190 self.errored = true;
191 const diagnostic = .{ .tag = tag, .extra = extra };191 const diagnostic: CharDiagnostic = .{ .tag = tag, .extra = extra };
192 if (self.errors_len == self.errors_buffer.len) {192 if (self.errors_len == self.errors_buffer.len) {
193 self.errors_buffer[self.errors_buffer.len - 1] = diagnostic;193 self.errors_buffer[self.errors_buffer.len - 1] = diagnostic;
194 } else {194 } else {
lib/compiler/aro_translate_c.zig+1-1
...@@ -749,7 +749,7 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH...@@ -749,7 +749,7 @@ fn transType(c: *Context, scope: *Scope, raw_ty: Type, qual_handling: Type.QualH
749 const is_const = is_fn_proto or child_type.isConst();749 const is_const = is_fn_proto or child_type.isConst();
750 const is_volatile = child_type.qual.@"volatile";750 const is_volatile = child_type.qual.@"volatile";
751 const elem_type = try transType(c, scope, child_type, qual_handling, source_loc);751 const elem_type = try transType(c, scope, child_type, qual_handling, source_loc);
752 const ptr_info = .{752 const ptr_info: @FieldType(ast.Payload.Pointer, "data") = .{
753 .is_const = is_const,753 .is_const = is_const,
754 .is_volatile = is_volatile,754 .is_volatile = is_volatile,
755 .elem_type = elem_type,755 .elem_type = elem_type,
lib/compiler/test_runner.zig+1-1
...@@ -6,7 +6,7 @@ const io = std.io;...@@ -6,7 +6,7 @@ const io = std.io;
6const testing = std.testing;6const testing = std.testing;
7const assert = std.debug.assert;7const assert = std.debug.assert;
88
9pub const std_options = .{9pub const std_options: std.Options = .{
10 .logFn = log,10 .logFn = log,
11};11};
1212
lib/std/SemanticVersion.zig+1-1
...@@ -299,7 +299,7 @@ test "precedence" {...@@ -299,7 +299,7 @@ test "precedence" {
299299
300test "zig_version" {300test "zig_version" {
301 // An approximate Zig build that predates this test.301 // An approximate Zig build that predates this test.
302 const older_version = .{ .major = 0, .minor = 8, .patch = 0, .pre = "dev.874" };302 const older_version: Version = .{ .major = 0, .minor = 8, .patch = 0, .pre = "dev.874" };
303303
304 // Simulated compatibility check using Zig version.304 // Simulated compatibility check using Zig version.
305 const compatible = comptime @import("builtin").zig_version.order(older_version) == .gt;305 const compatible = comptime @import("builtin").zig_version.order(older_version) == .gt;
lib/std/Target.zig+1-1
...@@ -509,7 +509,7 @@ pub const Os = struct {...@@ -509,7 +509,7 @@ pub const Os = struct {
509 .max = .{ .major = 6, .minor = 10, .patch = 3 },509 .max = .{ .major = 6, .minor = 10, .patch = 3 },
510 },510 },
511 .glibc = blk: {511 .glibc = blk: {
512 const default_min = .{ .major = 2, .minor = 28, .patch = 0 };512 const default_min: std.SemanticVersion = .{ .major = 2, .minor = 28, .patch = 0 };
513513
514 for (std.zig.target.available_libcs) |libc| {514 for (std.zig.target.available_libcs) |libc| {
515 // We don't know the ABI here. We can get away with not checking it515 // We don't know the ABI here. We can get away with not checking it
lib/std/array_list.zig+1-1
...@@ -100,7 +100,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -100,7 +100,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
100 /// of this ArrayList. Empties this ArrayList.100 /// of this ArrayList. Empties this ArrayList.
101 pub fn moveToUnmanaged(self: *Self) ArrayListAlignedUnmanaged(T, alignment) {101 pub fn moveToUnmanaged(self: *Self) ArrayListAlignedUnmanaged(T, alignment) {
102 const allocator = self.allocator;102 const allocator = self.allocator;
103 const result = .{ .items = self.items, .capacity = self.capacity };103 const result: ArrayListAlignedUnmanaged(T, alignment) = .{ .items = self.items, .capacity = self.capacity };
104 self.* = init(allocator);104 self.* = init(allocator);
105 return result;105 return result;
106 }106 }
lib/std/crypto/phc_encoding.zig+1-2
...@@ -258,8 +258,7 @@ fn kvSplit(str: []const u8) !struct { key: []const u8, value: []const u8 } {...@@ -258,8 +258,7 @@ fn kvSplit(str: []const u8) !struct { key: []const u8, value: []const u8 } {
258 var it = mem.splitScalar(u8, str, kv_delimiter_scalar);258 var it = mem.splitScalar(u8, str, kv_delimiter_scalar);
259 const key = it.first();259 const key = it.first();
260 const value = it.next() orelse return Error.InvalidEncoding;260 const value = it.next() orelse return Error.InvalidEncoding;
261 const ret = .{ .key = key, .value = value };261 return .{ .key = key, .value = value };
262 return ret;
263}262}
264263
265test "phc format - encoding/decoding" {264test "phc format - encoding/decoding" {
lib/std/mem.zig+3-1
...@@ -3965,7 +3965,9 @@ fn CopyPtrAttrs(...@@ -3965,7 +3965,9 @@ fn CopyPtrAttrs(
3965}3965}
39663966
3967fn AsBytesReturnType(comptime P: type) type {3967fn AsBytesReturnType(comptime P: type) type {
3968 const size = @sizeOf(std.meta.Child(P));3968 const pointer = @typeInfo(P).pointer;
3969 assert(pointer.size == .One);
3970 const size = @sizeOf(pointer.child);
3969 return CopyPtrAttrs(P, .One, [size]u8);3971 return CopyPtrAttrs(P, .One, [size]u8);
3970}3972}
39713973
lib/std/meta.zig+1-1
...@@ -1018,7 +1018,7 @@ fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type {...@@ -1018,7 +1018,7 @@ fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type {
1018 .type = T,1018 .type = T,
1019 .default_value = null,1019 .default_value = null,
1020 .is_comptime = false,1020 .is_comptime = false,
1021 .alignment = if (@sizeOf(T) > 0) @alignOf(T) else 0,1021 .alignment = 0,
1022 };1022 };
1023 }1023 }
10241024
lib/std/zig/AstGen.zig+129-60
...@@ -1711,7 +1711,7 @@ fn structInitExpr(...@@ -1711,7 +1711,7 @@ fn structInitExpr(
1711 return rvalue(gz, ri, val, node);1711 return rvalue(gz, ri, val, node);
1712 },1712 },
1713 .none, .ref, .inferred_ptr => {1713 .none, .ref, .inferred_ptr => {
1714 return rvalue(gz, ri, .empty_struct, node);1714 return rvalue(gz, ri, .empty_tuple, node);
1715 },1715 },
1716 .destructure => |destructure| {1716 .destructure => |destructure| {
1717 return astgen.failNodeNotes(node, "empty initializer cannot be destructured", .{}, &.{1717 return astgen.failNodeNotes(node, "empty initializer cannot be destructured", .{}, &.{
...@@ -1888,6 +1888,8 @@ fn structInitExprAnon(...@@ -1888,6 +1888,8 @@ fn structInitExprAnon(
1888 const tree = astgen.tree;1888 const tree = astgen.tree;
18891889
1890 const payload_index = try addExtra(astgen, Zir.Inst.StructInitAnon{1890 const payload_index = try addExtra(astgen, Zir.Inst.StructInitAnon{
1891 .abs_node = node,
1892 .abs_line = astgen.source_line,
1891 .fields_len = @intCast(struct_init.ast.fields.len),1893 .fields_len = @intCast(struct_init.ast.fields.len),
1892 });1894 });
1893 const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).@"struct".fields.len;1895 const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).@"struct".fields.len;
...@@ -1919,6 +1921,8 @@ fn structInitExprTyped(...@@ -1919,6 +1921,8 @@ fn structInitExprTyped(
1919 const tree = astgen.tree;1921 const tree = astgen.tree;
19201922
1921 const payload_index = try addExtra(astgen, Zir.Inst.StructInit{1923 const payload_index = try addExtra(astgen, Zir.Inst.StructInit{
1924 .abs_node = node,
1925 .abs_line = astgen.source_line,
1922 .fields_len = @intCast(struct_init.ast.fields.len),1926 .fields_len = @intCast(struct_init.ast.fields.len),
1923 });1927 });
1924 const field_size = @typeInfo(Zir.Inst.StructInit.Item).@"struct".fields.len;1928 const field_size = @typeInfo(Zir.Inst.StructInit.Item).@"struct".fields.len;
...@@ -5007,6 +5011,25 @@ fn structDeclInner(...@@ -5007,6 +5011,25 @@ fn structDeclInner(
5007 layout: std.builtin.Type.ContainerLayout,5011 layout: std.builtin.Type.ContainerLayout,
5008 backing_int_node: Ast.Node.Index,5012 backing_int_node: Ast.Node.Index,
5009) InnerError!Zir.Inst.Ref {5013) InnerError!Zir.Inst.Ref {
5014 const astgen = gz.astgen;
5015 const gpa = astgen.gpa;
5016 const tree = astgen.tree;
5017
5018 {
5019 const is_tuple = for (container_decl.ast.members) |member_node| {
5020 const container_field = tree.fullContainerField(member_node) orelse continue;
5021 if (container_field.ast.tuple_like) break true;
5022 } else false;
5023
5024 if (is_tuple) {
5025 if (node == 0) {
5026 return astgen.failTok(0, "file cannot be a tuple", .{});
5027 } else {
5028 return tupleDecl(gz, scope, node, container_decl, layout, backing_int_node);
5029 }
5030 }
5031 }
5032
5010 const decl_inst = try gz.reserveInstructionIndex();5033 const decl_inst = try gz.reserveInstructionIndex();
50115034
5012 if (container_decl.ast.members.len == 0 and backing_int_node == 0) {5035 if (container_decl.ast.members.len == 0 and backing_int_node == 0) {
...@@ -5019,7 +5042,6 @@ fn structDeclInner(...@@ -5019,7 +5042,6 @@ fn structDeclInner(
5019 .has_backing_int = false,5042 .has_backing_int = false,
5020 .known_non_opv = false,5043 .known_non_opv = false,
5021 .known_comptime_only = false,5044 .known_comptime_only = false,
5022 .is_tuple = false,
5023 .any_comptime_fields = false,5045 .any_comptime_fields = false,
5024 .any_default_inits = false,5046 .any_default_inits = false,
5025 .any_aligned_fields = false,5047 .any_aligned_fields = false,
...@@ -5028,10 +5050,6 @@ fn structDeclInner(...@@ -5028,10 +5050,6 @@ fn structDeclInner(
5028 return decl_inst.toRef();5050 return decl_inst.toRef();
5029 }5051 }
50305052
5031 const astgen = gz.astgen;
5032 const gpa = astgen.gpa;
5033 const tree = astgen.tree;
5034
5035 var namespace: Scope.Namespace = .{5053 var namespace: Scope.Namespace = .{
5036 .parent = scope,5054 .parent = scope,
5037 .node = node,5055 .node = node,
...@@ -5106,46 +5124,6 @@ fn structDeclInner(...@@ -5106,46 +5124,6 @@ fn structDeclInner(
5106 // No defer needed here because it is handled by `wip_members.deinit()` above.5124 // No defer needed here because it is handled by `wip_members.deinit()` above.
5107 const bodies_start = astgen.scratch.items.len;5125 const bodies_start = astgen.scratch.items.len;
51085126
5109 const node_tags = tree.nodes.items(.tag);
5110 const is_tuple = for (container_decl.ast.members) |member_node| {
5111 const container_field = tree.fullContainerField(member_node) orelse continue;
5112 if (container_field.ast.tuple_like) break true;
5113 } else false;
5114
5115 if (is_tuple) switch (layout) {
5116 .auto => {},
5117 .@"extern" => return astgen.failNode(node, "extern tuples are not supported", .{}),
5118 .@"packed" => return astgen.failNode(node, "packed tuples are not supported", .{}),
5119 };
5120
5121 if (is_tuple) for (container_decl.ast.members) |member_node| {
5122 switch (node_tags[member_node]) {
5123 .container_field_init,
5124 .container_field_align,
5125 .container_field,
5126 .@"comptime",
5127 .test_decl,
5128 => continue,
5129 else => {
5130 const tuple_member = for (container_decl.ast.members) |maybe_tuple| switch (node_tags[maybe_tuple]) {
5131 .container_field_init,
5132 .container_field_align,
5133 .container_field,
5134 => break maybe_tuple,
5135 else => {},
5136 } else unreachable;
5137 return astgen.failNodeNotes(
5138 member_node,
5139 "tuple declarations cannot contain declarations",
5140 .{},
5141 &[_]u32{
5142 try astgen.errNoteNode(tuple_member, "tuple field here", .{}),
5143 },
5144 );
5145 },
5146 }
5147 };
5148
5149 const old_hasher = astgen.src_hasher;5127 const old_hasher = astgen.src_hasher;
5150 defer astgen.src_hasher = old_hasher;5128 defer astgen.src_hasher = old_hasher;
5151 astgen.src_hasher = std.zig.SrcHasher.init(.{});5129 astgen.src_hasher = std.zig.SrcHasher.init(.{});
...@@ -5167,16 +5145,10 @@ fn structDeclInner(...@@ -5167,16 +5145,10 @@ fn structDeclInner(
51675145
5168 astgen.src_hasher.update(tree.getNodeSource(member_node));5146 astgen.src_hasher.update(tree.getNodeSource(member_node));
51695147
5170 if (!is_tuple) {5148 const field_name = try astgen.identAsString(member.ast.main_token);
5171 const field_name = try astgen.identAsString(member.ast.main_token);5149 member.convertToNonTupleLike(astgen.tree.nodes);
51725150 assert(!member.ast.tuple_like);
5173 member.convertToNonTupleLike(astgen.tree.nodes);5151 wip_members.appendToField(@intFromEnum(field_name));
5174 assert(!member.ast.tuple_like);
5175
5176 wip_members.appendToField(@intFromEnum(field_name));
5177 } else if (!member.ast.tuple_like) {
5178 return astgen.failTok(member.ast.main_token, "tuple field has a name", .{});
5179 }
51805152
5181 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());5153 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
5182 wip_members.appendToField(@intFromEnum(doc_comment_index));5154 wip_members.appendToField(@intFromEnum(doc_comment_index));
...@@ -5270,7 +5242,6 @@ fn structDeclInner(...@@ -5270,7 +5242,6 @@ fn structDeclInner(
5270 .has_backing_int = backing_int_ref != .none,5242 .has_backing_int = backing_int_ref != .none,
5271 .known_non_opv = known_non_opv,5243 .known_non_opv = known_non_opv,
5272 .known_comptime_only = known_comptime_only,5244 .known_comptime_only = known_comptime_only,
5273 .is_tuple = is_tuple,
5274 .any_comptime_fields = any_comptime_fields,5245 .any_comptime_fields = any_comptime_fields,
5275 .any_default_inits = any_default_inits,5246 .any_default_inits = any_default_inits,
5276 .any_aligned_fields = any_aligned_fields,5247 .any_aligned_fields = any_aligned_fields,
...@@ -5300,6 +5271,106 @@ fn structDeclInner(...@@ -5300,6 +5271,106 @@ fn structDeclInner(
5300 return decl_inst.toRef();5271 return decl_inst.toRef();
5301}5272}
53025273
5274fn tupleDecl(
5275 gz: *GenZir,
5276 scope: *Scope,
5277 node: Ast.Node.Index,
5278 container_decl: Ast.full.ContainerDecl,
5279 layout: std.builtin.Type.ContainerLayout,
5280 backing_int_node: Ast.Node.Index,
5281) InnerError!Zir.Inst.Ref {
5282 const astgen = gz.astgen;
5283 const gpa = astgen.gpa;
5284 const tree = astgen.tree;
5285
5286 const node_tags = tree.nodes.items(.tag);
5287
5288 switch (layout) {
5289 .auto => {},
5290 .@"extern" => return astgen.failNode(node, "extern tuples are not supported", .{}),
5291 .@"packed" => return astgen.failNode(node, "packed tuples are not supported", .{}),
5292 }
5293
5294 if (backing_int_node != 0) {
5295 return astgen.failNode(backing_int_node, "tuple does not support backing integer type", .{});
5296 }
5297
5298 // We will use the scratch buffer, starting here, for the field data:
5299 // 1. fields: { // for every `fields_len` (stored in `extended.small`)
5300 // type: Inst.Ref,
5301 // init: Inst.Ref, // `.none` for non-`comptime` fields
5302 // }
5303 const fields_start = astgen.scratch.items.len;
5304 defer astgen.scratch.items.len = fields_start;
5305
5306 try astgen.scratch.ensureUnusedCapacity(gpa, container_decl.ast.members.len * 2);
5307
5308 for (container_decl.ast.members) |member_node| {
5309 const field = tree.fullContainerField(member_node) orelse {
5310 const tuple_member = for (container_decl.ast.members) |maybe_tuple| switch (node_tags[maybe_tuple]) {
5311 .container_field_init,
5312 .container_field_align,
5313 .container_field,
5314 => break maybe_tuple,
5315 else => {},
5316 } else unreachable;
5317 return astgen.failNodeNotes(
5318 member_node,
5319 "tuple declarations cannot contain declarations",
5320 .{},
5321 &.{try astgen.errNoteNode(tuple_member, "tuple field here", .{})},
5322 );
5323 };
5324
5325 if (!field.ast.tuple_like) {
5326 return astgen.failTok(field.ast.main_token, "tuple field has a name", .{});
5327 }
5328
5329 if (field.ast.align_expr != 0) {
5330 return astgen.failTok(field.ast.main_token, "tuple field has alignment", .{});
5331 }
5332
5333 if (field.ast.value_expr != 0 and field.comptime_token == null) {
5334 return astgen.failTok(field.ast.main_token, "non-comptime tuple field has default initialization value", .{});
5335 }
5336
5337 if (field.ast.value_expr == 0 and field.comptime_token != null) {
5338 return astgen.failTok(field.comptime_token.?, "comptime field without default initialization value", .{});
5339 }
5340
5341 const field_type_ref = try typeExpr(gz, scope, field.ast.type_expr);
5342 astgen.scratch.appendAssumeCapacity(@intFromEnum(field_type_ref));
5343
5344 if (field.ast.value_expr != 0) {
5345 const field_init_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_type_ref } }, field.ast.value_expr);
5346 astgen.scratch.appendAssumeCapacity(@intFromEnum(field_init_ref));
5347 } else {
5348 astgen.scratch.appendAssumeCapacity(@intFromEnum(Zir.Inst.Ref.none));
5349 }
5350 }
5351
5352 const fields_len = std.math.cast(u16, container_decl.ast.members.len) orelse {
5353 return astgen.failNode(node, "this compiler implementation only supports 65535 tuple fields", .{});
5354 };
5355
5356 const extra_trail = astgen.scratch.items[fields_start..];
5357 assert(extra_trail.len == fields_len * 2);
5358 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.TupleDecl).@"struct".fields.len + extra_trail.len);
5359 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.TupleDecl{
5360 .src_node = gz.nodeIndexToRelative(node),
5361 });
5362 astgen.extra.appendSliceAssumeCapacity(extra_trail);
5363
5364 return gz.add(.{
5365 .tag = .extended,
5366 .data = .{ .extended = .{
5367 .opcode = .tuple_decl,
5368 .small = fields_len,
5369 .operand = payload_index,
5370 } },
5371 });
5372}
5373
5303fn unionDeclInner(5374fn unionDeclInner(
5304 gz: *GenZir,5375 gz: *GenZir,
5305 scope: *Scope,5376 scope: *Scope,
...@@ -11172,7 +11243,7 @@ fn rvalueInner(...@@ -11172,7 +11243,7 @@ fn rvalueInner(
11172 as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_sentinel_0_type),11243 as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_sentinel_0_type),
11173 as_ty | @intFromEnum(Zir.Inst.Ref.anyerror_void_error_union_type),11244 as_ty | @intFromEnum(Zir.Inst.Ref.anyerror_void_error_union_type),
11174 as_ty | @intFromEnum(Zir.Inst.Ref.generic_poison_type),11245 as_ty | @intFromEnum(Zir.Inst.Ref.generic_poison_type),
11175 as_ty | @intFromEnum(Zir.Inst.Ref.empty_struct_type),11246 as_ty | @intFromEnum(Zir.Inst.Ref.empty_tuple_type),
11176 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero),11247 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero),
11177 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one),11248 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one),
11178 as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one),11249 as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one),
...@@ -13173,7 +13244,6 @@ const GenZir = struct {...@@ -13173,7 +13244,6 @@ const GenZir = struct {
13173 layout: std.builtin.Type.ContainerLayout,13244 layout: std.builtin.Type.ContainerLayout,
13174 known_non_opv: bool,13245 known_non_opv: bool,
13175 known_comptime_only: bool,13246 known_comptime_only: bool,
13176 is_tuple: bool,
13177 any_comptime_fields: bool,13247 any_comptime_fields: bool,
13178 any_default_inits: bool,13248 any_default_inits: bool,
13179 any_aligned_fields: bool,13249 any_aligned_fields: bool,
...@@ -13217,7 +13287,6 @@ const GenZir = struct {...@@ -13217,7 +13287,6 @@ const GenZir = struct {
13217 .has_backing_int = args.has_backing_int,13287 .has_backing_int = args.has_backing_int,
13218 .known_non_opv = args.known_non_opv,13288 .known_non_opv = args.known_non_opv,
13219 .known_comptime_only = args.known_comptime_only,13289 .known_comptime_only = args.known_comptime_only,
13220 .is_tuple = args.is_tuple,
13221 .name_strategy = gz.anon_name_strategy,13290 .name_strategy = gz.anon_name_strategy,
13222 .layout = args.layout,13291 .layout = args.layout,
13223 .any_comptime_fields = args.any_comptime_fields,13292 .any_comptime_fields = args.any_comptime_fields,
lib/std/zig/BuiltinFn.zig+4-3
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1const std = @import("std");
2
3pub const Tag = enum {1pub const Tag = enum {
4 add_with_overflow,2 add_with_overflow,
5 addrspace_cast,3 addrspace_cast,
...@@ -147,7 +145,7 @@ param_count: ?u8,...@@ -147,7 +145,7 @@ param_count: ?u8,
147145
148pub const list = list: {146pub const list = list: {
149 @setEvalBranchQuota(3000);147 @setEvalBranchQuota(3000);
150 break :list std.StaticStringMap(@This()).initComptime(.{148 break :list std.StaticStringMap(BuiltinFn).initComptime([_]struct { []const u8, BuiltinFn }{
151 .{149 .{
152 "@addWithOverflow",150 "@addWithOverflow",
153 .{151 .{
...@@ -1011,3 +1009,6 @@ pub const list = list: {...@@ -1011,3 +1009,6 @@ pub const list = list: {
1011 },1009 },
1012 });1010 });
1013};1011};
1012
1013const std = @import("std");
1014const BuiltinFn = @This();
lib/std/zig/Zir.zig+69-10
...@@ -1887,6 +1887,10 @@ pub const Inst = struct {...@@ -1887,6 +1887,10 @@ pub const Inst = struct {
1887 /// `operand` is payload index to `OpaqueDecl`.1887 /// `operand` is payload index to `OpaqueDecl`.
1888 /// `small` is `OpaqueDecl.Small`.1888 /// `small` is `OpaqueDecl.Small`.
1889 opaque_decl,1889 opaque_decl,
1890 /// A tuple type. Note that tuples are not namespace/container types.
1891 /// `operand` is payload index to `TupleDecl`.
1892 /// `small` is `fields_len: u16`.
1893 tuple_decl,
1890 /// Implements the `@This` builtin.1894 /// Implements the `@This` builtin.
1891 /// `operand` is `src_node: i32`.1895 /// `operand` is `src_node: i32`.
1892 this,1896 this,
...@@ -2187,7 +2191,7 @@ pub const Inst = struct {...@@ -2187,7 +2191,7 @@ pub const Inst = struct {
2187 anyerror_void_error_union_type,2191 anyerror_void_error_union_type,
2188 adhoc_inferred_error_set_type,2192 adhoc_inferred_error_set_type,
2189 generic_poison_type,2193 generic_poison_type,
2190 empty_struct_type,2194 empty_tuple_type,
2191 undef,2195 undef,
2192 zero,2196 zero,
2193 zero_usize,2197 zero_usize,
...@@ -2202,7 +2206,7 @@ pub const Inst = struct {...@@ -2202,7 +2206,7 @@ pub const Inst = struct {
2202 null_value,2206 null_value,
2203 bool_true,2207 bool_true,
2204 bool_false,2208 bool_false,
2205 empty_struct,2209 empty_tuple,
2206 generic_poison,2210 generic_poison,
22072211
2208 /// This Ref does not correspond to any ZIR instruction or constant2212 /// This Ref does not correspond to any ZIR instruction or constant
...@@ -3041,7 +3045,7 @@ pub const Inst = struct {...@@ -3041,7 +3045,7 @@ pub const Inst = struct {
3041 /// 0b0X00: whether corresponding field is comptime3045 /// 0b0X00: whether corresponding field is comptime
3042 /// 0bX000: whether corresponding field has a type expression3046 /// 0bX000: whether corresponding field has a type expression
3043 /// 9. fields: { // for every fields_len3047 /// 9. fields: { // for every fields_len
3044 /// field_name: u32, // if !is_tuple3048 /// field_name: u32,
3045 /// doc_comment: NullTerminatedString, // .empty if no doc comment3049 /// doc_comment: NullTerminatedString, // .empty if no doc comment
3046 /// field_type: Ref, // if corresponding bit is not set. none means anytype.3050 /// field_type: Ref, // if corresponding bit is not set. none means anytype.
3047 /// field_type_body_len: u32, // if corresponding bit is set3051 /// field_type_body_len: u32, // if corresponding bit is set
...@@ -3071,13 +3075,12 @@ pub const Inst = struct {...@@ -3071,13 +3075,12 @@ pub const Inst = struct {
3071 has_backing_int: bool,3075 has_backing_int: bool,
3072 known_non_opv: bool,3076 known_non_opv: bool,
3073 known_comptime_only: bool,3077 known_comptime_only: bool,
3074 is_tuple: bool,
3075 name_strategy: NameStrategy,3078 name_strategy: NameStrategy,
3076 layout: std.builtin.Type.ContainerLayout,3079 layout: std.builtin.Type.ContainerLayout,
3077 any_default_inits: bool,3080 any_default_inits: bool,
3078 any_comptime_fields: bool,3081 any_comptime_fields: bool,
3079 any_aligned_fields: bool,3082 any_aligned_fields: bool,
3080 _: u2 = undefined,3083 _: u3 = undefined,
3081 };3084 };
3082 };3085 };
30833086
...@@ -3302,6 +3305,15 @@ pub const Inst = struct {...@@ -3302,6 +3305,15 @@ pub const Inst = struct {
3302 };3305 };
3303 };3306 };
33043307
3308 /// Trailing:
3309 /// 1. fields: { // for every `fields_len` (stored in `extended.small`)
3310 /// type: Inst.Ref,
3311 /// init: Inst.Ref, // `.none` for non-`comptime` fields
3312 /// }
3313 pub const TupleDecl = struct {
3314 src_node: i32, // relative
3315 };
3316
3305 /// Trailing:3317 /// Trailing:
3306 /// { // for every fields_len3318 /// { // for every fields_len
3307 /// field_name: NullTerminatedString // null terminated string index3319 /// field_name: NullTerminatedString // null terminated string index
...@@ -3329,6 +3341,11 @@ pub const Inst = struct {...@@ -3329,6 +3341,11 @@ pub const Inst = struct {
33293341
3330 /// Trailing is an item per field.3342 /// Trailing is an item per field.
3331 pub const StructInit = struct {3343 pub const StructInit = struct {
3344 /// If this is an anonymous initialization (the operand is poison), this instruction becomes the owner of a type.
3345 /// To resolve source locations, we need an absolute source node.
3346 abs_node: Ast.Node.Index,
3347 /// Likewise, we need an absolute line number.
3348 abs_line: u32,
3332 fields_len: u32,3349 fields_len: u32,
33333350
3334 pub const Item = struct {3351 pub const Item = struct {
...@@ -3344,6 +3361,11 @@ pub const Inst = struct {...@@ -3344,6 +3361,11 @@ pub const Inst = struct {
3344 /// TODO make this instead array of inits followed by array of names because3361 /// TODO make this instead array of inits followed by array of names because
3345 /// it will be simpler Sema code and better for CPU cache.3362 /// it will be simpler Sema code and better for CPU cache.
3346 pub const StructInitAnon = struct {3363 pub const StructInitAnon = struct {
3364 /// This is an anonymous initialization, meaning this instruction becomes the owner of a type.
3365 /// To resolve source locations, we need an absolute source node.
3366 abs_node: Ast.Node.Index,
3367 /// Likewise, we need an absolute line number.
3368 abs_line: u32,
3347 fields_len: u32,3369 fields_len: u32,
33483370
3349 pub const Item = struct {3371 pub const Item = struct {
...@@ -3741,6 +3763,8 @@ fn findDeclsInner(...@@ -3741,6 +3763,8 @@ fn findDeclsInner(
3741 defers: *std.AutoHashMapUnmanaged(u32, void),3763 defers: *std.AutoHashMapUnmanaged(u32, void),
3742 inst: Inst.Index,3764 inst: Inst.Index,
3743) Allocator.Error!void {3765) Allocator.Error!void {
3766 comptime assert(Zir.inst_tracking_version == 0);
3767
3744 const tags = zir.instructions.items(.tag);3768 const tags = zir.instructions.items(.tag);
3745 const datas = zir.instructions.items(.data);3769 const datas = zir.instructions.items(.data);
37463770
...@@ -3884,9 +3908,6 @@ fn findDeclsInner(...@@ -3884,9 +3908,6 @@ fn findDeclsInner(
3884 .struct_init_empty,3908 .struct_init_empty,
3885 .struct_init_empty_result,3909 .struct_init_empty_result,
3886 .struct_init_empty_ref_result,3910 .struct_init_empty_ref_result,
3887 .struct_init_anon,
3888 .struct_init,
3889 .struct_init_ref,
3890 .validate_struct_init_ty,3911 .validate_struct_init_ty,
3891 .validate_struct_init_result_ty,3912 .validate_struct_init_result_ty,
3892 .validate_ptr_struct_init,3913 .validate_ptr_struct_init,
...@@ -3978,6 +3999,12 @@ fn findDeclsInner(...@@ -3978,6 +3999,12 @@ fn findDeclsInner(
3978 .restore_err_ret_index_fn_entry,3999 .restore_err_ret_index_fn_entry,
3979 => return,4000 => return,
39804001
4002 // Struct initializations need tracking, as they may create anonymous struct types.
4003 .struct_init,
4004 .struct_init_ref,
4005 .struct_init_anon,
4006 => return list.append(gpa, inst),
4007
3981 .extended => {4008 .extended => {
3982 const extended = datas[@intFromEnum(inst)].extended;4009 const extended = datas[@intFromEnum(inst)].extended;
3983 switch (extended.opcode) {4010 switch (extended.opcode) {
...@@ -4034,6 +4061,7 @@ fn findDeclsInner(...@@ -4034,6 +4061,7 @@ fn findDeclsInner(
4034 .builtin_value,4061 .builtin_value,
4035 .branch_hint,4062 .branch_hint,
4036 .inplace_arith_result_ty,4063 .inplace_arith_result_ty,
4064 .tuple_decl,
4037 => return,4065 => return,
40384066
4039 // `@TypeOf` has a body.4067 // `@TypeOf` has a body.
...@@ -4110,8 +4138,7 @@ fn findDeclsInner(...@@ -4110,8 +4138,7 @@ fn findDeclsInner(
4110 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;4138 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
4111 cur_bit_bag >>= 1;4139 cur_bit_bag >>= 1;
41124140
4113 fields_extra_index += @intFromBool(!small.is_tuple); // field_name4141 fields_extra_index += 2; // field_name, doc_comment
4114 fields_extra_index += 1; // doc_comment
41154142
4116 if (has_type_body) {4143 if (has_type_body) {
4117 const field_type_body_len = zir.extra[fields_extra_index];4144 const field_type_body_len = zir.extra[fields_extra_index];
...@@ -4736,3 +4763,35 @@ pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash {...@@ -4736,3 +4763,35 @@ pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash {
4736 else => return null,4763 else => return null,
4737 }4764 }
4738}4765}
4766
4767/// When the ZIR update tracking logic must be modified to consider new instructions,
4768/// change this constant to trigger compile errors at all relevant locations.
4769pub const inst_tracking_version = 0;
4770
4771/// Asserts that a ZIR instruction is tracked across incremental updates, and
4772/// thus may be given an `InternPool.TrackedInst`.
4773pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
4774 comptime assert(Zir.inst_tracking_version == 0);
4775 const inst = zir.instructions.get(@intFromEnum(inst_idx));
4776 switch (inst.tag) {
4777 .struct_init,
4778 .struct_init_ref,
4779 .struct_init_anon,
4780 => {}, // tracked in order, as the owner instructions of anonymous struct types
4781 .func,
4782 .func_inferred,
4783 .func_fancy,
4784 => {}, // tracked in order, as the owner instructions of function bodies
4785 .declaration => {}, // tracked by correlating names in the namespace of the parent container
4786 .extended => switch (inst.data.extended.opcode) {
4787 .struct_decl,
4788 .union_decl,
4789 .enum_decl,
4790 .opaque_decl,
4791 .reify,
4792 => {}, // tracked in order, as the owner instructions of explicit container types
4793 else => unreachable, // assertion failure; not trackable
4794 },
4795 else => unreachable, // assertion failure; not trackable
4796 }
4797}
lib/std/zig/system/darwin/macos.zig+3-3
...@@ -277,7 +277,7 @@ const SystemVersionTokenizer = struct {...@@ -277,7 +277,7 @@ const SystemVersionTokenizer = struct {
277};277};
278278
279test "detect" {279test "detect" {
280 const cases = .{280 const cases: [5]struct { []const u8, std.SemanticVersion } = .{
281 .{281 .{
282 \\<?xml version="1.0" encoding="UTF-8"?>282 \\<?xml version="1.0" encoding="UTF-8"?>
283 \\<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">283 \\<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
...@@ -388,8 +388,8 @@ test "detect" {...@@ -388,8 +388,8 @@ test "detect" {
388388
389 inline for (cases) |case| {389 inline for (cases) |case| {
390 const ver0 = try parseSystemVersion(case[0]);390 const ver0 = try parseSystemVersion(case[0]);
391 const ver1: std.SemanticVersion = case[1];391 const ver1 = case[1];
392 try testing.expectEqual(@as(std.math.Order, .eq), ver0.order(ver1));392 try testing.expectEqual(std.math.Order.eq, ver0.order(ver1));
393 }393 }
394}394}
395395
src/Air.zig+2-2
...@@ -962,7 +962,7 @@ pub const Inst = struct {...@@ -962,7 +962,7 @@ pub const Inst = struct {
962 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),962 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
963 adhoc_inferred_error_set_type = @intFromEnum(InternPool.Index.adhoc_inferred_error_set_type),963 adhoc_inferred_error_set_type = @intFromEnum(InternPool.Index.adhoc_inferred_error_set_type),
964 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),964 generic_poison_type = @intFromEnum(InternPool.Index.generic_poison_type),
965 empty_struct_type = @intFromEnum(InternPool.Index.empty_struct_type),965 empty_tuple_type = @intFromEnum(InternPool.Index.empty_tuple_type),
966 undef = @intFromEnum(InternPool.Index.undef),966 undef = @intFromEnum(InternPool.Index.undef),
967 zero = @intFromEnum(InternPool.Index.zero),967 zero = @intFromEnum(InternPool.Index.zero),
968 zero_usize = @intFromEnum(InternPool.Index.zero_usize),968 zero_usize = @intFromEnum(InternPool.Index.zero_usize),
...@@ -977,7 +977,7 @@ pub const Inst = struct {...@@ -977,7 +977,7 @@ pub const Inst = struct {
977 null_value = @intFromEnum(InternPool.Index.null_value),977 null_value = @intFromEnum(InternPool.Index.null_value),
978 bool_true = @intFromEnum(InternPool.Index.bool_true),978 bool_true = @intFromEnum(InternPool.Index.bool_true),
979 bool_false = @intFromEnum(InternPool.Index.bool_false),979 bool_false = @intFromEnum(InternPool.Index.bool_false),
980 empty_struct = @intFromEnum(InternPool.Index.empty_struct),980 empty_tuple = @intFromEnum(InternPool.Index.empty_tuple),
981 generic_poison = @intFromEnum(InternPool.Index.generic_poison),981 generic_poison = @intFromEnum(InternPool.Index.generic_poison),
982982
983 /// This Ref does not correspond to any AIR instruction or constant983 /// This Ref does not correspond to any AIR instruction or constant
src/Air/types_resolved.zig+1-1
...@@ -501,7 +501,7 @@ pub fn checkType(ty: Type, zcu: *Zcu) bool {...@@ -501,7 +501,7 @@ pub fn checkType(ty: Type, zcu: *Zcu) bool {
501 .auto, .@"extern" => struct_obj.flagsUnordered(ip).fully_resolved,501 .auto, .@"extern" => struct_obj.flagsUnordered(ip).fully_resolved,
502 };502 };
503 },503 },
504 .anon_struct_type => |tuple| {504 .tuple_type => |tuple| {
505 for (0..tuple.types.len) |i| {505 for (0..tuple.types.len) |i| {
506 const field_is_comptime = tuple.values.get(ip)[i] != .none;506 const field_is_comptime = tuple.values.get(ip)[i] != .none;
507 if (field_is_comptime) continue;507 if (field_is_comptime) continue;
src/Compilation.zig+1-1
...@@ -2081,7 +2081,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2081,7 +2081,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2081 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});2081 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
20822082
2083 // Compile the artifacts to a temporary directory.2083 // Compile the artifacts to a temporary directory.
2084 const tmp_artifact_directory = d: {2084 const tmp_artifact_directory: Directory = d: {
2085 const s = std.fs.path.sep_str;2085 const s = std.fs.path.sep_str;
2086 tmp_dir_rand_int = std.crypto.random.int(u64);2086 tmp_dir_rand_int = std.crypto.random.int(u64);
2087 const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int);2087 const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int);
src/InternPool.zig+109-230
...@@ -1787,10 +1787,11 @@ pub const Key = union(enum) {...@@ -1787,10 +1787,11 @@ pub const Key = union(enum) {
1787 /// or was created with `@Type`. It is unique and based on a declaration.1787 /// or was created with `@Type`. It is unique and based on a declaration.
1788 /// It may be a tuple, if declared like this: `struct {A, B, C}`.1788 /// It may be a tuple, if declared like this: `struct {A, B, C}`.
1789 struct_type: NamespaceType,1789 struct_type: NamespaceType,
1790 /// This is an anonymous struct or tuple type which has no corresponding1790 /// This is a tuple type. Tuples are logically similar to structs, but have some
1791 /// declaration. It is used for types that have no `struct` keyword in the1791 /// important differences in semantics; they do not undergo staged type resolution,
1792 /// source code, and were not created via `@Type`.1792 /// so cannot be self-referential, and they are not considered container/namespace
1793 anon_struct_type: AnonStructType,1793 /// types, so cannot have declarations and have structural equality properties.
1794 tuple_type: TupleType,
1794 union_type: NamespaceType,1795 union_type: NamespaceType,
1795 opaque_type: NamespaceType,1796 opaque_type: NamespaceType,
1796 enum_type: NamespaceType,1797 enum_type: NamespaceType,
...@@ -1919,27 +1920,10 @@ pub const Key = union(enum) {...@@ -1919,27 +1920,10 @@ pub const Key = union(enum) {
1919 child: Index,1920 child: Index,
1920 };1921 };
19211922
1922 pub const AnonStructType = struct {1923 pub const TupleType = struct {
1923 types: Index.Slice,1924 types: Index.Slice,
1924 /// This may be empty, indicating this is a tuple.
1925 names: NullTerminatedString.Slice,
1926 /// These elements may be `none`, indicating runtime-known.1925 /// These elements may be `none`, indicating runtime-known.
1927 values: Index.Slice,1926 values: Index.Slice,
1928
1929 pub fn isTuple(self: AnonStructType) bool {
1930 return self.names.len == 0;
1931 }
1932
1933 pub fn fieldName(
1934 self: AnonStructType,
1935 ip: *const InternPool,
1936 index: usize,
1937 ) OptionalNullTerminatedString {
1938 if (self.names.len == 0)
1939 return .none;
1940
1941 return self.names.get(ip)[index].toOptional();
1942 }
1943 };1927 };
19441928
1945 /// This is the hashmap key. To fetch other data associated with the type, see:1929 /// This is the hashmap key. To fetch other data associated with the type, see:
...@@ -1965,18 +1949,15 @@ pub const Key = union(enum) {...@@ -1965,18 +1949,15 @@ pub const Key = union(enum) {
1965 /// The union for which this is a tag type.1949 /// The union for which this is a tag type.
1966 union_type: Index,1950 union_type: Index,
1967 },1951 },
1968 /// This type originates from a reification via `@Type`.1952 /// This type originates from a reification via `@Type`, or from an anonymous initialization.
1969 /// It is hased based on its ZIR instruction index and fields, attributes, etc.1953 /// It is hashed based on its ZIR instruction index and fields, attributes, etc.
1970 /// To avoid making this key overly complex, the type-specific data is hased by Sema.1954 /// To avoid making this key overly complex, the type-specific data is hased by Sema.
1971 reified: struct {1955 reified: struct {
1972 /// A `reify` instruction.1956 /// A `reify`, `struct_init`, `struct_init_ref`, or `struct_init_anon` instruction.
1973 zir_index: TrackedInst.Index,1957 zir_index: TrackedInst.Index,
1974 /// A hash of this type's attributes, fields, etc, generated by Sema.1958 /// A hash of this type's attributes, fields, etc, generated by Sema.
1975 type_hash: u64,1959 type_hash: u64,
1976 },1960 },
1977 /// This type is `@TypeOf(.{})`.
1978 /// TODO: can we change the language spec to not special-case this type?
1979 empty_struct: void,
1980 };1961 };
19811962
1982 pub const FuncType = struct {1963 pub const FuncType = struct {
...@@ -2497,7 +2478,6 @@ pub const Key = union(enum) {...@@ -2497,7 +2478,6 @@ pub const Key = union(enum) {
2497 std.hash.autoHash(&hasher, reified.zir_index);2478 std.hash.autoHash(&hasher, reified.zir_index);
2498 std.hash.autoHash(&hasher, reified.type_hash);2479 std.hash.autoHash(&hasher, reified.type_hash);
2499 },2480 },
2500 .empty_struct => {},
2501 }2481 }
2502 return hasher.final();2482 return hasher.final();
2503 },2483 },
...@@ -2570,7 +2550,7 @@ pub const Key = union(enum) {...@@ -2570,7 +2550,7 @@ pub const Key = union(enum) {
2570 const child = switch (ip.indexToKey(aggregate.ty)) {2550 const child = switch (ip.indexToKey(aggregate.ty)) {
2571 .array_type => |array_type| array_type.child,2551 .array_type => |array_type| array_type.child,
2572 .vector_type => |vector_type| vector_type.child,2552 .vector_type => |vector_type| vector_type.child,
2573 .anon_struct_type, .struct_type => .none,2553 .tuple_type, .struct_type => .none,
2574 else => unreachable,2554 else => unreachable,
2575 };2555 };
25762556
...@@ -2625,11 +2605,10 @@ pub const Key = union(enum) {...@@ -2625,11 +2605,10 @@ pub const Key = union(enum) {
26252605
2626 .error_set_type => |x| Hash.hash(seed, std.mem.sliceAsBytes(x.names.get(ip))),2606 .error_set_type => |x| Hash.hash(seed, std.mem.sliceAsBytes(x.names.get(ip))),
26272607
2628 .anon_struct_type => |anon_struct_type| {2608 .tuple_type => |tuple_type| {
2629 var hasher = Hash.init(seed);2609 var hasher = Hash.init(seed);
2630 for (anon_struct_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem);2610 for (tuple_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2631 for (anon_struct_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem);2611 for (tuple_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2632 for (anon_struct_type.names.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2633 return hasher.final();2612 return hasher.final();
2634 },2613 },
26352614
...@@ -2929,7 +2908,6 @@ pub const Key = union(enum) {...@@ -2929,7 +2908,6 @@ pub const Key = union(enum) {
2929 return a_r.zir_index == b_r.zir_index and2908 return a_r.zir_index == b_r.zir_index and
2930 a_r.type_hash == b_r.type_hash;2909 a_r.type_hash == b_r.type_hash;
2931 },2910 },
2932 .empty_struct => return true,
2933 }2911 }
2934 },2912 },
2935 .aggregate => |a_info| {2913 .aggregate => |a_info| {
...@@ -2981,11 +2959,10 @@ pub const Key = union(enum) {...@@ -2981,11 +2959,10 @@ pub const Key = union(enum) {
2981 },2959 },
2982 }2960 }
2983 },2961 },
2984 .anon_struct_type => |a_info| {2962 .tuple_type => |a_info| {
2985 const b_info = b.anon_struct_type;2963 const b_info = b.tuple_type;
2986 return std.mem.eql(Index, a_info.types.get(ip), b_info.types.get(ip)) and2964 return std.mem.eql(Index, a_info.types.get(ip), b_info.types.get(ip)) and
2987 std.mem.eql(Index, a_info.values.get(ip), b_info.values.get(ip)) and2965 std.mem.eql(Index, a_info.values.get(ip), b_info.values.get(ip));
2988 std.mem.eql(NullTerminatedString, a_info.names.get(ip), b_info.names.get(ip));
2989 },2966 },
2990 .error_set_type => |a_info| {2967 .error_set_type => |a_info| {
2991 const b_info = b.error_set_type;2968 const b_info = b.error_set_type;
...@@ -3025,7 +3002,7 @@ pub const Key = union(enum) {...@@ -3025,7 +3002,7 @@ pub const Key = union(enum) {
3025 .union_type,3002 .union_type,
3026 .opaque_type,3003 .opaque_type,
3027 .enum_type,3004 .enum_type,
3028 .anon_struct_type,3005 .tuple_type,
3029 .func_type,3006 .func_type,
3030 => .type_type,3007 => .type_type,
30313008
...@@ -3054,7 +3031,7 @@ pub const Key = union(enum) {...@@ -3054,7 +3031,7 @@ pub const Key = union(enum) {
3054 .void => .void_type,3031 .void => .void_type,
3055 .null => .null_type,3032 .null => .null_type,
3056 .false, .true => .bool_type,3033 .false, .true => .bool_type,
3057 .empty_struct => .empty_struct_type,3034 .empty_tuple => .empty_tuple_type,
3058 .@"unreachable" => .noreturn_type,3035 .@"unreachable" => .noreturn_type,
3059 .generic_poison => .generic_poison_type,3036 .generic_poison => .generic_poison_type,
3060 },3037 },
...@@ -3411,13 +3388,11 @@ pub const LoadedStructType = struct {...@@ -3411,13 +3388,11 @@ pub const LoadedStructType = struct {
3411 // TODO: the non-fqn will be needed by the new dwarf structure3388 // TODO: the non-fqn will be needed by the new dwarf structure
3412 /// The name of this struct type.3389 /// The name of this struct type.
3413 name: NullTerminatedString,3390 name: NullTerminatedString,
3414 /// The `Cau` within which type resolution occurs. `none` when the struct is `@TypeOf(.{})`.3391 /// The `Cau` within which type resolution occurs.
3415 cau: Cau.Index.Optional,3392 cau: Cau.Index,
3416 /// `none` when the struct is `@TypeOf(.{})`.3393 namespace: NamespaceIndex,
3417 namespace: OptionalNamespaceIndex,
3418 /// Index of the `struct_decl` or `reify` ZIR instruction.3394 /// Index of the `struct_decl` or `reify` ZIR instruction.
3419 /// Only `none` when the struct is `@TypeOf(.{})`.3395 zir_index: TrackedInst.Index,
3420 zir_index: TrackedInst.Index.Optional,
3421 layout: std.builtin.Type.ContainerLayout,3396 layout: std.builtin.Type.ContainerLayout,
3422 field_names: NullTerminatedString.Slice,3397 field_names: NullTerminatedString.Slice,
3423 field_types: Index.Slice,3398 field_types: Index.Slice,
...@@ -3913,10 +3888,6 @@ pub const LoadedStructType = struct {...@@ -3913,10 +3888,6 @@ pub const LoadedStructType = struct {
3913 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);3888 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3914 }3889 }
39153890
3916 pub fn isTuple(s: LoadedStructType, ip: *InternPool) bool {
3917 return s.layout != .@"packed" and s.flagsUnordered(ip).is_tuple;
3918 }
3919
3920 pub fn hasReorderedFields(s: LoadedStructType) bool {3891 pub fn hasReorderedFields(s: LoadedStructType) bool {
3921 return s.layout == .auto;3892 return s.layout == .auto;
3922 }3893 }
...@@ -4008,24 +3979,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4008,24 +3979,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4008 const item = unwrapped_index.getItem(ip);3979 const item = unwrapped_index.getItem(ip);
4009 switch (item.tag) {3980 switch (item.tag) {
4010 .type_struct => {3981 .type_struct => {
4011 if (item.data == 0) return .{
4012 .tid = .main,
4013 .extra_index = 0,
4014 .name = .empty,
4015 .cau = .none,
4016 .namespace = .none,
4017 .zir_index = .none,
4018 .layout = .auto,
4019 .field_names = NullTerminatedString.Slice.empty,
4020 .field_types = Index.Slice.empty,
4021 .field_inits = Index.Slice.empty,
4022 .field_aligns = Alignment.Slice.empty,
4023 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
4024 .comptime_bits = LoadedStructType.ComptimeBits.empty,
4025 .offsets = LoadedStructType.Offsets.empty,
4026 .names_map = .none,
4027 .captures = CaptureValue.Slice.empty,
4028 };
4029 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);3982 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);
4030 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "cau").?]);3983 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "cau").?]);
4031 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);3984 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);
...@@ -4045,7 +3998,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4045,7 +3998,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4045 };3998 };
4046 extra_index += captures_len;3999 extra_index += captures_len;
4047 if (flags.is_reified) {4000 if (flags.is_reified) {
4048 extra_index += 2; // PackedU644001 extra_index += 2; // type_hash: PackedU64
4049 }4002 }
4050 const field_types: Index.Slice = .{4003 const field_types: Index.Slice = .{
4051 .tid = unwrapped_index.tid,4004 .tid = unwrapped_index.tid,
...@@ -4053,7 +4006,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4053,7 +4006,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4053 .len = fields_len,4006 .len = fields_len,
4054 };4007 };
4055 extra_index += fields_len;4008 extra_index += fields_len;
4056 const names_map: OptionalMapIndex, const names = if (!flags.is_tuple) n: {4009 const names_map: OptionalMapIndex, const names = n: {
4057 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);4010 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4058 extra_index += 1;4011 extra_index += 1;
4059 const names: NullTerminatedString.Slice = .{4012 const names: NullTerminatedString.Slice = .{
...@@ -4063,7 +4016,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4063,7 +4016,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4063 };4016 };
4064 extra_index += fields_len;4017 extra_index += fields_len;
4065 break :n .{ names_map, names };4018 break :n .{ names_map, names };
4066 } else .{ .none, NullTerminatedString.Slice.empty };4019 };
4067 const inits: Index.Slice = if (flags.any_default_inits) i: {4020 const inits: Index.Slice = if (flags.any_default_inits) i: {
4068 const inits: Index.Slice = .{4021 const inits: Index.Slice = .{
4069 .tid = unwrapped_index.tid,4022 .tid = unwrapped_index.tid,
...@@ -4114,9 +4067,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4114,9 +4067,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4114 .tid = unwrapped_index.tid,4067 .tid = unwrapped_index.tid,
4115 .extra_index = item.data,4068 .extra_index = item.data,
4116 .name = name,4069 .name = name,
4117 .cau = cau.toOptional(),4070 .cau = cau,
4118 .namespace = namespace.toOptional(),4071 .namespace = namespace,
4119 .zir_index = zir_index.toOptional(),4072 .zir_index = zir_index,
4120 .layout = if (flags.is_extern) .@"extern" else .auto,4073 .layout = if (flags.is_extern) .@"extern" else .auto,
4121 .field_names = names,4074 .field_names = names,
4122 .field_types = field_types,4075 .field_types = field_types,
...@@ -4178,9 +4131,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -4178,9 +4131,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
4178 .tid = unwrapped_index.tid,4131 .tid = unwrapped_index.tid,
4179 .extra_index = item.data,4132 .extra_index = item.data,
4180 .name = name,4133 .name = name,
4181 .cau = cau.toOptional(),4134 .cau = cau,
4182 .namespace = namespace.toOptional(),4135 .namespace = namespace,
4183 .zir_index = zir_index.toOptional(),4136 .zir_index = zir_index,
4184 .layout = .@"packed",4137 .layout = .@"packed",
4185 .field_names = field_names,4138 .field_names = field_names,
4186 .field_types = field_types,4139 .field_types = field_types,
...@@ -4407,9 +4360,9 @@ pub const Item = struct {...@@ -4407,9 +4360,9 @@ pub const Item = struct {
4407/// `primitives` in AstGen.zig.4360/// `primitives` in AstGen.zig.
4408pub const Index = enum(u32) {4361pub const Index = enum(u32) {
4409 pub const first_type: Index = .u0_type;4362 pub const first_type: Index = .u0_type;
4410 pub const last_type: Index = .empty_struct_type;4363 pub const last_type: Index = .empty_tuple_type;
4411 pub const first_value: Index = .undef;4364 pub const first_value: Index = .undef;
4412 pub const last_value: Index = .empty_struct;4365 pub const last_value: Index = .empty_tuple;
44134366
4414 u0_type,4367 u0_type,
4415 i0_type,4368 i0_type,
...@@ -4466,8 +4419,9 @@ pub const Index = enum(u32) {...@@ -4466,8 +4419,9 @@ pub const Index = enum(u32) {
4466 /// Used for the inferred error set of inline/comptime function calls.4419 /// Used for the inferred error set of inline/comptime function calls.
4467 adhoc_inferred_error_set_type,4420 adhoc_inferred_error_set_type,
4468 generic_poison_type,4421 generic_poison_type,
4469 /// `@TypeOf(.{})`4422 /// `@TypeOf(.{})`; a tuple with zero elements.
4470 empty_struct_type,4423 /// This is not the same as `struct {}`, since that is a struct rather than a tuple.
4424 empty_tuple_type,
44714425
4472 /// `undefined` (untyped)4426 /// `undefined` (untyped)
4473 undef,4427 undef,
...@@ -4497,8 +4451,8 @@ pub const Index = enum(u32) {...@@ -4497,8 +4451,8 @@ pub const Index = enum(u32) {
4497 bool_true,4451 bool_true,
4498 /// `false`4452 /// `false`
4499 bool_false,4453 bool_false,
4500 /// `.{}` (untyped)4454 /// `.{}`
4501 empty_struct,4455 empty_tuple,
45024456
4503 /// Used for generic parameters where the type and value4457 /// Used for generic parameters where the type and value
4504 /// is not known until generic function instantiation.4458 /// is not known until generic function instantiation.
...@@ -4606,16 +4560,14 @@ pub const Index = enum(u32) {...@@ -4606,16 +4560,14 @@ pub const Index = enum(u32) {
4606 values: []Index,4560 values: []Index,
4607 },4561 },
4608 };4562 };
4609 const DataIsExtraIndexOfTypeStructAnon = struct {4563 const DataIsExtraIndexOfTypeTuple = struct {
4610 const @"data.fields_len" = opaque {};4564 const @"data.fields_len" = opaque {};
4611 data: *TypeStructAnon,4565 data: *TypeTuple,
4612 @"trailing.types.len": *@"data.fields_len",4566 @"trailing.types.len": *@"data.fields_len",
4613 @"trailing.values.len": *@"data.fields_len",4567 @"trailing.values.len": *@"data.fields_len",
4614 @"trailing.names.len": *@"data.fields_len",
4615 trailing: struct {4568 trailing: struct {
4616 types: []Index,4569 types: []Index,
4617 values: []Index,4570 values: []Index,
4618 names: []NullTerminatedString,
4619 },4571 },
4620 };4572 };
46214573
...@@ -4649,10 +4601,9 @@ pub const Index = enum(u32) {...@@ -4649,10 +4601,9 @@ pub const Index = enum(u32) {
4649 simple_type: void,4601 simple_type: void,
4650 type_opaque: struct { data: *Tag.TypeOpaque },4602 type_opaque: struct { data: *Tag.TypeOpaque },
4651 type_struct: struct { data: *Tag.TypeStruct },4603 type_struct: struct { data: *Tag.TypeStruct },
4652 type_struct_anon: DataIsExtraIndexOfTypeStructAnon,
4653 type_struct_packed: struct { data: *Tag.TypeStructPacked },4604 type_struct_packed: struct { data: *Tag.TypeStructPacked },
4654 type_struct_packed_inits: struct { data: *Tag.TypeStructPacked },4605 type_struct_packed_inits: struct { data: *Tag.TypeStructPacked },
4655 type_tuple_anon: DataIsExtraIndexOfTypeStructAnon,4606 type_tuple: DataIsExtraIndexOfTypeTuple,
4656 type_union: struct { data: *Tag.TypeUnion },4607 type_union: struct { data: *Tag.TypeUnion },
4657 type_function: struct {4608 type_function: struct {
4658 const @"data.flags.has_comptime_bits" = opaque {};4609 const @"data.flags.has_comptime_bits" = opaque {};
...@@ -4936,11 +4887,10 @@ pub const static_keys = [_]Key{...@@ -4936,11 +4887,10 @@ pub const static_keys = [_]Key{
4936 // generic_poison_type4887 // generic_poison_type
4937 .{ .simple_type = .generic_poison },4888 .{ .simple_type = .generic_poison },
49384889
4939 // empty_struct_type4890 // empty_tuple_type
4940 .{ .anon_struct_type = .{4891 .{ .tuple_type = .{
4941 .types = Index.Slice.empty,4892 .types = .empty,
4942 .names = NullTerminatedString.Slice.empty,4893 .values = .empty,
4943 .values = Index.Slice.empty,
4944 } },4894 } },
49454895
4946 .{ .simple_value = .undefined },4896 .{ .simple_value = .undefined },
...@@ -4991,7 +4941,7 @@ pub const static_keys = [_]Key{...@@ -4991,7 +4941,7 @@ pub const static_keys = [_]Key{
4991 .{ .simple_value = .null },4941 .{ .simple_value = .null },
4992 .{ .simple_value = .true },4942 .{ .simple_value = .true },
4993 .{ .simple_value = .false },4943 .{ .simple_value = .false },
4994 .{ .simple_value = .empty_struct },4944 .{ .simple_value = .empty_tuple },
4995 .{ .simple_value = .generic_poison },4945 .{ .simple_value = .generic_poison },
4996};4946};
49974947
...@@ -5071,20 +5021,16 @@ pub const Tag = enum(u8) {...@@ -5071,20 +5021,16 @@ pub const Tag = enum(u8) {
5071 type_opaque,5021 type_opaque,
5072 /// A non-packed struct type.5022 /// A non-packed struct type.
5073 /// data is 0 or extra index of `TypeStruct`.5023 /// data is 0 or extra index of `TypeStruct`.
5074 /// data == 0 represents `@TypeOf(.{})`.
5075 type_struct,5024 type_struct,
5076 /// An AnonStructType which stores types, names, and values for fields.
5077 /// data is extra index of `TypeStructAnon`.
5078 type_struct_anon,
5079 /// A packed struct, no fields have any init values.5025 /// A packed struct, no fields have any init values.
5080 /// data is extra index of `TypeStructPacked`.5026 /// data is extra index of `TypeStructPacked`.
5081 type_struct_packed,5027 type_struct_packed,
5082 /// A packed struct, one or more fields have init values.5028 /// A packed struct, one or more fields have init values.
5083 /// data is extra index of `TypeStructPacked`.5029 /// data is extra index of `TypeStructPacked`.
5084 type_struct_packed_inits,5030 type_struct_packed_inits,
5085 /// An AnonStructType which has only types and values for fields.5031 /// A `TupleType`.
5086 /// data is extra index of `TypeStructAnon`.5032 /// data is extra index of `TypeTuple`.
5087 type_tuple_anon,5033 type_tuple,
5088 /// A union type.5034 /// A union type.
5089 /// `data` is extra index of `TypeUnion`.5035 /// `data` is extra index of `TypeUnion`.
5090 type_union,5036 type_union,
...@@ -5299,9 +5245,8 @@ pub const Tag = enum(u8) {...@@ -5299,9 +5245,8 @@ pub const Tag = enum(u8) {
5299 .simple_type => unreachable,5245 .simple_type => unreachable,
5300 .type_opaque => TypeOpaque,5246 .type_opaque => TypeOpaque,
5301 .type_struct => TypeStruct,5247 .type_struct => TypeStruct,
5302 .type_struct_anon => TypeStructAnon,
5303 .type_struct_packed, .type_struct_packed_inits => TypeStructPacked,5248 .type_struct_packed, .type_struct_packed_inits => TypeStructPacked,
5304 .type_tuple_anon => TypeStructAnon,5249 .type_tuple => TypeTuple,
5305 .type_union => TypeUnion,5250 .type_union => TypeUnion,
5306 .type_function => TypeFunction,5251 .type_function => TypeFunction,
53075252
...@@ -5546,18 +5491,15 @@ pub const Tag = enum(u8) {...@@ -5546,18 +5491,15 @@ pub const Tag = enum(u8) {
5546 /// 1. capture: CaptureValue // for each `captures_len`5491 /// 1. capture: CaptureValue // for each `captures_len`
5547 /// 2. type_hash: PackedU64 // if `is_reified`5492 /// 2. type_hash: PackedU64 // if `is_reified`
5548 /// 3. type: Index for each field in declared order5493 /// 3. type: Index for each field in declared order
5549 /// 4. if not is_tuple:5494 /// 4. if any_default_inits:
5550 /// names_map: MapIndex,
5551 /// name: NullTerminatedString // for each field in declared order
5552 /// 5. if any_default_inits:
5553 /// init: Index // for each field in declared order5495 /// init: Index // for each field in declared order
5554 /// 6. if any_aligned_fields:5496 /// 5. if any_aligned_fields:
5555 /// align: Alignment // for each field in declared order5497 /// align: Alignment // for each field in declared order
5556 /// 7. if any_comptime_fields:5498 /// 6. if any_comptime_fields:
5557 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 05499 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0
5558 /// 8. if not is_extern:5500 /// 7. if not is_extern:
5559 /// field_index: RuntimeOrder // for each field in runtime order5501 /// field_index: RuntimeOrder // for each field in runtime order
5560 /// 9. field_offset: u32 // for each field in declared order, undef until layout_resolved5502 /// 8. field_offset: u32 // for each field in declared order, undef until layout_resolved
5561 pub const TypeStruct = struct {5503 pub const TypeStruct = struct {
5562 name: NullTerminatedString,5504 name: NullTerminatedString,
5563 cau: Cau.Index,5505 cau: Cau.Index,
...@@ -5572,7 +5514,6 @@ pub const Tag = enum(u8) {...@@ -5572,7 +5514,6 @@ pub const Tag = enum(u8) {
5572 is_extern: bool = false,5514 is_extern: bool = false,
5573 known_non_opv: bool = false,5515 known_non_opv: bool = false,
5574 requires_comptime: RequiresComptime = @enumFromInt(0),5516 requires_comptime: RequiresComptime = @enumFromInt(0),
5575 is_tuple: bool = false,
5576 assumed_runtime_bits: bool = false,5517 assumed_runtime_bits: bool = false,
5577 assumed_pointer_aligned: bool = false,5518 assumed_pointer_aligned: bool = false,
5578 any_comptime_fields: bool = false,5519 any_comptime_fields: bool = false,
...@@ -5597,7 +5538,7 @@ pub const Tag = enum(u8) {...@@ -5597,7 +5538,7 @@ pub const Tag = enum(u8) {
5597 // which `layout_resolved` does not ensure.5538 // which `layout_resolved` does not ensure.
5598 fully_resolved: bool = false,5539 fully_resolved: bool = false,
5599 is_reified: bool = false,5540 is_reified: bool = false,
5600 _: u7 = 0,5541 _: u8 = 0,
5601 };5542 };
5602 };5543 };
56035544
...@@ -5659,9 +5600,7 @@ pub const Repeated = struct {...@@ -5659,9 +5600,7 @@ pub const Repeated = struct {
5659/// Trailing:5600/// Trailing:
5660/// 0. type: Index for each fields_len5601/// 0. type: Index for each fields_len
5661/// 1. value: Index for each fields_len5602/// 1. value: Index for each fields_len
5662/// 2. name: NullTerminatedString for each fields_len5603pub const TypeTuple = struct {
5663/// The set of field names is omitted when the `Tag` is `type_tuple_anon`.
5664pub const TypeStructAnon = struct {
5665 fields_len: u32,5604 fields_len: u32,
5666};5605};
56675606
...@@ -5708,8 +5647,8 @@ pub const SimpleValue = enum(u32) {...@@ -5708,8 +5647,8 @@ pub const SimpleValue = enum(u32) {
5708 void = @intFromEnum(Index.void_value),5647 void = @intFromEnum(Index.void_value),
5709 /// This is untyped `null`.5648 /// This is untyped `null`.
5710 null = @intFromEnum(Index.null_value),5649 null = @intFromEnum(Index.null_value),
5711 /// This is the untyped empty struct literal: `.{}`5650 /// This is the untyped empty struct/array literal: `.{}`
5712 empty_struct = @intFromEnum(Index.empty_struct),5651 empty_tuple = @intFromEnum(Index.empty_tuple),
5713 true = @intFromEnum(Index.bool_true),5652 true = @intFromEnum(Index.bool_true),
5714 false = @intFromEnum(Index.bool_false),5653 false = @intFromEnum(Index.bool_false),
5715 @"unreachable" = @intFromEnum(Index.unreachable_value),5654 @"unreachable" = @intFromEnum(Index.unreachable_value),
...@@ -6266,11 +6205,10 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -6266,11 +6205,10 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
6266 // This inserts all the statically-known values into the intern pool in the6205 // This inserts all the statically-known values into the intern pool in the
6267 // order expected.6206 // order expected.
6268 for (&static_keys, 0..) |key, key_index| switch (@as(Index, @enumFromInt(key_index))) {6207 for (&static_keys, 0..) |key, key_index| switch (@as(Index, @enumFromInt(key_index))) {
6269 .empty_struct_type => assert(try ip.getAnonStructType(gpa, .main, .{6208 .empty_tuple_type => assert(try ip.getTupleType(gpa, .main, .{
6270 .types = &.{},6209 .types = &.{},
6271 .names = &.{},
6272 .values = &.{},6210 .values = &.{},
6273 }) == .empty_struct_type),6211 }) == .empty_tuple_type),
6274 else => |expected_index| assert(try ip.get(gpa, .main, key) == expected_index),6212 else => |expected_index| assert(try ip.get(gpa, .main, key) == expected_index),
6275 };6213 };
62766214
...@@ -6412,7 +6350,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6412,7 +6350,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6412 } },6350 } },
64136351
6414 .type_struct => .{ .struct_type = ns: {6352 .type_struct => .{ .struct_type = ns: {
6415 if (data == 0) break :ns .empty_struct;
6416 const extra_list = unwrapped_index.getExtra(ip);6353 const extra_list = unwrapped_index.getExtra(ip);
6417 const extra_items = extra_list.view().items(.@"0");6354 const extra_items = extra_list.view().items(.@"0");
6418 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);6355 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
...@@ -6457,8 +6394,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6457,8 +6394,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6457 } else CaptureValue.Slice.empty },6394 } else CaptureValue.Slice.empty },
6458 } };6395 } };
6459 } },6396 } },
6460 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },6397 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6461 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6462 .type_union => .{ .union_type = ns: {6398 .type_union => .{ .union_type = ns: {
6463 const extra_list = unwrapped_index.getExtra(ip);6399 const extra_list = unwrapped_index.getExtra(ip);
6464 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);6400 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
...@@ -6764,10 +6700,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6764,10 +6700,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
67646700
6765 // There is only one possible value precisely due to the6701 // There is only one possible value precisely due to the
6766 // fact that this values slice is fully populated!6702 // fact that this values slice is fully populated!
6767 .type_struct_anon, .type_tuple_anon => {6703 .type_tuple => {
6768 const type_struct_anon = extraDataTrail(ty_extra, TypeStructAnon, ty_item.data);6704 const type_tuple = extraDataTrail(ty_extra, TypeTuple, ty_item.data);
6769 const fields_len = type_struct_anon.data.fields_len;6705 const fields_len = type_tuple.data.fields_len;
6770 const values = ty_extra.view().items(.@"0")[type_struct_anon.end + fields_len ..][0..fields_len];6706 const values = ty_extra.view().items(.@"0")[type_tuple.end + fields_len ..][0..fields_len];
6771 return .{ .aggregate = .{6707 return .{ .aggregate = .{
6772 .ty = ty,6708 .ty = ty,
6773 .storage = .{ .elems = @ptrCast(values) },6709 .storage = .{ .elems = @ptrCast(values) },
...@@ -6850,47 +6786,20 @@ fn extraErrorSet(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke...@@ -6850,47 +6786,20 @@ fn extraErrorSet(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
6850 };6786 };
6851}6787}
68526788
6853fn extraTypeStructAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {6789fn extraTypeTuple(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.TupleType {
6854 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);6790 const type_tuple = extraDataTrail(extra, TypeTuple, extra_index);
6855 const fields_len = type_struct_anon.data.fields_len;6791 const fields_len = type_tuple.data.fields_len;
6856 return .{6792 return .{
6857 .types = .{6793 .types = .{
6858 .tid = tid,6794 .tid = tid,
6859 .start = type_struct_anon.end,6795 .start = type_tuple.end,
6860 .len = fields_len,6796 .len = fields_len,
6861 },6797 },
6862 .values = .{6798 .values = .{
6863 .tid = tid,6799 .tid = tid,
6864 .start = type_struct_anon.end + fields_len,6800 .start = type_tuple.end + fields_len,
6865 .len = fields_len,6801 .len = fields_len,
6866 },6802 },
6867 .names = .{
6868 .tid = tid,
6869 .start = type_struct_anon.end + fields_len + fields_len,
6870 .len = fields_len,
6871 },
6872 };
6873}
6874
6875fn extraTypeTupleAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
6876 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
6877 const fields_len = type_struct_anon.data.fields_len;
6878 return .{
6879 .types = .{
6880 .tid = tid,
6881 .start = type_struct_anon.end,
6882 .len = fields_len,
6883 },
6884 .values = .{
6885 .tid = tid,
6886 .start = type_struct_anon.end + fields_len,
6887 .len = fields_len,
6888 },
6889 .names = .{
6890 .tid = tid,
6891 .start = 0,
6892 .len = 0,
6893 },
6894 };6803 };
6895}6804}
68966805
...@@ -7361,7 +7270,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7361,7 +7270,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7361 },7270 },
73627271
7363 .struct_type => unreachable, // use getStructType() instead7272 .struct_type => unreachable, // use getStructType() instead
7364 .anon_struct_type => unreachable, // use getAnonStructType() instead7273 .tuple_type => unreachable, // use getTupleType() instead
7365 .union_type => unreachable, // use getUnionType() instead7274 .union_type => unreachable, // use getUnionType() instead
7366 .opaque_type => unreachable, // use getOpaqueType() instead7275 .opaque_type => unreachable, // use getOpaqueType() instead
73677276
...@@ -7469,9 +7378,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7469,9 +7378,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7469 .field => {7378 .field => {
7470 assert(base_ptr_type.flags.size == .One);7379 assert(base_ptr_type.flags.size == .One);
7471 switch (ip.indexToKey(base_ptr_type.child)) {7380 switch (ip.indexToKey(base_ptr_type.child)) {
7472 .anon_struct_type => |anon_struct_type| {7381 .tuple_type => |tuple_type| {
7473 assert(ptr.base_addr == .field);7382 assert(ptr.base_addr == .field);
7474 assert(base_index.index < anon_struct_type.types.len);7383 assert(base_index.index < tuple_type.types.len);
7475 },7384 },
7476 .struct_type => {7385 .struct_type => {
7477 assert(ptr.base_addr == .field);7386 assert(ptr.base_addr == .field);
...@@ -7808,12 +7717,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7808,12 +7717,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7808 const child = switch (ty_key) {7717 const child = switch (ty_key) {
7809 .array_type => |array_type| array_type.child,7718 .array_type => |array_type| array_type.child,
7810 .vector_type => |vector_type| vector_type.child,7719 .vector_type => |vector_type| vector_type.child,
7811 .anon_struct_type, .struct_type => .none,7720 .tuple_type, .struct_type => .none,
7812 else => unreachable,7721 else => unreachable,
7813 };7722 };
7814 const sentinel = switch (ty_key) {7723 const sentinel = switch (ty_key) {
7815 .array_type => |array_type| array_type.sentinel,7724 .array_type => |array_type| array_type.sentinel,
7816 .vector_type, .anon_struct_type, .struct_type => .none,7725 .vector_type, .tuple_type, .struct_type => .none,
7817 else => unreachable,7726 else => unreachable,
7818 };7727 };
7819 const len_including_sentinel = len + @intFromBool(sentinel != .none);7728 const len_including_sentinel = len + @intFromBool(sentinel != .none);
...@@ -7845,8 +7754,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7845,8 +7754,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7845 assert(ip.typeOf(elem) == field_ty);7754 assert(ip.typeOf(elem) == field_ty);
7846 }7755 }
7847 },7756 },
7848 .anon_struct_type => |anon_struct_type| {7757 .tuple_type => |tuple_type| {
7849 for (aggregate.storage.values(), anon_struct_type.types.get(ip)) |elem, ty| {7758 for (aggregate.storage.values(), tuple_type.types.get(ip)) |elem, ty| {
7850 assert(ip.typeOf(elem) == ty);7759 assert(ip.typeOf(elem) == ty);
7851 }7760 }
7852 },7761 },
...@@ -7862,9 +7771,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7862,9 +7771,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7862 }7771 }
78637772
7864 switch (ty_key) {7773 switch (ty_key) {
7865 .anon_struct_type => |anon_struct_type| opv: {7774 .tuple_type => |tuple_type| opv: {
7866 switch (aggregate.storage) {7775 switch (aggregate.storage) {
7867 .bytes => |bytes| for (anon_struct_type.values.get(ip), bytes.at(0, ip)..) |value, byte| {7776 .bytes => |bytes| for (tuple_type.values.get(ip), bytes.at(0, ip)..) |value, byte| {
7868 if (value == .none) break :opv;7777 if (value == .none) break :opv;
7869 switch (ip.indexToKey(value)) {7778 switch (ip.indexToKey(value)) {
7870 .undef => break :opv,7779 .undef => break :opv,
...@@ -7877,10 +7786,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7877,10 +7786,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7877 },7786 },
7878 .elems => |elems| if (!std.mem.eql(7787 .elems => |elems| if (!std.mem.eql(
7879 Index,7788 Index,
7880 anon_struct_type.values.get(ip),7789 tuple_type.values.get(ip),
7881 elems,7790 elems,
7882 )) break :opv,7791 )) break :opv,
7883 .repeated_elem => |elem| for (anon_struct_type.values.get(ip)) |value| {7792 .repeated_elem => |elem| for (tuple_type.values.get(ip)) |value| {
7884 if (value != elem) break :opv;7793 if (value != elem) break :opv;
7885 },7794 },
7886 }7795 }
...@@ -8244,7 +8153,6 @@ pub const StructTypeInit = struct {...@@ -8244,7 +8153,6 @@ pub const StructTypeInit = struct {
8244 fields_len: u32,8153 fields_len: u32,
8245 known_non_opv: bool,8154 known_non_opv: bool,
8246 requires_comptime: RequiresComptime,8155 requires_comptime: RequiresComptime,
8247 is_tuple: bool,
8248 any_comptime_fields: bool,8156 any_comptime_fields: bool,
8249 any_default_inits: bool,8157 any_default_inits: bool,
8250 inits_resolved: bool,8158 inits_resolved: bool,
...@@ -8404,7 +8312,6 @@ pub fn getStructType(...@@ -8404,7 +8312,6 @@ pub fn getStructType(
8404 .is_extern = is_extern,8312 .is_extern = is_extern,
8405 .known_non_opv = ini.known_non_opv,8313 .known_non_opv = ini.known_non_opv,
8406 .requires_comptime = ini.requires_comptime,8314 .requires_comptime = ini.requires_comptime,
8407 .is_tuple = ini.is_tuple,
8408 .assumed_runtime_bits = false,8315 .assumed_runtime_bits = false,
8409 .assumed_pointer_aligned = false,8316 .assumed_pointer_aligned = false,
8410 .any_comptime_fields = ini.any_comptime_fields,8317 .any_comptime_fields = ini.any_comptime_fields,
...@@ -8442,10 +8349,8 @@ pub fn getStructType(...@@ -8442,10 +8349,8 @@ pub fn getStructType(
8442 },8349 },
8443 }8350 }
8444 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);8351 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
8445 if (!ini.is_tuple) {8352 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
8446 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});8353 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
8447 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
8448 }
8449 if (ini.any_default_inits) {8354 if (ini.any_default_inits) {
8450 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);8355 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
8451 }8356 }
...@@ -8468,19 +8373,17 @@ pub fn getStructType(...@@ -8468,19 +8373,17 @@ pub fn getStructType(
8468 } };8373 } };
8469}8374}
84708375
8471pub const AnonStructTypeInit = struct {8376pub const TupleTypeInit = struct {
8472 types: []const Index,8377 types: []const Index,
8473 /// This may be empty, indicating this is a tuple.
8474 names: []const NullTerminatedString,
8475 /// These elements may be `none`, indicating runtime-known.8378 /// These elements may be `none`, indicating runtime-known.
8476 values: []const Index,8379 values: []const Index,
8477};8380};
84788381
8479pub fn getAnonStructType(8382pub fn getTupleType(
8480 ip: *InternPool,8383 ip: *InternPool,
8481 gpa: Allocator,8384 gpa: Allocator,
8482 tid: Zcu.PerThread.Id,8385 tid: Zcu.PerThread.Id,
8483 ini: AnonStructTypeInit,8386 ini: TupleTypeInit,
8484) Allocator.Error!Index {8387) Allocator.Error!Index {
8485 assert(ini.types.len == ini.values.len);8388 assert(ini.types.len == ini.values.len);
8486 for (ini.types) |elem| assert(elem != .none);8389 for (ini.types) |elem| assert(elem != .none);
...@@ -8494,23 +8397,17 @@ pub fn getAnonStructType(...@@ -8494,23 +8397,17 @@ pub fn getAnonStructType(
84948397
8495 try items.ensureUnusedCapacity(1);8398 try items.ensureUnusedCapacity(1);
8496 try extra.ensureUnusedCapacity(8399 try extra.ensureUnusedCapacity(
8497 @typeInfo(TypeStructAnon).@"struct".fields.len + (fields_len * 3),8400 @typeInfo(TypeTuple).@"struct".fields.len + (fields_len * 3),
8498 );8401 );
84998402
8500 const extra_index = addExtraAssumeCapacity(extra, TypeStructAnon{8403 const extra_index = addExtraAssumeCapacity(extra, TypeTuple{
8501 .fields_len = fields_len,8404 .fields_len = fields_len,
8502 });8405 });
8503 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.types)});8406 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.types)});
8504 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});8407 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
8505 errdefer extra.mutate.len = prev_extra_len;8408 errdefer extra.mutate.len = prev_extra_len;
85068409
8507 var gop = try ip.getOrPutKey(gpa, tid, .{8410 var gop = try ip.getOrPutKey(gpa, tid, .{ .tuple_type = extraTypeTuple(tid, extra.list.*, extra_index) });
8508 .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(tid, extra.list.*, extra_index) else k: {
8509 assert(ini.names.len == ini.types.len);
8510 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
8511 break :k extraTypeStructAnon(tid, extra.list.*, extra_index);
8512 },
8513 });
8514 defer gop.deinit();8411 defer gop.deinit();
8515 if (gop == .existing) {8412 if (gop == .existing) {
8516 extra.mutate.len = prev_extra_len;8413 extra.mutate.len = prev_extra_len;
...@@ -8518,7 +8415,7 @@ pub fn getAnonStructType(...@@ -8518,7 +8415,7 @@ pub fn getAnonStructType(
8518 }8415 }
85198416
8520 items.appendAssumeCapacity(.{8417 items.appendAssumeCapacity(.{
8521 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,8418 .tag = .type_tuple,
8522 .data = extra_index,8419 .data = extra_index,
8523 });8420 });
8524 return gop.put();8421 return gop.put();
...@@ -10181,12 +10078,12 @@ pub fn getCoerced(...@@ -10181,12 +10078,12 @@ pub fn getCoerced(
10181 direct: {10078 direct: {
10182 const old_ty_child = switch (ip.indexToKey(old_ty)) {10079 const old_ty_child = switch (ip.indexToKey(old_ty)) {
10183 inline .array_type, .vector_type => |seq_type| seq_type.child,10080 inline .array_type, .vector_type => |seq_type| seq_type.child,
10184 .anon_struct_type, .struct_type => break :direct,10081 .tuple_type, .struct_type => break :direct,
10185 else => unreachable,10082 else => unreachable,
10186 };10083 };
10187 const new_ty_child = switch (ip.indexToKey(new_ty)) {10084 const new_ty_child = switch (ip.indexToKey(new_ty)) {
10188 inline .array_type, .vector_type => |seq_type| seq_type.child,10085 inline .array_type, .vector_type => |seq_type| seq_type.child,
10189 .anon_struct_type, .struct_type => break :direct,10086 .tuple_type, .struct_type => break :direct,
10190 else => unreachable,10087 else => unreachable,
10191 };10088 };
10192 if (old_ty_child != new_ty_child) break :direct;10089 if (old_ty_child != new_ty_child) break :direct;
...@@ -10235,7 +10132,7 @@ pub fn getCoerced(...@@ -10235,7 +10132,7 @@ pub fn getCoerced(
10235 for (agg_elems, 0..) |*elem, i| {10132 for (agg_elems, 0..) |*elem, i| {
10236 const new_elem_ty = switch (ip.indexToKey(new_ty)) {10133 const new_elem_ty = switch (ip.indexToKey(new_ty)) {
10237 inline .array_type, .vector_type => |seq_type| seq_type.child,10134 inline .array_type, .vector_type => |seq_type| seq_type.child,
10238 .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[i],10135 .tuple_type => |tuple_type| tuple_type.types.get(ip)[i],
10239 .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i],10136 .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i],
10240 else => unreachable,10137 else => unreachable,
10241 };10138 };
...@@ -10425,7 +10322,7 @@ pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {...@@ -10425,7 +10322,7 @@ pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {
1042510322
10426pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {10323pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {
10427 return switch (ip.indexToKey(ty)) {10324 return switch (ip.indexToKey(ty)) {
10428 .array_type, .vector_type, .anon_struct_type, .struct_type => true,10325 .array_type, .vector_type, .tuple_type, .struct_type => true,
10429 else => false,10326 else => false,
10430 };10327 };
10431}10328}
...@@ -10549,7 +10446,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10549,7 +10446,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10549 break :b @sizeOf(u32) * ints;10446 break :b @sizeOf(u32) * ints;
10550 },10447 },
10551 .type_struct => b: {10448 .type_struct => b: {
10552 if (data == 0) break :b 0;
10553 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);10449 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
10554 const info = extra.data;10450 const info = extra.data;
10555 var ints: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;10451 var ints: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
...@@ -10558,10 +10454,8 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10558,10 +10454,8 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10558 ints += 1 + captures_len;10454 ints += 1 + captures_len;
10559 }10455 }
10560 ints += info.fields_len; // types10456 ints += info.fields_len; // types
10561 if (!info.flags.is_tuple) {10457 ints += 1; // names_map
10562 ints += 1; // names_map10458 ints += info.fields_len; // names
10563 ints += info.fields_len; // names
10564 }
10565 if (info.flags.any_default_inits)10459 if (info.flags.any_default_inits)
10566 ints += info.fields_len; // inits10460 ints += info.fields_len; // inits
10567 if (info.flags.any_aligned_fields)10461 if (info.flags.any_aligned_fields)
...@@ -10573,10 +10467,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10573,10 +10467,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10573 ints += info.fields_len; // offsets10467 ints += info.fields_len; // offsets
10574 break :b @sizeOf(u32) * ints;10468 break :b @sizeOf(u32) * ints;
10575 },10469 },
10576 .type_struct_anon => b: {
10577 const info = extraData(extra_list, TypeStructAnon, data);
10578 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
10579 },
10580 .type_struct_packed => b: {10470 .type_struct_packed => b: {
10581 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);10471 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
10582 const captures_len = if (extra.data.flags.any_captures)10472 const captures_len = if (extra.data.flags.any_captures)
...@@ -10597,9 +10487,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10597,9 +10487,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10597 @intFromBool(extra.data.flags.any_captures) + captures_len +10487 @intFromBool(extra.data.flags.any_captures) + captures_len +
10598 extra.data.fields_len * 3);10488 extra.data.fields_len * 3);
10599 },10489 },
10600 .type_tuple_anon => b: {10490 .type_tuple => b: {
10601 const info = extraData(extra_list, TypeStructAnon, data);10491 const info = extraData(extra_list, TypeTuple, data);
10602 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);10492 break :b @sizeOf(TypeTuple) + (@sizeOf(u32) * 2 * info.fields_len);
10603 },10493 },
1060410494
10605 .type_union => b: {10495 .type_union => b: {
...@@ -10760,10 +10650,9 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -10760,10 +10650,9 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
10760 .type_enum_auto,10650 .type_enum_auto,
10761 .type_opaque,10651 .type_opaque,
10762 .type_struct,10652 .type_struct,
10763 .type_struct_anon,
10764 .type_struct_packed,10653 .type_struct_packed,
10765 .type_struct_packed_inits,10654 .type_struct_packed_inits,
10766 .type_tuple_anon,10655 .type_tuple,
10767 .type_union,10656 .type_union,
10768 .type_function,10657 .type_function,
10769 .undef,10658 .undef,
...@@ -11396,7 +11285,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -11396,7 +11285,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
11396 .anyerror_void_error_union_type,11285 .anyerror_void_error_union_type,
11397 .adhoc_inferred_error_set_type,11286 .adhoc_inferred_error_set_type,
11398 .generic_poison_type,11287 .generic_poison_type,
11399 .empty_struct_type,11288 .empty_tuple_type,
11400 => .type_type,11289 => .type_type,
1140111290
11402 .undef => .undefined_type,11291 .undef => .undefined_type,
...@@ -11407,7 +11296,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -11407,7 +11296,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
11407 .unreachable_value => .noreturn_type,11296 .unreachable_value => .noreturn_type,
11408 .null_value => .null_type,11297 .null_value => .null_type,
11409 .bool_true, .bool_false => .bool_type,11298 .bool_true, .bool_false => .bool_type,
11410 .empty_struct => .empty_struct_type,11299 .empty_tuple => .empty_tuple_type,
11411 .generic_poison => .generic_poison_type,11300 .generic_poison => .generic_poison_type,
1141211301
11413 // This optimization on tags is needed so that indexToKey can call11302 // This optimization on tags is needed so that indexToKey can call
...@@ -11436,10 +11325,9 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -11436,10 +11325,9 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
11436 .type_enum_nonexhaustive,11325 .type_enum_nonexhaustive,
11437 .type_opaque,11326 .type_opaque,
11438 .type_struct,11327 .type_struct,
11439 .type_struct_anon,
11440 .type_struct_packed,11328 .type_struct_packed,
11441 .type_struct_packed_inits,11329 .type_struct_packed_inits,
11442 .type_tuple_anon,11330 .type_tuple,
11443 .type_union,11331 .type_union,
11444 .type_function,11332 .type_function,
11445 => .type_type,11333 => .type_type,
...@@ -11533,7 +11421,7 @@ pub fn toEnum(ip: *const InternPool, comptime E: type, i: Index) E {...@@ -11533,7 +11421,7 @@ pub fn toEnum(ip: *const InternPool, comptime E: type, i: Index) E {
11533pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {11421pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {
11534 return switch (ip.indexToKey(ty)) {11422 return switch (ip.indexToKey(ty)) {
11535 .struct_type => ip.loadStructType(ty).field_types.len,11423 .struct_type => ip.loadStructType(ty).field_types.len,
11536 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,11424 .tuple_type => |tuple_type| tuple_type.types.len,
11537 .array_type => |array_type| array_type.len,11425 .array_type => |array_type| array_type.len,
11538 .vector_type => |vector_type| vector_type.len,11426 .vector_type => |vector_type| vector_type.len,
11539 else => unreachable,11427 else => unreachable,
...@@ -11543,7 +11431,7 @@ pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {...@@ -11543,7 +11431,7 @@ pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {
11543pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {11431pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
11544 return switch (ip.indexToKey(ty)) {11432 return switch (ip.indexToKey(ty)) {
11545 .struct_type => ip.loadStructType(ty).field_types.len,11433 .struct_type => ip.loadStructType(ty).field_types.len,
11546 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,11434 .tuple_type => |tuple_type| tuple_type.types.len,
11547 .array_type => |array_type| array_type.lenIncludingSentinel(),11435 .array_type => |array_type| array_type.lenIncludingSentinel(),
11548 .vector_type => |vector_type| vector_type.len,11436 .vector_type => |vector_type| vector_type.len,
11549 else => unreachable,11437 else => unreachable,
...@@ -11708,7 +11596,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11708,7 +11596,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1170811596
11709 .optional_noreturn_type => .optional,11597 .optional_noreturn_type => .optional,
11710 .anyerror_void_error_union_type => .error_union,11598 .anyerror_void_error_union_type => .error_union,
11711 .empty_struct_type => .@"struct",11599 .empty_tuple_type => .@"struct",
1171211600
11713 .generic_poison_type => return error.GenericPoison,11601 .generic_poison_type => return error.GenericPoison,
1171411602
...@@ -11727,7 +11615,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11727,7 +11615,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
11727 .null_value => unreachable,11615 .null_value => unreachable,
11728 .bool_true => unreachable,11616 .bool_true => unreachable,
11729 .bool_false => unreachable,11617 .bool_false => unreachable,
11730 .empty_struct => unreachable,11618 .empty_tuple => unreachable,
11731 .generic_poison => unreachable,11619 .generic_poison => unreachable,
1173211620
11733 _ => switch (index.unwrap(ip).getTag(ip)) {11621 _ => switch (index.unwrap(ip).getTag(ip)) {
...@@ -11768,10 +11656,9 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11768,10 +11656,9 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
11768 .type_opaque => .@"opaque",11656 .type_opaque => .@"opaque",
1176911657
11770 .type_struct,11658 .type_struct,
11771 .type_struct_anon,
11772 .type_struct_packed,11659 .type_struct_packed,
11773 .type_struct_packed_inits,11660 .type_struct_packed_inits,
11774 .type_tuple_anon,11661 .type_tuple,
11775 => .@"struct",11662 => .@"struct",
1177611663
11777 .type_union => .@"union",11664 .type_union => .@"union",
...@@ -12013,14 +11900,6 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {...@@ -12013,14 +11900,6 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
12013 };11900 };
12014}11901}
1201511902
12016pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index {
12017 return ip.indexToKey(i).anon_struct_type.types;
12018}
12019
12020pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {
12021 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);
12022}
12023
12024/// Returns the already-existing field with the same name, if any.11903/// Returns the already-existing field with the same name, if any.
12025pub fn addFieldName(11904pub fn addFieldName(
12026 ip: *InternPool,11905 ip: *InternPool,
src/Sema.zig+384-424
...@@ -844,6 +844,7 @@ pub const Block = struct {...@@ -844,6 +844,7 @@ pub const Block = struct {
844844
845 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {845 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
846 const pt = block.sema.pt;846 const pt = block.sema.pt;
847 block.sema.code.assertTrackable(inst);
847 return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{848 return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{
848 .file = block.getFileScopeIndex(pt.zcu),849 .file = block.getFileScopeIndex(pt.zcu),
849 .inst = inst,850 .inst = inst,
...@@ -1277,6 +1278,7 @@ fn analyzeBodyInner(...@@ -1277,6 +1278,7 @@ fn analyzeBodyInner(
1277 .enum_decl => try sema.zirEnumDecl( block, extended, inst),1278 .enum_decl => try sema.zirEnumDecl( block, extended, inst),
1278 .union_decl => try sema.zirUnionDecl( block, extended, inst),1279 .union_decl => try sema.zirUnionDecl( block, extended, inst),
1279 .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst),1280 .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst),
1281 .tuple_decl => try sema.zirTupleDecl( block, extended),
1280 .this => try sema.zirThis( block, extended),1282 .this => try sema.zirThis( block, extended),
1281 .ret_addr => try sema.zirRetAddr( block, extended),1283 .ret_addr => try sema.zirRetAddr( block, extended),
1282 .builtin_src => try sema.zirBuiltinSrc( block, extended),1284 .builtin_src => try sema.zirBuiltinSrc( block, extended),
...@@ -2338,7 +2340,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS...@@ -2338,7 +2340,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
23382340
2339 const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg;2341 const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg;
2340 try sema.errNote(.{2342 try sema.errNote(.{
2341 .base_node_inst = struct_type.zir_index.unwrap().?,2343 .base_node_inst = struct_type.zir_index,
2342 .offset = .{ .container_field_value = @intCast(field_index) },2344 .offset = .{ .container_field_value = @intCast(field_index) },
2343 }, msg, "default value set here", .{});2345 }, msg, "default value set here", .{});
2344 break :msg msg;2346 break :msg msg;
...@@ -2651,6 +2653,94 @@ fn analyzeValueAsCallconv(...@@ -2651,6 +2653,94 @@ fn analyzeValueAsCallconv(
2651 };2653 };
2652}2654}
26532655
2656fn zirTupleDecl(
2657 sema: *Sema,
2658 block: *Block,
2659 extended: Zir.Inst.Extended.InstData,
2660) CompileError!Air.Inst.Ref {
2661 const gpa = sema.gpa;
2662 const pt = sema.pt;
2663 const zcu = pt.zcu;
2664 const fields_len = extended.small;
2665 const extra = sema.code.extraData(Zir.Inst.TupleDecl, extended.operand);
2666 var extra_index = extra.end;
2667
2668 const types = try sema.arena.alloc(InternPool.Index, fields_len);
2669 const inits = try sema.arena.alloc(InternPool.Index, fields_len);
2670
2671 const extra_as_refs: []const Zir.Inst.Ref = @ptrCast(sema.code.extra);
2672
2673 for (types, inits, 0..) |*field_ty, *field_init, field_index| {
2674 const zir_field_ty, const zir_field_init = extra_as_refs[extra_index..][0..2].*;
2675 extra_index += 2;
2676
2677 const type_src = block.src(.{ .tuple_field_type = .{
2678 .tuple_decl_node_offset = extra.data.src_node,
2679 .elem_index = @intCast(field_index),
2680 } });
2681 const init_src = block.src(.{ .tuple_field_init = .{
2682 .tuple_decl_node_offset = extra.data.src_node,
2683 .elem_index = @intCast(field_index),
2684 } });
2685
2686 const uncoerced_field_ty = try sema.resolveInst(zir_field_ty);
2687 const field_type = try sema.analyzeAsType(block, type_src, uncoerced_field_ty);
2688 try sema.validateTupleFieldType(block, field_type, type_src);
2689
2690 field_ty.* = field_type.toIntern();
2691 field_init.* = init: {
2692 if (zir_field_init != .none) {
2693 const uncoerced_field_init = try sema.resolveInst(zir_field_init);
2694 const coerced_field_init = try sema.coerce(block, field_type, uncoerced_field_init, init_src);
2695 const field_init_val = try sema.resolveConstDefinedValue(block, init_src, coerced_field_init, .{
2696 .needed_comptime_reason = "tuple field default value must be comptime-known",
2697 });
2698 if (field_init_val.canMutateComptimeVarState(zcu)) {
2699 return sema.fail(block, init_src, "field default value contains reference to comptime-mutable memory", .{});
2700 }
2701 break :init field_init_val.toIntern();
2702 }
2703 if (try sema.typeHasOnePossibleValue(field_type)) |opv| {
2704 break :init opv.toIntern();
2705 }
2706 break :init .none;
2707 };
2708 }
2709
2710 return Air.internedToRef(try zcu.intern_pool.getTupleType(gpa, pt.tid, .{
2711 .types = types,
2712 .values = inits,
2713 }));
2714}
2715
2716fn validateTupleFieldType(
2717 sema: *Sema,
2718 block: *Block,
2719 field_ty: Type,
2720 field_ty_src: LazySrcLoc,
2721) CompileError!void {
2722 const gpa = sema.gpa;
2723 const zcu = sema.pt.zcu;
2724 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
2725 return sema.failWithOwnedErrorMsg(block, msg: {
2726 const msg = try sema.errMsg(field_ty_src, "opaque types have unknown size and therefore cannot be directly embedded in tuples", .{});
2727 errdefer msg.destroy(gpa);
2728
2729 try sema.addDeclaredHereNote(msg, field_ty);
2730 break :msg msg;
2731 });
2732 }
2733 if (field_ty.zigTypeTag(zcu) == .noreturn) {
2734 return sema.failWithOwnedErrorMsg(block, msg: {
2735 const msg = try sema.errMsg(field_ty_src, "tuple fields cannot be 'noreturn'", .{});
2736 errdefer msg.destroy(gpa);
2737
2738 try sema.addDeclaredHereNote(msg, field_ty);
2739 break :msg msg;
2740 });
2741 }
2742}
2743
2654/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,2744/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
2655/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.2745/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.
2656fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {2746fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {
...@@ -2774,7 +2864,6 @@ fn zirStructDecl(...@@ -2774,7 +2864,6 @@ fn zirStructDecl(
2774 .fields_len = fields_len,2864 .fields_len = fields_len,
2775 .known_non_opv = small.known_non_opv,2865 .known_non_opv = small.known_non_opv,
2776 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,2866 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
2777 .is_tuple = small.is_tuple,
2778 .any_comptime_fields = small.any_comptime_fields,2867 .any_comptime_fields = small.any_comptime_fields,
2779 .any_default_inits = small.any_default_inits,2868 .any_default_inits = small.any_default_inits,
2780 .inits_resolved = false,2869 .inits_resolved = false,
...@@ -4912,7 +5001,7 @@ fn validateStructInit(...@@ -4912,7 +5001,7 @@ fn validateStructInit(
4912 const default_field_ptr = if (struct_ty.isTuple(zcu))5001 const default_field_ptr = if (struct_ty.isTuple(zcu))
4913 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)5002 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)
4914 else5003 else
4915 try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), field_src, struct_ty, true);5004 try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), struct_ty);
4916 const init = Air.internedToRef(default_val.toIntern());5005 const init = Air.internedToRef(default_val.toIntern());
4917 try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store);5006 try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store);
4918 }5007 }
...@@ -5104,7 +5193,7 @@ fn validateStructInit(...@@ -5104,7 +5193,7 @@ fn validateStructInit(
5104 const default_field_ptr = if (struct_ty.isTuple(zcu))5193 const default_field_ptr = if (struct_ty.isTuple(zcu))
5105 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)5194 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)
5106 else5195 else
5107 try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), field_src, struct_ty, true);5196 try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), struct_ty);
5108 try sema.checkKnownAllocPtr(block, struct_ptr, default_field_ptr);5197 try sema.checkKnownAllocPtr(block, struct_ptr, default_field_ptr);
5109 const init = Air.internedToRef(field_values[i]);5198 const init = Air.internedToRef(field_values[i]);
5110 try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store);5199 try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store);
...@@ -8430,22 +8519,6 @@ fn instantiateGenericCall(...@@ -8430,22 +8519,6 @@ fn instantiateGenericCall(
8430 return result;8519 return result;
8431}8520}
84328521
8433fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
8434 const pt = sema.pt;
8435 const zcu = pt.zcu;
8436 const ip = &zcu.intern_pool;
8437 const tuple = switch (ip.indexToKey(ty.toIntern())) {
8438 .anon_struct_type => |tuple| tuple,
8439 else => return,
8440 };
8441 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
8442 try sema.resolveTupleLazyValues(block, src, Type.fromInterned(field_ty));
8443 if (field_val == .none) continue;
8444 // TODO: mutate in intern pool
8445 _ = try sema.resolveLazyValue(Value.fromInterned(field_val));
8446 }
8447}
8448
8449fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8522fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8450 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;8523 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;
8451 const ty = try sema.pt.intType(int_type.signedness, int_type.bit_count);8524 const ty = try sema.pt.intType(int_type.signedness, int_type.bit_count);
...@@ -14321,13 +14394,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14321,13 +14394,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14321 },14394 },
14322 else => {},14395 else => {},
14323 },14396 },
14324 .anon_struct_type => |anon_struct| {14397 .tuple_type => |tuple| {
14325 if (anon_struct.names.len != 0) {14398 const field_index = field_name.toUnsigned(ip) orelse break :hf false;
14326 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names.get(ip), field_name) != null;14399 break :hf field_index < tuple.types.len;
14327 } else {
14328 const field_index = field_name.toUnsigned(ip) orelse break :hf false;
14329 break :hf field_index < ty.structFieldCount(zcu);
14330 }
14331 },14400 },
14332 .struct_type => {14401 .struct_type => {
14333 break :hf ip.loadStructType(ty.toIntern()).nameIndex(ip, field_name) != null;14402 break :hf ip.loadStructType(ty.toIntern()).nameIndex(ip, field_name) != null;
...@@ -14882,7 +14951,7 @@ fn analyzeTupleCat(...@@ -14882,7 +14951,7 @@ fn analyzeTupleCat(
14882 const dest_fields = lhs_len + rhs_len;14951 const dest_fields = lhs_len + rhs_len;
1488314952
14884 if (dest_fields == 0) {14953 if (dest_fields == 0) {
14885 return Air.internedToRef(Value.empty_struct.toIntern());14954 return .empty_tuple;
14886 }14955 }
14887 if (lhs_len == 0) {14956 if (lhs_len == 0) {
14888 return rhs;14957 return rhs;
...@@ -14928,10 +14997,9 @@ fn analyzeTupleCat(...@@ -14928,10 +14997,9 @@ fn analyzeTupleCat(
14928 break :rs runtime_src;14997 break :rs runtime_src;
14929 };14998 };
1493014999
14931 const tuple_ty = try zcu.intern_pool.getAnonStructType(zcu.gpa, pt.tid, .{15000 const tuple_ty = try zcu.intern_pool.getTupleType(zcu.gpa, pt.tid, .{
14932 .types = types,15001 .types = types,
14933 .values = values,15002 .values = values,
14934 .names = &.{},
14935 });15003 });
1493615004
14937 const runtime_src = opt_runtime_src orelse {15005 const runtime_src = opt_runtime_src orelse {
...@@ -15263,7 +15331,7 @@ fn analyzeTupleMul(...@@ -15263,7 +15331,7 @@ fn analyzeTupleMul(
15263 return sema.fail(block, len_src, "operation results in overflow", .{});15331 return sema.fail(block, len_src, "operation results in overflow", .{});
1526415332
15265 if (final_len == 0) {15333 if (final_len == 0) {
15266 return Air.internedToRef(Value.empty_struct.toIntern());15334 return .empty_tuple;
15267 }15335 }
15268 const types = try sema.arena.alloc(InternPool.Index, final_len);15336 const types = try sema.arena.alloc(InternPool.Index, final_len);
15269 const values = try sema.arena.alloc(InternPool.Index, final_len);15337 const values = try sema.arena.alloc(InternPool.Index, final_len);
...@@ -15289,10 +15357,9 @@ fn analyzeTupleMul(...@@ -15289,10 +15357,9 @@ fn analyzeTupleMul(
15289 break :rs runtime_src;15357 break :rs runtime_src;
15290 };15358 };
1529115359
15292 const tuple_ty = try zcu.intern_pool.getAnonStructType(zcu.gpa, pt.tid, .{15360 const tuple_ty = try zcu.intern_pool.getTupleType(zcu.gpa, pt.tid, .{
15293 .types = types,15361 .types = types,
15294 .values = values,15362 .values = values,
15295 .names = &.{},
15296 });15363 });
1529715364
15298 const runtime_src = opt_runtime_src orelse {15365 const runtime_src = opt_runtime_src orelse {
...@@ -16689,7 +16756,7 @@ fn zirOverflowArithmetic(...@@ -16689,7 +16756,7 @@ fn zirOverflowArithmetic(
16689 const maybe_rhs_val = try sema.resolveValue(rhs);16756 const maybe_rhs_val = try sema.resolveValue(rhs);
1669016757
16691 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);16758 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
16692 const overflow_ty = Type.fromInterned(ip.indexToKey(tuple_ty.toIntern()).anon_struct_type.types.get(ip)[1]);16759 const overflow_ty = Type.fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]);
1669316760
16694 var result: struct {16761 var result: struct {
16695 inst: Air.Inst.Ref = .none,16762 inst: Air.Inst.Ref = .none,
...@@ -16873,10 +16940,9 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {...@@ -16873,10 +16940,9 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
1687316940
16874 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };16941 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };
16875 const values = [2]InternPool.Index{ .none, .none };16942 const values = [2]InternPool.Index{ .none, .none };
16876 const tuple_ty = try ip.getAnonStructType(zcu.gpa, pt.tid, .{16943 const tuple_ty = try ip.getTupleType(zcu.gpa, pt.tid, .{
16877 .types = &types,16944 .types = &types,
16878 .values = &values,16945 .values = &values,
16879 .names = &.{},
16880 });16946 });
16881 return Type.fromInterned(tuple_ty);16947 return Type.fromInterned(tuple_ty);
16882}16948}
...@@ -18908,16 +18974,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18908,16 +18974,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18908 defer gpa.free(struct_field_vals);18974 defer gpa.free(struct_field_vals);
18909 fv: {18975 fv: {
18910 const struct_type = switch (ip.indexToKey(ty.toIntern())) {18976 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
18911 .anon_struct_type => |anon_struct_type| {18977 .tuple_type => |tuple_type| {
18912 struct_field_vals = try gpa.alloc(InternPool.Index, anon_struct_type.types.len);18978 struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len);
18913 for (struct_field_vals, 0..) |*struct_field_val, field_index| {18979 for (struct_field_vals, 0..) |*struct_field_val, field_index| {
18914 const field_ty = anon_struct_type.types.get(ip)[field_index];18980 const field_ty = tuple_type.types.get(ip)[field_index];
18915 const field_val = anon_struct_type.values.get(ip)[field_index];18981 const field_val = tuple_type.values.get(ip)[field_index];
18916 const name_val = v: {18982 const name_val = v: {
18917 const field_name = if (anon_struct_type.names.len != 0)18983 const field_name = try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
18918 anon_struct_type.names.get(ip)[field_index]
18919 else
18920 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
18921 const field_name_len = field_name.length(ip);18984 const field_name_len = field_name.length(ip);
18922 const new_decl_ty = try pt.arrayType(.{18985 const new_decl_ty = try pt.arrayType(.{
18923 .len = field_name_len,18986 .len = field_name_len,
...@@ -20509,8 +20572,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -20509,8 +20572,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
20509 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;20572 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20510 const src = block.nodeOffset(inst_data.src_node);20573 const src = block.nodeOffset(inst_data.src_node);
20511 const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {20574 const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) {
20512 // Generic poison means this is an untyped anonymous empty struct init20575 // Generic poison means this is an untyped anonymous empty struct/array init
20513 error.GenericPoison => return .empty_struct,20576 error.GenericPoison => return .empty_tuple,
20514 else => |e| return e,20577 else => |e| return e,
20515 };20578 };
20516 const init_ty = if (is_byref) ty: {20579 const init_ty = if (is_byref) ty: {
...@@ -20671,7 +20734,7 @@ fn zirStructInit(...@@ -20671,7 +20734,7 @@ fn zirStructInit(
20671 const result_ty = sema.resolveType(block, src, first_field_type_extra.container_type) catch |err| switch (err) {20734 const result_ty = sema.resolveType(block, src, first_field_type_extra.container_type) catch |err| switch (err) {
20672 error.GenericPoison => {20735 error.GenericPoison => {
20673 // The type wasn't actually known, so treat this as an anon struct init.20736 // The type wasn't actually known, so treat this as an anon struct init.
20674 return sema.structInitAnon(block, src, .typed_init, extra.data, extra.end, is_ref);20737 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);
20675 },20738 },
20676 else => |e| return e,20739 else => |e| return e,
20677 };20740 };
...@@ -20837,39 +20900,28 @@ fn finishStructInit(...@@ -20837,39 +20900,28 @@ fn finishStructInit(
20837 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);20900 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
2083820901
20839 switch (ip.indexToKey(struct_ty.toIntern())) {20902 switch (ip.indexToKey(struct_ty.toIntern())) {
20840 .anon_struct_type => |anon_struct| {20903 .tuple_type => |tuple| {
20841 // We can't get the slices, as the coercion may invalidate them.20904 // We can't get the slices, as the coercion may invalidate them.
20842 for (0..anon_struct.types.len) |i| {20905 for (0..tuple.types.len) |i| {
20843 if (field_inits[i] != .none) {20906 if (field_inits[i] != .none) {
20844 // Coerce the init value to the field type.20907 // Coerce the init value to the field type.
20845 const field_src = block.src(.{ .init_elem = .{20908 const field_src = block.src(.{ .init_elem = .{
20846 .init_node_offset = init_src.offset.node_offset.x,20909 .init_node_offset = init_src.offset.node_offset.x,
20847 .elem_index = @intCast(i),20910 .elem_index = @intCast(i),
20848 } });20911 } });
20849 const field_ty = Type.fromInterned(anon_struct.types.get(ip)[i]);20912 const field_ty = Type.fromInterned(tuple.types.get(ip)[i]);
20850 field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);20913 field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);
20851 continue;20914 continue;
20852 }20915 }
2085320916
20854 const default_val = anon_struct.values.get(ip)[i];20917 const default_val = tuple.values.get(ip)[i];
2085520918
20856 if (default_val == .none) {20919 if (default_val == .none) {
20857 if (anon_struct.names.len == 0) {20920 const template = "missing tuple field with index {d}";
20858 const template = "missing tuple field with index {d}";20921 if (root_msg) |msg| {
20859 if (root_msg) |msg| {20922 try sema.errNote(init_src, msg, template, .{i});
20860 try sema.errNote(init_src, msg, template, .{i});
20861 } else {
20862 root_msg = try sema.errMsg(init_src, template, .{i});
20863 }
20864 } else {20923 } else {
20865 const field_name = anon_struct.names.get(ip)[i];20924 root_msg = try sema.errMsg(init_src, template, .{i});
20866 const template = "missing struct field: {}";
20867 const args = .{field_name.fmt(ip)};
20868 if (root_msg) |msg| {
20869 try sema.errNote(init_src, msg, template, args);
20870 } else {
20871 root_msg = try sema.errMsg(init_src, template, args);
20872 }
20873 }20925 }
20874 } else {20926 } else {
20875 field_inits[i] = Air.internedToRef(default_val);20927 field_inits[i] = Air.internedToRef(default_val);
...@@ -20894,22 +20946,13 @@ fn finishStructInit(...@@ -20894,22 +20946,13 @@ fn finishStructInit(
2089420946
20895 const field_init = struct_type.fieldInit(ip, i);20947 const field_init = struct_type.fieldInit(ip, i);
20896 if (field_init == .none) {20948 if (field_init == .none) {
20897 if (!struct_type.isTuple(ip)) {20949 const field_name = struct_type.field_names.get(ip)[i];
20898 const field_name = struct_type.field_names.get(ip)[i];20950 const template = "missing struct field: {}";
20899 const template = "missing struct field: {}";20951 const args = .{field_name.fmt(ip)};
20900 const args = .{field_name.fmt(ip)};20952 if (root_msg) |msg| {
20901 if (root_msg) |msg| {20953 try sema.errNote(init_src, msg, template, args);
20902 try sema.errNote(init_src, msg, template, args);
20903 } else {
20904 root_msg = try sema.errMsg(init_src, template, args);
20905 }
20906 } else {20954 } else {
20907 const template = "missing tuple field with index {d}";20955 root_msg = try sema.errMsg(init_src, template, args);
20908 if (root_msg) |msg| {
20909 try sema.errNote(init_src, msg, template, .{i});
20910 } else {
20911 root_msg = try sema.errMsg(init_src, template, .{i});
20912 }
20913 }20956 }
20914 } else {20957 } else {
20915 field_inits[i] = Air.internedToRef(field_init);20958 field_inits[i] = Air.internedToRef(field_init);
...@@ -20970,8 +21013,7 @@ fn finishStructInit(...@@ -20970,8 +21013,7 @@ fn finishStructInit(
20970 const base_ptr = try sema.optEuBasePtrInit(block, alloc, init_src);21013 const base_ptr = try sema.optEuBasePtrInit(block, alloc, init_src);
20971 for (field_inits, 0..) |field_init, i_usize| {21014 for (field_inits, 0..) |field_init, i_usize| {
20972 const i: u32 = @intCast(i_usize);21015 const i: u32 = @intCast(i_usize);
20973 const field_src = dest_src;21016 const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, base_ptr, i, struct_ty);
20974 const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, base_ptr, i, field_src, struct_ty, true);
20975 try sema.storePtr(block, dest_src, field_ptr, field_init);21017 try sema.storePtr(block, dest_src, field_ptr, field_init);
20976 }21018 }
2097721019
...@@ -20995,13 +21037,14 @@ fn zirStructInitAnon(...@@ -20995,13 +21037,14 @@ fn zirStructInitAnon(
20995 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;21037 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
20996 const src = block.nodeOffset(inst_data.src_node);21038 const src = block.nodeOffset(inst_data.src_node);
20997 const extra = sema.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);21039 const extra = sema.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index);
20998 return sema.structInitAnon(block, src, .anon_init, extra.data, extra.end, false);21040 return sema.structInitAnon(block, src, inst, .anon_init, extra.data, extra.end, false);
20999}21041}
2100021042
21001fn structInitAnon(21043fn structInitAnon(
21002 sema: *Sema,21044 sema: *Sema,
21003 block: *Block,21045 block: *Block,
21004 src: LazySrcLoc,21046 src: LazySrcLoc,
21047 inst: Zir.Inst.Index,
21005 /// It is possible for a typed struct_init to be downgraded to an anonymous init due to a21048 /// It is possible for a typed struct_init to be downgraded to an anonymous init due to a
21006 /// generic poison type. In this case, we need to know to interpret the extra data differently.21049 /// generic poison type. In this case, we need to know to interpret the extra data differently.
21007 comptime kind: enum { anon_init, typed_init },21050 comptime kind: enum { anon_init, typed_init },
...@@ -21022,6 +21065,8 @@ fn structInitAnon(...@@ -21022,6 +21065,8 @@ fn structInitAnon(
21022 const values = try sema.arena.alloc(InternPool.Index, types.len);21065 const values = try sema.arena.alloc(InternPool.Index, types.len);
21023 const names = try sema.arena.alloc(InternPool.NullTerminatedString, types.len);21066 const names = try sema.arena.alloc(InternPool.NullTerminatedString, types.len);
2102421067
21068 var any_values = false;
21069
21025 // Find which field forces the expression to be runtime, if any.21070 // Find which field forces the expression to be runtime, if any.
21026 const opt_runtime_index = rs: {21071 const opt_runtime_index = rs: {
21027 var runtime_index: ?usize = null;21072 var runtime_index: ?usize = null;
...@@ -21063,6 +21108,7 @@ fn structInitAnon(...@@ -21063,6 +21108,7 @@ fn structInitAnon(
21063 }21108 }
21064 if (try sema.resolveValue(init)) |init_val| {21109 if (try sema.resolveValue(init)) |init_val| {
21065 field_val.* = init_val.toIntern();21110 field_val.* = init_val.toIntern();
21111 any_values = true;
21066 } else {21112 } else {
21067 field_val.* = .none;21113 field_val.* = .none;
21068 runtime_index = @intCast(i_usize);21114 runtime_index = @intCast(i_usize);
...@@ -21071,18 +21117,76 @@ fn structInitAnon(...@@ -21071,18 +21117,76 @@ fn structInitAnon(
21071 break :rs runtime_index;21117 break :rs runtime_index;
21072 };21118 };
2107321119
21074 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{21120 // We treat anonymous struct types as reified types, because there are similarities:
21075 .names = names,21121 // * They use a form of structural equivalence, which we can easily model using a custom hash
21076 .types = types,21122 // * They do not have captures
21077 .values = values,21123 // * They immediately have their fields resolved
21078 });21124 // In general, other code should treat anon struct types and reified struct types identically,
21125 // so there's no point having a separate `InternPool.NamespaceType` field for them.
21126 const type_hash: u64 = hash: {
21127 var hasher = std.hash.Wyhash.init(0);
21128 hasher.update(std.mem.sliceAsBytes(types));
21129 hasher.update(std.mem.sliceAsBytes(values));
21130 hasher.update(std.mem.sliceAsBytes(names));
21131 break :hash hasher.final();
21132 };
21133 const tracked_inst = try block.trackZir(inst);
21134 const struct_ty = switch (try ip.getStructType(gpa, pt.tid, .{
21135 .layout = .auto,
21136 .fields_len = extra_data.fields_len,
21137 .known_non_opv = false,
21138 .requires_comptime = .unknown,
21139 .any_comptime_fields = any_values,
21140 .any_default_inits = any_values,
21141 .inits_resolved = true,
21142 .any_aligned_fields = false,
21143 .key = .{ .reified = .{
21144 .zir_index = tracked_inst,
21145 .type_hash = type_hash,
21146 } },
21147 }, false)) {
21148 .wip => |wip| ty: {
21149 errdefer wip.cancel(ip, pt.tid);
21150 wip.setName(ip, try sema.createTypeName(block, .anon, "struct", inst, wip.index));
21151
21152 const struct_type = ip.loadStructType(wip.index);
21153
21154 for (names, values, 0..) |name, init_val, field_idx| {
21155 assert(struct_type.addFieldName(ip, name) == null);
21156 if (init_val != .none) struct_type.setFieldComptime(ip, field_idx);
21157 }
21158
21159 @memcpy(struct_type.field_types.get(ip), types);
21160 if (any_values) {
21161 @memcpy(struct_type.field_inits.get(ip), values);
21162 }
21163
21164 const new_namespace_index = try pt.createNamespace(.{
21165 .parent = block.namespace.toOptional(),
21166 .owner_type = wip.index,
21167 .file_scope = block.getFileScopeIndex(zcu),
21168 .generation = zcu.generation,
21169 });
21170 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip.index);
21171 try zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });
21172 codegen_type: {
21173 if (zcu.comp.config.use_llvm) break :codegen_type;
21174 if (block.ownerModule().strip) break :codegen_type;
21175 try zcu.comp.queueJob(.{ .codegen_type = wip.index });
21176 }
21177 break :ty wip.finish(ip, new_cau_index.toOptional(), new_namespace_index);
21178 },
21179 .existing => |ty| ty,
21180 };
21181 try sema.declareDependency(.{ .interned = struct_ty });
21182 try sema.addTypeReferenceEntry(src, struct_ty);
2107921183
21080 const runtime_index = opt_runtime_index orelse {21184 const runtime_index = opt_runtime_index orelse {
21081 const tuple_val = try pt.intern(.{ .aggregate = .{21185 const struct_val = try pt.intern(.{ .aggregate = .{
21082 .ty = tuple_ty,21186 .ty = struct_ty,
21083 .storage = .{ .elems = values },21187 .storage = .{ .elems = values },
21084 } });21188 } });
21085 return sema.addConstantMaybeRef(tuple_val, is_ref);21189 return sema.addConstantMaybeRef(struct_val, is_ref);
21086 };21190 };
2108721191
21088 try sema.requireRuntimeBlock(block, LazySrcLoc.unneeded, block.src(.{ .init_elem = .{21192 try sema.requireRuntimeBlock(block, LazySrcLoc.unneeded, block.src(.{ .init_elem = .{
...@@ -21093,7 +21197,7 @@ fn structInitAnon(...@@ -21093,7 +21197,7 @@ fn structInitAnon(
21093 if (is_ref) {21197 if (is_ref) {
21094 const target = zcu.getTarget();21198 const target = zcu.getTarget();
21095 const alloc_ty = try pt.ptrTypeSema(.{21199 const alloc_ty = try pt.ptrTypeSema(.{
21096 .child = tuple_ty,21200 .child = struct_ty,
21097 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },21201 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
21098 });21202 });
21099 const alloc = try block.addTy(.alloc, alloc_ty);21203 const alloc = try block.addTy(.alloc, alloc_ty);
...@@ -21131,7 +21235,7 @@ fn structInitAnon(...@@ -21131,7 +21235,7 @@ fn structInitAnon(
21131 element_refs[i] = try sema.resolveInst(item.data.init);21235 element_refs[i] = try sema.resolveInst(item.data.init);
21132 }21236 }
2113321237
21134 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);21238 return block.addAggregateInit(Type.fromInterned(struct_ty), element_refs);
21135}21239}
2113621240
21137fn zirArrayInit(21241fn zirArrayInit(
...@@ -21340,10 +21444,9 @@ fn arrayInitAnon(...@@ -21340,10 +21444,9 @@ fn arrayInitAnon(
21340 break :rs runtime_src;21444 break :rs runtime_src;
21341 };21445 };
2134221446
21343 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{21447 const tuple_ty = try ip.getTupleType(gpa, pt.tid, .{
21344 .types = types,21448 .types = types,
21345 .values = values,21449 .values = values,
21346 .names = &.{},
21347 });21450 });
2134821451
21349 const runtime_src = opt_runtime_src orelse {21452 const runtime_src = opt_runtime_src orelse {
...@@ -21440,12 +21543,9 @@ fn fieldType(...@@ -21440,12 +21543,9 @@ fn fieldType(
21440 try cur_ty.resolveFields(pt);21543 try cur_ty.resolveFields(pt);
21441 switch (cur_ty.zigTypeTag(zcu)) {21544 switch (cur_ty.zigTypeTag(zcu)) {
21442 .@"struct" => switch (ip.indexToKey(cur_ty.toIntern())) {21545 .@"struct" => switch (ip.indexToKey(cur_ty.toIntern())) {
21443 .anon_struct_type => |anon_struct| {21546 .tuple_type => |tuple| {
21444 const field_index = if (anon_struct.names.len == 0)21547 const field_index = try sema.tupleFieldIndex(block, cur_ty, field_name, field_src);
21445 try sema.tupleFieldIndex(block, cur_ty, field_name, field_src)21548 return Air.internedToRef(tuple.types.get(ip)[field_index]);
21446 else
21447 try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
21448 return Air.internedToRef(anon_struct.types.get(ip)[field_index]);
21449 },21549 },
21450 .struct_type => {21550 .struct_type => {
21451 const struct_type = ip.loadStructType(cur_ty.toIntern());21551 const struct_type = ip.loadStructType(cur_ty.toIntern());
...@@ -22095,7 +22195,16 @@ fn zirReify(...@@ -22095,7 +22195,16 @@ fn zirReify(
22095 .needed_comptime_reason = "struct fields must be comptime-known",22195 .needed_comptime_reason = "struct fields must be comptime-known",
22096 });22196 });
2209722197
22098 return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool());22198 if (is_tuple_val.toBool()) {
22199 switch (layout) {
22200 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),
22201 .@"packed" => return sema.fail(block, src, "packed tuples are not supported", .{}),
22202 .auto => {},
22203 }
22204 return sema.reifyTuple(block, src, fields_arr);
22205 } else {
22206 return sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy);
22207 }
22099 },22208 },
22100 .@"enum" => {22209 .@"enum" => {
22101 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));22210 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
...@@ -22696,6 +22805,104 @@ fn reifyUnion(...@@ -22696,6 +22805,104 @@ fn reifyUnion(
22696 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));22805 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
22697}22806}
2269822807
22808fn reifyTuple(
22809 sema: *Sema,
22810 block: *Block,
22811 src: LazySrcLoc,
22812 fields_val: Value,
22813) CompileError!Air.Inst.Ref {
22814 const pt = sema.pt;
22815 const zcu = pt.zcu;
22816 const gpa = sema.gpa;
22817 const ip = &zcu.intern_pool;
22818
22819 const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu));
22820
22821 const types = try sema.arena.alloc(InternPool.Index, fields_len);
22822 const inits = try sema.arena.alloc(InternPool.Index, fields_len);
22823
22824 for (types, inits, 0..) |*field_ty, *field_init, field_idx| {
22825 const field_info = try fields_val.elemValue(pt, field_idx);
22826
22827 const field_name_val = try field_info.fieldValue(pt, 0);
22828 const field_type_val = try field_info.fieldValue(pt, 1);
22829 const field_default_value_val = try field_info.fieldValue(pt, 2);
22830 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
22831 const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 4));
22832
22833 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{
22834 .needed_comptime_reason = "tuple field name must be comptime-known",
22835 });
22836 const field_type = field_type_val.toType();
22837 const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(zcu)) |ptr_val| d: {
22838 const ptr_ty = try pt.singleConstPtrType(field_type_val.toType());
22839 // We need to do this deref here, so we won't check for this error case later on.
22840 const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(
22841 block,
22842 src,
22843 .{ .needed_comptime_reason = "tuple field default value must be comptime-known" },
22844 );
22845 // Resolve the value so that lazy values do not create distinct types.
22846 break :d (try sema.resolveLazyValue(val)).toIntern();
22847 } else .none;
22848
22849 const field_name_index = field_name.toUnsigned(ip) orelse return sema.fail(
22850 block,
22851 src,
22852 "tuple cannot have non-numeric field '{}'",
22853 .{field_name.fmt(ip)},
22854 );
22855 if (field_name_index != field_idx) {
22856 return sema.fail(
22857 block,
22858 src,
22859 "tuple field name '{}' does not match field index {}",
22860 .{ field_name_index, field_idx },
22861 );
22862 }
22863
22864 try sema.validateTupleFieldType(block, field_type, src);
22865
22866 {
22867 const alignment_ok = ok: {
22868 if (field_alignment_val.toIntern() == .zero) break :ok true;
22869 const given_align = try field_alignment_val.getUnsignedIntSema(pt) orelse break :ok false;
22870 const abi_align = (try field_type.abiAlignmentSema(pt)).toByteUnits() orelse 0;
22871 break :ok abi_align == given_align;
22872 };
22873 if (!alignment_ok) {
22874 return sema.fail(block, src, "tuple fields cannot specify alignment", .{});
22875 }
22876 }
22877
22878 if (field_is_comptime_val.toBool() and field_default_value == .none) {
22879 return sema.fail(block, src, "comptime field without default initialization value", .{});
22880 }
22881
22882 if (!field_is_comptime_val.toBool() and field_default_value != .none) {
22883 return sema.fail(block, src, "non-comptime tuple fields cannot specify default initialization value", .{});
22884 }
22885
22886 const default_or_opv: InternPool.Index = default: {
22887 if (field_default_value != .none) {
22888 break :default field_default_value;
22889 }
22890 if (try sema.typeHasOnePossibleValue(field_type)) |opv| {
22891 break :default opv.toIntern();
22892 }
22893 break :default .none;
22894 };
22895
22896 field_ty.* = field_type.toIntern();
22897 field_init.* = default_or_opv;
22898 }
22899
22900 return Air.internedToRef(try zcu.intern_pool.getTupleType(gpa, pt.tid, .{
22901 .types = types,
22902 .values = inits,
22903 }));
22904}
22905
22699fn reifyStruct(22906fn reifyStruct(
22700 sema: *Sema,22907 sema: *Sema,
22701 block: *Block,22908 block: *Block,
...@@ -22705,7 +22912,6 @@ fn reifyStruct(...@@ -22705,7 +22912,6 @@ fn reifyStruct(
22705 opt_backing_int_val: Value,22912 opt_backing_int_val: Value,
22706 fields_val: Value,22913 fields_val: Value,
22707 name_strategy: Zir.Inst.NameStrategy,22914 name_strategy: Zir.Inst.NameStrategy,
22708 is_tuple: bool,
22709) CompileError!Air.Inst.Ref {22915) CompileError!Air.Inst.Ref {
22710 const pt = sema.pt;22916 const pt = sema.pt;
22711 const zcu = pt.zcu;22917 const zcu = pt.zcu;
...@@ -22725,7 +22931,6 @@ fn reifyStruct(...@@ -22725,7 +22931,6 @@ fn reifyStruct(
22725 var hasher = std.hash.Wyhash.init(0);22931 var hasher = std.hash.Wyhash.init(0);
22726 std.hash.autoHash(&hasher, layout);22932 std.hash.autoHash(&hasher, layout);
22727 std.hash.autoHash(&hasher, opt_backing_int_val.toIntern());22933 std.hash.autoHash(&hasher, opt_backing_int_val.toIntern());
22728 std.hash.autoHash(&hasher, is_tuple);
22729 std.hash.autoHash(&hasher, fields_len);22934 std.hash.autoHash(&hasher, fields_len);
2273022935
22731 var any_comptime_fields = false;22936 var any_comptime_fields = false;
...@@ -22781,7 +22986,6 @@ fn reifyStruct(...@@ -22781,7 +22986,6 @@ fn reifyStruct(
22781 .fields_len = fields_len,22986 .fields_len = fields_len,
22782 .known_non_opv = false,22987 .known_non_opv = false,
22783 .requires_comptime = .unknown,22988 .requires_comptime = .unknown,
22784 .is_tuple = is_tuple,
22785 .any_comptime_fields = any_comptime_fields,22989 .any_comptime_fields = any_comptime_fields,
22786 .any_default_inits = any_default_inits,22990 .any_default_inits = any_default_inits,
22787 .any_aligned_fields = any_aligned_fields,22991 .any_aligned_fields = any_aligned_fields,
...@@ -22800,12 +23004,6 @@ fn reifyStruct(...@@ -22800,12 +23004,6 @@ fn reifyStruct(
22800 };23004 };
22801 errdefer wip_ty.cancel(ip, pt.tid);23005 errdefer wip_ty.cancel(ip, pt.tid);
2280223006
22803 if (is_tuple) switch (layout) {
22804 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),
22805 .@"packed" => return sema.fail(block, src, "packed tuples are not supported", .{}),
22806 .auto => {},
22807 };
22808
22809 wip_ty.setName(ip, try sema.createTypeName(23007 wip_ty.setName(ip, try sema.createTypeName(
22810 block,23008 block,
22811 name_strategy,23009 name_strategy,
...@@ -22828,22 +23026,7 @@ fn reifyStruct(...@@ -22828,22 +23026,7 @@ fn reifyStruct(
22828 const field_ty = field_type_val.toType();23026 const field_ty = field_type_val.toType();
22829 // Don't pass a reason; first loop acts as an assertion that this is valid.23027 // Don't pass a reason; first loop acts as an assertion that this is valid.
22830 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);23028 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
22831 if (is_tuple) {23029 if (struct_type.addFieldName(ip, field_name)) |prev_index| {
22832 const field_name_index = field_name.toUnsigned(ip) orelse return sema.fail(
22833 block,
22834 src,
22835 "tuple cannot have non-numeric field '{}'",
22836 .{field_name.fmt(ip)},
22837 );
22838 if (field_name_index != field_idx) {
22839 return sema.fail(
22840 block,
22841 src,
22842 "tuple field name '{}' does not match field index {}",
22843 .{ field_name_index, field_idx },
22844 );
22845 }
22846 } else if (struct_type.addFieldName(ip, field_name)) |prev_index| {
22847 _ = prev_index; // TODO: better source location23030 _ = prev_index; // TODO: better source location
22848 return sema.fail(block, src, "duplicate struct field name {}", .{field_name.fmt(ip)});23031 return sema.fail(block, src, "duplicate struct field name {}", .{field_name.fmt(ip)});
22849 }23032 }
...@@ -25579,7 +25762,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -25579,7 +25762,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
25579 const args = try sema.resolveInst(extra.args);25762 const args = try sema.resolveInst(extra.args);
2558025763
25581 const args_ty = sema.typeOf(args);25764 const args_ty = sema.typeOf(args);
25582 if (!args_ty.isTuple(zcu) and args_ty.toIntern() != .empty_struct_type) {25765 if (!args_ty.isTuple(zcu)) {
25583 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)});25766 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)});
25584 }25767 }
2558525768
...@@ -27471,7 +27654,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -27471,7 +27654,7 @@ fn explainWhyTypeIsComptimeInner(
27471 for (0..struct_type.field_types.len) |i| {27654 for (0..struct_type.field_types.len) |i| {
27472 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);27655 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
27473 const field_src: LazySrcLoc = .{27656 const field_src: LazySrcLoc = .{
27474 .base_node_inst = struct_type.zir_index.unwrap().?,27657 .base_node_inst = struct_type.zir_index,
27475 .offset = .{ .container_field_type = @intCast(i) },27658 .offset = .{ .container_field_type = @intCast(i) },
27476 };27659 };
2747727660
...@@ -28236,11 +28419,10 @@ fn fieldVal(...@@ -28236,11 +28419,10 @@ fn fieldVal(
28236 return Air.internedToRef(enum_val.toIntern());28419 return Air.internedToRef(enum_val.toIntern());
28237 },28420 },
28238 .@"struct", .@"opaque" => {28421 .@"struct", .@"opaque" => {
28239 switch (child_type.toIntern()) {28422 if (!child_type.isTuple(zcu) and child_type.toIntern() != .anyopaque_type) {
28240 .empty_struct_type, .anyopaque_type => {}, // no namespace28423 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
28241 else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
28242 return inst;28424 return inst;
28243 },28425 }
28244 }28426 }
28245 return sema.failWithBadMemberAccess(block, child_type, src, field_name);28427 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
28246 },28428 },
...@@ -28788,9 +28970,6 @@ fn structFieldPtr(...@@ -28788,9 +28970,6 @@ fn structFieldPtr(
28788 }28970 }
28789 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);28971 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
28790 return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing);28972 return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing);
28791 } else if (struct_ty.isAnonStruct(zcu)) {
28792 const field_index = try sema.anonStructFieldIndex(block, struct_ty, field_name, field_name_src);
28793 return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing);
28794 }28973 }
2879528974
28796 const struct_type = zcu.typeToStruct(struct_ty).?;28975 const struct_type = zcu.typeToStruct(struct_ty).?;
...@@ -28798,7 +28977,7 @@ fn structFieldPtr(...@@ -28798,7 +28977,7 @@ fn structFieldPtr(
28798 const field_index = struct_type.nameIndex(ip, field_name) orelse28977 const field_index = struct_type.nameIndex(ip, field_name) orelse
28799 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);28978 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
2880028979
28801 return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, field_name_src, struct_ty, initializing);28980 return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, struct_ty);
28802}28981}
2880328982
28804fn structFieldPtrByIndex(28983fn structFieldPtrByIndex(
...@@ -28807,16 +28986,11 @@ fn structFieldPtrByIndex(...@@ -28807,16 +28986,11 @@ fn structFieldPtrByIndex(
28807 src: LazySrcLoc,28986 src: LazySrcLoc,
28808 struct_ptr: Air.Inst.Ref,28987 struct_ptr: Air.Inst.Ref,
28809 field_index: u32,28988 field_index: u32,
28810 field_src: LazySrcLoc,
28811 struct_ty: Type,28989 struct_ty: Type,
28812 initializing: bool,
28813) CompileError!Air.Inst.Ref {28990) CompileError!Air.Inst.Ref {
28814 const pt = sema.pt;28991 const pt = sema.pt;
28815 const zcu = pt.zcu;28992 const zcu = pt.zcu;
28816 const ip = &zcu.intern_pool;28993 const ip = &zcu.intern_pool;
28817 if (struct_ty.isAnonStruct(zcu)) {
28818 return sema.tupleFieldPtr(block, src, struct_ptr, field_src, field_index, initializing);
28819 }
2882028994
28821 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {28995 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
28822 const val = try struct_ptr_val.ptrField(field_index, pt);28996 const val = try struct_ptr_val.ptrField(field_index, pt);
...@@ -28909,8 +29083,6 @@ fn structFieldVal(...@@ -28909,8 +29083,6 @@ fn structFieldVal(
28909 switch (ip.indexToKey(struct_ty.toIntern())) {29083 switch (ip.indexToKey(struct_ty.toIntern())) {
28910 .struct_type => {29084 .struct_type => {
28911 const struct_type = ip.loadStructType(struct_ty.toIntern());29085 const struct_type = ip.loadStructType(struct_ty.toIntern());
28912 if (struct_type.isTuple(ip))
28913 return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
2891429086
28915 const field_index = struct_type.nameIndex(ip, field_name) orelse29087 const field_index = struct_type.nameIndex(ip, field_name) orelse
28916 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);29088 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
...@@ -28935,13 +29107,8 @@ fn structFieldVal(...@@ -28935,13 +29107,8 @@ fn structFieldVal(
28935 try field_ty.resolveLayout(pt);29107 try field_ty.resolveLayout(pt);
28936 return block.addStructFieldVal(struct_byval, field_index, field_ty);29108 return block.addStructFieldVal(struct_byval, field_index, field_ty);
28937 },29109 },
28938 .anon_struct_type => |anon_struct| {29110 .tuple_type => {
28939 if (anon_struct.names.len == 0) {29111 return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
28940 return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
28941 } else {
28942 const field_index = try sema.anonStructFieldIndex(block, struct_ty, field_name, field_name_src);
28943 return sema.tupleFieldValByIndex(block, src, struct_byval, field_index, struct_ty);
28944 }
28945 },29112 },
28946 else => unreachable,29113 else => unreachable,
28947 }29114 }
...@@ -30087,39 +30254,7 @@ fn coerceExtra(...@@ -30087,39 +30254,7 @@ fn coerceExtra(
30087 },30254 },
30088 else => {},30255 else => {},
30089 },30256 },
30090 .One => switch (Type.fromInterned(dest_info.child).zigTypeTag(zcu)) {30257 .One => {},
30091 .@"union" => {
30092 // pointer to anonymous struct to pointer to union
30093 if (inst_ty.isSinglePointer(zcu) and
30094 inst_ty.childType(zcu).isAnonStruct(zcu) and
30095 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
30096 {
30097 return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
30098 }
30099 },
30100 .@"struct" => {
30101 // pointer to anonymous struct to pointer to struct
30102 if (inst_ty.isSinglePointer(zcu) and
30103 inst_ty.childType(zcu).isAnonStruct(zcu) and
30104 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
30105 {
30106 return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src) catch |err| switch (err) {
30107 error.NotCoercible => break :pointer,
30108 else => |e| return e,
30109 };
30110 }
30111 },
30112 .array => {
30113 // pointer to tuple to pointer to array
30114 if (inst_ty.isSinglePointer(zcu) and
30115 inst_ty.childType(zcu).isTuple(zcu) and
30116 sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
30117 {
30118 return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
30119 }
30120 },
30121 else => {},
30122 },
30123 .Slice => to_slice: {30258 .Slice => to_slice: {
30124 if (inst_ty.zigTypeTag(zcu) == .array) {30259 if (inst_ty.zigTypeTag(zcu) == .array) {
30125 return sema.fail(30260 return sema.fail(
...@@ -30368,11 +30503,6 @@ fn coerceExtra(...@@ -30368,11 +30503,6 @@ fn coerceExtra(
30368 },30503 },
30369 .@"union" => switch (inst_ty.zigTypeTag(zcu)) {30504 .@"union" => switch (inst_ty.zigTypeTag(zcu)) {
30370 .@"enum", .enum_literal => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src),30505 .@"enum", .enum_literal => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src),
30371 .@"struct" => {
30372 if (inst_ty.isAnonStruct(zcu)) {
30373 return sema.coerceAnonStructToUnion(block, dest_ty, dest_ty_src, inst, inst_src);
30374 }
30375 },
30376 else => {},30506 else => {},
30377 },30507 },
30378 .array => switch (inst_ty.zigTypeTag(zcu)) {30508 .array => switch (inst_ty.zigTypeTag(zcu)) {
...@@ -30402,9 +30532,6 @@ fn coerceExtra(...@@ -30402,9 +30532,6 @@ fn coerceExtra(
30402 },30532 },
30403 .vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),30533 .vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),
30404 .@"struct" => {30534 .@"struct" => {
30405 if (inst == .empty_struct) {
30406 return sema.arrayInitEmpty(block, inst_src, dest_ty);
30407 }
30408 if (inst_ty.isTuple(zcu)) {30535 if (inst_ty.isTuple(zcu)) {
30409 return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src);30536 return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src);
30410 }30537 }
...@@ -30421,10 +30548,7 @@ fn coerceExtra(...@@ -30421,10 +30548,7 @@ fn coerceExtra(
30421 else => {},30548 else => {},
30422 },30549 },
30423 .@"struct" => blk: {30550 .@"struct" => blk: {
30424 if (inst == .empty_struct) {30551 if (inst_ty.isTuple(zcu)) {
30425 return sema.structInitEmpty(block, dest_ty, dest_ty_src, inst_src);
30426 }
30427 if (inst_ty.isTupleOrAnonStruct(zcu)) {
30428 return sema.coerceTupleToStruct(block, dest_ty, inst, inst_src) catch |err| switch (err) {30552 return sema.coerceTupleToStruct(block, dest_ty, inst, inst_src) catch |err| switch (err) {
30429 error.NotCoercible => break :blk,30553 error.NotCoercible => break :blk,
30430 else => |e| return e,30554 else => |e| return e,
...@@ -32208,97 +32332,6 @@ fn coerceEnumToUnion(...@@ -32208,97 +32332,6 @@ fn coerceEnumToUnion(
32208 return sema.failWithOwnedErrorMsg(block, msg);32332 return sema.failWithOwnedErrorMsg(block, msg);
32209}32333}
3221032334
32211fn coerceAnonStructToUnion(
32212 sema: *Sema,
32213 block: *Block,
32214 union_ty: Type,
32215 union_ty_src: LazySrcLoc,
32216 inst: Air.Inst.Ref,
32217 inst_src: LazySrcLoc,
32218) !Air.Inst.Ref {
32219 const pt = sema.pt;
32220 const zcu = pt.zcu;
32221 const ip = &zcu.intern_pool;
32222 const inst_ty = sema.typeOf(inst);
32223 const field_info: union(enum) {
32224 name: InternPool.NullTerminatedString,
32225 count: usize,
32226 } = switch (ip.indexToKey(inst_ty.toIntern())) {
32227 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1)
32228 .{ .name = anon_struct_type.names.get(ip)[0] }
32229 else
32230 .{ .count = anon_struct_type.names.len },
32231 .struct_type => name: {
32232 const field_names = ip.loadStructType(inst_ty.toIntern()).field_names.get(ip);
32233 break :name if (field_names.len == 1)
32234 .{ .name = field_names[0] }
32235 else
32236 .{ .count = field_names.len };
32237 },
32238 else => unreachable,
32239 };
32240 switch (field_info) {
32241 .name => |field_name| {
32242 const init = try sema.structFieldVal(block, inst_src, inst, field_name, inst_src, inst_ty);
32243 return sema.unionInit(block, init, inst_src, union_ty, union_ty_src, field_name, inst_src);
32244 },
32245 .count => |field_count| {
32246 assert(field_count != 1);
32247 const msg = msg: {
32248 const msg = if (field_count > 1) try sema.errMsg(
32249 inst_src,
32250 "cannot initialize multiple union fields at once; unions can only have one active field",
32251 .{},
32252 ) else try sema.errMsg(
32253 inst_src,
32254 "union initializer must initialize one field",
32255 .{},
32256 );
32257 errdefer msg.destroy(sema.gpa);
32258
32259 // TODO add notes for where the anon struct was created to point out
32260 // the extra fields.
32261
32262 try sema.addDeclaredHereNote(msg, union_ty);
32263 break :msg msg;
32264 };
32265 return sema.failWithOwnedErrorMsg(block, msg);
32266 },
32267 }
32268}
32269
32270fn coerceAnonStructToUnionPtrs(
32271 sema: *Sema,
32272 block: *Block,
32273 ptr_union_ty: Type,
32274 union_ty_src: LazySrcLoc,
32275 ptr_anon_struct: Air.Inst.Ref,
32276 anon_struct_src: LazySrcLoc,
32277) !Air.Inst.Ref {
32278 const pt = sema.pt;
32279 const zcu = pt.zcu;
32280 const union_ty = ptr_union_ty.childType(zcu);
32281 const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src);
32282 const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src);
32283 return sema.analyzeRef(block, union_ty_src, union_inst);
32284}
32285
32286fn coerceAnonStructToStructPtrs(
32287 sema: *Sema,
32288 block: *Block,
32289 ptr_struct_ty: Type,
32290 struct_ty_src: LazySrcLoc,
32291 ptr_anon_struct: Air.Inst.Ref,
32292 anon_struct_src: LazySrcLoc,
32293) !Air.Inst.Ref {
32294 const pt = sema.pt;
32295 const zcu = pt.zcu;
32296 const struct_ty = ptr_struct_ty.childType(zcu);
32297 const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src);
32298 const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src);
32299 return sema.analyzeRef(block, struct_ty_src, struct_inst);
32300}
32301
32302/// If the lengths match, coerces element-wise.32335/// If the lengths match, coerces element-wise.
32303fn coerceArrayLike(32336fn coerceArrayLike(
32304 sema: *Sema,32337 sema: *Sema,
...@@ -32530,7 +32563,7 @@ fn coerceTupleToStruct(...@@ -32530,7 +32563,7 @@ fn coerceTupleToStruct(
32530 try struct_ty.resolveFields(pt);32563 try struct_ty.resolveFields(pt);
32531 try struct_ty.resolveStructFieldInits(pt);32564 try struct_ty.resolveStructFieldInits(pt);
3253232565
32533 if (struct_ty.isTupleOrAnonStruct(zcu)) {32566 if (struct_ty.isTuple(zcu)) {
32534 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);32567 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
32535 }32568 }
3253632569
...@@ -32542,7 +32575,7 @@ fn coerceTupleToStruct(...@@ -32542,7 +32575,7 @@ fn coerceTupleToStruct(
32542 const inst_ty = sema.typeOf(inst);32575 const inst_ty = sema.typeOf(inst);
32543 var runtime_src: ?LazySrcLoc = null;32576 var runtime_src: ?LazySrcLoc = null;
32544 const field_count = switch (ip.indexToKey(inst_ty.toIntern())) {32577 const field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
32545 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,32578 .tuple_type => |tuple| tuple.types.len,
32546 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,32579 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,
32547 else => unreachable,32580 else => unreachable,
32548 };32581 };
...@@ -32557,7 +32590,7 @@ fn coerceTupleToStruct(...@@ -32557,7 +32590,7 @@ fn coerceTupleToStruct(
32557 const coerced = try sema.coerce(block, struct_field_ty, elem_ref, field_src);32590 const coerced = try sema.coerce(block, struct_field_ty, elem_ref, field_src);
32558 field_refs[struct_field_index] = coerced;32591 field_refs[struct_field_index] = coerced;
32559 if (struct_type.fieldIsComptime(ip, struct_field_index)) {32592 if (struct_type.fieldIsComptime(ip, struct_field_index)) {
32560 const init_val = (try sema.resolveValue(coerced)) orelse {32593 const init_val = try sema.resolveValue(coerced) orelse {
32561 return sema.failWithNeededComptime(block, field_src, .{32594 return sema.failWithNeededComptime(block, field_src, .{
32562 .needed_comptime_reason = "value stored in comptime field must be comptime-known",32595 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
32563 });32596 });
...@@ -32636,8 +32669,7 @@ fn coerceTupleToTuple(...@@ -32636,8 +32669,7 @@ fn coerceTupleToTuple(
32636 const zcu = pt.zcu;32669 const zcu = pt.zcu;
32637 const ip = &zcu.intern_pool;32670 const ip = &zcu.intern_pool;
32638 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {32671 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {
32639 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,32672 .tuple_type => |tuple_type| tuple_type.types.len,
32640 .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.len,
32641 else => unreachable,32673 else => unreachable,
32642 };32674 };
32643 const field_vals = try sema.arena.alloc(InternPool.Index, dest_field_count);32675 const field_vals = try sema.arena.alloc(InternPool.Index, dest_field_count);
...@@ -32646,8 +32678,7 @@ fn coerceTupleToTuple(...@@ -32646,8 +32678,7 @@ fn coerceTupleToTuple(
3264632678
32647 const inst_ty = sema.typeOf(inst);32679 const inst_ty = sema.typeOf(inst);
32648 const src_field_count = switch (ip.indexToKey(inst_ty.toIntern())) {32680 const src_field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
32649 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,32681 .tuple_type => |tuple_type| tuple_type.types.len,
32650 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,
32651 else => unreachable,32682 else => unreachable,
32652 };32683 };
32653 if (src_field_count > dest_field_count) return error.NotCoercible;32684 if (src_field_count > dest_field_count) return error.NotCoercible;
...@@ -32656,24 +32687,19 @@ fn coerceTupleToTuple(...@@ -32656,24 +32687,19 @@ fn coerceTupleToTuple(
32656 for (0..dest_field_count) |field_index_usize| {32687 for (0..dest_field_count) |field_index_usize| {
32657 const field_i: u32 = @intCast(field_index_usize);32688 const field_i: u32 = @intCast(field_index_usize);
32658 const field_src = inst_src; // TODO better source location32689 const field_src = inst_src; // TODO better source location
32659 const field_name = inst_ty.structFieldName(field_index_usize, zcu).unwrap() orelse
32660 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index_usize}, .no_embedded_nulls);
32661
32662 if (field_name.eqlSlice("len", ip))
32663 return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
3266432690
32665 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {32691 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
32666 .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[field_index_usize],32692 .tuple_type => |tuple_type| tuple_type.types.get(ip)[field_index_usize],
32667 .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.get(ip)[field_index_usize],32693 .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.get(ip)[field_index_usize],
32668 else => unreachable,32694 else => unreachable,
32669 };32695 };
32670 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {32696 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
32671 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[field_index_usize],32697 .tuple_type => |tuple_type| tuple_type.values.get(ip)[field_index_usize],
32672 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, field_index_usize),32698 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, field_index_usize),
32673 else => unreachable,32699 else => unreachable,
32674 };32700 };
3267532701
32676 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_src);32702 const field_index: u32 = @intCast(field_index_usize);
3267732703
32678 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);32704 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);
32679 const coerced = try sema.coerce(block, Type.fromInterned(field_ty), elem_ref, field_src);32705 const coerced = try sema.coerce(block, Type.fromInterned(field_ty), elem_ref, field_src);
...@@ -32707,28 +32733,18 @@ fn coerceTupleToTuple(...@@ -32707,28 +32733,18 @@ fn coerceTupleToTuple(
32707 if (field_ref.* != .none) continue;32733 if (field_ref.* != .none) continue;
3270832734
32709 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {32735 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
32710 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[i],32736 .tuple_type => |tuple_type| tuple_type.values.get(ip)[i],
32711 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, i),32737 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, i),
32712 else => unreachable,32738 else => unreachable,
32713 };32739 };
3271432740
32715 const field_src = inst_src; // TODO better source location32741 const field_src = inst_src; // TODO better source location
32716 if (default_val == .none) {32742 if (default_val == .none) {
32717 const field_name = tuple_ty.structFieldName(i, zcu).unwrap() orelse {32743 const template = "missing tuple field: {d}";
32718 const template = "missing tuple field: {d}";
32719 if (root_msg) |msg| {
32720 try sema.errNote(field_src, msg, template, .{i});
32721 } else {
32722 root_msg = try sema.errMsg(field_src, template, .{i});
32723 }
32724 continue;
32725 };
32726 const template = "missing struct field: {}";
32727 const args = .{field_name.fmt(ip)};
32728 if (root_msg) |msg| {32744 if (root_msg) |msg| {
32729 try sema.errNote(field_src, msg, template, args);32745 try sema.errNote(field_src, msg, template, .{i});
32730 } else {32746 } else {
32731 root_msg = try sema.errMsg(field_src, template, args);32747 root_msg = try sema.errMsg(field_src, template, .{i});
32732 }32748 }
32733 continue;32749 continue;
32734 }32750 }
...@@ -34265,8 +34281,8 @@ const PeerResolveStrategy = enum {...@@ -34265,8 +34281,8 @@ const PeerResolveStrategy = enum {
34265 fixed_int,34281 fixed_int,
34266 /// The type must be some fixed-width float type.34282 /// The type must be some fixed-width float type.
34267 fixed_float,34283 fixed_float,
34268 /// The type must be a struct literal or tuple type.34284 /// The type must be a tuple.
34269 coercible_struct,34285 tuple,
34270 /// The peers must all be of the same type.34286 /// The peers must all be of the same type.
34271 exact,34287 exact,
3427234288
...@@ -34350,9 +34366,9 @@ const PeerResolveStrategy = enum {...@@ -34350,9 +34366,9 @@ const PeerResolveStrategy = enum {
34350 .fixed_float => .{ .either, .fixed_float },34366 .fixed_float => .{ .either, .fixed_float },
34351 else => .{ .all_s1, s1 }, // doesn't override anything later34367 else => .{ .all_s1, s1 }, // doesn't override anything later
34352 },34368 },
34353 .coercible_struct => switch (s1) {34369 .tuple => switch (s1) {
34354 .exact => .{ .all_s1, .exact },34370 .exact => .{ .all_s1, .exact },
34355 else => .{ .all_s0, .coercible_struct },34371 else => .{ .all_s0, .tuple },
34356 },34372 },
34357 .exact => .{ .all_s0, .exact },34373 .exact => .{ .all_s0, .exact },
34358 };34374 };
...@@ -34393,7 +34409,7 @@ const PeerResolveStrategy = enum {...@@ -34393,7 +34409,7 @@ const PeerResolveStrategy = enum {
34393 .error_set => .error_set,34409 .error_set => .error_set,
34394 .error_union => .error_union,34410 .error_union => .error_union,
34395 .enum_literal, .@"enum", .@"union" => .enum_or_union,34411 .enum_literal, .@"enum", .@"union" => .enum_or_union,
34396 .@"struct" => if (ty.isTupleOrAnonStruct(zcu)) .coercible_struct else .exact,34412 .@"struct" => if (ty.isTuple(zcu)) .tuple else .exact,
34397 .@"fn" => .func,34413 .@"fn" => .func,
34398 };34414 };
34399 }34415 }
...@@ -35501,19 +35517,17 @@ fn resolvePeerTypesInner(...@@ -35501,19 +35517,17 @@ fn resolvePeerTypesInner(
35501 return .{ .success = opt_cur_ty.? };35517 return .{ .success = opt_cur_ty.? };
35502 },35518 },
3550335519
35504 .coercible_struct => {35520 .tuple => {
35505 // First, check that every peer has the same approximate structure (field count and names)35521 // First, check that every peer has the same approximate structure (field count)
3550635522
35507 var opt_first_idx: ?usize = null;35523 var opt_first_idx: ?usize = null;
35508 var is_tuple: bool = undefined;35524 var is_tuple: bool = undefined;
35509 var field_count: usize = undefined;35525 var field_count: usize = undefined;
35510 // Only defined for non-tuples.
35511 var field_names: []InternPool.NullTerminatedString = undefined;
3551235526
35513 for (peer_tys, 0..) |opt_ty, i| {35527 for (peer_tys, 0..) |opt_ty, i| {
35514 const ty = opt_ty orelse continue;35528 const ty = opt_ty orelse continue;
3551535529
35516 if (!ty.isTupleOrAnonStruct(zcu)) {35530 if (!ty.isTuple(zcu)) {
35517 return .{ .conflict = .{35531 return .{ .conflict = .{
35518 .peer_idx_a = strat_reason,35532 .peer_idx_a = strat_reason,
35519 .peer_idx_b = i,35533 .peer_idx_b = i,
...@@ -35524,31 +35538,15 @@ fn resolvePeerTypesInner(...@@ -35524,31 +35538,15 @@ fn resolvePeerTypesInner(
35524 opt_first_idx = i;35538 opt_first_idx = i;
35525 is_tuple = ty.isTuple(zcu);35539 is_tuple = ty.isTuple(zcu);
35526 field_count = ty.structFieldCount(zcu);35540 field_count = ty.structFieldCount(zcu);
35527 if (!is_tuple) {
35528 const names = ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip);
35529 field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names);
35530 }
35531 continue;35541 continue;
35532 };35542 };
3553335543
35534 if (ty.isTuple(zcu) != is_tuple or ty.structFieldCount(zcu) != field_count) {35544 if (ty.structFieldCount(zcu) != field_count) {
35535 return .{ .conflict = .{35545 return .{ .conflict = .{
35536 .peer_idx_a = first_idx,35546 .peer_idx_a = first_idx,
35537 .peer_idx_b = i,35547 .peer_idx_b = i,
35538 } };35548 } };
35539 }35549 }
35540
35541 if (!is_tuple) {
35542 for (field_names, 0..) |expected, field_index_usize| {
35543 const field_index: u32 = @intCast(field_index_usize);
35544 const actual = ty.structFieldName(field_index, zcu).unwrap().?;
35545 if (actual == expected) continue;
35546 return .{ .conflict = .{
35547 .peer_idx_a = first_idx,
35548 .peer_idx_b = i,
35549 } };
35550 }
35551 }
35552 }35550 }
3555335551
35554 assert(opt_first_idx != null);35552 assert(opt_first_idx != null);
...@@ -35578,10 +35576,7 @@ fn resolvePeerTypesInner(...@@ -35578,10 +35576,7 @@ fn resolvePeerTypesInner(
35578 else => |result| {35576 else => |result| {
35579 const result_buf = try sema.arena.create(PeerResolveResult);35577 const result_buf = try sema.arena.create(PeerResolveResult);
35580 result_buf.* = result;35578 result_buf.* = result;
35581 const field_name = if (is_tuple)35579 const field_name = try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
35582 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls)
35583 else
35584 field_names[field_index];
3558535580
35586 // The error info needs the field types, but we can't reuse sub_peer_tys35581 // The error info needs the field types, but we can't reuse sub_peer_tys
35587 // since the recursive call may have clobbered it.35582 // since the recursive call may have clobbered it.
...@@ -35636,9 +35631,8 @@ fn resolvePeerTypesInner(...@@ -35636,9 +35631,8 @@ fn resolvePeerTypesInner(
35636 field_val.* = if (comptime_val) |v| v.toIntern() else .none;35631 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
35637 }35632 }
3563835633
35639 const final_ty = try ip.getAnonStructType(zcu.gpa, pt.tid, .{35634 const final_ty = try ip.getTupleType(zcu.gpa, pt.tid, .{
35640 .types = field_types,35635 .types = field_types,
35641 .names = if (is_tuple) &.{} else field_names,
35642 .values = field_vals,35636 .values = field_vals,
35643 });35637 });
3564435638
...@@ -35778,7 +35772,7 @@ pub fn resolveStructAlignment(...@@ -35778,7 +35772,7 @@ pub fn resolveStructAlignment(
35778 const ip = &zcu.intern_pool;35772 const ip = &zcu.intern_pool;
35779 const target = zcu.getTarget();35773 const target = zcu.getTarget();
3578035774
35781 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);35775 assert(sema.owner.unwrap().cau == struct_type.cau);
3578235776
35783 assert(struct_type.layout != .@"packed");35777 assert(struct_type.layout != .@"packed");
35784 assert(struct_type.flagsUnordered(ip).alignment == .none);35778 assert(struct_type.flagsUnordered(ip).alignment == .none);
...@@ -35821,7 +35815,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35821,7 +35815,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35821 const ip = &zcu.intern_pool;35815 const ip = &zcu.intern_pool;
35822 const struct_type = zcu.typeToStruct(ty) orelse return;35816 const struct_type = zcu.typeToStruct(ty) orelse return;
3582335817
35824 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);35818 assert(sema.owner.unwrap().cau == struct_type.cau);
3582535819
35826 if (struct_type.haveLayout(ip))35820 if (struct_type.haveLayout(ip))
35827 return;35821 return;
...@@ -35921,12 +35915,14 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35921,12 +35915,14 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35921 return a_align.compare(.gt, b_align);35915 return a_align.compare(.gt, b_align);
35922 }35916 }
35923 };35917 };
35924 if (struct_type.isTuple(ip) or !zcu.backendSupportsFeature(.field_reordering)) {35918 if (!zcu.backendSupportsFeature(.field_reordering)) {
35925 // TODO: don't handle tuples differently. This logic exists only because it35919 // TODO: we should probably also reorder tuple fields? This is a bit weird because it'll involve
35926 // uncovers latent bugs if removed. Fix the latent bugs and remove this logic!35920 // mutating the `InternPool` for a non-container type.
35927 // Likewise, implement field reordering support in all the backends!35921 //
35922 // TODO: implement field reordering support in all the backends!
35923 //
35928 // This logic does not reorder fields; it only moves the omitted ones to the end35924 // This logic does not reorder fields; it only moves the omitted ones to the end
35929 // so that logic elsewhere does not need to special-case tuples.35925 // so that logic elsewhere does not need to special-case here.
35930 var i: usize = 0;35926 var i: usize = 0;
35931 var off: usize = 0;35927 var off: usize = 0;
35932 while (i + off < runtime_order.len) {35928 while (i + off < runtime_order.len) {
...@@ -35966,7 +35962,7 @@ fn backingIntType(...@@ -35966,7 +35962,7 @@ fn backingIntType(
35966 const gpa = zcu.gpa;35962 const gpa = zcu.gpa;
35967 const ip = &zcu.intern_pool;35963 const ip = &zcu.intern_pool;
3596835964
35969 const cau_index = struct_type.cau.unwrap().?;35965 const cau_index = struct_type.cau;
3597035966
35971 var analysis_arena = std.heap.ArenaAllocator.init(gpa);35967 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
35972 defer analysis_arena.deinit();35968 defer analysis_arena.deinit();
...@@ -35978,7 +35974,7 @@ fn backingIntType(...@@ -35978,7 +35974,7 @@ fn backingIntType(
35978 .instructions = .{},35974 .instructions = .{},
35979 .inlining = null,35975 .inlining = null,
35980 .is_comptime = true,35976 .is_comptime = true,
35981 .src_base_inst = struct_type.zir_index.unwrap().?,35977 .src_base_inst = struct_type.zir_index,
35982 .type_name_ctx = struct_type.name,35978 .type_name_ctx = struct_type.name,
35983 };35979 };
35984 defer assert(block.instructions.items.len == 0);35980 defer assert(block.instructions.items.len == 0);
...@@ -35992,8 +35988,8 @@ fn backingIntType(...@@ -35992,8 +35988,8 @@ fn backingIntType(
35992 break :blk accumulator;35988 break :blk accumulator;
35993 };35989 };
3599435990
35995 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;35991 const zir = zcu.namespacePtr(struct_type.namespace).fileScope(zcu).zir;
35996 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip) orelse return error.AnalysisFail;35992 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
35997 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;35993 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
35998 assert(extended.opcode == .struct_decl);35994 assert(extended.opcode == .struct_decl);
35999 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);35995 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
...@@ -36014,7 +36010,7 @@ fn backingIntType(...@@ -36014,7 +36010,7 @@ fn backingIntType(
36014 extra_index += 1;36010 extra_index += 1;
3601536011
36016 const backing_int_src: LazySrcLoc = .{36012 const backing_int_src: LazySrcLoc = .{
36017 .base_node_inst = struct_type.zir_index.unwrap().?,36013 .base_node_inst = struct_type.zir_index,
36018 .offset = .{ .node_offset_container_tag = 0 },36014 .offset = .{ .node_offset_container_tag = 0 },
36019 };36015 };
36020 const backing_int_ty = blk: {36016 const backing_int_ty = blk: {
...@@ -36261,7 +36257,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {...@@ -36261,7 +36257,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
36261 const ip = &zcu.intern_pool;36257 const ip = &zcu.intern_pool;
36262 const struct_type = zcu.typeToStruct(ty).?;36258 const struct_type = zcu.typeToStruct(ty).?;
3626336259
36264 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);36260 assert(sema.owner.unwrap().cau == struct_type.cau);
3626536261
36266 if (struct_type.setFullyResolved(ip)) return;36262 if (struct_type.setFullyResolved(ip)) return;
36267 errdefer struct_type.clearFullyResolved(ip);36263 errdefer struct_type.clearFullyResolved(ip);
...@@ -36319,7 +36315,7 @@ pub fn resolveStructFieldTypes(...@@ -36319,7 +36315,7 @@ pub fn resolveStructFieldTypes(
36319 const zcu = pt.zcu;36315 const zcu = pt.zcu;
36320 const ip = &zcu.intern_pool;36316 const ip = &zcu.intern_pool;
3632136317
36322 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);36318 assert(sema.owner.unwrap().cau == struct_type.cau);
3632336319
36324 if (struct_type.haveFieldTypes(ip)) return;36320 if (struct_type.haveFieldTypes(ip)) return;
3632536321
...@@ -36345,7 +36341,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -36345,7 +36341,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
36345 const ip = &zcu.intern_pool;36341 const ip = &zcu.intern_pool;
36346 const struct_type = zcu.typeToStruct(ty) orelse return;36342 const struct_type = zcu.typeToStruct(ty) orelse return;
3634736343
36348 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);36344 assert(sema.owner.unwrap().cau == struct_type.cau);
3634936345
36350 // Inits can start as resolved36346 // Inits can start as resolved
36351 if (struct_type.haveFieldInits(ip)) return;36347 if (struct_type.haveFieldInits(ip)) return;
...@@ -36607,12 +36603,12 @@ fn structFields(...@@ -36607,12 +36603,12 @@ fn structFields(
36607 const zcu = pt.zcu;36603 const zcu = pt.zcu;
36608 const gpa = zcu.gpa;36604 const gpa = zcu.gpa;
36609 const ip = &zcu.intern_pool;36605 const ip = &zcu.intern_pool;
36610 const cau_index = struct_type.cau.unwrap().?;36606 const cau_index = struct_type.cau;
36611 const namespace_index = ip.getCau(cau_index).namespace;36607 const namespace_index = ip.getCau(cau_index).namespace;
36612 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;36608 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36613 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip) orelse return error.AnalysisFail;36609 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
3661436610
36615 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);36611 const fields_len, _, var extra_index = structZirInfo(zir, zir_index);
3661636612
36617 if (fields_len == 0) switch (struct_type.layout) {36613 if (fields_len == 0) switch (struct_type.layout) {
36618 .@"packed" => {36614 .@"packed" => {
...@@ -36632,7 +36628,7 @@ fn structFields(...@@ -36632,7 +36628,7 @@ fn structFields(
36632 .instructions = .{},36628 .instructions = .{},
36633 .inlining = null,36629 .inlining = null,
36634 .is_comptime = true,36630 .is_comptime = true,
36635 .src_base_inst = struct_type.zir_index.unwrap().?,36631 .src_base_inst = struct_type.zir_index,
36636 .type_name_ctx = struct_type.name,36632 .type_name_ctx = struct_type.name,
36637 };36633 };
36638 defer assert(block_scope.instructions.items.len == 0);36634 defer assert(block_scope.instructions.items.len == 0);
...@@ -36673,12 +36669,8 @@ fn structFields(...@@ -36673,12 +36669,8 @@ fn structFields(
3667336669
36674 if (is_comptime) struct_type.setFieldComptime(ip, field_i);36670 if (is_comptime) struct_type.setFieldComptime(ip, field_i);
3667536671
36676 var opt_field_name_zir: ?[:0]const u8 = null;36672 const field_name_zir: [:0]const u8 = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
36677 if (!small.is_tuple) {36673 extra_index += 2; // field_name, doc_comment
36678 opt_field_name_zir = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
36679 extra_index += 1;
36680 }
36681 extra_index += 1; // doc_comment
3668236674
36683 fields[field_i] = .{};36675 fields[field_i] = .{};
3668436676
...@@ -36690,10 +36682,8 @@ fn structFields(...@@ -36690,10 +36682,8 @@ fn structFields(
36690 extra_index += 1;36682 extra_index += 1;
3669136683
36692 // This string needs to outlive the ZIR code.36684 // This string needs to outlive the ZIR code.
36693 if (opt_field_name_zir) |field_name_zir| {36685 const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
36694 const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);36686 assert(struct_type.addFieldName(ip, field_name) == null);
36695 assert(struct_type.addFieldName(ip, field_name) == null);
36696 }
3669736687
36698 if (has_align) {36688 if (has_align) {
36699 fields[field_i].align_body_len = zir.extra[extra_index];36689 fields[field_i].align_body_len = zir.extra[extra_index];
...@@ -36713,7 +36703,7 @@ fn structFields(...@@ -36713,7 +36703,7 @@ fn structFields(
3671336703
36714 for (fields, 0..) |zir_field, field_i| {36704 for (fields, 0..) |zir_field, field_i| {
36715 const ty_src: LazySrcLoc = .{36705 const ty_src: LazySrcLoc = .{
36716 .base_node_inst = struct_type.zir_index.unwrap().?,36706 .base_node_inst = struct_type.zir_index,
36717 .offset = .{ .container_field_type = @intCast(field_i) },36707 .offset = .{ .container_field_type = @intCast(field_i) },
36718 };36708 };
36719 const field_ty: Type = ty: {36709 const field_ty: Type = ty: {
...@@ -36785,7 +36775,7 @@ fn structFields(...@@ -36785,7 +36775,7 @@ fn structFields(
36785 extra_index += body.len;36775 extra_index += body.len;
36786 const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);36776 const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
36787 const align_src: LazySrcLoc = .{36777 const align_src: LazySrcLoc = .{
36788 .base_node_inst = struct_type.zir_index.unwrap().?,36778 .base_node_inst = struct_type.zir_index,
36789 .offset = .{ .container_field_align = @intCast(field_i) },36779 .offset = .{ .container_field_align = @intCast(field_i) },
36790 };36780 };
36791 const field_align = try sema.analyzeAsAlign(&block_scope, align_src, align_ref);36781 const field_align = try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
...@@ -36812,11 +36802,11 @@ fn structFieldInits(...@@ -36812,11 +36802,11 @@ fn structFieldInits(
3681236802
36813 assert(!struct_type.haveFieldInits(ip));36803 assert(!struct_type.haveFieldInits(ip));
3681436804
36815 const cau_index = struct_type.cau.unwrap().?;36805 const cau_index = struct_type.cau;
36816 const namespace_index = ip.getCau(cau_index).namespace;36806 const namespace_index = ip.getCau(cau_index).namespace;
36817 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;36807 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36818 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip) orelse return error.AnalysisFail;36808 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
36819 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);36809 const fields_len, _, var extra_index = structZirInfo(zir, zir_index);
3682036810
36821 var block_scope: Block = .{36811 var block_scope: Block = .{
36822 .parent = null,36812 .parent = null,
...@@ -36825,7 +36815,7 @@ fn structFieldInits(...@@ -36825,7 +36815,7 @@ fn structFieldInits(
36825 .instructions = .{},36815 .instructions = .{},
36826 .inlining = null,36816 .inlining = null,
36827 .is_comptime = true,36817 .is_comptime = true,
36828 .src_base_inst = struct_type.zir_index.unwrap().?,36818 .src_base_inst = struct_type.zir_index,
36829 .type_name_ctx = struct_type.name,36819 .type_name_ctx = struct_type.name,
36830 };36820 };
36831 defer assert(block_scope.instructions.items.len == 0);36821 defer assert(block_scope.instructions.items.len == 0);
...@@ -36860,10 +36850,7 @@ fn structFieldInits(...@@ -36860,10 +36850,7 @@ fn structFieldInits(
36860 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;36850 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
36861 cur_bit_bag >>= 1;36851 cur_bit_bag >>= 1;
3686236852
36863 if (!small.is_tuple) {36853 extra_index += 2; // field_name, doc_comment
36864 extra_index += 1;
36865 }
36866 extra_index += 1; // doc_comment
3686736854
36868 fields[field_i] = .{};36855 fields[field_i] = .{};
3686936856
...@@ -36901,7 +36888,7 @@ fn structFieldInits(...@@ -36901,7 +36888,7 @@ fn structFieldInits(
36901 sema.inst_map.putAssumeCapacity(zir_index, type_ref);36888 sema.inst_map.putAssumeCapacity(zir_index, type_ref);
3690236889
36903 const init_src: LazySrcLoc = .{36890 const init_src: LazySrcLoc = .{
36904 .base_node_inst = struct_type.zir_index.unwrap().?,36891 .base_node_inst = struct_type.zir_index,
36905 .offset = .{ .container_field_value = @intCast(field_i) },36892 .offset = .{ .container_field_value = @intCast(field_i) },
36906 };36893 };
3690736894
...@@ -37430,7 +37417,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37430,7 +37417,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37430 .undefined_type => Value.undef,37417 .undefined_type => Value.undef,
37431 .optional_noreturn_type => try pt.nullValue(ty),37418 .optional_noreturn_type => try pt.nullValue(ty),
37432 .generic_poison_type => error.GenericPoison,37419 .generic_poison_type => error.GenericPoison,
37433 .empty_struct_type => Value.empty_struct,37420 .empty_tuple_type => Value.empty_tuple,
37434 // values, not types37421 // values, not types
37435 .undef,37422 .undef,
37436 .zero,37423 .zero,
...@@ -37446,7 +37433,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37446,7 +37433,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37446 .null_value,37433 .null_value,
37447 .bool_true,37434 .bool_true,
37448 .bool_false,37435 .bool_false,
37449 .empty_struct,37436 .empty_tuple,
37450 .generic_poison,37437 .generic_poison,
37451 // invalid37438 // invalid
37452 .none,37439 .none,
...@@ -37532,10 +37519,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37532,10 +37519,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37532 .type_enum_explicit,37519 .type_enum_explicit,
37533 .type_enum_nonexhaustive,37520 .type_enum_nonexhaustive,
37534 .type_struct,37521 .type_struct,
37535 .type_struct_anon,
37536 .type_struct_packed,37522 .type_struct_packed,
37537 .type_struct_packed_inits,37523 .type_struct_packed_inits,
37538 .type_tuple_anon,37524 .type_tuple,
37539 .type_union,37525 .type_union,
37540 => switch (ip.indexToKey(ty.toIntern())) {37526 => switch (ip.indexToKey(ty.toIntern())) {
37541 inline .array_type, .vector_type => |seq_type, seq_tag| {37527 inline .array_type, .vector_type => |seq_type, seq_tag| {
...@@ -37594,7 +37580,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37594,7 +37580,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37594 } }));37580 } }));
37595 },37581 },
3759637582
37597 .anon_struct_type => |tuple| {37583 .tuple_type => |tuple| {
37598 for (tuple.values.get(ip)) |val| {37584 for (tuple.values.get(ip)) |val| {
37599 if (val == .none) return null;37585 if (val == .none) return null;
37600 }37586 }
...@@ -37965,35 +37951,9 @@ fn structFieldIndex(...@@ -37965,35 +37951,9 @@ fn structFieldIndex(
37965 const zcu = pt.zcu;37951 const zcu = pt.zcu;
37966 const ip = &zcu.intern_pool;37952 const ip = &zcu.intern_pool;
37967 try struct_ty.resolveFields(pt);37953 try struct_ty.resolveFields(pt);
37968 if (struct_ty.isAnonStruct(zcu)) {37954 const struct_type = zcu.typeToStruct(struct_ty).?;
37969 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);37955 return struct_type.nameIndex(ip, field_name) orelse
37970 } else {37956 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);
37971 const struct_type = zcu.typeToStruct(struct_ty).?;
37972 return struct_type.nameIndex(ip, field_name) orelse
37973 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);
37974 }
37975}
37976
37977fn anonStructFieldIndex(
37978 sema: *Sema,
37979 block: *Block,
37980 struct_ty: Type,
37981 field_name: InternPool.NullTerminatedString,
37982 field_src: LazySrcLoc,
37983) !u32 {
37984 const pt = sema.pt;
37985 const zcu = pt.zcu;
37986 const ip = &zcu.intern_pool;
37987 switch (ip.indexToKey(struct_ty.toIntern())) {
37988 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {
37989 if (name == field_name) return @intCast(i);
37990 },
37991 .struct_type => if (ip.loadStructType(struct_ty.toIntern()).nameIndex(ip, field_name)) |i| return i,
37992 else => unreachable,
37993 }
37994 return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{
37995 field_name.fmt(ip), struct_ty.fmt(pt),
37996 });
37997}37957}
3799837958
37999/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting37959/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
src/Sema/bitcast.zig+1-1
...@@ -246,7 +246,7 @@ const UnpackValueBits = struct {...@@ -246,7 +246,7 @@ const UnpackValueBits = struct {
246 .error_union_type,246 .error_union_type,
247 .simple_type,247 .simple_type,
248 .struct_type,248 .struct_type,
249 .anon_struct_type,249 .tuple_type,
250 .union_type,250 .union_type,
251 .opaque_type,251 .opaque_type,
252 .enum_type,252 .enum_type,
src/Type.zig+63-115
...@@ -320,33 +320,20 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -320,33 +320,20 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
320 },320 },
321 .struct_type => {321 .struct_type => {
322 const name = ip.loadStructType(ty.toIntern()).name;322 const name = ip.loadStructType(ty.toIntern()).name;
323 if (name == .empty) {323 try writer.print("{}", .{name.fmt(ip)});
324 try writer.writeAll("@TypeOf(.{})");
325 } else {
326 try writer.print("{}", .{name.fmt(ip)});
327 }
328 },324 },
329 .anon_struct_type => |anon_struct| {325 .tuple_type => |tuple| {
330 if (anon_struct.types.len == 0) {326 if (tuple.types.len == 0) {
331 return writer.writeAll("@TypeOf(.{})");327 return writer.writeAll("@TypeOf(.{})");
332 }328 }
333 try writer.writeAll("struct{");329 try writer.writeAll("struct {");
334 for (anon_struct.types.get(ip), anon_struct.values.get(ip), 0..) |field_ty, val, i| {330 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, val, i| {
335 if (i != 0) try writer.writeAll(", ");331 try writer.writeAll(if (i == 0) " " else ", ");
336 if (val != .none) {332 if (val != .none) try writer.writeAll("comptime ");
337 try writer.writeAll("comptime ");
338 }
339 if (anon_struct.names.len != 0) {
340 try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&zcu.intern_pool)});
341 }
342
343 try print(Type.fromInterned(field_ty), writer, pt);333 try print(Type.fromInterned(field_ty), writer, pt);
344334 if (val != .none) try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)});
345 if (val != .none) {
346 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)});
347 }
348 }335 }
349 try writer.writeAll("}");336 try writer.writeAll(" }");
350 },337 },
351338
352 .union_type => {339 .union_type => {
...@@ -489,8 +476,7 @@ pub fn hasRuntimeBitsInner(...@@ -489,8 +476,7 @@ pub fn hasRuntimeBitsInner(
489) RuntimeBitsError!bool {476) RuntimeBitsError!bool {
490 const ip = &zcu.intern_pool;477 const ip = &zcu.intern_pool;
491 return switch (ty.toIntern()) {478 return switch (ty.toIntern()) {
492 // False because it is a comptime-only type.479 .empty_tuple_type => false,
493 .empty_struct_type => false,
494 else => switch (ip.indexToKey(ty.toIntern())) {480 else => switch (ip.indexToKey(ty.toIntern())) {
495 .int_type => |int_type| int_type.bits != 0,481 .int_type => |int_type| int_type.bits != 0,
496 .ptr_type => {482 .ptr_type => {
...@@ -593,7 +579,7 @@ pub fn hasRuntimeBitsInner(...@@ -593,7 +579,7 @@ pub fn hasRuntimeBitsInner(
593 return false;579 return false;
594 }580 }
595 },581 },
596 .anon_struct_type => |tuple| {582 .tuple_type => |tuple| {
597 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {583 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
598 if (val != .none) continue; // comptime field584 if (val != .none) continue; // comptime field
599 if (try Type.fromInterned(field_ty).hasRuntimeBitsInner(585 if (try Type.fromInterned(field_ty).hasRuntimeBitsInner(
...@@ -691,7 +677,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {...@@ -691,7 +677,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
691 .error_union_type,677 .error_union_type,
692 .error_set_type,678 .error_set_type,
693 .inferred_error_set_type,679 .inferred_error_set_type,
694 .anon_struct_type,680 .tuple_type,
695 .opaque_type,681 .opaque_type,
696 .anyframe_type,682 .anyframe_type,
697 // These are function bodies, not function pointers.683 // These are function bodies, not function pointers.
...@@ -966,7 +952,7 @@ pub fn abiAlignmentInner(...@@ -966,7 +952,7 @@ pub fn abiAlignmentInner(
966 const ip = &zcu.intern_pool;952 const ip = &zcu.intern_pool;
967953
968 switch (ty.toIntern()) {954 switch (ty.toIntern()) {
969 .empty_struct_type => return .{ .scalar = .@"1" },955 .empty_tuple_type => return .{ .scalar = .@"1" },
970 else => switch (ip.indexToKey(ty.toIntern())) {956 else => switch (ip.indexToKey(ty.toIntern())) {
971 .int_type => |int_type| {957 .int_type => |int_type| {
972 if (int_type.bits == 0) return .{ .scalar = .@"1" };958 if (int_type.bits == 0) return .{ .scalar = .@"1" };
...@@ -1109,7 +1095,7 @@ pub fn abiAlignmentInner(...@@ -1109,7 +1095,7 @@ pub fn abiAlignmentInner(
11091095
1110 return .{ .scalar = struct_type.flagsUnordered(ip).alignment };1096 return .{ .scalar = struct_type.flagsUnordered(ip).alignment };
1111 },1097 },
1112 .anon_struct_type => |tuple| {1098 .tuple_type => |tuple| {
1113 var big_align: Alignment = .@"1";1099 var big_align: Alignment = .@"1";
1114 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {1100 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
1115 if (val != .none) continue; // comptime field1101 if (val != .none) continue; // comptime field
...@@ -1295,7 +1281,7 @@ pub fn abiSizeInner(...@@ -1295,7 +1281,7 @@ pub fn abiSizeInner(
1295 const ip = &zcu.intern_pool;1281 const ip = &zcu.intern_pool;
12961282
1297 switch (ty.toIntern()) {1283 switch (ty.toIntern()) {
1298 .empty_struct_type => return .{ .scalar = 0 },1284 .empty_tuple_type => return .{ .scalar = 0 },
12991285
1300 else => switch (ip.indexToKey(ty.toIntern())) {1286 else => switch (ip.indexToKey(ty.toIntern())) {
1301 .int_type => |int_type| {1287 .int_type => |int_type| {
...@@ -1498,7 +1484,7 @@ pub fn abiSizeInner(...@@ -1498,7 +1484,7 @@ pub fn abiSizeInner(
1498 },1484 },
1499 }1485 }
1500 },1486 },
1501 .anon_struct_type => |tuple| {1487 .tuple_type => |tuple| {
1502 switch (strat) {1488 switch (strat) {
1503 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),1489 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),
1504 .lazy, .eager => {},1490 .lazy, .eager => {},
...@@ -1831,8 +1817,7 @@ pub fn bitSizeInner(...@@ -1831,8 +1817,7 @@ pub fn bitSizeInner(
1831 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;1817 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1832 },1818 },
18331819
1834 .anon_struct_type => {1820 .tuple_type => {
1835 if (strat == .sema) try ty.resolveFields(strat.pt(zcu, tid));
1836 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;1821 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1837 },1822 },
18381823
...@@ -2176,7 +2161,7 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo...@@ -2176,7 +2161,7 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo
2176 const ip = &zcu.intern_pool;2161 const ip = &zcu.intern_pool;
2177 return switch (ip.indexToKey(ty.toIntern())) {2162 return switch (ip.indexToKey(ty.toIntern())) {
2178 .struct_type => ip.loadStructType(ty.toIntern()).layout,2163 .struct_type => ip.loadStructType(ty.toIntern()).layout,
2179 .anon_struct_type => .auto,2164 .tuple_type => .auto,
2180 .union_type => ip.loadUnionType(ty.toIntern()).flagsUnordered(ip).layout,2165 .union_type => ip.loadUnionType(ty.toIntern()).flagsUnordered(ip).layout,
2181 else => unreachable,2166 else => unreachable,
2182 };2167 };
...@@ -2295,7 +2280,7 @@ pub fn arrayLenIncludingSentinel(ty: Type, zcu: *const Zcu) u64 {...@@ -2295,7 +2280,7 @@ pub fn arrayLenIncludingSentinel(ty: Type, zcu: *const Zcu) u64 {
2295pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 {2280pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 {
2296 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {2281 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
2297 .vector_type => |vector_type| vector_type.len,2282 .vector_type => |vector_type| vector_type.len,
2298 .anon_struct_type => |tuple| @intCast(tuple.types.len),2283 .tuple_type => |tuple| @intCast(tuple.types.len),
2299 else => unreachable,2284 else => unreachable,
2300 };2285 };
2301}2286}
...@@ -2305,7 +2290,7 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {...@@ -2305,7 +2290,7 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {
2305 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {2290 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
2306 .vector_type,2291 .vector_type,
2307 .struct_type,2292 .struct_type,
2308 .anon_struct_type,2293 .tuple_type,
2309 => null,2294 => null,
23102295
2311 .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null,2296 .array_type => |t| if (t.sentinel != .none) Value.fromInterned(t.sentinel) else null,
...@@ -2386,7 +2371,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {...@@ -2386,7 +2371,7 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
2386 return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() };2371 return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() };
2387 },2372 },
23882373
2389 .anon_struct_type => unreachable,2374 .tuple_type => unreachable,
23902375
2391 .ptr_type => unreachable,2376 .ptr_type => unreachable,
2392 .anyframe_type => unreachable,2377 .anyframe_type => unreachable,
...@@ -2556,7 +2541,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {...@@ -2556,7 +2541,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
2556 var ty = starting_type;2541 var ty = starting_type;
2557 const ip = &zcu.intern_pool;2542 const ip = &zcu.intern_pool;
2558 while (true) switch (ty.toIntern()) {2543 while (true) switch (ty.toIntern()) {
2559 .empty_struct_type => return Value.empty_struct,2544 .empty_tuple_type => return Value.empty_tuple,
25602545
2561 else => switch (ip.indexToKey(ty.toIntern())) {2546 else => switch (ip.indexToKey(ty.toIntern())) {
2562 .int_type => |int_type| {2547 .int_type => |int_type| {
...@@ -2660,7 +2645,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {...@@ -2660,7 +2645,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
2660 } }));2645 } }));
2661 },2646 },
26622647
2663 .anon_struct_type => |tuple| {2648 .tuple_type => |tuple| {
2664 for (tuple.values.get(ip)) |val| {2649 for (tuple.values.get(ip)) |val| {
2665 if (val == .none) return null;2650 if (val == .none) return null;
2666 }2651 }
...@@ -2783,7 +2768,7 @@ pub fn comptimeOnlyInner(...@@ -2783,7 +2768,7 @@ pub fn comptimeOnlyInner(
2783) SemaError!bool {2768) SemaError!bool {
2784 const ip = &zcu.intern_pool;2769 const ip = &zcu.intern_pool;
2785 return switch (ty.toIntern()) {2770 return switch (ty.toIntern()) {
2786 .empty_struct_type => false,2771 .empty_tuple_type => false,
27872772
2788 else => switch (ip.indexToKey(ty.toIntern())) {2773 else => switch (ip.indexToKey(ty.toIntern())) {
2789 .int_type => false,2774 .int_type => false,
...@@ -2891,7 +2876,7 @@ pub fn comptimeOnlyInner(...@@ -2891,7 +2876,7 @@ pub fn comptimeOnlyInner(
2891 };2876 };
2892 },2877 },
28932878
2894 .anon_struct_type => |tuple| {2879 .tuple_type => |tuple| {
2895 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {2880 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
2896 const have_comptime_val = val != .none;2881 const have_comptime_val = val != .none;
2897 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) return true;2882 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) return true;
...@@ -3022,7 +3007,7 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex {...@@ -3022,7 +3007,7 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex {
3022 const ip = &zcu.intern_pool;3007 const ip = &zcu.intern_pool;
3023 return switch (ip.indexToKey(ty.toIntern())) {3008 return switch (ip.indexToKey(ty.toIntern())) {
3024 .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(),3009 .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(),
3025 .struct_type => ip.loadStructType(ty.toIntern()).namespace,3010 .struct_type => ip.loadStructType(ty.toIntern()).namespace.toOptional(),
3026 .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(),3011 .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(),
3027 .enum_type => ip.loadEnumType(ty.toIntern()).namespace.toOptional(),3012 .enum_type => ip.loadEnumType(ty.toIntern()).namespace.toOptional(),
3028 else => .none,3013 else => .none,
...@@ -3181,7 +3166,7 @@ pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.Optio...@@ -3181,7 +3166,7 @@ pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.Optio
3181 const ip = &zcu.intern_pool;3166 const ip = &zcu.intern_pool;
3182 return switch (ip.indexToKey(ty.toIntern())) {3167 return switch (ip.indexToKey(ty.toIntern())) {
3183 .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, index),3168 .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, index),
3184 .anon_struct_type => |anon_struct| anon_struct.fieldName(ip, index),3169 .tuple_type => .none,
3185 else => unreachable,3170 else => unreachable,
3186 };3171 };
3187}3172}
...@@ -3190,7 +3175,7 @@ pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {...@@ -3190,7 +3175,7 @@ pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {
3190 const ip = &zcu.intern_pool;3175 const ip = &zcu.intern_pool;
3191 return switch (ip.indexToKey(ty.toIntern())) {3176 return switch (ip.indexToKey(ty.toIntern())) {
3192 .struct_type => ip.loadStructType(ty.toIntern()).field_types.len,3177 .struct_type => ip.loadStructType(ty.toIntern()).field_types.len,
3193 .anon_struct_type => |anon_struct| anon_struct.types.len,3178 .tuple_type => |tuple| tuple.types.len,
3194 else => unreachable,3179 else => unreachable,
3195 };3180 };
3196}3181}
...@@ -3204,7 +3189,7 @@ pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {...@@ -3204,7 +3189,7 @@ pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
3204 const union_obj = ip.loadUnionType(ty.toIntern());3189 const union_obj = ip.loadUnionType(ty.toIntern());
3205 return Type.fromInterned(union_obj.field_types.get(ip)[index]);3190 return Type.fromInterned(union_obj.field_types.get(ip)[index]);
3206 },3191 },
3207 .anon_struct_type => |anon_struct| Type.fromInterned(anon_struct.types.get(ip)[index]),3192 .tuple_type => |tuple| Type.fromInterned(tuple.types.get(ip)[index]),
3208 else => unreachable,3193 else => unreachable,
3209 };3194 };
3210}3195}
...@@ -3238,8 +3223,8 @@ pub fn fieldAlignmentInner(...@@ -3238,8 +3223,8 @@ pub fn fieldAlignmentInner(
3238 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);3223 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3239 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);3224 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);
3240 },3225 },
3241 .anon_struct_type => |anon_struct| {3226 .tuple_type => |tuple| {
3242 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentInner(3227 return (try Type.fromInterned(tuple.types.get(ip)[index]).abiAlignmentInner(
3243 strat.toLazy(),3228 strat.toLazy(),
3244 zcu,3229 zcu,
3245 tid,3230 tid,
...@@ -3361,8 +3346,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) Value {...@@ -3361,8 +3346,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) Value {
3361 if (val == .none) return Value.@"unreachable";3346 if (val == .none) return Value.@"unreachable";
3362 return Value.fromInterned(val);3347 return Value.fromInterned(val);
3363 },3348 },
3364 .anon_struct_type => |anon_struct| {3349 .tuple_type => |tuple| {
3365 const val = anon_struct.values.get(ip)[index];3350 const val = tuple.values.get(ip)[index];
3366 // TODO: avoid using `unreachable` to indicate this.3351 // TODO: avoid using `unreachable` to indicate this.
3367 if (val == .none) return Value.@"unreachable";3352 if (val == .none) return Value.@"unreachable";
3368 return Value.fromInterned(val);3353 return Value.fromInterned(val);
...@@ -3384,7 +3369,7 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val...@@ -3384,7 +3369,7 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
3384 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);3369 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);
3385 }3370 }
3386 },3371 },
3387 .anon_struct_type => |tuple| {3372 .tuple_type => |tuple| {
3388 const val = tuple.values.get(ip)[index];3373 const val = tuple.values.get(ip)[index];
3389 if (val == .none) {3374 if (val == .none) {
3390 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt);3375 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt);
...@@ -3400,7 +3385,7 @@ pub fn structFieldIsComptime(ty: Type, index: usize, zcu: *const Zcu) bool {...@@ -3400,7 +3385,7 @@ pub fn structFieldIsComptime(ty: Type, index: usize, zcu: *const Zcu) bool {
3400 const ip = &zcu.intern_pool;3385 const ip = &zcu.intern_pool;
3401 return switch (ip.indexToKey(ty.toIntern())) {3386 return switch (ip.indexToKey(ty.toIntern())) {
3402 .struct_type => ip.loadStructType(ty.toIntern()).fieldIsComptime(ip, index),3387 .struct_type => ip.loadStructType(ty.toIntern()).fieldIsComptime(ip, index),
3403 .anon_struct_type => |anon_struct| anon_struct.values.get(ip)[index] != .none,3388 .tuple_type => |tuple| tuple.values.get(ip)[index] != .none,
3404 else => unreachable,3389 else => unreachable,
3405 };3390 };
3406}3391}
...@@ -3425,7 +3410,7 @@ pub fn structFieldOffset(...@@ -3425,7 +3410,7 @@ pub fn structFieldOffset(
3425 return struct_type.offsets.get(ip)[index];3410 return struct_type.offsets.get(ip)[index];
3426 },3411 },
34273412
3428 .anon_struct_type => |tuple| {3413 .tuple_type => |tuple| {
3429 var offset: u64 = 0;3414 var offset: u64 = 0;
3430 var big_align: Alignment = .none;3415 var big_align: Alignment = .none;
34313416
...@@ -3472,7 +3457,6 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {...@@ -3472,7 +3457,6 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
3472 .declared => |d| d.zir_index,3457 .declared => |d| d.zir_index,
3473 .reified => |r| r.zir_index,3458 .reified => |r| r.zir_index,
3474 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,3459 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3475 .empty_struct => return null,
3476 },3460 },
3477 else => return null,3461 else => return null,
3478 },3462 },
...@@ -3491,49 +3475,7 @@ pub fn isGenericPoison(ty: Type) bool {...@@ -3491,49 +3475,7 @@ pub fn isGenericPoison(ty: Type) bool {
3491pub fn isTuple(ty: Type, zcu: *const Zcu) bool {3475pub fn isTuple(ty: Type, zcu: *const Zcu) bool {
3492 const ip = &zcu.intern_pool;3476 const ip = &zcu.intern_pool;
3493 return switch (ip.indexToKey(ty.toIntern())) {3477 return switch (ip.indexToKey(ty.toIntern())) {
3494 .struct_type => {3478 .tuple_type => true,
3495 const struct_type = ip.loadStructType(ty.toIntern());
3496 if (struct_type.layout == .@"packed") return false;
3497 if (struct_type.cau == .none) return false;
3498 return struct_type.flagsUnordered(ip).is_tuple;
3499 },
3500 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,
3501 else => false,
3502 };
3503}
3504
3505pub fn isAnonStruct(ty: Type, zcu: *const Zcu) bool {
3506 if (ty.toIntern() == .empty_struct_type) return true;
3507 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
3508 .anon_struct_type => |anon_struct_type| anon_struct_type.names.len > 0,
3509 else => false,
3510 };
3511}
3512
3513pub fn isTupleOrAnonStruct(ty: Type, zcu: *const Zcu) bool {
3514 const ip = &zcu.intern_pool;
3515 return switch (ip.indexToKey(ty.toIntern())) {
3516 .struct_type => {
3517 const struct_type = ip.loadStructType(ty.toIntern());
3518 if (struct_type.layout == .@"packed") return false;
3519 if (struct_type.cau == .none) return false;
3520 return struct_type.flagsUnordered(ip).is_tuple;
3521 },
3522 .anon_struct_type => true,
3523 else => false,
3524 };
3525}
3526
3527pub fn isSimpleTuple(ty: Type, zcu: *const Zcu) bool {
3528 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
3529 .anon_struct_type => |anon_struct_type| anon_struct_type.names.len == 0,
3530 else => false,
3531 };
3532}
3533
3534pub fn isSimpleTupleOrAnonStruct(ty: Type, zcu: *const Zcu) bool {
3535 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
3536 .anon_struct_type => true,
3537 else => false,3479 else => false,
3538 };3480 };
3539}3481}
...@@ -3564,7 +3506,7 @@ pub fn toUnsigned(ty: Type, pt: Zcu.PerThread) !Type {...@@ -3564,7 +3506,7 @@ pub fn toUnsigned(ty: Type, pt: Zcu.PerThread) !Type {
3564pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {3506pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3565 const ip = &zcu.intern_pool;3507 const ip = &zcu.intern_pool;
3566 return switch (ip.indexToKey(ty.toIntern())) {3508 return switch (ip.indexToKey(ty.toIntern())) {
3567 .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(),3509 .struct_type => ip.loadStructType(ty.toIntern()).zir_index,
3568 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,3510 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3569 .enum_type => ip.loadEnumType(ty.toIntern()).zir_index.unwrap(),3511 .enum_type => ip.loadEnumType(ty.toIntern()).zir_index.unwrap(),
3570 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,3512 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
...@@ -3575,12 +3517,11 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {...@@ -3575,12 +3517,11 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3575pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {3517pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3576 const ip = &zcu.intern_pool;3518 const ip = &zcu.intern_pool;
3577 return switch (ip.indexToKey(ty.toIntern())) {3519 return switch (ip.indexToKey(ty.toIntern())) {
3578 .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(),3520 .struct_type => ip.loadStructType(ty.toIntern()).zir_index,
3579 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,3521 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3580 .enum_type => |e| switch (e) {3522 .enum_type => |e| switch (e) {
3581 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,3523 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3582 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,3524 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3583 .empty_struct => unreachable,
3584 },3525 },
3585 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,3526 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
3586 else => null,3527 else => null,
...@@ -3588,13 +3529,16 @@ pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.Trac...@@ -3588,13 +3529,16 @@ pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.Trac
3588}3529}
35893530
3590pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {3531pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3532 // Note that changes to ZIR instruction tracking only need to update this code
3533 // if a newly-tracked instruction can be a type's owner `zir_index`.
3534 comptime assert(Zir.inst_tracking_version == 0);
3535
3591 const ip = &zcu.intern_pool;3536 const ip = &zcu.intern_pool;
3592 const tracked = switch (ip.indexToKey(ty.toIntern())) {3537 const tracked = switch (ip.indexToKey(ty.toIntern())) {
3593 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {3538 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
3594 .declared => |d| d.zir_index,3539 .declared => |d| d.zir_index,
3595 .reified => |r| r.zir_index,3540 .reified => |r| r.zir_index,
3596 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,3541 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3597 .empty_struct => return null,
3598 },3542 },
3599 else => return null,3543 else => return null,
3600 };3544 };
...@@ -3603,13 +3547,17 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {...@@ -3603,13 +3547,17 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3603 assert(file.zir_loaded);3547 assert(file.zir_loaded);
3604 const zir = file.zir;3548 const zir = file.zir;
3605 const inst = zir.instructions.get(@intFromEnum(info.inst));3549 const inst = zir.instructions.get(@intFromEnum(info.inst));
3606 assert(inst.tag == .extended);3550 return switch (inst.tag) {
3607 return switch (inst.data.extended.opcode) {3551 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
3608 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_line,3552 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_line,
3609 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,3553 .extended => switch (inst.data.extended.opcode) {
3610 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,3554 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_line,
3611 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,3555 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,
3612 .reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.src_line,3556 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,
3557 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,
3558 .reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.src_line,
3559 else => unreachable,
3560 },
3613 else => unreachable,3561 else => unreachable,
3614 };3562 };
3615}3563}
...@@ -3697,8 +3645,8 @@ pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void {...@@ -3697,8 +3645,8 @@ pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void {
3697 const ip = &zcu.intern_pool;3645 const ip = &zcu.intern_pool;
3698 switch (ty.zigTypeTag(zcu)) {3646 switch (ty.zigTypeTag(zcu)) {
3699 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {3647 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
3700 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {3648 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |i| {
3701 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);3649 const field_ty = Type.fromInterned(tuple_type.types.get(ip)[i]);
3702 try field_ty.resolveLayout(pt);3650 try field_ty.resolveLayout(pt);
3703 },3651 },
3704 .struct_type => return ty.resolveStructInner(pt, .layout),3652 .struct_type => return ty.resolveStructInner(pt, .layout),
...@@ -3796,7 +3744,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {...@@ -3796,7 +3744,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
3796 .optional_noreturn_type,3744 .optional_noreturn_type,
3797 .anyerror_void_error_union_type,3745 .anyerror_void_error_union_type,
3798 .generic_poison_type,3746 .generic_poison_type,
3799 .empty_struct_type,3747 .empty_tuple_type,
3800 => {},3748 => {},
38013749
3802 .undef => unreachable,3750 .undef => unreachable,
...@@ -3813,7 +3761,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {...@@ -3813,7 +3761,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
3813 .null_value => unreachable,3761 .null_value => unreachable,
3814 .bool_true => unreachable,3762 .bool_true => unreachable,
3815 .bool_false => unreachable,3763 .bool_false => unreachable,
3816 .empty_struct => unreachable,3764 .empty_tuple => unreachable,
3817 .generic_poison => unreachable,3765 .generic_poison => unreachable,
38183766
3819 else => switch (ty_ip.unwrap(ip).getTag(ip)) {3767 else => switch (ty_ip.unwrap(ip).getTag(ip)) {
...@@ -3868,8 +3816,8 @@ pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void {...@@ -3868,8 +3816,8 @@ pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void {
3868 },3816 },
38693817
3870 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {3818 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
3871 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {3819 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |i| {
3872 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);3820 const field_ty = Type.fromInterned(tuple_type.types.get(ip)[i]);
3873 try field_ty.resolveFully(pt);3821 try field_ty.resolveFully(pt);
3874 },3822 },
3875 .struct_type => return ty.resolveStructInner(pt, .full),3823 .struct_type => return ty.resolveStructInner(pt, .full),
...@@ -3903,7 +3851,7 @@ fn resolveStructInner(...@@ -3903,7 +3851,7 @@ fn resolveStructInner(
3903 const gpa = zcu.gpa;3851 const gpa = zcu.gpa;
39043852
3905 const struct_obj = zcu.typeToStruct(ty).?;3853 const struct_obj = zcu.typeToStruct(ty).?;
3906 const owner = InternPool.AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap() orelse return });3854 const owner = InternPool.AnalUnit.wrap(.{ .cau = struct_obj.cau });
39073855
3908 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {3856 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3909 return error.AnalysisFail;3857 return error.AnalysisFail;
...@@ -3915,7 +3863,7 @@ fn resolveStructInner(...@@ -3915,7 +3863,7 @@ fn resolveStructInner(
3915 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);3863 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
3916 defer comptime_err_ret_trace.deinit();3864 defer comptime_err_ret_trace.deinit();
39173865
3918 const zir = zcu.namespacePtr(struct_obj.namespace.unwrap().?).fileScope(zcu).zir;3866 const zir = zcu.namespacePtr(struct_obj.namespace).fileScope(zcu).zir;
3919 var sema: Sema = .{3867 var sema: Sema = .{
3920 .pt = pt,3868 .pt = pt,
3921 .gpa = gpa,3869 .gpa = gpa,
...@@ -4196,7 +4144,7 @@ pub const single_const_pointer_to_comptime_int: Type = .{...@@ -4196,7 +4144,7 @@ pub const single_const_pointer_to_comptime_int: Type = .{
4196 .ip_index = .single_const_pointer_to_comptime_int_type,4144 .ip_index = .single_const_pointer_to_comptime_int_type,
4197};4145};
4198pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };4146pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };
4199pub const empty_struct_literal: Type = .{ .ip_index = .empty_struct_type };4147pub const empty_tuple_type: Type = .{ .ip_index = .empty_tuple_type };
42004148
4201pub const generic_poison: Type = .{ .ip_index = .generic_poison_type };4149pub const generic_poison: Type = .{ .ip_index = .generic_poison_type };
42024150
src/Value.zig+1-1
...@@ -3704,7 +3704,7 @@ pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };...@@ -3704,7 +3704,7 @@ pub const @"unreachable": Value = .{ .ip_index = .unreachable_value };
37043704
3705pub const generic_poison: Value = .{ .ip_index = .generic_poison };3705pub const generic_poison: Value = .{ .ip_index = .generic_poison };
3706pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type };3706pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type };
3707pub const empty_struct: Value = .{ .ip_index = .empty_struct };3707pub const empty_tuple: Value = .{ .ip_index = .empty_tuple };
37083708
3709pub fn makeBool(x: bool) Value {3709pub fn makeBool(x: bool) Value {
3710 return if (x) Value.true else Value.false;3710 return if (x) Value.true else Value.false;
src/Zcu.zig+33-2
...@@ -1497,6 +1497,20 @@ pub const SrcLoc = struct {...@@ -1497,6 +1497,20 @@ pub const SrcLoc = struct {
1497 }1497 }
1498 } else unreachable;1498 } else unreachable;
1499 },1499 },
1500 .tuple_field_type, .tuple_field_init => |field_info| {
1501 const tree = try src_loc.file_scope.getTree(gpa);
1502 const node = src_loc.relativeToNodeIndex(0);
1503 var buf: [2]Ast.Node.Index = undefined;
1504 const container_decl = tree.fullContainerDecl(&buf, node) orelse
1505 return tree.nodeToSpan(node);
1506
1507 const field = tree.fullContainerField(container_decl.ast.members[field_info.elem_index]).?;
1508 return tree.nodeToSpan(switch (src_loc.lazy) {
1509 .tuple_field_type => field.ast.type_expr,
1510 .tuple_field_init => field.ast.value_expr,
1511 else => unreachable,
1512 });
1513 },
1500 .init_elem => |init_elem| {1514 .init_elem => |init_elem| {
1501 const tree = try src_loc.file_scope.getTree(gpa);1515 const tree = try src_loc.file_scope.getTree(gpa);
1502 const init_node = src_loc.relativeToNodeIndex(init_elem.init_node_offset);1516 const init_node = src_loc.relativeToNodeIndex(init_elem.init_node_offset);
...@@ -1939,6 +1953,12 @@ pub const LazySrcLoc = struct {...@@ -1939,6 +1953,12 @@ pub const LazySrcLoc = struct {
1939 container_field_type: u32,1953 container_field_type: u32,
1940 /// Like `continer_field_name`, but points at the field's alignment.1954 /// Like `continer_field_name`, but points at the field's alignment.
1941 container_field_align: u32,1955 container_field_align: u32,
1956 /// The source location points to the type of the field at the given index
1957 /// of the tuple type declaration at `tuple_decl_node_offset`.
1958 tuple_field_type: TupleField,
1959 /// The source location points to the default init of the field at the given index
1960 /// of the tuple type declaration at `tuple_decl_node_offset`.
1961 tuple_field_init: TupleField,
1942 /// The source location points to the given element/field of a struct or1962 /// The source location points to the given element/field of a struct or
1943 /// array initialization expression.1963 /// array initialization expression.
1944 init_elem: struct {1964 init_elem: struct {
...@@ -2016,13 +2036,20 @@ pub const LazySrcLoc = struct {...@@ -2016,13 +2036,20 @@ pub const LazySrcLoc = struct {
2016 index: u31,2036 index: u31,
2017 };2037 };
20182038
2019 const ArrayCat = struct {2039 pub const ArrayCat = struct {
2020 /// Points to the array concat AST node.2040 /// Points to the array concat AST node.
2021 array_cat_offset: i32,2041 array_cat_offset: i32,
2022 /// The index of the element the source location points to.2042 /// The index of the element the source location points to.
2023 elem_index: u32,2043 elem_index: u32,
2024 };2044 };
20252045
2046 pub const TupleField = struct {
2047 /// Points to the AST node of the tuple type decaration.
2048 tuple_decl_node_offset: i32,
2049 /// The index of the tuple field the source location points to.
2050 elem_index: u32,
2051 };
2052
2026 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;2053 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
20272054
2028 noinline fn nodeOffsetDebug(node_offset: i32) Offset {2055 noinline fn nodeOffsetDebug(node_offset: i32) Offset {
...@@ -2052,6 +2079,8 @@ pub const LazySrcLoc = struct {...@@ -2052,6 +2079,8 @@ pub const LazySrcLoc = struct {
20522079
2053 /// Returns `null` if the ZIR instruction has been lost across incremental updates.2080 /// Returns `null` if the ZIR instruction has been lost across incremental updates.
2054 pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) ?struct { *File, Ast.Node.Index } {2081 pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) ?struct { *File, Ast.Node.Index } {
2082 comptime assert(Zir.inst_tracking_version == 0);
2083
2055 const ip = &zcu.intern_pool;2084 const ip = &zcu.intern_pool;
2056 const file_index, const zir_inst = inst: {2085 const file_index, const zir_inst = inst: {
2057 const info = base_node_inst.resolveFull(ip) orelse return null;2086 const info = base_node_inst.resolveFull(ip) orelse return null;
...@@ -2064,6 +2093,8 @@ pub const LazySrcLoc = struct {...@@ -2064,6 +2093,8 @@ pub const LazySrcLoc = struct {
2064 const inst = zir.instructions.get(@intFromEnum(zir_inst));2093 const inst = zir.instructions.get(@intFromEnum(zir_inst));
2065 const base_node: Ast.Node.Index = switch (inst.tag) {2094 const base_node: Ast.Node.Index = switch (inst.tag) {
2066 .declaration => inst.data.declaration.src_node,2095 .declaration => inst.data.declaration.src_node,
2096 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_node,
2097 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,
2067 .extended => switch (inst.data.extended.opcode) {2098 .extended => switch (inst.data.extended.opcode) {
2068 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_node,2099 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_node,
2069 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,2100 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,
...@@ -3215,7 +3246,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv...@@ -3215,7 +3246,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
32153246
3216 // If this type has a `Cau` for resolution, it's automatically referenced.3247 // If this type has a `Cau` for resolution, it's automatically referenced.
3217 const resolution_cau: InternPool.Cau.Index.Optional = switch (ip.indexToKey(ty)) {3248 const resolution_cau: InternPool.Cau.Index.Optional = switch (ip.indexToKey(ty)) {
3218 .struct_type => ip.loadStructType(ty).cau,3249 .struct_type => ip.loadStructType(ty).cau.toOptional(),
3219 .union_type => ip.loadUnionType(ty).cau.toOptional(),3250 .union_type => ip.loadUnionType(ty).cau.toOptional(),
3220 .enum_type => ip.loadEnumType(ty).cau,3251 .enum_type => ip.loadEnumType(ty).cau,
3221 .opaque_type => .none,3252 .opaque_type => .none,
src/Zcu/PerThread.zig+7-15
...@@ -985,7 +985,6 @@ fn createFileRootStruct(...@@ -985,7 +985,6 @@ fn createFileRootStruct(
985 .fields_len = fields_len,985 .fields_len = fields_len,
986 .known_non_opv = small.known_non_opv,986 .known_non_opv = small.known_non_opv,
987 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,987 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
988 .is_tuple = small.is_tuple,
989 .any_comptime_fields = small.any_comptime_fields,988 .any_comptime_fields = small.any_comptime_fields,
990 .any_default_inits = small.any_default_inits,989 .any_default_inits = small.any_default_inits,
991 .inits_resolved = false,990 .inits_resolved = false,
...@@ -3191,7 +3190,7 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat...@@ -3191,7 +3190,7 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat
3191 .struct_type => |key| {3190 .struct_type => |key| {
3192 const struct_obj = ip.loadStructType(ty);3191 const struct_obj = ip.loadStructType(ty);
3193 const outdated = already_updating or o: {3192 const outdated = already_updating or o: {
3194 const anal_unit = AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap().? });3193 const anal_unit = AnalUnit.wrap(.{ .cau = struct_obj.cau });
3195 const o = zcu.outdated.swapRemove(anal_unit) or3194 const o = zcu.outdated.swapRemove(anal_unit) or
3196 zcu.potentially_outdated.swapRemove(anal_unit);3195 zcu.potentially_outdated.swapRemove(anal_unit);
3197 if (o) {3196 if (o) {
...@@ -3252,7 +3251,6 @@ fn recreateStructType(...@@ -3252,7 +3251,6 @@ fn recreateStructType(
32523251
3253 const key = switch (full_key) {3252 const key = switch (full_key) {
3254 .reified => unreachable, // never outdated3253 .reified => unreachable, // never outdated
3255 .empty_struct => unreachable, // never outdated
3256 .generated_tag => unreachable, // not a struct3254 .generated_tag => unreachable, // not a struct
3257 .declared => |d| d,3255 .declared => |d| d,
3258 };3256 };
...@@ -3283,16 +3281,13 @@ fn recreateStructType(...@@ -3283,16 +3281,13 @@ fn recreateStructType(
3283 if (captures_len != key.captures.owned.len) return error.AnalysisFail;3281 if (captures_len != key.captures.owned.len) return error.AnalysisFail;
32843282
3285 // The old type will be unused, so drop its dependency information.3283 // The old type will be unused, so drop its dependency information.
3286 ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap().? }));3284 ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = struct_obj.cau }));
3287
3288 const namespace_index = struct_obj.namespace.unwrap().?;
32893285
3290 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{3286 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
3291 .layout = small.layout,3287 .layout = small.layout,
3292 .fields_len = fields_len,3288 .fields_len = fields_len,
3293 .known_non_opv = small.known_non_opv,3289 .known_non_opv = small.known_non_opv,
3294 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,3290 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
3295 .is_tuple = small.is_tuple,
3296 .any_comptime_fields = small.any_comptime_fields,3291 .any_comptime_fields = small.any_comptime_fields,
3297 .any_default_inits = small.any_default_inits,3292 .any_default_inits = small.any_default_inits,
3298 .inits_resolved = false,3293 .inits_resolved = false,
...@@ -3308,17 +3303,17 @@ fn recreateStructType(...@@ -3308,17 +3303,17 @@ fn recreateStructType(
3308 errdefer wip_ty.cancel(ip, pt.tid);3303 errdefer wip_ty.cancel(ip, pt.tid);
33093304
3310 wip_ty.setName(ip, struct_obj.name);3305 wip_ty.setName(ip, struct_obj.name);
3311 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, key.zir_index, namespace_index, wip_ty.index);3306 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, key.zir_index, struct_obj.namespace, wip_ty.index);
3312 try ip.addDependency(3307 try ip.addDependency(
3313 gpa,3308 gpa,
3314 AnalUnit.wrap(.{ .cau = new_cau_index }),3309 AnalUnit.wrap(.{ .cau = new_cau_index }),
3315 .{ .src_hash = key.zir_index },3310 .{ .src_hash = key.zir_index },
3316 );3311 );
3317 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;3312 zcu.namespacePtr(struct_obj.namespace).owner_type = wip_ty.index;
3318 // No need to re-scan the namespace -- `zirStructDecl` will ultimately do that if the type is still alive.3313 // No need to re-scan the namespace -- `zirStructDecl` will ultimately do that if the type is still alive.
3319 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });3314 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
33203315
3321 const new_ty = wip_ty.finish(ip, new_cau_index.toOptional(), namespace_index);3316 const new_ty = wip_ty.finish(ip, new_cau_index.toOptional(), struct_obj.namespace);
3322 if (inst_info.inst == .main_struct_inst) {3317 if (inst_info.inst == .main_struct_inst) {
3323 // This is the root type of a file! Update the reference.3318 // This is the root type of a file! Update the reference.
3324 zcu.setFileRootType(inst_info.file, new_ty);3319 zcu.setFileRootType(inst_info.file, new_ty);
...@@ -3337,7 +3332,6 @@ fn recreateUnionType(...@@ -3337,7 +3332,6 @@ fn recreateUnionType(
33373332
3338 const key = switch (full_key) {3333 const key = switch (full_key) {
3339 .reified => unreachable, // never outdated3334 .reified => unreachable, // never outdated
3340 .empty_struct => unreachable, // never outdated
3341 .generated_tag => unreachable, // not a union3335 .generated_tag => unreachable, // not a union
3342 .declared => |d| d,3336 .declared => |d| d,
3343 };3337 };
...@@ -3429,9 +3423,7 @@ fn recreateEnumType(...@@ -3429,9 +3423,7 @@ fn recreateEnumType(
3429 const ip = &zcu.intern_pool;3423 const ip = &zcu.intern_pool;
34303424
3431 const key = switch (full_key) {3425 const key = switch (full_key) {
3432 .reified => unreachable, // never outdated3426 .reified, .generated_tag => unreachable, // never outdated
3433 .empty_struct => unreachable, // never outdated
3434 .generated_tag => unreachable, // never outdated
3435 .declared => |d| d,3427 .declared => |d| d,
3436 };3428 };
34373429
...@@ -3575,7 +3567,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace...@@ -3575,7 +3567,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
3575 };3567 };
35763568
3577 const key = switch (full_key) {3569 const key = switch (full_key) {
3578 .reified, .empty_struct, .generated_tag => {3570 .reified, .generated_tag => {
3579 // Namespace always empty, so up-to-date.3571 // Namespace always empty, so up-to-date.
3580 namespace.generation = zcu.generation;3572 namespace.generation = zcu.generation;
3581 return;3573 return;
src/arch/sparc64/CodeGen.zig+5-7
...@@ -3114,7 +3114,7 @@ fn binOpImmediate(...@@ -3114,7 +3114,7 @@ fn binOpImmediate(
3114 const reg = try self.register_manager.allocReg(track_inst, gp);3114 const reg = try self.register_manager.allocReg(track_inst, gp);
31153115
3116 if (track_inst) |inst| {3116 if (track_inst) |inst| {
3117 const mcv = .{ .register = reg };3117 const mcv: MCValue = .{ .register = reg };
3118 log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv });3118 log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv });
3119 branch.inst_table.putAssumeCapacity(inst, mcv);3119 branch.inst_table.putAssumeCapacity(inst, mcv);
31203120
...@@ -3252,7 +3252,7 @@ fn binOpRegister(...@@ -3252,7 +3252,7 @@ fn binOpRegister(
32523252
3253 const reg = try self.register_manager.allocReg(track_inst, gp);3253 const reg = try self.register_manager.allocReg(track_inst, gp);
3254 if (track_inst) |inst| {3254 if (track_inst) |inst| {
3255 const mcv = .{ .register = reg };3255 const mcv: MCValue = .{ .register = reg };
3256 log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv });3256 log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv });
3257 branch.inst_table.putAssumeCapacity(inst, mcv);3257 branch.inst_table.putAssumeCapacity(inst, mcv);
32583258
...@@ -3276,7 +3276,7 @@ fn binOpRegister(...@@ -3276,7 +3276,7 @@ fn binOpRegister(
32763276
3277 const reg = try self.register_manager.allocReg(track_inst, gp);3277 const reg = try self.register_manager.allocReg(track_inst, gp);
3278 if (track_inst) |inst| {3278 if (track_inst) |inst| {
3279 const mcv = .{ .register = reg };3279 const mcv: MCValue = .{ .register = reg };
3280 log.debug("binOpRegister move rhs %{d} to register: {} -> {}", .{ inst, rhs, mcv });3280 log.debug("binOpRegister move rhs %{d} to register: {} -> {}", .{ inst, rhs, mcv });
3281 branch.inst_table.putAssumeCapacity(inst, mcv);3281 branch.inst_table.putAssumeCapacity(inst, mcv);
32823282
...@@ -3650,7 +3650,6 @@ fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_ty...@@ -3650,7 +3650,6 @@ fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_ty
3650 assert(off_type == Register or off_type == i13);3650 assert(off_type == Register or off_type == i13);
36513651
3652 const is_imm = (off_type == i13);3652 const is_imm = (off_type == i13);
3653 const rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off };
36543653
3655 switch (abi_size) {3654 switch (abi_size) {
3656 1, 2, 4, 8 => {3655 1, 2, 4, 8 => {
...@@ -3669,7 +3668,7 @@ fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_ty...@@ -3669,7 +3668,7 @@ fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_ty
3669 .is_imm = is_imm,3668 .is_imm = is_imm,
3670 .rd = value_reg,3669 .rd = value_reg,
3671 .rs1 = addr_reg,3670 .rs1 = addr_reg,
3672 .rs2_or_imm = rs2_or_imm,3671 .rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off },
3673 },3672 },
3674 },3673 },
3675 });3674 });
...@@ -4037,7 +4036,6 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t...@@ -4037,7 +4036,6 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t
4037 assert(off_type == Register or off_type == i13);4036 assert(off_type == Register or off_type == i13);
40384037
4039 const is_imm = (off_type == i13);4038 const is_imm = (off_type == i13);
4040 const rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off };
40414039
4042 switch (abi_size) {4040 switch (abi_size) {
4043 1, 2, 4, 8 => {4041 1, 2, 4, 8 => {
...@@ -4056,7 +4054,7 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t...@@ -4056,7 +4054,7 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t
4056 .is_imm = is_imm,4054 .is_imm = is_imm,
4057 .rd = value_reg,4055 .rd = value_reg,
4058 .rs1 = addr_reg,4056 .rs1 = addr_reg,
4059 .rs2_or_imm = rs2_or_imm,4057 .rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off },
4060 },4058 },
4061 },4059 },
4062 });4060 });
src/arch/wasm/CodeGen.zig+3-3
...@@ -3259,7 +3259,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3259,7 +3259,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3259 .error_union_type,3259 .error_union_type,
3260 .simple_type,3260 .simple_type,
3261 .struct_type,3261 .struct_type,
3262 .anon_struct_type,3262 .tuple_type,
3263 .union_type,3263 .union_type,
3264 .opaque_type,3264 .opaque_type,
3265 .enum_type,3265 .enum_type,
...@@ -3273,7 +3273,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3273,7 +3273,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3273 .undefined,3273 .undefined,
3274 .void,3274 .void,
3275 .null,3275 .null,
3276 .empty_struct,3276 .empty_tuple,
3277 .@"unreachable",3277 .@"unreachable",
3278 .generic_poison,3278 .generic_poison,
3279 => unreachable, // non-runtime values3279 => unreachable, // non-runtime values
...@@ -3708,7 +3708,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3708,7 +3708,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3708 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;3708 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
3709 const operand = try func.resolveInst(un_op);3709 const operand = try func.resolveInst(un_op);
3710 const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);3710 const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
3711 const errors_len = .{ .memory = @intFromEnum(sym_index) };3711 const errors_len: WValue = .{ .memory = @intFromEnum(sym_index) };
37123712
3713 try func.emitWValue(operand);3713 try func.emitWValue(operand);
3714 const pt = func.pt;3714 const pt = func.pt;
src/arch/x86_64/CodeGen.zig+1-1
...@@ -13683,7 +13683,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -13683,7 +13683,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
13683 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;13683 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
13684 const operand = try self.resolveInst(un_op);13684 const operand = try self.resolveInst(un_op);
13685 const ty = self.typeOf(un_op);13685 const ty = self.typeOf(un_op);
13686 const result = switch (try self.isNullPtr(inst, ty, operand)) {13686 const result: MCValue = switch (try self.isNullPtr(inst, ty, operand)) {
13687 .eflags => |cc| .{ .eflags = cc.negate() },13687 .eflags => |cc| .{ .eflags = cc.negate() },
13688 else => unreachable,13688 else => unreachable,
13689 };13689 };
src/codegen.zig+3-3
...@@ -216,7 +216,7 @@ pub fn generateSymbol(...@@ -216,7 +216,7 @@ pub fn generateSymbol(
216 .error_union_type,216 .error_union_type,
217 .simple_type,217 .simple_type,
218 .struct_type,218 .struct_type,
219 .anon_struct_type,219 .tuple_type,
220 .union_type,220 .union_type,
221 .opaque_type,221 .opaque_type,
222 .enum_type,222 .enum_type,
...@@ -230,7 +230,7 @@ pub fn generateSymbol(...@@ -230,7 +230,7 @@ pub fn generateSymbol(
230 .undefined,230 .undefined,
231 .void,231 .void,
232 .null,232 .null,
233 .empty_struct,233 .empty_tuple,
234 .@"unreachable",234 .@"unreachable",
235 .generic_poison,235 .generic_poison,
236 => unreachable, // non-runtime values236 => unreachable, // non-runtime values
...@@ -456,7 +456,7 @@ pub fn generateSymbol(...@@ -456,7 +456,7 @@ pub fn generateSymbol(
456 if (padding > 0) try code.appendNTimes(0, padding);456 if (padding > 0) try code.appendNTimes(0, padding);
457 }457 }
458 },458 },
459 .anon_struct_type => |tuple| {459 .tuple_type => |tuple| {
460 const struct_begin = code.items.len;460 const struct_begin = code.items.len;
461 for (461 for (
462 tuple.types.get(ip),462 tuple.types.get(ip),
src/codegen/c.zig+16-25
...@@ -891,7 +891,7 @@ pub const DeclGen = struct {...@@ -891,7 +891,7 @@ pub const DeclGen = struct {
891 .error_union_type,891 .error_union_type,
892 .simple_type,892 .simple_type,
893 .struct_type,893 .struct_type,
894 .anon_struct_type,894 .tuple_type,
895 .union_type,895 .union_type,
896 .opaque_type,896 .opaque_type,
897 .enum_type,897 .enum_type,
...@@ -908,7 +908,7 @@ pub const DeclGen = struct {...@@ -908,7 +908,7 @@ pub const DeclGen = struct {
908 .undefined => unreachable,908 .undefined => unreachable,
909 .void => unreachable,909 .void => unreachable,
910 .null => unreachable,910 .null => unreachable,
911 .empty_struct => unreachable,911 .empty_tuple => unreachable,
912 .@"unreachable" => unreachable,912 .@"unreachable" => unreachable,
913 .generic_poison => unreachable,913 .generic_poison => unreachable,
914914
...@@ -1194,7 +1194,7 @@ pub const DeclGen = struct {...@@ -1194,7 +1194,7 @@ pub const DeclGen = struct {
1194 try writer.writeByte('}');1194 try writer.writeByte('}');
1195 }1195 }
1196 },1196 },
1197 .anon_struct_type => |tuple| {1197 .tuple_type => |tuple| {
1198 if (!location.isInitializer()) {1198 if (!location.isInitializer()) {
1199 try writer.writeByte('(');1199 try writer.writeByte('(');
1200 try dg.renderCType(writer, ctype);1200 try dg.renderCType(writer, ctype);
...@@ -1605,7 +1605,7 @@ pub const DeclGen = struct {...@@ -1605,7 +1605,7 @@ pub const DeclGen = struct {
1605 }),1605 }),
1606 }1606 }
1607 },1607 },
1608 .anon_struct_type => |anon_struct_info| {1608 .tuple_type => |tuple_info| {
1609 if (!location.isInitializer()) {1609 if (!location.isInitializer()) {
1610 try writer.writeByte('(');1610 try writer.writeByte('(');
1611 try dg.renderCType(writer, ctype);1611 try dg.renderCType(writer, ctype);
...@@ -1614,9 +1614,9 @@ pub const DeclGen = struct {...@@ -1614,9 +1614,9 @@ pub const DeclGen = struct {
16141614
1615 try writer.writeByte('{');1615 try writer.writeByte('{');
1616 var need_comma = false;1616 var need_comma = false;
1617 for (0..anon_struct_info.types.len) |field_index| {1617 for (0..tuple_info.types.len) |field_index| {
1618 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;1618 if (tuple_info.values.get(ip)[field_index] != .none) continue;
1619 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);1619 const field_ty = Type.fromInterned(tuple_info.types.get(ip)[field_index]);
1620 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1620 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
16211621
1622 if (need_comma) try writer.writeByte(',');1622 if (need_comma) try writer.writeByte(',');
...@@ -5411,9 +5411,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5411,9 +5411,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5411 const input_val = try f.resolveInst(input);5411 const input_val = try f.resolveInst(input);
5412 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});5412 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
5413 try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: {5413 try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: {
5414 const input_local = .{ .local = locals_index };5414 const input_local_idx = locals_index;
5415 locals_index += 1;5415 locals_index += 1;
5416 break :local input_local;5416 break :local .{ .local = input_local_idx };
5417 } else input_val, .Other);5417 } else input_val, .Other);
5418 try writer.writeByte(')');5418 try writer.writeByte(')');
5419 }5419 }
...@@ -5651,15 +5651,12 @@ fn fieldLocation(...@@ -5651,15 +5651,12 @@ fn fieldLocation(
5651 .begin,5651 .begin,
5652 };5652 };
5653 },5653 },
5654 .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))5654 .tuple_type => return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
5655 .begin5655 .begin
5656 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))5656 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
5657 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }5657 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }
5658 else5658 else
5659 .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|5659 .{ .field = .{ .field = field_index } },
5660 .{ .identifier = field_name.toSlice(ip) }
5661 else
5662 .{ .field = field_index } },
5663 .union_type => {5660 .union_type => {
5664 const loaded_union = ip.loadUnionType(container_ty.toIntern());5661 const loaded_union = ip.loadUnionType(container_ty.toIntern());
5665 switch (loaded_union.flagsUnordered(ip).layout) {5662 switch (loaded_union.flagsUnordered(ip).layout) {
...@@ -5892,10 +5889,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5892,10 +5889,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5892 },5889 },
5893 }5890 }
5894 },5891 },
5895 .anon_struct_type => |anon_struct_info| if (anon_struct_info.fieldName(ip, extra.field_index).unwrap()) |field_name|5892 .tuple_type => .{ .field = extra.field_index },
5896 .{ .identifier = field_name.toSlice(ip) }
5897 else
5898 .{ .field = extra.field_index },
5899 .union_type => field_name: {5893 .union_type => field_name: {
5900 const loaded_union = ip.loadUnionType(struct_ty.toIntern());5894 const loaded_union = ip.loadUnionType(struct_ty.toIntern());
5901 switch (loaded_union.flagsUnordered(ip).layout) {5895 switch (loaded_union.flagsUnordered(ip).layout) {
...@@ -7366,16 +7360,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7366,16 +7360,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7366 },7360 },
7367 }7361 }
7368 },7362 },
7369 .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| {7363 .tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {
7370 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;7364 if (tuple_info.values.get(ip)[field_index] != .none) continue;
7371 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);7365 const field_ty = Type.fromInterned(tuple_info.types.get(ip)[field_index]);
7372 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7366 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
73737367
7374 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7368 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
7375 try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|7369 try f.writeCValueMember(writer, local, .{ .field = field_index });
7376 .{ .identifier = field_name.toSlice(ip) }
7377 else
7378 .{ .field = field_index });
7379 try a.assign(f, writer);7370 try a.assign(f, writer);
7380 try f.writeCValue(writer, resolved_elements[field_index], .Other);7371 try f.writeCValue(writer, resolved_elements[field_index], .Other);
7381 try a.end(f, writer);7372 try a.end(f, writer);
src/codegen/c/Type.zig+8-12
...@@ -1350,7 +1350,7 @@ pub const Pool = struct {...@@ -1350,7 +1350,7 @@ pub const Pool = struct {
1350 .i0_type,1350 .i0_type,
1351 .anyopaque_type,1351 .anyopaque_type,
1352 .void_type,1352 .void_type,
1353 .empty_struct_type,1353 .empty_tuple_type,
1354 .type_type,1354 .type_type,
1355 .comptime_int_type,1355 .comptime_int_type,
1356 .comptime_float_type,1356 .comptime_float_type,
...@@ -1450,7 +1450,7 @@ pub const Pool = struct {...@@ -1450,7 +1450,7 @@ pub const Pool = struct {
1450 .null_value,1450 .null_value,
1451 .bool_true,1451 .bool_true,
1452 .bool_false,1452 .bool_false,
1453 .empty_struct,1453 .empty_tuple,
1454 .generic_poison,1454 .generic_poison,
1455 .none,1455 .none,
1456 => unreachable,1456 => unreachable,
...@@ -1730,16 +1730,16 @@ pub const Pool = struct {...@@ -1730,16 +1730,16 @@ pub const Pool = struct {
1730 ),1730 ),
1731 }1731 }
1732 },1732 },
1733 .anon_struct_type => |anon_struct_info| {1733 .tuple_type => |tuple_info| {
1734 const scratch_top = scratch.items.len;1734 const scratch_top = scratch.items.len;
1735 defer scratch.shrinkRetainingCapacity(scratch_top);1735 defer scratch.shrinkRetainingCapacity(scratch_top);
1736 try scratch.ensureUnusedCapacity(allocator, anon_struct_info.types.len *1736 try scratch.ensureUnusedCapacity(allocator, tuple_info.types.len *
1737 @typeInfo(Field).@"struct".fields.len);1737 @typeInfo(Field).@"struct".fields.len);
1738 var hasher = Hasher.init;1738 var hasher = Hasher.init;
1739 for (0..anon_struct_info.types.len) |field_index| {1739 for (0..tuple_info.types.len) |field_index| {
1740 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;1740 if (tuple_info.values.get(ip)[field_index] != .none) continue;
1741 const field_type = Type.fromInterned(1741 const field_type = Type.fromInterned(
1742 anon_struct_info.types.get(ip)[field_index],1742 tuple_info.types.get(ip)[field_index],
1743 );1743 );
1744 const field_ctype = try pool.fromType(1744 const field_ctype = try pool.fromType(
1745 allocator,1745 allocator,
...@@ -1750,11 +1750,7 @@ pub const Pool = struct {...@@ -1750,11 +1750,7 @@ pub const Pool = struct {
1750 kind.noParameter(),1750 kind.noParameter(),
1751 );1751 );
1752 if (field_ctype.index == .void) continue;1752 if (field_ctype.index == .void) continue;
1753 const field_name = if (anon_struct_info.fieldName(ip, @intCast(field_index))1753 const field_name = try pool.fmt(allocator, "f{d}", .{field_index});
1754 .unwrap()) |field_name|
1755 try pool.string(allocator, field_name.toSlice(ip))
1756 else
1757 try pool.fmt(allocator, "f{d}", .{field_index});
1758 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{1754 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
1759 .name = field_name.index,1755 .name = field_name.index,
1760 .ctype = field_ctype.index,1756 .ctype = field_ctype.index,
src/codegen/llvm.zig+14-17
...@@ -2563,7 +2563,7 @@ pub const Object = struct {...@@ -2563,7 +2563,7 @@ pub const Object = struct {
2563 }2563 }
25642564
2565 switch (ip.indexToKey(ty.toIntern())) {2565 switch (ip.indexToKey(ty.toIntern())) {
2566 .anon_struct_type => |tuple| {2566 .tuple_type => |tuple| {
2567 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .empty;2567 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .empty;
2568 defer fields.deinit(gpa);2568 defer fields.deinit(gpa);
25692569
...@@ -2582,11 +2582,8 @@ pub const Object = struct {...@@ -2582,11 +2582,8 @@ pub const Object = struct {
2582 const field_offset = field_align.forward(offset);2582 const field_offset = field_align.forward(offset);
2583 offset = field_offset + field_size;2583 offset = field_offset + field_size;
25842584
2585 const field_name = if (tuple.names.len != 0)2585 var name_buf: [32]u8 = undefined;
2586 tuple.names.get(ip)[i].toSlice(ip)2586 const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{i}) catch unreachable;
2587 else
2588 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
2589 defer if (tuple.names.len == 0) gpa.free(field_name);
25902587
2591 fields.appendAssumeCapacity(try o.builder.debugMemberType(2588 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2592 try o.builder.metadataString(field_name),2589 try o.builder.metadataString(field_name),
...@@ -3426,7 +3423,7 @@ pub const Object = struct {...@@ -3426,7 +3423,7 @@ pub const Object = struct {
3426 .adhoc_inferred_error_set_type,3423 .adhoc_inferred_error_set_type,
3427 => try o.errorIntType(),3424 => try o.errorIntType(),
3428 .generic_poison_type,3425 .generic_poison_type,
3429 .empty_struct_type,3426 .empty_tuple_type,
3430 => unreachable,3427 => unreachable,
3431 // values, not types3428 // values, not types
3432 .undef,3429 .undef,
...@@ -3443,7 +3440,7 @@ pub const Object = struct {...@@ -3443,7 +3440,7 @@ pub const Object = struct {
3443 .null_value,3440 .null_value,
3444 .bool_true,3441 .bool_true,
3445 .bool_false,3442 .bool_false,
3446 .empty_struct,3443 .empty_tuple,
3447 .generic_poison,3444 .generic_poison,
3448 .none,3445 .none,
3449 => unreachable,3446 => unreachable,
...@@ -3610,13 +3607,13 @@ pub const Object = struct {...@@ -3610,13 +3607,13 @@ pub const Object = struct {
3610 );3607 );
3611 return ty;3608 return ty;
3612 },3609 },
3613 .anon_struct_type => |anon_struct_type| {3610 .tuple_type => |tuple_type| {
3614 var llvm_field_types: std.ArrayListUnmanaged(Builder.Type) = .empty;3611 var llvm_field_types: std.ArrayListUnmanaged(Builder.Type) = .empty;
3615 defer llvm_field_types.deinit(o.gpa);3612 defer llvm_field_types.deinit(o.gpa);
3616 // Although we can estimate how much capacity to add, these cannot be3613 // Although we can estimate how much capacity to add, these cannot be
3617 // relied upon because of the recursive calls to lowerType below.3614 // relied upon because of the recursive calls to lowerType below.
3618 try llvm_field_types.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len);3615 try llvm_field_types.ensureUnusedCapacity(o.gpa, tuple_type.types.len);
3619 try o.struct_field_map.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len);3616 try o.struct_field_map.ensureUnusedCapacity(o.gpa, tuple_type.types.len);
36203617
3621 comptime assert(struct_layout_version == 2);3618 comptime assert(struct_layout_version == 2);
3622 var offset: u64 = 0;3619 var offset: u64 = 0;
...@@ -3625,8 +3622,8 @@ pub const Object = struct {...@@ -3625,8 +3622,8 @@ pub const Object = struct {
3625 const struct_size = t.abiSize(zcu);3622 const struct_size = t.abiSize(zcu);
36263623
3627 for (3624 for (
3628 anon_struct_type.types.get(ip),3625 tuple_type.types.get(ip),
3629 anon_struct_type.values.get(ip),3626 tuple_type.values.get(ip),
3630 0..,3627 0..,
3631 ) |field_ty, field_val, field_index| {3628 ) |field_ty, field_val, field_index| {
3632 if (field_val != .none) continue;3629 if (field_val != .none) continue;
...@@ -3979,7 +3976,7 @@ pub const Object = struct {...@@ -3979,7 +3976,7 @@ pub const Object = struct {
3979 .error_union_type,3976 .error_union_type,
3980 .simple_type,3977 .simple_type,
3981 .struct_type,3978 .struct_type,
3982 .anon_struct_type,3979 .tuple_type,
3983 .union_type,3980 .union_type,
3984 .opaque_type,3981 .opaque_type,
3985 .enum_type,3982 .enum_type,
...@@ -3993,7 +3990,7 @@ pub const Object = struct {...@@ -3993,7 +3990,7 @@ pub const Object = struct {
3993 .undefined => unreachable, // non-runtime value3990 .undefined => unreachable, // non-runtime value
3994 .void => unreachable, // non-runtime value3991 .void => unreachable, // non-runtime value
3995 .null => unreachable, // non-runtime value3992 .null => unreachable, // non-runtime value
3996 .empty_struct => unreachable, // non-runtime value3993 .empty_tuple => unreachable, // non-runtime value
3997 .@"unreachable" => unreachable, // non-runtime value3994 .@"unreachable" => unreachable, // non-runtime value
3998 .generic_poison => unreachable, // non-runtime value3995 .generic_poison => unreachable, // non-runtime value
39993996
...@@ -4232,7 +4229,7 @@ pub const Object = struct {...@@ -4232,7 +4229,7 @@ pub const Object = struct {
4232 ),4229 ),
4233 }4230 }
4234 },4231 },
4235 .anon_struct_type => |tuple| {4232 .tuple_type => |tuple| {
4236 const struct_ty = try o.lowerType(ty);4233 const struct_ty = try o.lowerType(ty);
4237 const llvm_len = struct_ty.aggregateLen(&o.builder);4234 const llvm_len = struct_ty.aggregateLen(&o.builder);
42384235
...@@ -12516,7 +12513,7 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {...@@ -12516,7 +12513,7 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {
12516 .array, .frame => return ty.hasRuntimeBits(zcu),12513 .array, .frame => return ty.hasRuntimeBits(zcu),
12517 .@"struct" => {12514 .@"struct" => {
12518 const struct_type = switch (ip.indexToKey(ty.toIntern())) {12515 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
12519 .anon_struct_type => |tuple| {12516 .tuple_type => |tuple| {
12520 var count: usize = 0;12517 var count: usize = 0;
12521 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {12518 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
12522 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;12519 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
src/codegen/spirv.zig+32-31
...@@ -731,13 +731,15 @@ const NavGen = struct {...@@ -731,13 +731,15 @@ const NavGen = struct {
731 .direct => {731 .direct => {
732 const result_ty_id = try self.resolveType(Type.bool, .direct);732 const result_ty_id = try self.resolveType(Type.bool, .direct);
733 const result_id = self.spv.allocId();733 const result_id = self.spv.allocId();
734 const operands = .{
735 .id_result_type = result_ty_id,
736 .id_result = result_id,
737 };
738 switch (value) {734 switch (value) {
739 true => try section.emit(self.spv.gpa, .OpConstantTrue, operands),735 inline else => |val_ct| try section.emit(
740 false => try section.emit(self.spv.gpa, .OpConstantFalse, operands),736 self.spv.gpa,
737 if (val_ct) .OpConstantTrue else .OpConstantFalse,
738 .{
739 .id_result_type = result_ty_id,
740 .id_result = result_id,
741 },
742 ),
741 }743 }
742 return result_id;744 return result_id;
743 },745 },
...@@ -915,7 +917,7 @@ const NavGen = struct {...@@ -915,7 +917,7 @@ const NavGen = struct {
915 .error_union_type,917 .error_union_type,
916 .simple_type,918 .simple_type,
917 .struct_type,919 .struct_type,
918 .anon_struct_type,920 .tuple_type,
919 .union_type,921 .union_type,
920 .opaque_type,922 .opaque_type,
921 .enum_type,923 .enum_type,
...@@ -937,7 +939,7 @@ const NavGen = struct {...@@ -937,7 +939,7 @@ const NavGen = struct {
937 .undefined,939 .undefined,
938 .void,940 .void,
939 .null,941 .null,
940 .empty_struct,942 .empty_tuple,
941 .@"unreachable",943 .@"unreachable",
942 .generic_poison,944 .generic_poison,
943 => unreachable, // non-runtime values945 => unreachable, // non-runtime values
...@@ -1125,7 +1127,7 @@ const NavGen = struct {...@@ -1125,7 +1127,7 @@ const NavGen = struct {
11251127
1126 return try self.constructStruct(ty, types.items, constituents.items);1128 return try self.constructStruct(ty, types.items, constituents.items);
1127 },1129 },
1128 .anon_struct_type => unreachable, // TODO1130 .tuple_type => unreachable, // TODO
1129 else => unreachable,1131 else => unreachable,
1130 },1132 },
1131 .un => |un| {1133 .un => |un| {
...@@ -1718,7 +1720,7 @@ const NavGen = struct {...@@ -1718,7 +1720,7 @@ const NavGen = struct {
1718 },1720 },
1719 .@"struct" => {1721 .@"struct" => {
1720 const struct_type = switch (ip.indexToKey(ty.toIntern())) {1722 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
1721 .anon_struct_type => |tuple| {1723 .tuple_type => |tuple| {
1722 const member_types = try self.gpa.alloc(IdRef, tuple.values.len);1724 const member_types = try self.gpa.alloc(IdRef, tuple.values.len);
1723 defer self.gpa.free(member_types);1725 defer self.gpa.free(member_types);
17241726
...@@ -2831,18 +2833,12 @@ const NavGen = struct {...@@ -2831,18 +2833,12 @@ const NavGen = struct {
2831 }2833 }
2832 },2834 },
2833 .vulkan => {2835 .vulkan => {
2834 const op_result_ty = blk: {2836 // Operations return a struct{T, T}
2835 // Operations return a struct{T, T}2837 // where T is maybe vectorized.
2836 // where T is maybe vectorized.2838 const op_result_ty: Type = .fromInterned(try ip.getTupleType(zcu.gpa, pt.tid, .{
2837 const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() };2839 .types = &.{ arith_op_ty.toIntern(), arith_op_ty.toIntern() },
2838 const values = [2]InternPool.Index{ .none, .none };2840 .values = &.{ .none, .none },
2839 const index = try ip.getAnonStructType(zcu.gpa, pt.tid, .{2841 }));
2840 .types = &types,
2841 .values = &values,
2842 .names = &.{},
2843 });
2844 break :blk Type.fromInterned(index);
2845 };
2846 const op_result_ty_id = try self.resolveType(op_result_ty, .direct);2842 const op_result_ty_id = try self.resolveType(op_result_ty, .direct);
28472843
2848 const opcode: Opcode = switch (op) {2844 const opcode: Opcode = switch (op) {
...@@ -4867,7 +4863,7 @@ const NavGen = struct {...@@ -4867,7 +4863,7 @@ const NavGen = struct {
4867 var index: usize = 0;4863 var index: usize = 0;
48684864
4869 switch (ip.indexToKey(result_ty.toIntern())) {4865 switch (ip.indexToKey(result_ty.toIntern())) {
4870 .anon_struct_type => |tuple| {4866 .tuple_type => |tuple| {
4871 for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {4867 for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {
4872 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;4868 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
4873 assert(Type.fromInterned(field_ty).hasRuntimeBits(zcu));4869 assert(Type.fromInterned(field_ty).hasRuntimeBits(zcu));
...@@ -6216,15 +6212,20 @@ const NavGen = struct {...@@ -6216,15 +6212,20 @@ const NavGen = struct {
6216 try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());6212 try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
62176213
6218 const result_id = self.spv.allocId();6214 const result_id = self.spv.allocId();
6219 const operands = .{
6220 .id_result_type = bool_ty_id,
6221 .id_result = result_id,
6222 .operand_1 = error_id,
6223 .operand_2 = try self.constInt(Type.anyerror, 0, .direct),
6224 };
6225 switch (pred) {6215 switch (pred) {
6226 .is_err => try self.func.body.emit(self.spv.gpa, .OpINotEqual, operands),6216 inline else => |pred_ct| try self.func.body.emit(
6227 .is_non_err => try self.func.body.emit(self.spv.gpa, .OpIEqual, operands),6217 self.spv.gpa,
6218 switch (pred_ct) {
6219 .is_err => .OpINotEqual,
6220 .is_non_err => .OpIEqual,
6221 },
6222 .{
6223 .id_result_type = bool_ty_id,
6224 .id_result = result_id,
6225 .operand_1 = error_id,
6226 .operand_2 = try self.constInt(Type.anyerror, 0, .direct),
6227 },
6228 ),
6228 }6229 }
6229 return result_id;6230 return result_id;
6230 }6231 }
src/link/Dwarf.zig+29-20
...@@ -2599,16 +2599,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2599,16 +2599,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2599 .anyframe_type,2599 .anyframe_type,
2600 .error_union_type,2600 .error_union_type,
2601 .simple_type,2601 .simple_type,
2602 .anon_struct_type,2602 .tuple_type,
2603 .func_type,2603 .func_type,
2604 .error_set_type,2604 .error_set_type,
2605 .inferred_error_set_type,2605 .inferred_error_set_type,
2606 => .decl_alias,2606 => .decl_alias,
2607 .struct_type => tag: {2607 .struct_type => tag: {
2608 const loaded_struct = ip.loadStructType(nav_val.toIntern());2608 const loaded_struct = ip.loadStructType(nav_val.toIntern());
2609 if (loaded_struct.zir_index == .none) break :tag .decl_alias;
26102609
2611 const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;2610 const type_inst_info = loaded_struct.zir_index.resolveFull(ip).?;
2612 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;2611 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
26132612
2614 const value_inst = value_inst: {2613 const value_inst = value_inst: {
...@@ -3349,7 +3348,7 @@ fn updateType(...@@ -3349,7 +3348,7 @@ fn updateType(
3349 .union_type,3348 .union_type,
3350 .opaque_type,3349 .opaque_type,
3351 => unreachable,3350 => unreachable,
3352 .anon_struct_type => |anon_struct_type| if (anon_struct_type.types.len == 0) {3351 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
3353 try wip_nav.abbrevCode(.namespace_struct_type);3352 try wip_nav.abbrevCode(.namespace_struct_type);
3354 try wip_nav.strp(name);3353 try wip_nav.strp(name);
3355 try diw.writeByte(@intFromBool(false));3354 try diw.writeByte(@intFromBool(false));
...@@ -3359,15 +3358,15 @@ fn updateType(...@@ -3359,15 +3358,15 @@ fn updateType(
3359 try uleb128(diw, ty.abiSize(zcu));3358 try uleb128(diw, ty.abiSize(zcu));
3360 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);3359 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3361 var field_byte_offset: u64 = 0;3360 var field_byte_offset: u64 = 0;
3362 for (0..anon_struct_type.types.len) |field_index| {3361 for (0..tuple_type.types.len) |field_index| {
3363 const comptime_value = anon_struct_type.values.get(ip)[field_index];3362 const comptime_value = tuple_type.values.get(ip)[field_index];
3364 try wip_nav.abbrevCode(if (comptime_value != .none) .struct_field_comptime else .struct_field);3363 try wip_nav.abbrevCode(if (comptime_value != .none) .struct_field_comptime else .struct_field);
3365 if (anon_struct_type.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {3364 {
3366 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});3365 var name_buf: [32]u8 = undefined;
3367 defer dwarf.gpa.free(field_name);3366 const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{field_index}) catch unreachable;
3368 try wip_nav.strp(field_name);3367 try wip_nav.strp(field_name);
3369 }3368 }
3370 const field_type = Type.fromInterned(anon_struct_type.types.get(ip)[field_index]);3369 const field_type = Type.fromInterned(tuple_type.types.get(ip)[field_index]);
3371 try wip_nav.refType(field_type);3370 try wip_nav.refType(field_type);
3372 if (comptime_value != .none) try wip_nav.blockValue(3371 if (comptime_value != .none) try wip_nav.blockValue(
3373 src_loc,3372 src_loc,
...@@ -3595,16 +3594,26 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -3595,16 +3594,26 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
3595 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);3594 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
3596 try wip_nav.flush(ty_src_loc);3595 try wip_nav.flush(ty_src_loc);
3597 } else {3596 } else {
3598 const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));3597 {
3599 assert(decl_inst.tag == .extended);3598 // Note that changes to ZIR instruction tracking only need to update this code
3600 if (switch (decl_inst.data.extended.opcode) {3599 // if a newly-tracked instruction can be a type's owner `zir_index`.
3601 .struct_decl => @as(Zir.Inst.StructDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,3600 comptime assert(Zir.inst_tracking_version == 0);
3602 .enum_decl => @as(Zir.Inst.EnumDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,3601
3603 .union_decl => @as(Zir.Inst.UnionDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,3602 const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
3604 .opaque_decl => @as(Zir.Inst.OpaqueDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,3603 const name_strat: Zir.Inst.NameStrategy = switch (decl_inst.tag) {
3605 .reify => @as(Zir.Inst.NameStrategy, @enumFromInt(decl_inst.data.extended.small)),3604 .struct_init, .struct_init_ref, .struct_init_anon => .anon,
3606 else => unreachable,3605 .extended => switch (decl_inst.data.extended.opcode) {
3607 } == .parent) return;3606 .struct_decl => @as(Zir.Inst.StructDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3607 .enum_decl => @as(Zir.Inst.EnumDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3608 .union_decl => @as(Zir.Inst.UnionDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3609 .opaque_decl => @as(Zir.Inst.OpaqueDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3610 .reify => @as(Zir.Inst.NameStrategy, @enumFromInt(decl_inst.data.extended.small)),
3611 else => unreachable,
3612 },
3613 else => unreachable,
3614 };
3615 if (name_strat == .parent) return;
3616 }
36083617
3609 const unit = try dwarf.getUnit(file.mod);3618 const unit = try dwarf.getUnit(file.mod);
3610 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);3619 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
src/link/Plan9.zig+1-1
...@@ -931,7 +931,7 @@ fn addNavExports(...@@ -931,7 +931,7 @@ fn addNavExports(
931 break;931 break;
932 }932 }
933 }933 }
934 const sym = .{934 const sym: aout.Sym = .{
935 .value = atom.offset.?,935 .value = atom.offset.?,
936 .type = atom.type.toGlobal(),936 .type = atom.type.toGlobal(),
937 .name = try gpa.dupe(u8, exp_name),937 .name = try gpa.dupe(u8, exp_name),
src/main.zig+1-1
...@@ -34,7 +34,7 @@ const Zcu = @import("Zcu.zig");...@@ -34,7 +34,7 @@ const Zcu = @import("Zcu.zig");
34const mingw = @import("mingw.zig");34const mingw = @import("mingw.zig");
35const dev = @import("dev.zig");35const dev = @import("dev.zig");
3636
37pub const std_options = .{37pub const std_options: std.Options = .{
38 .wasiCwd = wasi_cwd,38 .wasiCwd = wasi_cwd,
39 .logFn = log,39 .logFn = log,
40 .enable_segfault_handler = false,40 .enable_segfault_handler = false,
src/print_value.zig+2-2
...@@ -74,7 +74,7 @@ pub fn print(...@@ -74,7 +74,7 @@ pub fn print(
74 .error_union_type,74 .error_union_type,
75 .simple_type,75 .simple_type,
76 .struct_type,76 .struct_type,
77 .anon_struct_type,77 .tuple_type,
78 .union_type,78 .union_type,
79 .opaque_type,79 .opaque_type,
80 .enum_type,80 .enum_type,
...@@ -85,7 +85,7 @@ pub fn print(...@@ -85,7 +85,7 @@ pub fn print(
85 .undef => try writer.writeAll("undefined"),85 .undef => try writer.writeAll("undefined"),
86 .simple_value => |simple_value| switch (simple_value) {86 .simple_value => |simple_value| switch (simple_value) {
87 .void => try writer.writeAll("{}"),87 .void => try writer.writeAll("{}"),
88 .empty_struct => try writer.writeAll(".{}"),88 .empty_tuple => try writer.writeAll(".{}"),
89 .generic_poison => try writer.writeAll("(generic poison)"),89 .generic_poison => try writer.writeAll("(generic poison)"),
90 else => try writer.writeAll(@tagName(simple_value)),90 else => try writer.writeAll(@tagName(simple_value)),
91 },91 },
src/print_zir.zig+30-6
...@@ -563,6 +563,8 @@ const Writer = struct {...@@ -563,6 +563,8 @@ const Writer = struct {
563 .enum_decl => try self.writeEnumDecl(stream, extended),563 .enum_decl => try self.writeEnumDecl(stream, extended),
564 .opaque_decl => try self.writeOpaqueDecl(stream, extended),564 .opaque_decl => try self.writeOpaqueDecl(stream, extended),
565565
566 .tuple_decl => try self.writeTupleDecl(stream, extended),
567
566 .await_nosuspend,568 .await_nosuspend,
567 .c_undef,569 .c_undef,
568 .c_include,570 .c_include,
...@@ -1421,7 +1423,6 @@ const Writer = struct {...@@ -1421,7 +1423,6 @@ const Writer = struct {
14211423
1422 try self.writeFlag(stream, "known_non_opv, ", small.known_non_opv);1424 try self.writeFlag(stream, "known_non_opv, ", small.known_non_opv);
1423 try self.writeFlag(stream, "known_comptime_only, ", small.known_comptime_only);1425 try self.writeFlag(stream, "known_comptime_only, ", small.known_comptime_only);
1424 try self.writeFlag(stream, "tuple, ", small.is_tuple);
14251426
1426 try stream.print("{s}, ", .{@tagName(small.name_strategy)});1427 try stream.print("{s}, ", .{@tagName(small.name_strategy)});
14271428
...@@ -1506,11 +1507,8 @@ const Writer = struct {...@@ -1506,11 +1507,8 @@ const Writer = struct {
1506 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;1507 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
1507 cur_bit_bag >>= 1;1508 cur_bit_bag >>= 1;
15081509
1509 var field_name_index: Zir.NullTerminatedString = .empty;1510 const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1510 if (!small.is_tuple) {1511 extra_index += 1;
1511 field_name_index = @enumFromInt(self.code.extra[extra_index]);
1512 extra_index += 1;
1513 }
1514 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);1512 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1515 extra_index += 1;1513 extra_index += 1;
15161514
...@@ -1948,6 +1946,32 @@ const Writer = struct {...@@ -1948,6 +1946,32 @@ const Writer = struct {
1948 try self.writeSrcNode(stream, 0);1946 try self.writeSrcNode(stream, 0);
1949 }1947 }
19501948
1949 fn writeTupleDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1950 const fields_len = extended.small;
1951 assert(fields_len != 0);
1952 const extra = self.code.extraData(Zir.Inst.TupleDecl, extended.operand);
1953
1954 var extra_index = extra.end;
1955
1956 try stream.writeAll("{ ");
1957
1958 for (0..fields_len) |field_idx| {
1959 if (field_idx != 0) try stream.writeAll(", ");
1960
1961 const field_ty, const field_init = self.code.extra[extra_index..][0..2].*;
1962 extra_index += 2;
1963
1964 try stream.print("@\"{d}\": ", .{field_idx});
1965 try self.writeInstRef(stream, @enumFromInt(field_ty));
1966 try stream.writeAll(" = ");
1967 try self.writeInstRef(stream, @enumFromInt(field_init));
1968 }
1969
1970 try stream.writeAll(" }) ");
1971
1972 try self.writeSrcNode(stream, extra.data.src_node);
1973 }
1974
1951 fn writeErrorSetDecl(1975 fn writeErrorSetDecl(
1952 self: *Writer,1976 self: *Writer,
1953 stream: anytype,1977 stream: anytype,
src/translate_c.zig+8-5
...@@ -2314,8 +2314,11 @@ fn transStringLiteralInitializer(...@@ -2314,8 +2314,11 @@ fn transStringLiteralInitializer(
2314 while (i < num_inits) : (i += 1) {2314 while (i < num_inits) : (i += 1) {
2315 init_list[i] = try transCreateCharLitNode(c, false, stmt.getCodeUnit(i));2315 init_list[i] = try transCreateCharLitNode(c, false, stmt.getCodeUnit(i));
2316 }2316 }
2317 const init_args = .{ .len = num_inits, .elem_type = elem_type };2317 const init_args: ast.Payload.Array.ArrayTypeInfo = .{ .len = num_inits, .elem_type = elem_type };
2318 const init_array_type = try if (array_type.tag() == .array_type) Tag.array_type.create(c.arena, init_args) else Tag.null_sentinel_array_type.create(c.arena, init_args);2318 const init_array_type = if (array_type.tag() == .array_type)
2319 try Tag.array_type.create(c.arena, init_args)
2320 else
2321 try Tag.null_sentinel_array_type.create(c.arena, init_args);
2319 break :blk try Tag.array_init.create(c.arena, .{2322 break :blk try Tag.array_init.create(c.arena, .{
2320 .cond = init_array_type,2323 .cond = init_array_type,
2321 .cases = init_list,2324 .cases = init_list,
...@@ -3910,7 +3913,7 @@ fn transCreateCompoundAssign(...@@ -3910,7 +3913,7 @@ fn transCreateCompoundAssign(
39103913
3911 if ((is_mod or is_div) and is_signed) {3914 if ((is_mod or is_div) and is_signed) {
3912 if (requires_cast) rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node);3915 if (requires_cast) rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node);
3913 const operands = .{ .lhs = lhs_node, .rhs = rhs_node };3916 const operands: @FieldType(ast.Payload.BinOp, "data") = .{ .lhs = lhs_node, .rhs = rhs_node };
3914 const builtin = if (is_mod)3917 const builtin = if (is_mod)
3915 try Tag.signed_remainder.create(c.arena, operands)3918 try Tag.signed_remainder.create(c.arena, operands)
3916 else3919 else
...@@ -3949,7 +3952,7 @@ fn transCreateCompoundAssign(...@@ -3949,7 +3952,7 @@ fn transCreateCompoundAssign(
3949 if (is_ptr_op_signed) rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node);3952 if (is_ptr_op_signed) rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node);
3950 if ((is_mod or is_div) and is_signed) {3953 if ((is_mod or is_div) and is_signed) {
3951 if (requires_cast) rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node);3954 if (requires_cast) rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node);
3952 const operands = .{ .lhs = ref_node, .rhs = rhs_node };3955 const operands: @FieldType(ast.Payload.BinOp, "data") = .{ .lhs = ref_node, .rhs = rhs_node };
3953 const builtin = if (is_mod)3956 const builtin = if (is_mod)
3954 try Tag.signed_remainder.create(c.arena, operands)3957 try Tag.signed_remainder.create(c.arena, operands)
3955 else3958 else
...@@ -4777,7 +4780,7 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan...@@ -4777,7 +4780,7 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
4777 const is_const = is_fn_proto or child_qt.isConstQualified();4780 const is_const = is_fn_proto or child_qt.isConstQualified();
4778 const is_volatile = child_qt.isVolatileQualified();4781 const is_volatile = child_qt.isVolatileQualified();
4779 const elem_type = try transQualType(c, scope, child_qt, source_loc);4782 const elem_type = try transQualType(c, scope, child_qt, source_loc);
4780 const ptr_info = .{4783 const ptr_info: @FieldType(ast.Payload.Pointer, "data") = .{
4781 .is_const = is_const,4784 .is_const = is_const,
4782 .is_volatile = is_volatile,4785 .is_volatile = is_volatile,
4783 .elem_type = elem_type,4786 .elem_type = elem_type,
test/behavior.zig-1
...@@ -26,7 +26,6 @@ test {...@@ -26,7 +26,6 @@ test {
26 _ = @import("behavior/duplicated_test_names.zig");26 _ = @import("behavior/duplicated_test_names.zig");
27 _ = @import("behavior/defer.zig");27 _ = @import("behavior/defer.zig");
28 _ = @import("behavior/destructure.zig");28 _ = @import("behavior/destructure.zig");
29 _ = @import("behavior/empty_tuple_fields.zig");
30 _ = @import("behavior/empty_union.zig");29 _ = @import("behavior/empty_union.zig");
31 _ = @import("behavior/enum.zig");30 _ = @import("behavior/enum.zig");
32 _ = @import("behavior/error.zig");31 _ = @import("behavior/error.zig");
test/behavior/array.zig+1-35
...@@ -596,7 +596,7 @@ test "type coercion of anon struct literal to array" {...@@ -596,7 +596,7 @@ test "type coercion of anon struct literal to array" {
596596
597 var x2: U = .{ .a = 42 };597 var x2: U = .{ .a = 42 };
598 _ = &x2;598 _ = &x2;
599 const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } };599 const t2 = .{ x2, U{ .b = true }, U{ .c = "hello" } };
600 const arr2: [3]U = t2;600 const arr2: [3]U = t2;
601 try expect(arr2[0].a == 42);601 try expect(arr2[0].a == 42);
602 try expect(arr2[1].b == true);602 try expect(arr2[1].b == true);
...@@ -607,40 +607,6 @@ test "type coercion of anon struct literal to array" {...@@ -607,40 +607,6 @@ test "type coercion of anon struct literal to array" {
607 try comptime S.doTheTest();607 try comptime S.doTheTest();
608}608}
609609
610test "type coercion of pointer to anon struct literal to pointer to array" {
611 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
612 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
613 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
614
615 const S = struct {
616 const U = union {
617 a: u32,
618 b: bool,
619 c: []const u8,
620 };
621
622 fn doTheTest() !void {
623 var x1: u8 = 42;
624 _ = &x1;
625 const t1 = &.{ x1, 56, 54 };
626 const arr1: *const [3]u8 = t1;
627 try expect(arr1[0] == 42);
628 try expect(arr1[1] == 56);
629 try expect(arr1[2] == 54);
630
631 var x2: U = .{ .a = 42 };
632 _ = &x2;
633 const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } };
634 const arr2: *const [3]U = t2;
635 try expect(arr2[0].a == 42);
636 try expect(arr2[1].b == true);
637 try expect(mem.eql(u8, arr2[2].c, "hello"));
638 }
639 };
640 try S.doTheTest();
641 try comptime S.doTheTest();
642}
643
644test "array with comptime-only element type" {610test "array with comptime-only element type" {
645 const a = [_]type{ u32, i32 };611 const a = [_]type{ u32, i32 };
646 try testing.expect(a[0] == u32);612 try testing.expect(a[0] == u32);
test/behavior/cast.zig-26
...@@ -2600,32 +2600,6 @@ test "result type is preserved into comptime block" {...@@ -2600,32 +2600,6 @@ test "result type is preserved into comptime block" {
2600 try expect(x == 123);2600 try expect(x == 123);
2601}2601}
26022602
2603test "implicit cast from ptr to tuple to ptr to struct" {
2604 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
2605 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2606 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2607 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2608
2609 const ComptimeReason = union(enum) {
2610 c_import: struct {
2611 a: u32,
2612 },
2613 };
2614
2615 const Block = struct {
2616 reason: ?*const ComptimeReason,
2617 };
2618
2619 var a: u32 = 16;
2620 _ = &a;
2621 var reason = .{ .c_import = .{ .a = a } };
2622 var block = Block{
2623 .reason = &reason,
2624 };
2625 _ = &block;
2626 try expect(block.reason.?.c_import.a == 16);
2627}
2628
2629test "bitcast vector" {2603test "bitcast vector" {
2630 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO2604 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
2631 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO2605 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/empty_file_level_struct.zig deleted-1
...@@ -1 +0,0 @@
1struct {}
test/behavior/empty_file_level_union.zig deleted-1
...@@ -1 +0,0 @@
1union {}
test/behavior/empty_tuple_fields.zig deleted-28
...@@ -1,28 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4test "empty file level struct" {
5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
9
10 const T = @import("empty_file_level_struct.zig");
11 const info = @typeInfo(T);
12 try std.testing.expectEqual(@as(usize, 1), info.@"struct".fields.len);
13 try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
14 try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"struct");
15}
16
17test "empty file level union" {
18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
21 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
22
23 const T = @import("empty_file_level_union.zig");
24 const info = @typeInfo(T);
25 try std.testing.expectEqual(@as(usize, 1), info.@"struct".fields.len);
26 try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
27 try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"union");
28}
test/behavior/struct.zig+17-78
...@@ -1013,84 +1013,6 @@ test "struct with 0-length union array field" {...@@ -1013,84 +1013,6 @@ test "struct with 0-length union array field" {
1013 try expectEqual(@as(usize, 0), s.zero_length.len);1013 try expectEqual(@as(usize, 0), s.zero_length.len);
1014}1014}
10151015
1016test "type coercion of anon struct literal to struct" {
1017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1018 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1019 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1020 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1021
1022 const S = struct {
1023 const S2 = struct {
1024 A: u32,
1025 B: []const u8,
1026 C: void,
1027 D: Foo = .{},
1028 };
1029
1030 const Foo = struct {
1031 field: i32 = 1234,
1032 };
1033
1034 fn doTheTest() !void {
1035 var y: u32 = 42;
1036 _ = &y;
1037 const t0 = .{ .A = 123, .B = "foo", .C = {} };
1038 const t1 = .{ .A = y, .B = "foo", .C = {} };
1039 const y0: S2 = t0;
1040 const y1: S2 = t1;
1041 try expect(y0.A == 123);
1042 try expect(std.mem.eql(u8, y0.B, "foo"));
1043 try expect(y0.C == {});
1044 try expect(y0.D.field == 1234);
1045 try expect(y1.A == y);
1046 try expect(std.mem.eql(u8, y1.B, "foo"));
1047 try expect(y1.C == {});
1048 try expect(y1.D.field == 1234);
1049 }
1050 };
1051 try S.doTheTest();
1052 try comptime S.doTheTest();
1053}
1054
1055test "type coercion of pointer to anon struct literal to pointer to struct" {
1056 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1057 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1058 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1059 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1060
1061 const S = struct {
1062 const S2 = struct {
1063 A: u32,
1064 B: []const u8,
1065 C: void,
1066 D: Foo = .{},
1067 };
1068
1069 const Foo = struct {
1070 field: i32 = 1234,
1071 };
1072
1073 fn doTheTest() !void {
1074 var y: u32 = 42;
1075 _ = &y;
1076 const t0 = &.{ .A = 123, .B = "foo", .C = {} };
1077 const t1 = &.{ .A = y, .B = "foo", .C = {} };
1078 const y0: *const S2 = t0;
1079 const y1: *const S2 = t1;
1080 try expect(y0.A == 123);
1081 try expect(std.mem.eql(u8, y0.B, "foo"));
1082 try expect(y0.C == {});
1083 try expect(y0.D.field == 1234);
1084 try expect(y1.A == y);
1085 try expect(std.mem.eql(u8, y1.B, "foo"));
1086 try expect(y1.C == {});
1087 try expect(y1.D.field == 1234);
1088 }
1089 };
1090 try S.doTheTest();
1091 try comptime S.doTheTest();
1092}
1093
1094test "packed struct with undefined initializers" {1016test "packed struct with undefined initializers" {
1095 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1017 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1096 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1018 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -2183,3 +2105,20 @@ test "extern struct @FieldType" {...@@ -2183,3 +2105,20 @@ test "extern struct @FieldType" {
2183 comptime assert(@FieldType(S, "b") == f64);2105 comptime assert(@FieldType(S, "b") == f64);
2184 comptime assert(@FieldType(S, "c") == *S);2106 comptime assert(@FieldType(S, "c") == *S);
2185}2107}
2108
2109test "anonymous struct equivalence" {
2110 const S = struct {
2111 fn anonStructType(comptime x: anytype) type {
2112 const val = .{ .a = "hello", .b = x };
2113 return @TypeOf(val);
2114 }
2115 };
2116
2117 const A = S.anonStructType(123);
2118 const B = S.anonStructType(123);
2119 const C = S.anonStructType(456);
2120
2121 comptime assert(A == B);
2122 comptime assert(A != C);
2123 comptime assert(B != C);
2124}
test/behavior/tuple.zig+23-11
...@@ -150,7 +150,7 @@ test "array-like initializer for tuple types" {...@@ -150,7 +150,7 @@ test "array-like initializer for tuple types" {
150 .type = u8,150 .type = u8,
151 .default_value = null,151 .default_value = null,
152 .is_comptime = false,152 .is_comptime = false,
153 .alignment = @alignOf(i32),153 .alignment = @alignOf(u8),
154 },154 },
155 },155 },
156 },156 },
...@@ -566,16 +566,28 @@ test "comptime fields in tuple can be initialized" {...@@ -566,16 +566,28 @@ test "comptime fields in tuple can be initialized" {
566 _ = &a;566 _ = &a;
567}567}
568568
569test "tuple default values" {569test "empty struct in tuple" {
570 const T = struct {570 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
571 usize,571 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
572 usize = 123,572 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
573 usize = 456,573 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
574 };
575574
576 const t: T = .{1};575 const T = struct { struct {} };
576 const info = @typeInfo(T);
577 try std.testing.expectEqual(@as(usize, 1), info.@"struct".fields.len);
578 try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
579 try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"struct");
580}
581
582test "empty union in tuple" {
583 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
584 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
585 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
586 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
577587
578 try expectEqual(1, t[0]);588 const T = struct { union {} };
579 try expectEqual(123, t[1]);589 const info = @typeInfo(T);
580 try expectEqual(456, t[2]);590 try std.testing.expectEqual(@as(usize, 1), info.@"struct".fields.len);
591 try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name);
592 try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"union");
581}593}
test/behavior/tuple_declarations.zig+3-3
...@@ -9,7 +9,7 @@ test "tuple declaration type info" {...@@ -9,7 +9,7 @@ test "tuple declaration type info" {
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1010
11 {11 {
12 const T = struct { comptime u32 align(2) = 1, []const u8 };12 const T = struct { comptime u32 = 1, []const u8 };
13 const info = @typeInfo(T).@"struct";13 const info = @typeInfo(T).@"struct";
1414
15 try expect(info.layout == .auto);15 try expect(info.layout == .auto);
...@@ -22,7 +22,7 @@ test "tuple declaration type info" {...@@ -22,7 +22,7 @@ test "tuple declaration type info" {
22 try expect(info.fields[0].type == u32);22 try expect(info.fields[0].type == u32);
23 try expect(@as(*const u32, @ptrCast(@alignCast(info.fields[0].default_value))).* == 1);23 try expect(@as(*const u32, @ptrCast(@alignCast(info.fields[0].default_value))).* == 1);
24 try expect(info.fields[0].is_comptime);24 try expect(info.fields[0].is_comptime);
25 try expect(info.fields[0].alignment == 2);25 try expect(info.fields[0].alignment == @alignOf(u32));
2626
27 try expectEqualStrings(info.fields[1].name, "1");27 try expectEqualStrings(info.fields[1].name, "1");
28 try expect(info.fields[1].type == []const u8);28 try expect(info.fields[1].type == []const u8);
...@@ -32,7 +32,7 @@ test "tuple declaration type info" {...@@ -32,7 +32,7 @@ test "tuple declaration type info" {
32 }32 }
33}33}
3434
35test "Tuple declaration usage" {35test "tuple declaration usage" {
36 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;36 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
37 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;37 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
3838
test/behavior/union.zig-70
...@@ -986,76 +986,6 @@ test "function call result coerces from tagged union to the tag" {...@@ -986,76 +986,6 @@ test "function call result coerces from tagged union to the tag" {
986 try comptime S.doTheTest();986 try comptime S.doTheTest();
987}987}
988988
989test "cast from anonymous struct to union" {
990 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
991 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
992 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
993 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
994
995 const S = struct {
996 const U = union(enum) {
997 A: u32,
998 B: []const u8,
999 C: void,
1000 };
1001 fn doTheTest() !void {
1002 var y: u32 = 42;
1003 _ = &y;
1004 const t0 = .{ .A = 123 };
1005 const t1 = .{ .B = "foo" };
1006 const t2 = .{ .C = {} };
1007 const t3 = .{ .A = y };
1008 const x0: U = t0;
1009 var x1: U = t1;
1010 _ = &x1;
1011 const x2: U = t2;
1012 var x3: U = t3;
1013 _ = &x3;
1014 try expect(x0.A == 123);
1015 try expect(std.mem.eql(u8, x1.B, "foo"));
1016 try expect(x2 == .C);
1017 try expect(x3.A == y);
1018 }
1019 };
1020 try S.doTheTest();
1021 try comptime S.doTheTest();
1022}
1023
1024test "cast from pointer to anonymous struct to pointer to union" {
1025 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1026 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1027 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1028 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1029
1030 const S = struct {
1031 const U = union(enum) {
1032 A: u32,
1033 B: []const u8,
1034 C: void,
1035 };
1036 fn doTheTest() !void {
1037 var y: u32 = 42;
1038 _ = &y;
1039 const t0 = &.{ .A = 123 };
1040 const t1 = &.{ .B = "foo" };
1041 const t2 = &.{ .C = {} };
1042 const t3 = &.{ .A = y };
1043 const x0: *const U = t0;
1044 var x1: *const U = t1;
1045 _ = &x1;
1046 const x2: *const U = t2;
1047 var x3: *const U = t3;
1048 _ = &x3;
1049 try expect(x0.A == 123);
1050 try expect(std.mem.eql(u8, x1.B, "foo"));
1051 try expect(x2.* == .C);
1052 try expect(x3.A == y);
1053 }
1054 };
1055 try S.doTheTest();
1056 try comptime S.doTheTest();
1057}
1058
1059test "switching on non exhaustive union" {989test "switching on non exhaustive union" {
1060 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO990 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1061 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO991 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/cases/compile_errors/array slice sentinel mismatch non-scalar.zig +3-2
...@@ -1,7 +1,8 @@...@@ -1,7 +1,8 @@
1export fn foo() void {1export fn foo() void {
2 const S = struct { a: u32 };2 const S = struct { a: u32 };
3 const sentinel: S = .{ .a = 1 };
3 var arr = [_]S{ .{ .a = 1 }, .{ .a = 2 } };4 var arr = [_]S{ .{ .a = 1 }, .{ .a = 2 } };
4 const s = arr[0..1 :.{ .a = 1 }];5 const s = arr[0..1 :sentinel];
5 _ = s;6 _ = s;
6}7}
78
...@@ -9,5 +10,5 @@ export fn foo() void {...@@ -9,5 +10,5 @@ export fn foo() void {
9// backend=stage210// backend=stage2
10// target=native11// target=native
11//12//
12// :4:26: error: non-scalar sentinel type 'tmp.foo.S'13// :5:25: error: non-scalar sentinel type 'tmp.foo.S'
13// :2:15: note: struct declared here14// :2:15: note: struct declared here
test/cases/compile_errors/bogus_method_call_on_slice.zig+2-1
...@@ -18,4 +18,5 @@ pub export fn entry2() void {...@@ -18,4 +18,5 @@ pub export fn entry2() void {
18//18//
19// :3:6: error: no field or member function named 'copy' in '[]const u8'19// :3:6: error: no field or member function named 'copy' in '[]const u8'
20// :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})'20// :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})'
21// :12:18: error: no field or member function named 'bar' in 'struct{comptime foo: comptime_int = 1}'21// :12:18: error: no field or member function named 'bar' in 'tmp.entry2__struct_170'
22// :12:6: note: struct declared here
test/cases/compile_errors/coerce_anon_struct.zig created+11
...@@ -0,0 +1,11 @@
1const T = struct { x: u32 };
2export fn foo() void {
3 const a = .{ .x = 123 };
4 _ = @as(T, a);
5}
6
7// error
8//
9// :4:16: error: expected type 'tmp.T', found 'tmp.foo__struct_159'
10// :3:16: note: struct declared here
11// :1:11: note: struct declared here
test/cases/compile_errors/destructure_error_union.zig+1-1
...@@ -10,6 +10,6 @@ pub export fn entry() void {...@@ -10,6 +10,6 @@ pub export fn entry() void {
10// backend=stage210// backend=stage2
11// target=native11// target=native
12//12//
13// :4:28: error: type 'anyerror!tmp.entry.Foo' cannot be destructured13// :4:28: error: type 'anyerror!struct { u8, u8 }' cannot be destructured
14// :4:26: note: result destructured here14// :4:26: note: result destructured here
15// :4:28: note: consider using 'try', 'catch', or 'if'15// :4:28: note: consider using 'try', 'catch', or 'if'
test/cases/compile_errors/file_level_tuple.zig created+6
...@@ -0,0 +1,6 @@
1u32,
2comptime u8 = 123,
3
4// error
5//
6// :1:1: error: file cannot be a tuple
test/cases/compile_errors/invalid_peer_type_resolution.zig+6-16
...@@ -10,11 +10,6 @@ export fn badTupleField() void {...@@ -10,11 +10,6 @@ export fn badTupleField() void {
10 _ = .{ &x, &y };10 _ = .{ &x, &y };
11 _ = @TypeOf(x, y);11 _ = @TypeOf(x, y);
12}12}
13export fn badNestedField() void {
14 const x = .{ .foo = "hi", .bar = .{ 0, 1 } };
15 const y = .{ .foo = "hello", .bar = .{ 2, "hi" } };
16 _ = @TypeOf(x, y);
17}
18export fn incompatiblePointers() void {13export fn incompatiblePointers() void {
19 const x: []const u8 = "foo";14 const x: []const u8 = "foo";
20 const y: [*:0]const u8 = "bar";15 const y: [*:0]const u8 = "bar";
...@@ -39,14 +34,9 @@ export fn incompatiblePointers4() void {...@@ -39,14 +34,9 @@ export fn incompatiblePointers4() void {
39// :11:9: note: incompatible types: 'u32' and '*const [5:0]u8'34// :11:9: note: incompatible types: 'u32' and '*const [5:0]u8'
40// :11:17: note: type 'u32' here35// :11:17: note: type 'u32' here
41// :11:20: note: type '*const [5:0]u8' here36// :11:20: note: type '*const [5:0]u8' here
42// :16:9: error: struct field 'bar' has conflicting types37// :16:9: error: incompatible types: '[]const u8' and '[*:0]const u8'
43// :16:9: note: struct field '1' has conflicting types38// :16:17: note: type '[]const u8' here
44// :16:9: note: incompatible types: 'comptime_int' and '*const [2:0]u8'39// :16:20: note: type '[*:0]const u8' here
45// :16:17: note: type 'comptime_int' here40// :23:9: error: incompatible types: '[]const u8' and '[*]const u8'
46// :16:20: note: type '*const [2:0]u8' here41// :23:23: note: type '[]const u8' here
47// :21:9: error: incompatible types: '[]const u8' and '[*:0]const u8'42// :23:26: note: type '[*]const u8' here
48// :21:17: note: type '[]const u8' here
49// :21:20: note: type '[*:0]const u8' here
50// :28:9: error: incompatible types: '[]const u8' and '[*]const u8'
51// :28:23: note: type '[]const u8' here
52// :28:26: note: type '[*]const u8' here
test/cases/compile_errors/missing_field_in_struct_value_expression.zig-2
...@@ -29,7 +29,5 @@ export fn h() void {...@@ -29,7 +29,5 @@ export fn h() void {
29// :9:16: error: missing struct field: x29// :9:16: error: missing struct field: x
30// :1:11: note: struct declared here30// :1:11: note: struct declared here
31// :18:16: error: missing tuple field with index 131// :18:16: error: missing tuple field with index 1
32// :16:11: note: struct declared here
33// :22:16: error: missing tuple field with index 032// :22:16: error: missing tuple field with index 0
34// :22:16: note: missing tuple field with index 133// :22:16: note: missing tuple field with index 1
35// :16:11: note: struct declared here
test/cases/compile_errors/overflow_arithmetic_on_vector_with_undefined_elems.zig+3-3
...@@ -21,6 +21,6 @@ comptime {...@@ -21,6 +21,6 @@ comptime {
21// :14:5: note: also here21// :14:5: note: also here
22//22//
23// Compile Log Output:23// Compile Log Output:
24// @as(struct{@Vector(3, u8), @Vector(3, u1)}, .{ .{ 2, 144, undefined }, .{ 0, 1, undefined } })24// @as(struct { @Vector(3, u8), @Vector(3, u1) }, .{ .{ 2, 144, undefined }, .{ 0, 1, undefined } })
25// @as(struct{@Vector(3, u8), @Vector(3, u1)}, .{ .{ 1, 255, undefined }, .{ 0, 1, undefined } })25// @as(struct { @Vector(3, u8), @Vector(3, u1) }, .{ .{ 1, 255, undefined }, .{ 0, 1, undefined } })
26// @as(struct{@Vector(3, u8), @Vector(3, u1)}, .{ .{ 1, 64, undefined }, .{ 0, 1, undefined } })26// @as(struct { @Vector(3, u8), @Vector(3, u1) }, .{ .{ 1, 64, undefined }, .{ 0, 1, undefined } })
test/cases/compile_errors/tuple_init_edge_cases.zig+1-2
...@@ -72,6 +72,5 @@ pub export fn entry6() void {...@@ -72,6 +72,5 @@ pub export fn entry6() void {
72// :18:14: error: missing tuple field with index 172// :18:14: error: missing tuple field with index 1
73// :25:14: error: missing tuple field with index 173// :25:14: error: missing tuple field with index 1
74// :43:14: error: expected at most 2 tuple fields; found 374// :43:14: error: expected at most 2 tuple fields; found 3
75// :50:30: error: index '2' out of bounds of tuple 'struct{comptime comptime_int = 123, u32}'75// :50:30: error: index '2' out of bounds of tuple 'struct { comptime comptime_int = 123, u32 }'
76// :63:37: error: missing tuple field with index 376// :63:37: error: missing tuple field with index 3
77// :58:32: note: struct declared here
test/cases/compile_errors/type_mismatch_with_tuple_concatenation.zig+1-1
...@@ -7,4 +7,4 @@ export fn entry() void {...@@ -7,4 +7,4 @@ export fn entry() void {
7// backend=stage27// backend=stage2
8// target=native8// target=native
9//9//
10// :3:11: error: expected type '@TypeOf(.{})', found 'struct{comptime comptime_int = 1, comptime comptime_int = 2, comptime comptime_int = 3}'10// :3:11: error: expected type '@TypeOf(.{})', found 'struct { comptime comptime_int = 1, comptime comptime_int = 2, comptime comptime_int = 3 }'
test/compare_output.zig+2-2
...@@ -440,7 +440,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -440,7 +440,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
440 cases.add("std.log per scope log level override",440 cases.add("std.log per scope log level override",
441 \\const std = @import("std");441 \\const std = @import("std");
442 \\442 \\
443 \\pub const std_options = .{443 \\pub const std_options: std.Options = .{
444 \\ .log_level = .debug,444 \\ .log_level = .debug,
445 \\ 445 \\
446 \\ .log_scope_levels = &.{446 \\ .log_scope_levels = &.{
...@@ -497,7 +497,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -497,7 +497,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
497 cases.add("std.heap.LoggingAllocator logs to std.log",497 cases.add("std.heap.LoggingAllocator logs to std.log",
498 \\const std = @import("std");498 \\const std = @import("std");
499 \\499 \\
500 \\pub const std_options = .{500 \\pub const std_options: std.Options = .{
501 \\ .log_level = .debug,501 \\ .log_level = .debug,
502 \\ .logFn = log,502 \\ .logFn = log,
503 \\};503 \\};
test/src/Debugger.zig+14-14
...@@ -1532,18 +1532,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -1532,18 +1532,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
1532 ,1532 ,
1533 &.{1533 &.{
1534 \\(lldb) frame variable --show-types -- list0 list0.len list0.capacity list0[0] list0[1] list0[2] list0.0 list0.1 list0.21534 \\(lldb) frame variable --show-types -- list0 list0.len list0.capacity list0[0] list0[1] list0[2] list0.0 list0.1 list0.2
1535 \\(std.multi_array_list.MultiArrayList(main.Elem0)) list0 = len=3 capacity=8 {1535 \\(std.multi_array_list.MultiArrayList(struct { u32, u8, u16 })) list0 = len=3 capacity=8 {
1536 \\ (root.main.Elem0) [0] = {1536 \\ (std.struct { u32, u8, u16 }) [0] = {
1537 \\ (u32) .@"0" = 11537 \\ (u32) .@"0" = 1
1538 \\ (u8) .@"1" = 21538 \\ (u8) .@"1" = 2
1539 \\ (u16) .@"2" = 31539 \\ (u16) .@"2" = 3
1540 \\ }1540 \\ }
1541 \\ (root.main.Elem0) [1] = {1541 \\ (std.struct { u32, u8, u16 }) [1] = {
1542 \\ (u32) .@"0" = 41542 \\ (u32) .@"0" = 4
1543 \\ (u8) .@"1" = 51543 \\ (u8) .@"1" = 5
1544 \\ (u16) .@"2" = 61544 \\ (u16) .@"2" = 6
1545 \\ }1545 \\ }
1546 \\ (root.main.Elem0) [2] = {1546 \\ (std.struct { u32, u8, u16 }) [2] = {
1547 \\ (u32) .@"0" = 71547 \\ (u32) .@"0" = 7
1548 \\ (u8) .@"1" = 81548 \\ (u8) .@"1" = 8
1549 \\ (u16) .@"2" = 91549 \\ (u16) .@"2" = 9
...@@ -1551,17 +1551,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -1551,17 +1551,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
1551 \\}1551 \\}
1552 \\(usize) list0.len = 31552 \\(usize) list0.len = 3
1553 \\(usize) list0.capacity = 81553 \\(usize) list0.capacity = 8
1554 \\(root.main.Elem0) list0[0] = {1554 \\(std.struct { u32, u8, u16 }) list0[0] = {
1555 \\ (u32) .@"0" = 11555 \\ (u32) .@"0" = 1
1556 \\ (u8) .@"1" = 21556 \\ (u8) .@"1" = 2
1557 \\ (u16) .@"2" = 31557 \\ (u16) .@"2" = 3
1558 \\}1558 \\}
1559 \\(root.main.Elem0) list0[1] = {1559 \\(std.struct { u32, u8, u16 }) list0[1] = {
1560 \\ (u32) .@"0" = 41560 \\ (u32) .@"0" = 4
1561 \\ (u8) .@"1" = 51561 \\ (u8) .@"1" = 5
1562 \\ (u16) .@"2" = 61562 \\ (u16) .@"2" = 6
1563 \\}1563 \\}
1564 \\(root.main.Elem0) list0[2] = {1564 \\(std.struct { u32, u8, u16 }) list0[2] = {
1565 \\ (u32) .@"0" = 71565 \\ (u32) .@"0" = 7
1566 \\ (u8) .@"1" = 81566 \\ (u8) .@"1" = 8
1567 \\ (u16) .@"2" = 91567 \\ (u16) .@"2" = 9
...@@ -1582,18 +1582,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -1582,18 +1582,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
1582 \\ (u16) [2] = 91582 \\ (u16) [2] = 9
1583 \\}1583 \\}
1584 \\(lldb) frame variable --show-types -- slice0 slice0.len slice0.capacity slice0[0] slice0[1] slice0[2] slice0.0 slice0.1 slice0.21584 \\(lldb) frame variable --show-types -- slice0 slice0.len slice0.capacity slice0[0] slice0[1] slice0[2] slice0.0 slice0.1 slice0.2
1585 \\(std.multi_array_list.MultiArrayList(main.Elem0).Slice) slice0 = len=3 capacity=8 {1585 \\(std.multi_array_list.MultiArrayList(struct { u32, u8, u16 }).Slice) slice0 = len=3 capacity=8 {
1586 \\ (root.main.Elem0) [0] = {1586 \\ (std.struct { u32, u8, u16 }) [0] = {
1587 \\ (u32) .@"0" = 11587 \\ (u32) .@"0" = 1
1588 \\ (u8) .@"1" = 21588 \\ (u8) .@"1" = 2
1589 \\ (u16) .@"2" = 31589 \\ (u16) .@"2" = 3
1590 \\ }1590 \\ }
1591 \\ (root.main.Elem0) [1] = {1591 \\ (std.struct { u32, u8, u16 }) [1] = {
1592 \\ (u32) .@"0" = 41592 \\ (u32) .@"0" = 4
1593 \\ (u8) .@"1" = 51593 \\ (u8) .@"1" = 5
1594 \\ (u16) .@"2" = 61594 \\ (u16) .@"2" = 6
1595 \\ }1595 \\ }
1596 \\ (root.main.Elem0) [2] = {1596 \\ (std.struct { u32, u8, u16 }) [2] = {
1597 \\ (u32) .@"0" = 71597 \\ (u32) .@"0" = 7
1598 \\ (u8) .@"1" = 81598 \\ (u8) .@"1" = 8
1599 \\ (u16) .@"2" = 91599 \\ (u16) .@"2" = 9
...@@ -1601,17 +1601,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -1601,17 +1601,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
1601 \\}1601 \\}
1602 \\(usize) slice0.len = 31602 \\(usize) slice0.len = 3
1603 \\(usize) slice0.capacity = 81603 \\(usize) slice0.capacity = 8
1604 \\(root.main.Elem0) slice0[0] = {1604 \\(std.struct { u32, u8, u16 }) slice0[0] = {
1605 \\ (u32) .@"0" = 11605 \\ (u32) .@"0" = 1
1606 \\ (u8) .@"1" = 21606 \\ (u8) .@"1" = 2
1607 \\ (u16) .@"2" = 31607 \\ (u16) .@"2" = 3
1608 \\}1608 \\}
1609 \\(root.main.Elem0) slice0[1] = {1609 \\(std.struct { u32, u8, u16 }) slice0[1] = {
1610 \\ (u32) .@"0" = 41610 \\ (u32) .@"0" = 4
1611 \\ (u8) .@"1" = 51611 \\ (u8) .@"1" = 5
1612 \\ (u16) .@"2" = 61612 \\ (u16) .@"2" = 6
1613 \\}1613 \\}
1614 \\(root.main.Elem0) slice0[2] = {1614 \\(std.struct { u32, u8, u16 }) slice0[2] = {
1615 \\ (u32) .@"0" = 71615 \\ (u32) .@"0" = 7
1616 \\ (u8) .@"1" = 81616 \\ (u8) .@"1" = 8
1617 \\ (u16) .@"2" = 91617 \\ (u16) .@"2" = 9
test/standalone/sigpipe/breakpipe.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const build_options = @import("build_options");2const build_options = @import("build_options");
33
4pub const std_options = .{4pub const std_options: std.Options = .{
5 .keep_sigpipe = build_options.keep_sigpipe,5 .keep_sigpipe = build_options.keep_sigpipe,
6};6};
77
test/standalone/simple/issue_7030.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const std = @import("std");1const std = @import("std");
22
3pub const std_options = .{3pub const std_options: std.Options = .{
4 .logFn = log,4 .logFn = log,
5};5};
66