authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-10-26 23:13:58+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-10-31 20:42:53+00:00
logd11bbde5f9c64ef58405604601d55f88bb5d5f3a
tree4e05b679cd791e90db68f3f2198294667a6fc57c
parenta916bc7fdd3975a9e2ef13c44f814c71ce017193
signaturelock-open Commit is signed but in an unrecognized format.

compiler: remove anonymous struct types, unify all tuples

This commit reworks how anonymous struct literals and tuples work. Previously, an untyped anonymous struct literal (e.g. `const x = .{ .a = 123 }`) was given an "anonymous struct type", which is a special kind of struct which coerces using structural equivalence. This mechanism was a holdover from before we used RLS / result types as the primary mechanism of type inference. This commit changes the language so that the type assigned here is a "normal" struct type. It uses a form of equivalence based on the AST node and the type's structure, much like a reified (`@Type`) type. Additionally, tuples have been simplified. The distinction between "simple" and "complex" tuple types is eliminated. All tuples, even those explicitly declared using `struct { ... }` syntax, use structural equivalence, and do not undergo staged type resolution. Tuples are very restricted: they cannot have non-`auto` layouts, cannot have aligned fields, and cannot have default values with the exception of `comptime` fields. Tuples currently do not have optimized layout, but this can be changed in the future. This change simplifies the language, and fixes some problematic coercions through pointers which led to unintuitive behavior. Resolves: #16865

62 files changed, 1066 insertions(+), 1313 deletions(-)

lib/compiler/aro/aro/Builtins.zig+1-1
......@@ -157,7 +157,7 @@ fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *c
157157 .len = element_count,
158158 .elem = child_ty,
159159 };
160 const vector_ty = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
160 const vector_ty: Type = .{ .specifier = .vector, .data = .{ .array = arr_ty } };
161161 builder.specifier = Type.Builder.fromType(vector_ty);
162162 },
163163 .q => {
lib/compiler/aro/aro/Parser.zig+1-1
......@@ -8095,7 +8095,7 @@ fn primaryExpr(p: *Parser) Error!Result {
80958095
80968096fn makePredefinedIdentifier(p: *Parser, strings_top: usize) !Result {
80978097 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 } };
80998099 const arr_ty = try p.arena.create(Type.Array);
81008100 arr_ty.* = .{ .elem = elem_ty, .len = end - strings_top };
81018101 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 {
188188 pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void {
189189 if (self.errored) return;
190190 self.errored = true;
191 const diagnostic = .{ .tag = tag, .extra = extra };
191 const diagnostic: CharDiagnostic = .{ .tag = tag, .extra = extra };
192192 if (self.errors_len == self.errors_buffer.len) {
193193 self.errors_buffer[self.errors_buffer.len - 1] = diagnostic;
194194 } 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
749749 const is_const = is_fn_proto or child_type.isConst();
750750 const is_volatile = child_type.qual.@"volatile";
751751 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") = .{
753753 .is_const = is_const,
754754 .is_volatile = is_volatile,
755755 .elem_type = elem_type,
lib/compiler/test_runner.zig+1-1
......@@ -6,7 +6,7 @@ const io = std.io;
66const testing = std.testing;
77const assert = std.debug.assert;
88
9pub const std_options = .{
9pub const std_options: std.Options = .{
1010 .logFn = log,
1111};
1212
lib/std/SemanticVersion.zig+1-1
......@@ -299,7 +299,7 @@ test "precedence" {
299299
300300test "zig_version" {
301301 // 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
304304 // Simulated compatibility check using Zig version.
305305 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 {
509509 .max = .{ .major = 6, .minor = 10, .patch = 3 },
510510 },
511511 .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
514514 for (std.zig.target.available_libcs) |libc| {
515515 // 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 {
100100 /// of this ArrayList. Empties this ArrayList.
101101 pub fn moveToUnmanaged(self: *Self) ArrayListAlignedUnmanaged(T, alignment) {
102102 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 };
104104 self.* = init(allocator);
105105 return result;
106106 }
lib/std/crypto/phc_encoding.zig+1-2
......@@ -258,8 +258,7 @@ fn kvSplit(str: []const u8) !struct { key: []const u8, value: []const u8 } {
258258 var it = mem.splitScalar(u8, str, kv_delimiter_scalar);
259259 const key = it.first();
260260 const value = it.next() orelse return Error.InvalidEncoding;
261 const ret = .{ .key = key, .value = value };
262 return ret;
261 return .{ .key = key, .value = value };
263262}
264263
265264test "phc format - encoding/decoding" {
lib/std/meta.zig+1-1
......@@ -1018,7 +1018,7 @@ fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type {
10181018 .type = T,
10191019 .default_value = null,
10201020 .is_comptime = false,
1021 .alignment = if (@sizeOf(T) > 0) @alignOf(T) else 0,
1021 .alignment = 0,
10221022 };
10231023 }
10241024
lib/std/zig/AstGen.zig+129-60
......@@ -1711,7 +1711,7 @@ fn structInitExpr(
17111711 return rvalue(gz, ri, val, node);
17121712 },
17131713 .none, .ref, .inferred_ptr => {
1714 return rvalue(gz, ri, .empty_struct, node);
1714 return rvalue(gz, ri, .empty_tuple, node);
17151715 },
17161716 .destructure => |destructure| {
17171717 return astgen.failNodeNotes(node, "empty initializer cannot be destructured", .{}, &.{
......@@ -1888,6 +1888,8 @@ fn structInitExprAnon(
18881888 const tree = astgen.tree;
18891889
18901890 const payload_index = try addExtra(astgen, Zir.Inst.StructInitAnon{
1891 .abs_node = node,
1892 .abs_line = astgen.source_line,
18911893 .fields_len = @intCast(struct_init.ast.fields.len),
18921894 });
18931895 const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).@"struct".fields.len;
......@@ -1919,6 +1921,8 @@ fn structInitExprTyped(
19191921 const tree = astgen.tree;
19201922
19211923 const payload_index = try addExtra(astgen, Zir.Inst.StructInit{
1924 .abs_node = node,
1925 .abs_line = astgen.source_line,
19221926 .fields_len = @intCast(struct_init.ast.fields.len),
19231927 });
19241928 const field_size = @typeInfo(Zir.Inst.StructInit.Item).@"struct".fields.len;
......@@ -5007,6 +5011,25 @@ fn structDeclInner(
50075011 layout: std.builtin.Type.ContainerLayout,
50085012 backing_int_node: Ast.Node.Index,
50095013) 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
50105033 const decl_inst = try gz.reserveInstructionIndex();
50115034
50125035 if (container_decl.ast.members.len == 0 and backing_int_node == 0) {
......@@ -5019,7 +5042,6 @@ fn structDeclInner(
50195042 .has_backing_int = false,
50205043 .known_non_opv = false,
50215044 .known_comptime_only = false,
5022 .is_tuple = false,
50235045 .any_comptime_fields = false,
50245046 .any_default_inits = false,
50255047 .any_aligned_fields = false,
......@@ -5028,10 +5050,6 @@ fn structDeclInner(
50285050 return decl_inst.toRef();
50295051 }
50305052
5031 const astgen = gz.astgen;
5032 const gpa = astgen.gpa;
5033 const tree = astgen.tree;
5034
50355053 var namespace: Scope.Namespace = .{
50365054 .parent = scope,
50375055 .node = node,
......@@ -5106,46 +5124,6 @@ fn structDeclInner(
51065124 // No defer needed here because it is handled by `wip_members.deinit()` above.
51075125 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
51495127 const old_hasher = astgen.src_hasher;
51505128 defer astgen.src_hasher = old_hasher;
51515129 astgen.src_hasher = std.zig.SrcHasher.init(.{});
......@@ -5167,16 +5145,10 @@ fn structDeclInner(
51675145
51685146 astgen.src_hasher.update(tree.getNodeSource(member_node));
51695147
5170 if (!is_tuple) {
5171 const field_name = try astgen.identAsString(member.ast.main_token);
5172
5173 member.convertToNonTupleLike(astgen.tree.nodes);
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 }
5148 const field_name = try astgen.identAsString(member.ast.main_token);
5149 member.convertToNonTupleLike(astgen.tree.nodes);
5150 assert(!member.ast.tuple_like);
5151 wip_members.appendToField(@intFromEnum(field_name));
51805152
51815153 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
51825154 wip_members.appendToField(@intFromEnum(doc_comment_index));
......@@ -5270,7 +5242,6 @@ fn structDeclInner(
52705242 .has_backing_int = backing_int_ref != .none,
52715243 .known_non_opv = known_non_opv,
52725244 .known_comptime_only = known_comptime_only,
5273 .is_tuple = is_tuple,
52745245 .any_comptime_fields = any_comptime_fields,
52755246 .any_default_inits = any_default_inits,
52765247 .any_aligned_fields = any_aligned_fields,
......@@ -5300,6 +5271,106 @@ fn structDeclInner(
53005271 return decl_inst.toRef();
53015272}
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
53035374fn unionDeclInner(
53045375 gz: *GenZir,
53055376 scope: *Scope,
......@@ -11172,7 +11243,7 @@ fn rvalueInner(
1117211243 as_ty | @intFromEnum(Zir.Inst.Ref.slice_const_u8_sentinel_0_type),
1117311244 as_ty | @intFromEnum(Zir.Inst.Ref.anyerror_void_error_union_type),
1117411245 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),
1117611247 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero),
1117711248 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one),
1117811249 as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one),
......@@ -13173,7 +13244,6 @@ const GenZir = struct {
1317313244 layout: std.builtin.Type.ContainerLayout,
1317413245 known_non_opv: bool,
1317513246 known_comptime_only: bool,
13176 is_tuple: bool,
1317713247 any_comptime_fields: bool,
1317813248 any_default_inits: bool,
1317913249 any_aligned_fields: bool,
......@@ -13217,7 +13287,6 @@ const GenZir = struct {
1321713287 .has_backing_int = args.has_backing_int,
1321813288 .known_non_opv = args.known_non_opv,
1321913289 .known_comptime_only = args.known_comptime_only,
13220 .is_tuple = args.is_tuple,
1322113290 .name_strategy = gz.anon_name_strategy,
1322213291 .layout = args.layout,
1322313292 .any_comptime_fields = args.any_comptime_fields,
lib/std/zig/BuiltinFn.zig+4-3
......@@ -1,5 +1,3 @@
1const std = @import("std");
2
31pub const Tag = enum {
42 add_with_overflow,
53 addrspace_cast,
......@@ -147,7 +145,7 @@ param_count: ?u8,
147145
148146pub const list = list: {
149147 @setEvalBranchQuota(3000);
150 break :list std.StaticStringMap(@This()).initComptime(.{
148 break :list std.StaticStringMap(BuiltinFn).initComptime([_]struct { []const u8, BuiltinFn }{
151149 .{
152150 "@addWithOverflow",
153151 .{
......@@ -1011,3 +1009,6 @@ pub const list = list: {
10111009 },
10121010 });
10131011};
1012
1013const std = @import("std");
1014const BuiltinFn = @This();
lib/std/zig/Zir.zig+69-10
......@@ -1887,6 +1887,10 @@ pub const Inst = struct {
18871887 /// `operand` is payload index to `OpaqueDecl`.
18881888 /// `small` is `OpaqueDecl.Small`.
18891889 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,
18901894 /// Implements the `@This` builtin.
18911895 /// `operand` is `src_node: i32`.
18921896 this,
......@@ -2187,7 +2191,7 @@ pub const Inst = struct {
21872191 anyerror_void_error_union_type,
21882192 adhoc_inferred_error_set_type,
21892193 generic_poison_type,
2190 empty_struct_type,
2194 empty_tuple_type,
21912195 undef,
21922196 zero,
21932197 zero_usize,
......@@ -2202,7 +2206,7 @@ pub const Inst = struct {
22022206 null_value,
22032207 bool_true,
22042208 bool_false,
2205 empty_struct,
2209 empty_tuple,
22062210 generic_poison,
22072211
22082212 /// This Ref does not correspond to any ZIR instruction or constant
......@@ -3041,7 +3045,7 @@ pub const Inst = struct {
30413045 /// 0b0X00: whether corresponding field is comptime
30423046 /// 0bX000: whether corresponding field has a type expression
30433047 /// 9. fields: { // for every fields_len
3044 /// field_name: u32, // if !is_tuple
3048 /// field_name: u32,
30453049 /// doc_comment: NullTerminatedString, // .empty if no doc comment
30463050 /// field_type: Ref, // if corresponding bit is not set. none means anytype.
30473051 /// field_type_body_len: u32, // if corresponding bit is set
......@@ -3071,13 +3075,12 @@ pub const Inst = struct {
30713075 has_backing_int: bool,
30723076 known_non_opv: bool,
30733077 known_comptime_only: bool,
3074 is_tuple: bool,
30753078 name_strategy: NameStrategy,
30763079 layout: std.builtin.Type.ContainerLayout,
30773080 any_default_inits: bool,
30783081 any_comptime_fields: bool,
30793082 any_aligned_fields: bool,
3080 _: u2 = undefined,
3083 _: u3 = undefined,
30813084 };
30823085 };
30833086
......@@ -3302,6 +3305,15 @@ pub const Inst = struct {
33023305 };
33033306 };
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
33053317 /// Trailing:
33063318 /// { // for every fields_len
33073319 /// field_name: NullTerminatedString // null terminated string index
......@@ -3329,6 +3341,11 @@ pub const Inst = struct {
33293341
33303342 /// Trailing is an item per field.
33313343 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,
33323349 fields_len: u32,
33333350
33343351 pub const Item = struct {
......@@ -3344,6 +3361,11 @@ pub const Inst = struct {
33443361 /// TODO make this instead array of inits followed by array of names because
33453362 /// it will be simpler Sema code and better for CPU cache.
33463363 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,
33473369 fields_len: u32,
33483370
33493371 pub const Item = struct {
......@@ -3741,6 +3763,8 @@ fn findDeclsInner(
37413763 defers: *std.AutoHashMapUnmanaged(u32, void),
37423764 inst: Inst.Index,
37433765) Allocator.Error!void {
3766 comptime assert(Zir.inst_tracking_version == 0);
3767
37443768 const tags = zir.instructions.items(.tag);
37453769 const datas = zir.instructions.items(.data);
37463770
......@@ -3884,9 +3908,6 @@ fn findDeclsInner(
38843908 .struct_init_empty,
38853909 .struct_init_empty_result,
38863910 .struct_init_empty_ref_result,
3887 .struct_init_anon,
3888 .struct_init,
3889 .struct_init_ref,
38903911 .validate_struct_init_ty,
38913912 .validate_struct_init_result_ty,
38923913 .validate_ptr_struct_init,
......@@ -3978,6 +3999,12 @@ fn findDeclsInner(
39783999 .restore_err_ret_index_fn_entry,
39794000 => 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
39814008 .extended => {
39824009 const extended = datas[@intFromEnum(inst)].extended;
39834010 switch (extended.opcode) {
......@@ -4034,6 +4061,7 @@ fn findDeclsInner(
40344061 .builtin_value,
40354062 .branch_hint,
40364063 .inplace_arith_result_ty,
4064 .tuple_decl,
40374065 => return,
40384066
40394067 // `@TypeOf` has a body.
......@@ -4110,8 +4138,7 @@ fn findDeclsInner(
41104138 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
41114139 cur_bit_bag >>= 1;
41124140
4113 fields_extra_index += @intFromBool(!small.is_tuple); // field_name
4114 fields_extra_index += 1; // doc_comment
4141 fields_extra_index += 2; // field_name, doc_comment
41154142
41164143 if (has_type_body) {
41174144 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 {
47364763 else => return null,
47374764 }
47384765}
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 {
277277};
278278
279279test "detect" {
280 const cases = .{
280 const cases: [5]struct { []const u8, std.SemanticVersion } = .{
281281 .{
282282 \\<?xml version="1.0" encoding="UTF-8"?>
283283 \\<!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" {
388388
389389 inline for (cases) |case| {
390390 const ver0 = try parseSystemVersion(case[0]);
391 const ver1: std.SemanticVersion = case[1];
392 try testing.expectEqual(@as(std.math.Order, .eq), ver0.order(ver1));
391 const ver1 = case[1];
392 try testing.expectEqual(std.math.Order.eq, ver0.order(ver1));
393393 }
394394}
395395
src/Air.zig+2-2
......@@ -962,7 +962,7 @@ pub const Inst = struct {
962962 anyerror_void_error_union_type = @intFromEnum(InternPool.Index.anyerror_void_error_union_type),
963963 adhoc_inferred_error_set_type = @intFromEnum(InternPool.Index.adhoc_inferred_error_set_type),
964964 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),
966966 undef = @intFromEnum(InternPool.Index.undef),
967967 zero = @intFromEnum(InternPool.Index.zero),
968968 zero_usize = @intFromEnum(InternPool.Index.zero_usize),
......@@ -977,7 +977,7 @@ pub const Inst = struct {
977977 null_value = @intFromEnum(InternPool.Index.null_value),
978978 bool_true = @intFromEnum(InternPool.Index.bool_true),
979979 bool_false = @intFromEnum(InternPool.Index.bool_false),
980 empty_struct = @intFromEnum(InternPool.Index.empty_struct),
980 empty_tuple = @intFromEnum(InternPool.Index.empty_tuple),
981981 generic_poison = @intFromEnum(InternPool.Index.generic_poison),
982982
983983 /// 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 {
501501 .auto, .@"extern" => struct_obj.flagsUnordered(ip).fully_resolved,
502502 };
503503 },
504 .anon_struct_type => |tuple| {
504 .tuple_type => |tuple| {
505505 for (0..tuple.types.len) |i| {
506506 const field_is_comptime = tuple.values.get(ip)[i] != .none;
507507 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 {
20812081 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
20822082
20832083 // Compile the artifacts to a temporary directory.
2084 const tmp_artifact_directory = d: {
2084 const tmp_artifact_directory: Directory = d: {
20852085 const s = std.fs.path.sep_str;
20862086 tmp_dir_rand_int = std.crypto.random.int(u64);
20872087 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) {
17871787 /// or was created with `@Type`. It is unique and based on a declaration.
17881788 /// It may be a tuple, if declared like this: `struct {A, B, C}`.
17891789 struct_type: NamespaceType,
1790 /// This is an anonymous struct or tuple type which has no corresponding
1791 /// declaration. It is used for types that have no `struct` keyword in the
1792 /// source code, and were not created via `@Type`.
1793 anon_struct_type: AnonStructType,
1790 /// This is a tuple type. Tuples are logically similar to structs, but have some
1791 /// important differences in semantics; they do not undergo staged type resolution,
1792 /// so cannot be self-referential, and they are not considered container/namespace
1793 /// types, so cannot have declarations and have structural equality properties.
1794 tuple_type: TupleType,
17941795 union_type: NamespaceType,
17951796 opaque_type: NamespaceType,
17961797 enum_type: NamespaceType,
......@@ -1919,27 +1920,10 @@ pub const Key = union(enum) {
19191920 child: Index,
19201921 };
19211922
1922 pub const AnonStructType = struct {
1923 pub const TupleType = struct {
19231924 types: Index.Slice,
1924 /// This may be empty, indicating this is a tuple.
1925 names: NullTerminatedString.Slice,
19261925 /// These elements may be `none`, indicating runtime-known.
19271926 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 }
19431927 };
19441928
19451929 /// This is the hashmap key. To fetch other data associated with the type, see:
......@@ -1965,18 +1949,15 @@ pub const Key = union(enum) {
19651949 /// The union for which this is a tag type.
19661950 union_type: Index,
19671951 },
1968 /// This type originates from a reification via `@Type`.
1969 /// It is hased based on its ZIR instruction index and fields, attributes, etc.
1952 /// This type originates from a reification via `@Type`, or from an anonymous initialization.
1953 /// It is hashed based on its ZIR instruction index and fields, attributes, etc.
19701954 /// To avoid making this key overly complex, the type-specific data is hased by Sema.
19711955 reified: struct {
1972 /// A `reify` instruction.
1956 /// A `reify`, `struct_init`, `struct_init_ref`, or `struct_init_anon` instruction.
19731957 zir_index: TrackedInst.Index,
19741958 /// A hash of this type's attributes, fields, etc, generated by Sema.
19751959 type_hash: u64,
19761960 },
1977 /// This type is `@TypeOf(.{})`.
1978 /// TODO: can we change the language spec to not special-case this type?
1979 empty_struct: void,
19801961 };
19811962
19821963 pub const FuncType = struct {
......@@ -2497,7 +2478,6 @@ pub const Key = union(enum) {
24972478 std.hash.autoHash(&hasher, reified.zir_index);
24982479 std.hash.autoHash(&hasher, reified.type_hash);
24992480 },
2500 .empty_struct => {},
25012481 }
25022482 return hasher.final();
25032483 },
......@@ -2570,7 +2550,7 @@ pub const Key = union(enum) {
25702550 const child = switch (ip.indexToKey(aggregate.ty)) {
25712551 .array_type => |array_type| array_type.child,
25722552 .vector_type => |vector_type| vector_type.child,
2573 .anon_struct_type, .struct_type => .none,
2553 .tuple_type, .struct_type => .none,
25742554 else => unreachable,
25752555 };
25762556
......@@ -2625,11 +2605,10 @@ pub const Key = union(enum) {
26252605
26262606 .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| {
26292609 var hasher = Hash.init(seed);
2630 for (anon_struct_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2631 for (anon_struct_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2632 for (anon_struct_type.names.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2610 for (tuple_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
2611 for (tuple_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
26332612 return hasher.final();
26342613 },
26352614
......@@ -2929,7 +2908,6 @@ pub const Key = union(enum) {
29292908 return a_r.zir_index == b_r.zir_index and
29302909 a_r.type_hash == b_r.type_hash;
29312910 },
2932 .empty_struct => return true,
29332911 }
29342912 },
29352913 .aggregate => |a_info| {
......@@ -2981,11 +2959,10 @@ pub const Key = union(enum) {
29812959 },
29822960 }
29832961 },
2984 .anon_struct_type => |a_info| {
2985 const b_info = b.anon_struct_type;
2962 .tuple_type => |a_info| {
2963 const b_info = b.tuple_type;
29862964 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)) and
2988 std.mem.eql(NullTerminatedString, a_info.names.get(ip), b_info.names.get(ip));
2965 std.mem.eql(Index, a_info.values.get(ip), b_info.values.get(ip));
29892966 },
29902967 .error_set_type => |a_info| {
29912968 const b_info = b.error_set_type;
......@@ -3025,7 +3002,7 @@ pub const Key = union(enum) {
30253002 .union_type,
30263003 .opaque_type,
30273004 .enum_type,
3028 .anon_struct_type,
3005 .tuple_type,
30293006 .func_type,
30303007 => .type_type,
30313008
......@@ -3054,7 +3031,7 @@ pub const Key = union(enum) {
30543031 .void => .void_type,
30553032 .null => .null_type,
30563033 .false, .true => .bool_type,
3057 .empty_struct => .empty_struct_type,
3034 .empty_tuple => .empty_tuple_type,
30583035 .@"unreachable" => .noreturn_type,
30593036 .generic_poison => .generic_poison_type,
30603037 },
......@@ -3411,13 +3388,11 @@ pub const LoadedStructType = struct {
34113388 // TODO: the non-fqn will be needed by the new dwarf structure
34123389 /// The name of this struct type.
34133390 name: NullTerminatedString,
3414 /// The `Cau` within which type resolution occurs. `none` when the struct is `@TypeOf(.{})`.
3415 cau: Cau.Index.Optional,
3416 /// `none` when the struct is `@TypeOf(.{})`.
3417 namespace: OptionalNamespaceIndex,
3391 /// The `Cau` within which type resolution occurs.
3392 cau: Cau.Index,
3393 namespace: NamespaceIndex,
34183394 /// Index of the `struct_decl` or `reify` ZIR instruction.
3419 /// Only `none` when the struct is `@TypeOf(.{})`.
3420 zir_index: TrackedInst.Index.Optional,
3395 zir_index: TrackedInst.Index,
34213396 layout: std.builtin.Type.ContainerLayout,
34223397 field_names: NullTerminatedString.Slice,
34233398 field_types: Index.Slice,
......@@ -3913,10 +3888,6 @@ pub const LoadedStructType = struct {
39133888 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
39143889 }
39153890
3916 pub fn isTuple(s: LoadedStructType, ip: *InternPool) bool {
3917 return s.layout != .@"packed" and s.flagsUnordered(ip).is_tuple;
3918 }
3919
39203891 pub fn hasReorderedFields(s: LoadedStructType) bool {
39213892 return s.layout == .auto;
39223893 }
......@@ -4008,24 +3979,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
40083979 const item = unwrapped_index.getItem(ip);
40093980 switch (item.tag) {
40103981 .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 };
40293982 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);
40303983 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "cau").?]);
40313984 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 {
40453998 };
40463999 extra_index += captures_len;
40474000 if (flags.is_reified) {
4048 extra_index += 2; // PackedU64
4001 extra_index += 2; // type_hash: PackedU64
40494002 }
40504003 const field_types: Index.Slice = .{
40514004 .tid = unwrapped_index.tid,
......@@ -4053,7 +4006,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
40534006 .len = fields_len,
40544007 };
40554008 extra_index += fields_len;
4056 const names_map: OptionalMapIndex, const names = if (!flags.is_tuple) n: {
4009 const names_map: OptionalMapIndex, const names = n: {
40574010 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
40584011 extra_index += 1;
40594012 const names: NullTerminatedString.Slice = .{
......@@ -4063,7 +4016,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
40634016 };
40644017 extra_index += fields_len;
40654018 break :n .{ names_map, names };
4066 } else .{ .none, NullTerminatedString.Slice.empty };
4019 };
40674020 const inits: Index.Slice = if (flags.any_default_inits) i: {
40684021 const inits: Index.Slice = .{
40694022 .tid = unwrapped_index.tid,
......@@ -4114,9 +4067,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
41144067 .tid = unwrapped_index.tid,
41154068 .extra_index = item.data,
41164069 .name = name,
4117 .cau = cau.toOptional(),
4118 .namespace = namespace.toOptional(),
4119 .zir_index = zir_index.toOptional(),
4070 .cau = cau,
4071 .namespace = namespace,
4072 .zir_index = zir_index,
41204073 .layout = if (flags.is_extern) .@"extern" else .auto,
41214074 .field_names = names,
41224075 .field_types = field_types,
......@@ -4178,9 +4131,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
41784131 .tid = unwrapped_index.tid,
41794132 .extra_index = item.data,
41804133 .name = name,
4181 .cau = cau.toOptional(),
4182 .namespace = namespace.toOptional(),
4183 .zir_index = zir_index.toOptional(),
4134 .cau = cau,
4135 .namespace = namespace,
4136 .zir_index = zir_index,
41844137 .layout = .@"packed",
41854138 .field_names = field_names,
41864139 .field_types = field_types,
......@@ -4407,9 +4360,9 @@ pub const Item = struct {
44074360/// `primitives` in AstGen.zig.
44084361pub const Index = enum(u32) {
44094362 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;
44114364 pub const first_value: Index = .undef;
4412 pub const last_value: Index = .empty_struct;
4365 pub const last_value: Index = .empty_tuple;
44134366
44144367 u0_type,
44154368 i0_type,
......@@ -4466,8 +4419,9 @@ pub const Index = enum(u32) {
44664419 /// Used for the inferred error set of inline/comptime function calls.
44674420 adhoc_inferred_error_set_type,
44684421 generic_poison_type,
4469 /// `@TypeOf(.{})`
4470 empty_struct_type,
4422 /// `@TypeOf(.{})`; a tuple with zero elements.
4423 /// This is not the same as `struct {}`, since that is a struct rather than a tuple.
4424 empty_tuple_type,
44714425
44724426 /// `undefined` (untyped)
44734427 undef,
......@@ -4497,8 +4451,8 @@ pub const Index = enum(u32) {
44974451 bool_true,
44984452 /// `false`
44994453 bool_false,
4500 /// `.{}` (untyped)
4501 empty_struct,
4454 /// `.{}`
4455 empty_tuple,
45024456
45034457 /// Used for generic parameters where the type and value
45044458 /// is not known until generic function instantiation.
......@@ -4606,16 +4560,14 @@ pub const Index = enum(u32) {
46064560 values: []Index,
46074561 },
46084562 };
4609 const DataIsExtraIndexOfTypeStructAnon = struct {
4563 const DataIsExtraIndexOfTypeTuple = struct {
46104564 const @"data.fields_len" = opaque {};
4611 data: *TypeStructAnon,
4565 data: *TypeTuple,
46124566 @"trailing.types.len": *@"data.fields_len",
46134567 @"trailing.values.len": *@"data.fields_len",
4614 @"trailing.names.len": *@"data.fields_len",
46154568 trailing: struct {
46164569 types: []Index,
46174570 values: []Index,
4618 names: []NullTerminatedString,
46194571 },
46204572 };
46214573
......@@ -4649,10 +4601,9 @@ pub const Index = enum(u32) {
46494601 simple_type: void,
46504602 type_opaque: struct { data: *Tag.TypeOpaque },
46514603 type_struct: struct { data: *Tag.TypeStruct },
4652 type_struct_anon: DataIsExtraIndexOfTypeStructAnon,
46534604 type_struct_packed: struct { data: *Tag.TypeStructPacked },
46544605 type_struct_packed_inits: struct { data: *Tag.TypeStructPacked },
4655 type_tuple_anon: DataIsExtraIndexOfTypeStructAnon,
4606 type_tuple: DataIsExtraIndexOfTypeTuple,
46564607 type_union: struct { data: *Tag.TypeUnion },
46574608 type_function: struct {
46584609 const @"data.flags.has_comptime_bits" = opaque {};
......@@ -4936,11 +4887,10 @@ pub const static_keys = [_]Key{
49364887 // generic_poison_type
49374888 .{ .simple_type = .generic_poison },
49384889
4939 // empty_struct_type
4940 .{ .anon_struct_type = .{
4941 .types = Index.Slice.empty,
4942 .names = NullTerminatedString.Slice.empty,
4943 .values = Index.Slice.empty,
4890 // empty_tuple_type
4891 .{ .tuple_type = .{
4892 .types = .empty,
4893 .values = .empty,
49444894 } },
49454895
49464896 .{ .simple_value = .undefined },
......@@ -4991,7 +4941,7 @@ pub const static_keys = [_]Key{
49914941 .{ .simple_value = .null },
49924942 .{ .simple_value = .true },
49934943 .{ .simple_value = .false },
4994 .{ .simple_value = .empty_struct },
4944 .{ .simple_value = .empty_tuple },
49954945 .{ .simple_value = .generic_poison },
49964946};
49974947
......@@ -5071,20 +5021,16 @@ pub const Tag = enum(u8) {
50715021 type_opaque,
50725022 /// A non-packed struct type.
50735023 /// data is 0 or extra index of `TypeStruct`.
5074 /// data == 0 represents `@TypeOf(.{})`.
50755024 type_struct,
5076 /// An AnonStructType which stores types, names, and values for fields.
5077 /// data is extra index of `TypeStructAnon`.
5078 type_struct_anon,
50795025 /// A packed struct, no fields have any init values.
50805026 /// data is extra index of `TypeStructPacked`.
50815027 type_struct_packed,
50825028 /// A packed struct, one or more fields have init values.
50835029 /// data is extra index of `TypeStructPacked`.
50845030 type_struct_packed_inits,
5085 /// An AnonStructType which has only types and values for fields.
5086 /// data is extra index of `TypeStructAnon`.
5087 type_tuple_anon,
5031 /// A `TupleType`.
5032 /// data is extra index of `TypeTuple`.
5033 type_tuple,
50885034 /// A union type.
50895035 /// `data` is extra index of `TypeUnion`.
50905036 type_union,
......@@ -5299,9 +5245,8 @@ pub const Tag = enum(u8) {
52995245 .simple_type => unreachable,
53005246 .type_opaque => TypeOpaque,
53015247 .type_struct => TypeStruct,
5302 .type_struct_anon => TypeStructAnon,
53035248 .type_struct_packed, .type_struct_packed_inits => TypeStructPacked,
5304 .type_tuple_anon => TypeStructAnon,
5249 .type_tuple => TypeTuple,
53055250 .type_union => TypeUnion,
53065251 .type_function => TypeFunction,
53075252
......@@ -5546,18 +5491,15 @@ pub const Tag = enum(u8) {
55465491 /// 1. capture: CaptureValue // for each `captures_len`
55475492 /// 2. type_hash: PackedU64 // if `is_reified`
55485493 /// 3. type: Index for each field in declared order
5549 /// 4. if not is_tuple:
5550 /// names_map: MapIndex,
5551 /// name: NullTerminatedString // for each field in declared order
5552 /// 5. if any_default_inits:
5494 /// 4. if any_default_inits:
55535495 /// init: Index // for each field in declared order
5554 /// 6. if any_aligned_fields:
5496 /// 5. if any_aligned_fields:
55555497 /// align: Alignment // for each field in declared order
5556 /// 7. if any_comptime_fields:
5498 /// 6. if any_comptime_fields:
55575499 /// 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:
55595501 /// field_index: RuntimeOrder // for each field in runtime order
5560 /// 9. field_offset: u32 // for each field in declared order, undef until layout_resolved
5502 /// 8. field_offset: u32 // for each field in declared order, undef until layout_resolved
55615503 pub const TypeStruct = struct {
55625504 name: NullTerminatedString,
55635505 cau: Cau.Index,
......@@ -5572,7 +5514,6 @@ pub const Tag = enum(u8) {
55725514 is_extern: bool = false,
55735515 known_non_opv: bool = false,
55745516 requires_comptime: RequiresComptime = @enumFromInt(0),
5575 is_tuple: bool = false,
55765517 assumed_runtime_bits: bool = false,
55775518 assumed_pointer_aligned: bool = false,
55785519 any_comptime_fields: bool = false,
......@@ -5597,7 +5538,7 @@ pub const Tag = enum(u8) {
55975538 // which `layout_resolved` does not ensure.
55985539 fully_resolved: bool = false,
55995540 is_reified: bool = false,
5600 _: u7 = 0,
5541 _: u8 = 0,
56015542 };
56025543 };
56035544
......@@ -5659,9 +5600,7 @@ pub const Repeated = struct {
56595600/// Trailing:
56605601/// 0. type: Index for each fields_len
56615602/// 1. value: Index for each fields_len
5662/// 2. name: NullTerminatedString for each fields_len
5663/// The set of field names is omitted when the `Tag` is `type_tuple_anon`.
5664pub const TypeStructAnon = struct {
5603pub const TypeTuple = struct {
56655604 fields_len: u32,
56665605};
56675606
......@@ -5708,8 +5647,8 @@ pub const SimpleValue = enum(u32) {
57085647 void = @intFromEnum(Index.void_value),
57095648 /// This is untyped `null`.
57105649 null = @intFromEnum(Index.null_value),
5711 /// This is the untyped empty struct literal: `.{}`
5712 empty_struct = @intFromEnum(Index.empty_struct),
5650 /// This is the untyped empty struct/array literal: `.{}`
5651 empty_tuple = @intFromEnum(Index.empty_tuple),
57135652 true = @intFromEnum(Index.bool_true),
57145653 false = @intFromEnum(Index.bool_false),
57155654 @"unreachable" = @intFromEnum(Index.unreachable_value),
......@@ -6266,11 +6205,10 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
62666205 // This inserts all the statically-known values into the intern pool in the
62676206 // order expected.
62686207 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, .{
62706209 .types = &.{},
6271 .names = &.{},
62726210 .values = &.{},
6273 }) == .empty_struct_type),
6211 }) == .empty_tuple_type),
62746212 else => |expected_index| assert(try ip.get(gpa, .main, key) == expected_index),
62756213 };
62766214
......@@ -6412,7 +6350,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
64126350 } },
64136351
64146352 .type_struct => .{ .struct_type = ns: {
6415 if (data == 0) break :ns .empty_struct;
64166353 const extra_list = unwrapped_index.getExtra(ip);
64176354 const extra_items = extra_list.view().items(.@"0");
64186355 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 {
64576394 } else CaptureValue.Slice.empty },
64586395 } };
64596396 } },
6460 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6461 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6397 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
64626398 .type_union => .{ .union_type = ns: {
64636399 const extra_list = unwrapped_index.getExtra(ip);
64646400 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
......@@ -6764,10 +6700,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
67646700
67656701 // There is only one possible value precisely due to the
67666702 // fact that this values slice is fully populated!
6767 .type_struct_anon, .type_tuple_anon => {
6768 const type_struct_anon = extraDataTrail(ty_extra, TypeStructAnon, ty_item.data);
6769 const fields_len = type_struct_anon.data.fields_len;
6770 const values = ty_extra.view().items(.@"0")[type_struct_anon.end + fields_len ..][0..fields_len];
6703 .type_tuple => {
6704 const type_tuple = extraDataTrail(ty_extra, TypeTuple, ty_item.data);
6705 const fields_len = type_tuple.data.fields_len;
6706 const values = ty_extra.view().items(.@"0")[type_tuple.end + fields_len ..][0..fields_len];
67716707 return .{ .aggregate = .{
67726708 .ty = ty,
67736709 .storage = .{ .elems = @ptrCast(values) },
......@@ -6850,47 +6786,20 @@ fn extraErrorSet(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
68506786 };
68516787}
68526788
6853fn extraTypeStructAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
6854 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
6855 const fields_len = type_struct_anon.data.fields_len;
6789fn extraTypeTuple(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.TupleType {
6790 const type_tuple = extraDataTrail(extra, TypeTuple, extra_index);
6791 const fields_len = type_tuple.data.fields_len;
68566792 return .{
68576793 .types = .{
68586794 .tid = tid,
6859 .start = type_struct_anon.end,
6795 .start = type_tuple.end,
68606796 .len = fields_len,
68616797 },
68626798 .values = .{
68636799 .tid = tid,
6864 .start = type_struct_anon.end + fields_len,
6800 .start = type_tuple.end + fields_len,
68656801 .len = fields_len,
68666802 },
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 },
68946803 };
68956804}
68966805
......@@ -7361,7 +7270,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
73617270 },
73627271
73637272 .struct_type => unreachable, // use getStructType() instead
7364 .anon_struct_type => unreachable, // use getAnonStructType() instead
7273 .tuple_type => unreachable, // use getTupleType() instead
73657274 .union_type => unreachable, // use getUnionType() instead
73667275 .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
74697378 .field => {
74707379 assert(base_ptr_type.flags.size == .One);
74717380 switch (ip.indexToKey(base_ptr_type.child)) {
7472 .anon_struct_type => |anon_struct_type| {
7381 .tuple_type => |tuple_type| {
74737382 assert(ptr.base_addr == .field);
7474 assert(base_index.index < anon_struct_type.types.len);
7383 assert(base_index.index < tuple_type.types.len);
74757384 },
74767385 .struct_type => {
74777386 assert(ptr.base_addr == .field);
......@@ -7808,12 +7717,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
78087717 const child = switch (ty_key) {
78097718 .array_type => |array_type| array_type.child,
78107719 .vector_type => |vector_type| vector_type.child,
7811 .anon_struct_type, .struct_type => .none,
7720 .tuple_type, .struct_type => .none,
78127721 else => unreachable,
78137722 };
78147723 const sentinel = switch (ty_key) {
78157724 .array_type => |array_type| array_type.sentinel,
7816 .vector_type, .anon_struct_type, .struct_type => .none,
7725 .vector_type, .tuple_type, .struct_type => .none,
78177726 else => unreachable,
78187727 };
78197728 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
78457754 assert(ip.typeOf(elem) == field_ty);
78467755 }
78477756 },
7848 .anon_struct_type => |anon_struct_type| {
7849 for (aggregate.storage.values(), anon_struct_type.types.get(ip)) |elem, ty| {
7757 .tuple_type => |tuple_type| {
7758 for (aggregate.storage.values(), tuple_type.types.get(ip)) |elem, ty| {
78507759 assert(ip.typeOf(elem) == ty);
78517760 }
78527761 },
......@@ -7862,9 +7771,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
78627771 }
78637772
78647773 switch (ty_key) {
7865 .anon_struct_type => |anon_struct_type| opv: {
7774 .tuple_type => |tuple_type| opv: {
78667775 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| {
78687777 if (value == .none) break :opv;
78697778 switch (ip.indexToKey(value)) {
78707779 .undef => break :opv,
......@@ -7877,10 +7786,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
78777786 },
78787787 .elems => |elems| if (!std.mem.eql(
78797788 Index,
7880 anon_struct_type.values.get(ip),
7789 tuple_type.values.get(ip),
78817790 elems,
78827791 )) 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| {
78847793 if (value != elem) break :opv;
78857794 },
78867795 }
......@@ -8244,7 +8153,6 @@ pub const StructTypeInit = struct {
82448153 fields_len: u32,
82458154 known_non_opv: bool,
82468155 requires_comptime: RequiresComptime,
8247 is_tuple: bool,
82488156 any_comptime_fields: bool,
82498157 any_default_inits: bool,
82508158 inits_resolved: bool,
......@@ -8404,7 +8312,6 @@ pub fn getStructType(
84048312 .is_extern = is_extern,
84058313 .known_non_opv = ini.known_non_opv,
84068314 .requires_comptime = ini.requires_comptime,
8407 .is_tuple = ini.is_tuple,
84088315 .assumed_runtime_bits = false,
84098316 .assumed_pointer_aligned = false,
84108317 .any_comptime_fields = ini.any_comptime_fields,
......@@ -8442,10 +8349,8 @@ pub fn getStructType(
84428349 },
84438350 }
84448351 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
8445 if (!ini.is_tuple) {
8446 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
8447 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
8448 }
8352 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
8353 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
84498354 if (ini.any_default_inits) {
84508355 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
84518356 }
......@@ -8468,19 +8373,17 @@ pub fn getStructType(
84688373 } };
84698374}
84708375
8471pub const AnonStructTypeInit = struct {
8376pub const TupleTypeInit = struct {
84728377 types: []const Index,
8473 /// This may be empty, indicating this is a tuple.
8474 names: []const NullTerminatedString,
84758378 /// These elements may be `none`, indicating runtime-known.
84768379 values: []const Index,
84778380};
84788381
8479pub fn getAnonStructType(
8382pub fn getTupleType(
84808383 ip: *InternPool,
84818384 gpa: Allocator,
84828385 tid: Zcu.PerThread.Id,
8483 ini: AnonStructTypeInit,
8386 ini: TupleTypeInit,
84848387) Allocator.Error!Index {
84858388 assert(ini.types.len == ini.values.len);
84868389 for (ini.types) |elem| assert(elem != .none);
......@@ -8494,23 +8397,17 @@ pub fn getAnonStructType(
84948397
84958398 try items.ensureUnusedCapacity(1);
84968399 try extra.ensureUnusedCapacity(
8497 @typeInfo(TypeStructAnon).@"struct".fields.len + (fields_len * 3),
8400 @typeInfo(TypeTuple).@"struct".fields.len + (fields_len * 3),
84988401 );
84998402
8500 const extra_index = addExtraAssumeCapacity(extra, TypeStructAnon{
8403 const extra_index = addExtraAssumeCapacity(extra, TypeTuple{
85018404 .fields_len = fields_len,
85028405 });
85038406 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.types)});
85048407 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
85058408 errdefer extra.mutate.len = prev_extra_len;
85068409
8507 var gop = try ip.getOrPutKey(gpa, tid, .{
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 });
8410 var gop = try ip.getOrPutKey(gpa, tid, .{ .tuple_type = extraTypeTuple(tid, extra.list.*, extra_index) });
85148411 defer gop.deinit();
85158412 if (gop == .existing) {
85168413 extra.mutate.len = prev_extra_len;
......@@ -8518,7 +8415,7 @@ pub fn getAnonStructType(
85188415 }
85198416
85208417 items.appendAssumeCapacity(.{
8521 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,
8418 .tag = .type_tuple,
85228419 .data = extra_index,
85238420 });
85248421 return gop.put();
......@@ -10181,12 +10078,12 @@ pub fn getCoerced(
1018110078 direct: {
1018210079 const old_ty_child = switch (ip.indexToKey(old_ty)) {
1018310080 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,
1018510082 else => unreachable,
1018610083 };
1018710084 const new_ty_child = switch (ip.indexToKey(new_ty)) {
1018810085 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,
1019010087 else => unreachable,
1019110088 };
1019210089 if (old_ty_child != new_ty_child) break :direct;
......@@ -10235,7 +10132,7 @@ pub fn getCoerced(
1023510132 for (agg_elems, 0..) |*elem, i| {
1023610133 const new_elem_ty = switch (ip.indexToKey(new_ty)) {
1023710134 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],
1023910136 .struct_type => ip.loadStructType(new_ty).field_types.get(ip)[i],
1024010137 else => unreachable,
1024110138 };
......@@ -10425,7 +10322,7 @@ pub fn isErrorUnionType(ip: *const InternPool, ty: Index) bool {
1042510322
1042610323pub fn isAggregateType(ip: *const InternPool, ty: Index) bool {
1042710324 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,
1042910326 else => false,
1043010327 };
1043110328}
......@@ -10549,7 +10446,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1054910446 break :b @sizeOf(u32) * ints;
1055010447 },
1055110448 .type_struct => b: {
10552 if (data == 0) break :b 0;
1055310449 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
1055410450 const info = extra.data;
1055510451 var ints: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
......@@ -10558,10 +10454,8 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1055810454 ints += 1 + captures_len;
1055910455 }
1056010456 ints += info.fields_len; // types
10561 if (!info.flags.is_tuple) {
10562 ints += 1; // names_map
10563 ints += info.fields_len; // names
10564 }
10457 ints += 1; // names_map
10458 ints += info.fields_len; // names
1056510459 if (info.flags.any_default_inits)
1056610460 ints += info.fields_len; // inits
1056710461 if (info.flags.any_aligned_fields)
......@@ -10573,10 +10467,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1057310467 ints += info.fields_len; // offsets
1057410468 break :b @sizeOf(u32) * ints;
1057510469 },
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 },
1058010470 .type_struct_packed => b: {
1058110471 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
1058210472 const captures_len = if (extra.data.flags.any_captures)
......@@ -10597,9 +10487,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1059710487 @intFromBool(extra.data.flags.any_captures) + captures_len +
1059810488 extra.data.fields_len * 3);
1059910489 },
10600 .type_tuple_anon => b: {
10601 const info = extraData(extra_list, TypeStructAnon, data);
10602 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
10490 .type_tuple => b: {
10491 const info = extraData(extra_list, TypeTuple, data);
10492 break :b @sizeOf(TypeTuple) + (@sizeOf(u32) * 2 * info.fields_len);
1060310493 },
1060410494
1060510495 .type_union => b: {
......@@ -10760,10 +10650,9 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1076010650 .type_enum_auto,
1076110651 .type_opaque,
1076210652 .type_struct,
10763 .type_struct_anon,
1076410653 .type_struct_packed,
1076510654 .type_struct_packed_inits,
10766 .type_tuple_anon,
10655 .type_tuple,
1076710656 .type_union,
1076810657 .type_function,
1076910658 .undef,
......@@ -11396,7 +11285,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1139611285 .anyerror_void_error_union_type,
1139711286 .adhoc_inferred_error_set_type,
1139811287 .generic_poison_type,
11399 .empty_struct_type,
11288 .empty_tuple_type,
1140011289 => .type_type,
1140111290
1140211291 .undef => .undefined_type,
......@@ -11407,7 +11296,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1140711296 .unreachable_value => .noreturn_type,
1140811297 .null_value => .null_type,
1140911298 .bool_true, .bool_false => .bool_type,
11410 .empty_struct => .empty_struct_type,
11299 .empty_tuple => .empty_tuple_type,
1141111300 .generic_poison => .generic_poison_type,
1141211301
1141311302 // This optimization on tags is needed so that indexToKey can call
......@@ -11436,10 +11325,9 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1143611325 .type_enum_nonexhaustive,
1143711326 .type_opaque,
1143811327 .type_struct,
11439 .type_struct_anon,
1144011328 .type_struct_packed,
1144111329 .type_struct_packed_inits,
11442 .type_tuple_anon,
11330 .type_tuple,
1144311331 .type_union,
1144411332 .type_function,
1144511333 => .type_type,
......@@ -11533,7 +11421,7 @@ pub fn toEnum(ip: *const InternPool, comptime E: type, i: Index) E {
1153311421pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {
1153411422 return switch (ip.indexToKey(ty)) {
1153511423 .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,
1153711425 .array_type => |array_type| array_type.len,
1153811426 .vector_type => |vector_type| vector_type.len,
1153911427 else => unreachable,
......@@ -11543,7 +11431,7 @@ pub fn aggregateTypeLen(ip: *const InternPool, ty: Index) u64 {
1154311431pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
1154411432 return switch (ip.indexToKey(ty)) {
1154511433 .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,
1154711435 .array_type => |array_type| array_type.lenIncludingSentinel(),
1154811436 .vector_type => |vector_type| vector_type.len,
1154911437 else => unreachable,
......@@ -11708,7 +11596,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1170811596
1170911597 .optional_noreturn_type => .optional,
1171011598 .anyerror_void_error_union_type => .error_union,
11711 .empty_struct_type => .@"struct",
11599 .empty_tuple_type => .@"struct",
1171211600
1171311601 .generic_poison_type => return error.GenericPoison,
1171411602
......@@ -11727,7 +11615,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1172711615 .null_value => unreachable,
1172811616 .bool_true => unreachable,
1172911617 .bool_false => unreachable,
11730 .empty_struct => unreachable,
11618 .empty_tuple => unreachable,
1173111619 .generic_poison => unreachable,
1173211620
1173311621 _ => switch (index.unwrap(ip).getTag(ip)) {
......@@ -11768,10 +11656,9 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1176811656 .type_opaque => .@"opaque",
1176911657
1177011658 .type_struct,
11771 .type_struct_anon,
1177211659 .type_struct_packed,
1177311660 .type_struct_packed_inits,
11774 .type_tuple_anon,
11661 .type_tuple,
1177511662 => .@"struct",
1177611663
1177711664 .type_union => .@"union",
......@@ -12013,14 +11900,6 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
1201311900 };
1201411901}
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
1202411903/// Returns the already-existing field with the same name, if any.
1202511904pub fn addFieldName(
1202611905 ip: *InternPool,
src/Sema.zig+384-424
......@@ -844,6 +844,7 @@ pub const Block = struct {
844844
845845 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
846846 const pt = block.sema.pt;
847 block.sema.code.assertTrackable(inst);
847848 return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{
848849 .file = block.getFileScopeIndex(pt.zcu),
849850 .inst = inst,
......@@ -1277,6 +1278,7 @@ fn analyzeBodyInner(
12771278 .enum_decl => try sema.zirEnumDecl( block, extended, inst),
12781279 .union_decl => try sema.zirUnionDecl( block, extended, inst),
12791280 .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst),
1281 .tuple_decl => try sema.zirTupleDecl( block, extended),
12801282 .this => try sema.zirThis( block, extended),
12811283 .ret_addr => try sema.zirRetAddr( block, extended),
12821284 .builtin_src => try sema.zirBuiltinSrc( block, extended),
......@@ -2338,7 +2340,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
23382340
23392341 const struct_type = zcu.typeToStruct(container_ty) orelse break :msg msg;
23402342 try sema.errNote(.{
2341 .base_node_inst = struct_type.zir_index.unwrap().?,
2343 .base_node_inst = struct_type.zir_index,
23422344 .offset = .{ .container_field_value = @intCast(field_index) },
23432345 }, msg, "default value set here", .{});
23442346 break :msg msg;
......@@ -2651,6 +2653,94 @@ fn analyzeValueAsCallconv(
26512653 };
26522654}
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
26542744/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
26552745/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.
26562746fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {
......@@ -2774,7 +2864,6 @@ fn zirStructDecl(
27742864 .fields_len = fields_len,
27752865 .known_non_opv = small.known_non_opv,
27762866 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
2777 .is_tuple = small.is_tuple,
27782867 .any_comptime_fields = small.any_comptime_fields,
27792868 .any_default_inits = small.any_default_inits,
27802869 .inits_resolved = false,
......@@ -4912,7 +5001,7 @@ fn validateStructInit(
49125001 const default_field_ptr = if (struct_ty.isTuple(zcu))
49135002 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)
49145003 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);
49165005 const init = Air.internedToRef(default_val.toIntern());
49175006 try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store);
49185007 }
......@@ -5104,7 +5193,7 @@ fn validateStructInit(
51045193 const default_field_ptr = if (struct_ty.isTuple(zcu))
51055194 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)
51065195 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);
51085197 try sema.checkKnownAllocPtr(block, struct_ptr, default_field_ptr);
51095198 const init = Air.internedToRef(field_values[i]);
51105199 try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store);
......@@ -8430,22 +8519,6 @@ fn instantiateGenericCall(
84308519 return result;
84318520}
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
84498522fn zirIntType(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
84508523 const int_type = sema.code.instructions.items(.data)[@intFromEnum(inst)].int_type;
84518524 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
1432114394 },
1432214395 else => {},
1432314396 },
14324 .anon_struct_type => |anon_struct| {
14325 if (anon_struct.names.len != 0) {
14326 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names.get(ip), field_name) != null;
14327 } else {
14328 const field_index = field_name.toUnsigned(ip) orelse break :hf false;
14329 break :hf field_index < ty.structFieldCount(zcu);
14330 }
14397 .tuple_type => |tuple| {
14398 const field_index = field_name.toUnsigned(ip) orelse break :hf false;
14399 break :hf field_index < tuple.types.len;
1433114400 },
1433214401 .struct_type => {
1433314402 break :hf ip.loadStructType(ty.toIntern()).nameIndex(ip, field_name) != null;
......@@ -14882,7 +14951,7 @@ fn analyzeTupleCat(
1488214951 const dest_fields = lhs_len + rhs_len;
1488314952
1488414953 if (dest_fields == 0) {
14885 return Air.internedToRef(Value.empty_struct.toIntern());
14954 return .empty_tuple;
1488614955 }
1488714956 if (lhs_len == 0) {
1488814957 return rhs;
......@@ -14928,10 +14997,9 @@ fn analyzeTupleCat(
1492814997 break :rs runtime_src;
1492914998 };
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, .{
1493215001 .types = types,
1493315002 .values = values,
14934 .names = &.{},
1493515003 });
1493615004
1493715005 const runtime_src = opt_runtime_src orelse {
......@@ -15263,7 +15331,7 @@ fn analyzeTupleMul(
1526315331 return sema.fail(block, len_src, "operation results in overflow", .{});
1526415332
1526515333 if (final_len == 0) {
15266 return Air.internedToRef(Value.empty_struct.toIntern());
15334 return .empty_tuple;
1526715335 }
1526815336 const types = try sema.arena.alloc(InternPool.Index, final_len);
1526915337 const values = try sema.arena.alloc(InternPool.Index, final_len);
......@@ -15289,10 +15357,9 @@ fn analyzeTupleMul(
1528915357 break :rs runtime_src;
1529015358 };
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, .{
1529315361 .types = types,
1529415362 .values = values,
15295 .names = &.{},
1529615363 });
1529715364
1529815365 const runtime_src = opt_runtime_src orelse {
......@@ -16689,7 +16756,7 @@ fn zirOverflowArithmetic(
1668916756 const maybe_rhs_val = try sema.resolveValue(rhs);
1669016757
1669116758 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
1669416761 var result: struct {
1669516762 inst: Air.Inst.Ref = .none,
......@@ -16873,10 +16940,9 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
1687316940
1687416941 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };
1687516942 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, .{
1687716944 .types = &types,
1687816945 .values = &values,
16879 .names = &.{},
1688016946 });
1688116947 return Type.fromInterned(tuple_ty);
1688216948}
......@@ -18908,16 +18974,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1890818974 defer gpa.free(struct_field_vals);
1890918975 fv: {
1891018976 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
18911 .anon_struct_type => |anon_struct_type| {
18912 struct_field_vals = try gpa.alloc(InternPool.Index, anon_struct_type.types.len);
18977 .tuple_type => |tuple_type| {
18978 struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len);
1891318979 for (struct_field_vals, 0..) |*struct_field_val, field_index| {
18914 const field_ty = anon_struct_type.types.get(ip)[field_index];
18915 const field_val = anon_struct_type.values.get(ip)[field_index];
18980 const field_ty = tuple_type.types.get(ip)[field_index];
18981 const field_val = tuple_type.values.get(ip)[field_index];
1891618982 const name_val = v: {
18917 const field_name = if (anon_struct_type.names.len != 0)
18918 anon_struct_type.names.get(ip)[field_index]
18919 else
18920 try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
18983 const field_name = try ip.getOrPutStringFmt(gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
1892118984 const field_name_len = field_name.length(ip);
1892218985 const new_decl_ty = try pt.arrayType(.{
1892318986 .len = field_name_len,
......@@ -20509,8 +20572,8 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
2050920572 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2051020573 const src = block.nodeOffset(inst_data.src_node);
2051120574 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 init
20513 error.GenericPoison => return .empty_struct,
20575 // Generic poison means this is an untyped anonymous empty struct/array init
20576 error.GenericPoison => return .empty_tuple,
2051420577 else => |e| return e,
2051520578 };
2051620579 const init_ty = if (is_byref) ty: {
......@@ -20671,7 +20734,7 @@ fn zirStructInit(
2067120734 const result_ty = sema.resolveType(block, src, first_field_type_extra.container_type) catch |err| switch (err) {
2067220735 error.GenericPoison => {
2067320736 // 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);
2067520738 },
2067620739 else => |e| return e,
2067720740 };
......@@ -20837,39 +20900,28 @@ fn finishStructInit(
2083720900 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
2083820901
2083920902 switch (ip.indexToKey(struct_ty.toIntern())) {
20840 .anon_struct_type => |anon_struct| {
20903 .tuple_type => |tuple| {
2084120904 // 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| {
2084320906 if (field_inits[i] != .none) {
2084420907 // Coerce the init value to the field type.
2084520908 const field_src = block.src(.{ .init_elem = .{
2084620909 .init_node_offset = init_src.offset.node_offset.x,
2084720910 .elem_index = @intCast(i),
2084820911 } });
20849 const field_ty = Type.fromInterned(anon_struct.types.get(ip)[i]);
20912 const field_ty = Type.fromInterned(tuple.types.get(ip)[i]);
2085020913 field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);
2085120914 continue;
2085220915 }
2085320916
20854 const default_val = anon_struct.values.get(ip)[i];
20917 const default_val = tuple.values.get(ip)[i];
2085520918
2085620919 if (default_val == .none) {
20857 if (anon_struct.names.len == 0) {
20858 const template = "missing tuple field with index {d}";
20859 if (root_msg) |msg| {
20860 try sema.errNote(init_src, msg, template, .{i});
20861 } else {
20862 root_msg = try sema.errMsg(init_src, template, .{i});
20863 }
20920 const template = "missing tuple field with index {d}";
20921 if (root_msg) |msg| {
20922 try sema.errNote(init_src, msg, template, .{i});
2086420923 } else {
20865 const field_name = anon_struct.names.get(ip)[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 }
20924 root_msg = try sema.errMsg(init_src, template, .{i});
2087320925 }
2087420926 } else {
2087520927 field_inits[i] = Air.internedToRef(default_val);
......@@ -20894,22 +20946,13 @@ fn finishStructInit(
2089420946
2089520947 const field_init = struct_type.fieldInit(ip, i);
2089620948 if (field_init == .none) {
20897 if (!struct_type.isTuple(ip)) {
20898 const field_name = struct_type.field_names.get(ip)[i];
20899 const template = "missing struct field: {}";
20900 const args = .{field_name.fmt(ip)};
20901 if (root_msg) |msg| {
20902 try sema.errNote(init_src, msg, template, args);
20903 } else {
20904 root_msg = try sema.errMsg(init_src, template, args);
20905 }
20949 const field_name = struct_type.field_names.get(ip)[i];
20950 const template = "missing struct field: {}";
20951 const args = .{field_name.fmt(ip)};
20952 if (root_msg) |msg| {
20953 try sema.errNote(init_src, msg, template, args);
2090620954 } else {
20907 const template = "missing tuple field with index {d}";
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 }
20955 root_msg = try sema.errMsg(init_src, template, args);
2091320956 }
2091420957 } else {
2091520958 field_inits[i] = Air.internedToRef(field_init);
......@@ -20970,8 +21013,7 @@ fn finishStructInit(
2097021013 const base_ptr = try sema.optEuBasePtrInit(block, alloc, init_src);
2097121014 for (field_inits, 0..) |field_init, i_usize| {
2097221015 const i: u32 = @intCast(i_usize);
20973 const field_src = dest_src;
20974 const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, base_ptr, i, field_src, struct_ty, true);
21016 const field_ptr = try sema.structFieldPtrByIndex(block, dest_src, base_ptr, i, struct_ty);
2097521017 try sema.storePtr(block, dest_src, field_ptr, field_init);
2097621018 }
2097721019
......@@ -20995,13 +21037,14 @@ fn zirStructInitAnon(
2099521037 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
2099621038 const src = block.nodeOffset(inst_data.src_node);
2099721039 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);
2099921041}
2100021042
2100121043fn structInitAnon(
2100221044 sema: *Sema,
2100321045 block: *Block,
2100421046 src: LazySrcLoc,
21047 inst: Zir.Inst.Index,
2100521048 /// It is possible for a typed struct_init to be downgraded to an anonymous init due to a
2100621049 /// generic poison type. In this case, we need to know to interpret the extra data differently.
2100721050 comptime kind: enum { anon_init, typed_init },
......@@ -21022,6 +21065,8 @@ fn structInitAnon(
2102221065 const values = try sema.arena.alloc(InternPool.Index, types.len);
2102321066 const names = try sema.arena.alloc(InternPool.NullTerminatedString, types.len);
2102421067
21068 var any_values = false;
21069
2102521070 // Find which field forces the expression to be runtime, if any.
2102621071 const opt_runtime_index = rs: {
2102721072 var runtime_index: ?usize = null;
......@@ -21063,6 +21108,7 @@ fn structInitAnon(
2106321108 }
2106421109 if (try sema.resolveValue(init)) |init_val| {
2106521110 field_val.* = init_val.toIntern();
21111 any_values = true;
2106621112 } else {
2106721113 field_val.* = .none;
2106821114 runtime_index = @intCast(i_usize);
......@@ -21071,18 +21117,76 @@ fn structInitAnon(
2107121117 break :rs runtime_index;
2107221118 };
2107321119
21074 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{
21075 .names = names,
21076 .types = types,
21077 .values = values,
21078 });
21120 // We treat anonymous struct types as reified types, because there are similarities:
21121 // * They use a form of structural equivalence, which we can easily model using a custom hash
21122 // * They do not have captures
21123 // * They immediately have their fields resolved
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
2108021184 const runtime_index = opt_runtime_index orelse {
21081 const tuple_val = try pt.intern(.{ .aggregate = .{
21082 .ty = tuple_ty,
21185 const struct_val = try pt.intern(.{ .aggregate = .{
21186 .ty = struct_ty,
2108321187 .storage = .{ .elems = values },
2108421188 } });
21085 return sema.addConstantMaybeRef(tuple_val, is_ref);
21189 return sema.addConstantMaybeRef(struct_val, is_ref);
2108621190 };
2108721191
2108821192 try sema.requireRuntimeBlock(block, LazySrcLoc.unneeded, block.src(.{ .init_elem = .{
......@@ -21093,7 +21197,7 @@ fn structInitAnon(
2109321197 if (is_ref) {
2109421198 const target = zcu.getTarget();
2109521199 const alloc_ty = try pt.ptrTypeSema(.{
21096 .child = tuple_ty,
21200 .child = struct_ty,
2109721201 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2109821202 });
2109921203 const alloc = try block.addTy(.alloc, alloc_ty);
......@@ -21131,7 +21235,7 @@ fn structInitAnon(
2113121235 element_refs[i] = try sema.resolveInst(item.data.init);
2113221236 }
2113321237
21134 return block.addAggregateInit(Type.fromInterned(tuple_ty), element_refs);
21238 return block.addAggregateInit(Type.fromInterned(struct_ty), element_refs);
2113521239}
2113621240
2113721241fn zirArrayInit(
......@@ -21340,10 +21444,9 @@ fn arrayInitAnon(
2134021444 break :rs runtime_src;
2134121445 };
2134221446
21343 const tuple_ty = try ip.getAnonStructType(gpa, pt.tid, .{
21447 const tuple_ty = try ip.getTupleType(gpa, pt.tid, .{
2134421448 .types = types,
2134521449 .values = values,
21346 .names = &.{},
2134721450 });
2134821451
2134921452 const runtime_src = opt_runtime_src orelse {
......@@ -21440,12 +21543,9 @@ fn fieldType(
2144021543 try cur_ty.resolveFields(pt);
2144121544 switch (cur_ty.zigTypeTag(zcu)) {
2144221545 .@"struct" => switch (ip.indexToKey(cur_ty.toIntern())) {
21443 .anon_struct_type => |anon_struct| {
21444 const field_index = if (anon_struct.names.len == 0)
21445 try sema.tupleFieldIndex(block, cur_ty, field_name, field_src)
21446 else
21447 try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
21448 return Air.internedToRef(anon_struct.types.get(ip)[field_index]);
21546 .tuple_type => |tuple| {
21547 const field_index = try sema.tupleFieldIndex(block, cur_ty, field_name, field_src);
21548 return Air.internedToRef(tuple.types.get(ip)[field_index]);
2144921549 },
2145021550 .struct_type => {
2145121551 const struct_type = ip.loadStructType(cur_ty.toIntern());
......@@ -22095,7 +22195,16 @@ fn zirReify(
2209522195 .needed_comptime_reason = "struct fields must be comptime-known",
2209622196 });
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 }
2209922208 },
2210022209 .@"enum" => {
2210122210 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
......@@ -22696,6 +22805,104 @@ fn reifyUnion(
2269622805 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
2269722806}
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
2269922906fn reifyStruct(
2270022907 sema: *Sema,
2270122908 block: *Block,
......@@ -22705,7 +22912,6 @@ fn reifyStruct(
2270522912 opt_backing_int_val: Value,
2270622913 fields_val: Value,
2270722914 name_strategy: Zir.Inst.NameStrategy,
22708 is_tuple: bool,
2270922915) CompileError!Air.Inst.Ref {
2271022916 const pt = sema.pt;
2271122917 const zcu = pt.zcu;
......@@ -22725,7 +22931,6 @@ fn reifyStruct(
2272522931 var hasher = std.hash.Wyhash.init(0);
2272622932 std.hash.autoHash(&hasher, layout);
2272722933 std.hash.autoHash(&hasher, opt_backing_int_val.toIntern());
22728 std.hash.autoHash(&hasher, is_tuple);
2272922934 std.hash.autoHash(&hasher, fields_len);
2273022935
2273122936 var any_comptime_fields = false;
......@@ -22781,7 +22986,6 @@ fn reifyStruct(
2278122986 .fields_len = fields_len,
2278222987 .known_non_opv = false,
2278322988 .requires_comptime = .unknown,
22784 .is_tuple = is_tuple,
2278522989 .any_comptime_fields = any_comptime_fields,
2278622990 .any_default_inits = any_default_inits,
2278722991 .any_aligned_fields = any_aligned_fields,
......@@ -22800,12 +23004,6 @@ fn reifyStruct(
2280023004 };
2280123005 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
2280923007 wip_ty.setName(ip, try sema.createTypeName(
2281023008 block,
2281123009 name_strategy,
......@@ -22828,22 +23026,7 @@ fn reifyStruct(
2282823026 const field_ty = field_type_val.toType();
2282923027 // Don't pass a reason; first loop acts as an assertion that this is valid.
2283023028 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
22831 if (is_tuple) {
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| {
23029 if (struct_type.addFieldName(ip, field_name)) |prev_index| {
2284723030 _ = prev_index; // TODO: better source location
2284823031 return sema.fail(block, src, "duplicate struct field name {}", .{field_name.fmt(ip)});
2284923032 }
......@@ -25579,7 +25762,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2557925762 const args = try sema.resolveInst(extra.args);
2558025763
2558125764 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)) {
2558325766 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)});
2558425767 }
2558525768
......@@ -27471,7 +27654,7 @@ fn explainWhyTypeIsComptimeInner(
2747127654 for (0..struct_type.field_types.len) |i| {
2747227655 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
2747327656 const field_src: LazySrcLoc = .{
27474 .base_node_inst = struct_type.zir_index.unwrap().?,
27657 .base_node_inst = struct_type.zir_index,
2747527658 .offset = .{ .container_field_type = @intCast(i) },
2747627659 };
2747727660
......@@ -28236,11 +28419,10 @@ fn fieldVal(
2823628419 return Air.internedToRef(enum_val.toIntern());
2823728420 },
2823828421 .@"struct", .@"opaque" => {
28239 switch (child_type.toIntern()) {
28240 .empty_struct_type, .anyopaque_type => {}, // no namespace
28241 else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
28422 if (!child_type.isTuple(zcu) and child_type.toIntern() != .anyopaque_type) {
28423 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2824228424 return inst;
28243 },
28425 }
2824428426 }
2824528427 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
2824628428 },
......@@ -28788,9 +28970,6 @@ fn structFieldPtr(
2878828970 }
2878928971 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
2879028972 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);
2879428973 }
2879528974
2879628975 const struct_type = zcu.typeToStruct(struct_ty).?;
......@@ -28798,7 +28977,7 @@ fn structFieldPtr(
2879828977 const field_index = struct_type.nameIndex(ip, field_name) orelse
2879928978 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);
2880228981}
2880328982
2880428983fn structFieldPtrByIndex(
......@@ -28807,16 +28986,11 @@ fn structFieldPtrByIndex(
2880728986 src: LazySrcLoc,
2880828987 struct_ptr: Air.Inst.Ref,
2880928988 field_index: u32,
28810 field_src: LazySrcLoc,
2881128989 struct_ty: Type,
28812 initializing: bool,
2881328990) CompileError!Air.Inst.Ref {
2881428991 const pt = sema.pt;
2881528992 const zcu = pt.zcu;
2881628993 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
2882128995 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
2882228996 const val = try struct_ptr_val.ptrField(field_index, pt);
......@@ -28909,8 +29083,6 @@ fn structFieldVal(
2890929083 switch (ip.indexToKey(struct_ty.toIntern())) {
2891029084 .struct_type => {
2891129085 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
2891529087 const field_index = struct_type.nameIndex(ip, field_name) orelse
2891629088 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
......@@ -28935,13 +29107,8 @@ fn structFieldVal(
2893529107 try field_ty.resolveLayout(pt);
2893629108 return block.addStructFieldVal(struct_byval, field_index, field_ty);
2893729109 },
28938 .anon_struct_type => |anon_struct| {
28939 if (anon_struct.names.len == 0) {
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 }
29110 .tuple_type => {
29111 return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
2894529112 },
2894629113 else => unreachable,
2894729114 }
......@@ -30087,39 +30254,7 @@ fn coerceExtra(
3008730254 },
3008830255 else => {},
3008930256 },
30090 .One => switch (Type.fromInterned(dest_info.child).zigTypeTag(zcu)) {
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 },
30257 .One => {},
3012330258 .Slice => to_slice: {
3012430259 if (inst_ty.zigTypeTag(zcu) == .array) {
3012530260 return sema.fail(
......@@ -30368,11 +30503,6 @@ fn coerceExtra(
3036830503 },
3036930504 .@"union" => switch (inst_ty.zigTypeTag(zcu)) {
3037030505 .@"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 },
3037630506 else => {},
3037730507 },
3037830508 .array => switch (inst_ty.zigTypeTag(zcu)) {
......@@ -30402,9 +30532,6 @@ fn coerceExtra(
3040230532 },
3040330533 .vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src),
3040430534 .@"struct" => {
30405 if (inst == .empty_struct) {
30406 return sema.arrayInitEmpty(block, inst_src, dest_ty);
30407 }
3040830535 if (inst_ty.isTuple(zcu)) {
3040930536 return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src);
3041030537 }
......@@ -30421,10 +30548,7 @@ fn coerceExtra(
3042130548 else => {},
3042230549 },
3042330550 .@"struct" => blk: {
30424 if (inst == .empty_struct) {
30425 return sema.structInitEmpty(block, dest_ty, dest_ty_src, inst_src);
30426 }
30427 if (inst_ty.isTupleOrAnonStruct(zcu)) {
30551 if (inst_ty.isTuple(zcu)) {
3042830552 return sema.coerceTupleToStruct(block, dest_ty, inst, inst_src) catch |err| switch (err) {
3042930553 error.NotCoercible => break :blk,
3043030554 else => |e| return e,
......@@ -32208,97 +32332,6 @@ fn coerceEnumToUnion(
3220832332 return sema.failWithOwnedErrorMsg(block, msg);
3220932333}
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
3230232335/// If the lengths match, coerces element-wise.
3230332336fn coerceArrayLike(
3230432337 sema: *Sema,
......@@ -32530,7 +32563,7 @@ fn coerceTupleToStruct(
3253032563 try struct_ty.resolveFields(pt);
3253132564 try struct_ty.resolveStructFieldInits(pt);
3253232565
32533 if (struct_ty.isTupleOrAnonStruct(zcu)) {
32566 if (struct_ty.isTuple(zcu)) {
3253432567 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
3253532568 }
3253632569
......@@ -32542,7 +32575,7 @@ fn coerceTupleToStruct(
3254232575 const inst_ty = sema.typeOf(inst);
3254332576 var runtime_src: ?LazySrcLoc = null;
3254432577 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,
3254632579 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,
3254732580 else => unreachable,
3254832581 };
......@@ -32557,7 +32590,7 @@ fn coerceTupleToStruct(
3255732590 const coerced = try sema.coerce(block, struct_field_ty, elem_ref, field_src);
3255832591 field_refs[struct_field_index] = coerced;
3255932592 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 {
3256132594 return sema.failWithNeededComptime(block, field_src, .{
3256232595 .needed_comptime_reason = "value stored in comptime field must be comptime-known",
3256332596 });
......@@ -32636,8 +32669,7 @@ fn coerceTupleToTuple(
3263632669 const zcu = pt.zcu;
3263732670 const ip = &zcu.intern_pool;
3263832671 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {
32639 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
32640 .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.len,
32672 .tuple_type => |tuple_type| tuple_type.types.len,
3264132673 else => unreachable,
3264232674 };
3264332675 const field_vals = try sema.arena.alloc(InternPool.Index, dest_field_count);
......@@ -32646,8 +32678,7 @@ fn coerceTupleToTuple(
3264632678
3264732679 const inst_ty = sema.typeOf(inst);
3264832680 const src_field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
32649 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
32650 .struct_type => ip.loadStructType(inst_ty.toIntern()).field_types.len,
32681 .tuple_type => |tuple_type| tuple_type.types.len,
3265132682 else => unreachable,
3265232683 };
3265332684 if (src_field_count > dest_field_count) return error.NotCoercible;
......@@ -32656,24 +32687,19 @@ fn coerceTupleToTuple(
3265632687 for (0..dest_field_count) |field_index_usize| {
3265732688 const field_i: u32 = @intCast(field_index_usize);
3265832689 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
3266532691 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],
3266732693 .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.get(ip)[field_index_usize],
3266832694 else => unreachable,
3266932695 };
3267032696 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],
3267232698 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, field_index_usize),
3267332699 else => unreachable,
3267432700 };
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
3267832704 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);
3267932705 const coerced = try sema.coerce(block, Type.fromInterned(field_ty), elem_ref, field_src);
......@@ -32707,28 +32733,18 @@ fn coerceTupleToTuple(
3270732733 if (field_ref.* != .none) continue;
3270832734
3270932735 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],
3271132737 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, i),
3271232738 else => unreachable,
3271332739 };
3271432740
3271532741 const field_src = inst_src; // TODO better source location
3271632742 if (default_val == .none) {
32717 const field_name = tuple_ty.structFieldName(i, zcu).unwrap() orelse {
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)};
32743 const template = "missing tuple field: {d}";
3272832744 if (root_msg) |msg| {
32729 try sema.errNote(field_src, msg, template, args);
32745 try sema.errNote(field_src, msg, template, .{i});
3273032746 } else {
32731 root_msg = try sema.errMsg(field_src, template, args);
32747 root_msg = try sema.errMsg(field_src, template, .{i});
3273232748 }
3273332749 continue;
3273432750 }
......@@ -34265,8 +34281,8 @@ const PeerResolveStrategy = enum {
3426534281 fixed_int,
3426634282 /// The type must be some fixed-width float type.
3426734283 fixed_float,
34268 /// The type must be a struct literal or tuple type.
34269 coercible_struct,
34284 /// The type must be a tuple.
34285 tuple,
3427034286 /// The peers must all be of the same type.
3427134287 exact,
3427234288
......@@ -34350,9 +34366,9 @@ const PeerResolveStrategy = enum {
3435034366 .fixed_float => .{ .either, .fixed_float },
3435134367 else => .{ .all_s1, s1 }, // doesn't override anything later
3435234368 },
34353 .coercible_struct => switch (s1) {
34369 .tuple => switch (s1) {
3435434370 .exact => .{ .all_s1, .exact },
34355 else => .{ .all_s0, .coercible_struct },
34371 else => .{ .all_s0, .tuple },
3435634372 },
3435734373 .exact => .{ .all_s0, .exact },
3435834374 };
......@@ -34393,7 +34409,7 @@ const PeerResolveStrategy = enum {
3439334409 .error_set => .error_set,
3439434410 .error_union => .error_union,
3439534411 .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,
3439734413 .@"fn" => .func,
3439834414 };
3439934415 }
......@@ -35501,19 +35517,17 @@ fn resolvePeerTypesInner(
3550135517 return .{ .success = opt_cur_ty.? };
3550235518 },
3550335519
35504 .coercible_struct => {
35505 // First, check that every peer has the same approximate structure (field count and names)
35520 .tuple => {
35521 // First, check that every peer has the same approximate structure (field count)
3550635522
3550735523 var opt_first_idx: ?usize = null;
3550835524 var is_tuple: bool = undefined;
3550935525 var field_count: usize = undefined;
35510 // Only defined for non-tuples.
35511 var field_names: []InternPool.NullTerminatedString = undefined;
3551235526
3551335527 for (peer_tys, 0..) |opt_ty, i| {
3551435528 const ty = opt_ty orelse continue;
3551535529
35516 if (!ty.isTupleOrAnonStruct(zcu)) {
35530 if (!ty.isTuple(zcu)) {
3551735531 return .{ .conflict = .{
3551835532 .peer_idx_a = strat_reason,
3551935533 .peer_idx_b = i,
......@@ -35524,31 +35538,15 @@ fn resolvePeerTypesInner(
3552435538 opt_first_idx = i;
3552535539 is_tuple = ty.isTuple(zcu);
3552635540 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 }
3553135541 continue;
3553235542 };
3553335543
35534 if (ty.isTuple(zcu) != is_tuple or ty.structFieldCount(zcu) != field_count) {
35544 if (ty.structFieldCount(zcu) != field_count) {
3553535545 return .{ .conflict = .{
3553635546 .peer_idx_a = first_idx,
3553735547 .peer_idx_b = i,
3553835548 } };
3553935549 }
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 }
3555235550 }
3555335551
3555435552 assert(opt_first_idx != null);
......@@ -35578,10 +35576,7 @@ fn resolvePeerTypesInner(
3557835576 else => |result| {
3557935577 const result_buf = try sema.arena.create(PeerResolveResult);
3558035578 result_buf.* = result;
35581 const field_name = if (is_tuple)
35582 try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls)
35583 else
35584 field_names[field_index];
35579 const field_name = try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{d}", .{field_index}, .no_embedded_nulls);
3558535580
3558635581 // The error info needs the field types, but we can't reuse sub_peer_tys
3558735582 // since the recursive call may have clobbered it.
......@@ -35636,9 +35631,8 @@ fn resolvePeerTypesInner(
3563635631 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
3563735632 }
3563835633
35639 const final_ty = try ip.getAnonStructType(zcu.gpa, pt.tid, .{
35634 const final_ty = try ip.getTupleType(zcu.gpa, pt.tid, .{
3564035635 .types = field_types,
35641 .names = if (is_tuple) &.{} else field_names,
3564235636 .values = field_vals,
3564335637 });
3564435638
......@@ -35778,7 +35772,7 @@ pub fn resolveStructAlignment(
3577835772 const ip = &zcu.intern_pool;
3577935773 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
3578335777 assert(struct_type.layout != .@"packed");
3578435778 assert(struct_type.flagsUnordered(ip).alignment == .none);
......@@ -35821,7 +35815,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3582135815 const ip = &zcu.intern_pool;
3582235816 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
3582635820 if (struct_type.haveLayout(ip))
3582735821 return;
......@@ -35921,12 +35915,14 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3592135915 return a_align.compare(.gt, b_align);
3592235916 }
3592335917 };
35924 if (struct_type.isTuple(ip) or !zcu.backendSupportsFeature(.field_reordering)) {
35925 // TODO: don't handle tuples differently. This logic exists only because it
35926 // uncovers latent bugs if removed. Fix the latent bugs and remove this logic!
35927 // Likewise, implement field reordering support in all the backends!
35918 if (!zcu.backendSupportsFeature(.field_reordering)) {
35919 // TODO: we should probably also reorder tuple fields? This is a bit weird because it'll involve
35920 // mutating the `InternPool` for a non-container type.
35921 //
35922 // TODO: implement field reordering support in all the backends!
35923 //
3592835924 // 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.
3593035926 var i: usize = 0;
3593135927 var off: usize = 0;
3593235928 while (i + off < runtime_order.len) {
......@@ -35966,7 +35962,7 @@ fn backingIntType(
3596635962 const gpa = zcu.gpa;
3596735963 const ip = &zcu.intern_pool;
3596835964
35969 const cau_index = struct_type.cau.unwrap().?;
35965 const cau_index = struct_type.cau;
3597035966
3597135967 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3597235968 defer analysis_arena.deinit();
......@@ -35978,7 +35974,7 @@ fn backingIntType(
3597835974 .instructions = .{},
3597935975 .inlining = null,
3598035976 .is_comptime = true,
35981 .src_base_inst = struct_type.zir_index.unwrap().?,
35977 .src_base_inst = struct_type.zir_index,
3598235978 .type_name_ctx = struct_type.name,
3598335979 };
3598435980 defer assert(block.instructions.items.len == 0);
......@@ -35992,8 +35988,8 @@ fn backingIntType(
3599235988 break :blk accumulator;
3599335989 };
3599435990
35995 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;
35996 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip) orelse return error.AnalysisFail;
35991 const zir = zcu.namespacePtr(struct_type.namespace).fileScope(zcu).zir;
35992 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
3599735993 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
3599835994 assert(extended.opcode == .struct_decl);
3599935995 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
......@@ -36014,7 +36010,7 @@ fn backingIntType(
3601436010 extra_index += 1;
3601536011
3601636012 const backing_int_src: LazySrcLoc = .{
36017 .base_node_inst = struct_type.zir_index.unwrap().?,
36013 .base_node_inst = struct_type.zir_index,
3601836014 .offset = .{ .node_offset_container_tag = 0 },
3601936015 };
3602036016 const backing_int_ty = blk: {
......@@ -36261,7 +36257,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3626136257 const ip = &zcu.intern_pool;
3626236258 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
3626636262 if (struct_type.setFullyResolved(ip)) return;
3626736263 errdefer struct_type.clearFullyResolved(ip);
......@@ -36319,7 +36315,7 @@ pub fn resolveStructFieldTypes(
3631936315 const zcu = pt.zcu;
3632036316 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
3632436320 if (struct_type.haveFieldTypes(ip)) return;
3632536321
......@@ -36345,7 +36341,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3634536341 const ip = &zcu.intern_pool;
3634636342 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
3635036346 // Inits can start as resolved
3635136347 if (struct_type.haveFieldInits(ip)) return;
......@@ -36607,12 +36603,12 @@ fn structFields(
3660736603 const zcu = pt.zcu;
3660836604 const gpa = zcu.gpa;
3660936605 const ip = &zcu.intern_pool;
36610 const cau_index = struct_type.cau.unwrap().?;
36606 const cau_index = struct_type.cau;
3661136607 const namespace_index = ip.getCau(cau_index).namespace;
3661236608 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
3661736613 if (fields_len == 0) switch (struct_type.layout) {
3661836614 .@"packed" => {
......@@ -36632,7 +36628,7 @@ fn structFields(
3663236628 .instructions = .{},
3663336629 .inlining = null,
3663436630 .is_comptime = true,
36635 .src_base_inst = struct_type.zir_index.unwrap().?,
36631 .src_base_inst = struct_type.zir_index,
3663636632 .type_name_ctx = struct_type.name,
3663736633 };
3663836634 defer assert(block_scope.instructions.items.len == 0);
......@@ -36673,12 +36669,8 @@ fn structFields(
3667336669
3667436670 if (is_comptime) struct_type.setFieldComptime(ip, field_i);
3667536671
36676 var opt_field_name_zir: ?[:0]const u8 = null;
36677 if (!small.is_tuple) {
36678 opt_field_name_zir = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
36679 extra_index += 1;
36680 }
36681 extra_index += 1; // doc_comment
36672 const field_name_zir: [:0]const u8 = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
36673 extra_index += 2; // field_name, doc_comment
3668236674
3668336675 fields[field_i] = .{};
3668436676
......@@ -36690,10 +36682,8 @@ fn structFields(
3669036682 extra_index += 1;
3669136683
3669236684 // This string needs to outlive the ZIR code.
36693 if (opt_field_name_zir) |field_name_zir| {
36694 const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
36695 assert(struct_type.addFieldName(ip, field_name) == null);
36696 }
36685 const field_name = try ip.getOrPutString(gpa, pt.tid, field_name_zir, .no_embedded_nulls);
36686 assert(struct_type.addFieldName(ip, field_name) == null);
3669736687
3669836688 if (has_align) {
3669936689 fields[field_i].align_body_len = zir.extra[extra_index];
......@@ -36713,7 +36703,7 @@ fn structFields(
3671336703
3671436704 for (fields, 0..) |zir_field, field_i| {
3671536705 const ty_src: LazySrcLoc = .{
36716 .base_node_inst = struct_type.zir_index.unwrap().?,
36706 .base_node_inst = struct_type.zir_index,
3671736707 .offset = .{ .container_field_type = @intCast(field_i) },
3671836708 };
3671936709 const field_ty: Type = ty: {
......@@ -36785,7 +36775,7 @@ fn structFields(
3678536775 extra_index += body.len;
3678636776 const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
3678736777 const align_src: LazySrcLoc = .{
36788 .base_node_inst = struct_type.zir_index.unwrap().?,
36778 .base_node_inst = struct_type.zir_index,
3678936779 .offset = .{ .container_field_align = @intCast(field_i) },
3679036780 };
3679136781 const field_align = try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
......@@ -36812,11 +36802,11 @@ fn structFieldInits(
3681236802
3681336803 assert(!struct_type.haveFieldInits(ip));
3681436804
36815 const cau_index = struct_type.cau.unwrap().?;
36805 const cau_index = struct_type.cau;
3681636806 const namespace_index = ip.getCau(cau_index).namespace;
3681736807 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36818 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip) orelse return error.AnalysisFail;
36819 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
36808 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
36809 const fields_len, _, var extra_index = structZirInfo(zir, zir_index);
3682036810
3682136811 var block_scope: Block = .{
3682236812 .parent = null,
......@@ -36825,7 +36815,7 @@ fn structFieldInits(
3682536815 .instructions = .{},
3682636816 .inlining = null,
3682736817 .is_comptime = true,
36828 .src_base_inst = struct_type.zir_index.unwrap().?,
36818 .src_base_inst = struct_type.zir_index,
3682936819 .type_name_ctx = struct_type.name,
3683036820 };
3683136821 defer assert(block_scope.instructions.items.len == 0);
......@@ -36860,10 +36850,7 @@ fn structFieldInits(
3686036850 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
3686136851 cur_bit_bag >>= 1;
3686236852
36863 if (!small.is_tuple) {
36864 extra_index += 1;
36865 }
36866 extra_index += 1; // doc_comment
36853 extra_index += 2; // field_name, doc_comment
3686736854
3686836855 fields[field_i] = .{};
3686936856
......@@ -36901,7 +36888,7 @@ fn structFieldInits(
3690136888 sema.inst_map.putAssumeCapacity(zir_index, type_ref);
3690236889
3690336890 const init_src: LazySrcLoc = .{
36904 .base_node_inst = struct_type.zir_index.unwrap().?,
36891 .base_node_inst = struct_type.zir_index,
3690536892 .offset = .{ .container_field_value = @intCast(field_i) },
3690636893 };
3690736894
......@@ -37430,7 +37417,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3743037417 .undefined_type => Value.undef,
3743137418 .optional_noreturn_type => try pt.nullValue(ty),
3743237419 .generic_poison_type => error.GenericPoison,
37433 .empty_struct_type => Value.empty_struct,
37420 .empty_tuple_type => Value.empty_tuple,
3743437421 // values, not types
3743537422 .undef,
3743637423 .zero,
......@@ -37446,7 +37433,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3744637433 .null_value,
3744737434 .bool_true,
3744837435 .bool_false,
37449 .empty_struct,
37436 .empty_tuple,
3745037437 .generic_poison,
3745137438 // invalid
3745237439 .none,
......@@ -37532,10 +37519,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3753237519 .type_enum_explicit,
3753337520 .type_enum_nonexhaustive,
3753437521 .type_struct,
37535 .type_struct_anon,
3753637522 .type_struct_packed,
3753737523 .type_struct_packed_inits,
37538 .type_tuple_anon,
37524 .type_tuple,
3753937525 .type_union,
3754037526 => switch (ip.indexToKey(ty.toIntern())) {
3754137527 inline .array_type, .vector_type => |seq_type, seq_tag| {
......@@ -37594,7 +37580,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3759437580 } }));
3759537581 },
3759637582
37597 .anon_struct_type => |tuple| {
37583 .tuple_type => |tuple| {
3759837584 for (tuple.values.get(ip)) |val| {
3759937585 if (val == .none) return null;
3760037586 }
......@@ -37965,35 +37951,9 @@ fn structFieldIndex(
3796537951 const zcu = pt.zcu;
3796637952 const ip = &zcu.intern_pool;
3796737953 try struct_ty.resolveFields(pt);
37968 if (struct_ty.isAnonStruct(zcu)) {
37969 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
37970 } else {
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 });
37954 const struct_type = zcu.typeToStruct(struct_ty).?;
37955 return struct_type.nameIndex(ip, field_name) orelse
37956 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);
3799737957}
3799837958
3799937959/// 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 {
246246 .error_union_type,
247247 .simple_type,
248248 .struct_type,
249 .anon_struct_type,
249 .tuple_type,
250250 .union_type,
251251 .opaque_type,
252252 .enum_type,
src/Type.zig+63-115
......@@ -320,33 +320,20 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
320320 },
321321 .struct_type => {
322322 const name = ip.loadStructType(ty.toIntern()).name;
323 if (name == .empty) {
324 try writer.writeAll("@TypeOf(.{})");
325 } else {
326 try writer.print("{}", .{name.fmt(ip)});
327 }
323 try writer.print("{}", .{name.fmt(ip)});
328324 },
329 .anon_struct_type => |anon_struct| {
330 if (anon_struct.types.len == 0) {
325 .tuple_type => |tuple| {
326 if (tuple.types.len == 0) {
331327 return writer.writeAll("@TypeOf(.{})");
332328 }
333 try writer.writeAll("struct{");
334 for (anon_struct.types.get(ip), anon_struct.values.get(ip), 0..) |field_ty, val, i| {
335 if (i != 0) try writer.writeAll(", ");
336 if (val != .none) {
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
329 try writer.writeAll("struct {");
330 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, val, i| {
331 try writer.writeAll(if (i == 0) " " else ", ");
332 if (val != .none) try writer.writeAll("comptime ");
343333 try print(Type.fromInterned(field_ty), writer, pt);
344
345 if (val != .none) {
346 try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)});
347 }
334 if (val != .none) try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)});
348335 }
349 try writer.writeAll("}");
336 try writer.writeAll(" }");
350337 },
351338
352339 .union_type => {
......@@ -489,8 +476,7 @@ pub fn hasRuntimeBitsInner(
489476) RuntimeBitsError!bool {
490477 const ip = &zcu.intern_pool;
491478 return switch (ty.toIntern()) {
492 // False because it is a comptime-only type.
493 .empty_struct_type => false,
479 .empty_tuple_type => false,
494480 else => switch (ip.indexToKey(ty.toIntern())) {
495481 .int_type => |int_type| int_type.bits != 0,
496482 .ptr_type => {
......@@ -593,7 +579,7 @@ pub fn hasRuntimeBitsInner(
593579 return false;
594580 }
595581 },
596 .anon_struct_type => |tuple| {
582 .tuple_type => |tuple| {
597583 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
598584 if (val != .none) continue; // comptime field
599585 if (try Type.fromInterned(field_ty).hasRuntimeBitsInner(
......@@ -691,7 +677,7 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
691677 .error_union_type,
692678 .error_set_type,
693679 .inferred_error_set_type,
694 .anon_struct_type,
680 .tuple_type,
695681 .opaque_type,
696682 .anyframe_type,
697683 // These are function bodies, not function pointers.
......@@ -966,7 +952,7 @@ pub fn abiAlignmentInner(
966952 const ip = &zcu.intern_pool;
967953
968954 switch (ty.toIntern()) {
969 .empty_struct_type => return .{ .scalar = .@"1" },
955 .empty_tuple_type => return .{ .scalar = .@"1" },
970956 else => switch (ip.indexToKey(ty.toIntern())) {
971957 .int_type => |int_type| {
972958 if (int_type.bits == 0) return .{ .scalar = .@"1" };
......@@ -1109,7 +1095,7 @@ pub fn abiAlignmentInner(
11091095
11101096 return .{ .scalar = struct_type.flagsUnordered(ip).alignment };
11111097 },
1112 .anon_struct_type => |tuple| {
1098 .tuple_type => |tuple| {
11131099 var big_align: Alignment = .@"1";
11141100 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
11151101 if (val != .none) continue; // comptime field
......@@ -1295,7 +1281,7 @@ pub fn abiSizeInner(
12951281 const ip = &zcu.intern_pool;
12961282
12971283 switch (ty.toIntern()) {
1298 .empty_struct_type => return .{ .scalar = 0 },
1284 .empty_tuple_type => return .{ .scalar = 0 },
12991285
13001286 else => switch (ip.indexToKey(ty.toIntern())) {
13011287 .int_type => |int_type| {
......@@ -1498,7 +1484,7 @@ pub fn abiSizeInner(
14981484 },
14991485 }
15001486 },
1501 .anon_struct_type => |tuple| {
1487 .tuple_type => |tuple| {
15021488 switch (strat) {
15031489 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),
15041490 .lazy, .eager => {},
......@@ -1831,8 +1817,7 @@ pub fn bitSizeInner(
18311817 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
18321818 },
18331819
1834 .anon_struct_type => {
1835 if (strat == .sema) try ty.resolveFields(strat.pt(zcu, tid));
1820 .tuple_type => {
18361821 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
18371822 },
18381823
......@@ -2176,7 +2161,7 @@ pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayo
21762161 const ip = &zcu.intern_pool;
21772162 return switch (ip.indexToKey(ty.toIntern())) {
21782163 .struct_type => ip.loadStructType(ty.toIntern()).layout,
2179 .anon_struct_type => .auto,
2164 .tuple_type => .auto,
21802165 .union_type => ip.loadUnionType(ty.toIntern()).flagsUnordered(ip).layout,
21812166 else => unreachable,
21822167 };
......@@ -2295,7 +2280,7 @@ pub fn arrayLenIncludingSentinel(ty: Type, zcu: *const Zcu) u64 {
22952280pub fn vectorLen(ty: Type, zcu: *const Zcu) u32 {
22962281 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
22972282 .vector_type => |vector_type| vector_type.len,
2298 .anon_struct_type => |tuple| @intCast(tuple.types.len),
2283 .tuple_type => |tuple| @intCast(tuple.types.len),
22992284 else => unreachable,
23002285 };
23012286}
......@@ -2305,7 +2290,7 @@ pub fn sentinel(ty: Type, zcu: *const Zcu) ?Value {
23052290 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
23062291 .vector_type,
23072292 .struct_type,
2308 .anon_struct_type,
2293 .tuple_type,
23092294 => null,
23102295
23112296 .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 {
23862371 return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() };
23872372 },
23882373
2389 .anon_struct_type => unreachable,
2374 .tuple_type => unreachable,
23902375
23912376 .ptr_type => unreachable,
23922377 .anyframe_type => unreachable,
......@@ -2556,7 +2541,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
25562541 var ty = starting_type;
25572542 const ip = &zcu.intern_pool;
25582543 while (true) switch (ty.toIntern()) {
2559 .empty_struct_type => return Value.empty_struct,
2544 .empty_tuple_type => return Value.empty_tuple,
25602545
25612546 else => switch (ip.indexToKey(ty.toIntern())) {
25622547 .int_type => |int_type| {
......@@ -2660,7 +2645,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
26602645 } }));
26612646 },
26622647
2663 .anon_struct_type => |tuple| {
2648 .tuple_type => |tuple| {
26642649 for (tuple.values.get(ip)) |val| {
26652650 if (val == .none) return null;
26662651 }
......@@ -2783,7 +2768,7 @@ pub fn comptimeOnlyInner(
27832768) SemaError!bool {
27842769 const ip = &zcu.intern_pool;
27852770 return switch (ty.toIntern()) {
2786 .empty_struct_type => false,
2771 .empty_tuple_type => false,
27872772
27882773 else => switch (ip.indexToKey(ty.toIntern())) {
27892774 .int_type => false,
......@@ -2891,7 +2876,7 @@ pub fn comptimeOnlyInner(
28912876 };
28922877 },
28932878
2894 .anon_struct_type => |tuple| {
2879 .tuple_type => |tuple| {
28952880 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
28962881 const have_comptime_val = val != .none;
28972882 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 {
30223007 const ip = &zcu.intern_pool;
30233008 return switch (ip.indexToKey(ty.toIntern())) {
30243009 .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(),
30263011 .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(),
30273012 .enum_type => ip.loadEnumType(ty.toIntern()).namespace.toOptional(),
30283013 else => .none,
......@@ -3181,7 +3166,7 @@ pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.Optio
31813166 const ip = &zcu.intern_pool;
31823167 return switch (ip.indexToKey(ty.toIntern())) {
31833168 .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, index),
3184 .anon_struct_type => |anon_struct| anon_struct.fieldName(ip, index),
3169 .tuple_type => .none,
31853170 else => unreachable,
31863171 };
31873172}
......@@ -3190,7 +3175,7 @@ pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {
31903175 const ip = &zcu.intern_pool;
31913176 return switch (ip.indexToKey(ty.toIntern())) {
31923177 .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,
31943179 else => unreachable,
31953180 };
31963181}
......@@ -3204,7 +3189,7 @@ pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
32043189 const union_obj = ip.loadUnionType(ty.toIntern());
32053190 return Type.fromInterned(union_obj.field_types.get(ip)[index]);
32063191 },
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]),
32083193 else => unreachable,
32093194 };
32103195}
......@@ -3238,8 +3223,8 @@ pub fn fieldAlignmentInner(
32383223 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
32393224 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);
32403225 },
3241 .anon_struct_type => |anon_struct| {
3242 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentInner(
3226 .tuple_type => |tuple| {
3227 return (try Type.fromInterned(tuple.types.get(ip)[index]).abiAlignmentInner(
32433228 strat.toLazy(),
32443229 zcu,
32453230 tid,
......@@ -3361,8 +3346,8 @@ pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) Value {
33613346 if (val == .none) return Value.@"unreachable";
33623347 return Value.fromInterned(val);
33633348 },
3364 .anon_struct_type => |anon_struct| {
3365 const val = anon_struct.values.get(ip)[index];
3349 .tuple_type => |tuple| {
3350 const val = tuple.values.get(ip)[index];
33663351 // TODO: avoid using `unreachable` to indicate this.
33673352 if (val == .none) return Value.@"unreachable";
33683353 return Value.fromInterned(val);
......@@ -3384,7 +3369,7 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
33843369 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);
33853370 }
33863371 },
3387 .anon_struct_type => |tuple| {
3372 .tuple_type => |tuple| {
33883373 const val = tuple.values.get(ip)[index];
33893374 if (val == .none) {
33903375 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 {
34003385 const ip = &zcu.intern_pool;
34013386 return switch (ip.indexToKey(ty.toIntern())) {
34023387 .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,
34043389 else => unreachable,
34053390 };
34063391}
......@@ -3425,7 +3410,7 @@ pub fn structFieldOffset(
34253410 return struct_type.offsets.get(ip)[index];
34263411 },
34273412
3428 .anon_struct_type => |tuple| {
3413 .tuple_type => |tuple| {
34293414 var offset: u64 = 0;
34303415 var big_align: Alignment = .none;
34313416
......@@ -3472,7 +3457,6 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
34723457 .declared => |d| d.zir_index,
34733458 .reified => |r| r.zir_index,
34743459 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3475 .empty_struct => return null,
34763460 },
34773461 else => return null,
34783462 },
......@@ -3491,49 +3475,7 @@ pub fn isGenericPoison(ty: Type) bool {
34913475pub fn isTuple(ty: Type, zcu: *const Zcu) bool {
34923476 const ip = &zcu.intern_pool;
34933477 return switch (ip.indexToKey(ty.toIntern())) {
3494 .struct_type => {
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,
3478 .tuple_type => true,
35373479 else => false,
35383480 };
35393481}
......@@ -3564,7 +3506,7 @@ pub fn toUnsigned(ty: Type, pt: Zcu.PerThread) !Type {
35643506pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
35653507 const ip = &zcu.intern_pool;
35663508 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,
35683510 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
35693511 .enum_type => ip.loadEnumType(ty.toIntern()).zir_index.unwrap(),
35703512 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
......@@ -3575,12 +3517,11 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
35753517pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
35763518 const ip = &zcu.intern_pool;
35773519 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,
35793521 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
35803522 .enum_type => |e| switch (e) {
35813523 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
35823524 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3583 .empty_struct => unreachable,
35843525 },
35853526 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
35863527 else => null,
......@@ -3588,13 +3529,16 @@ pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.Trac
35883529}
35893530
35903531pub 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
35913536 const ip = &zcu.intern_pool;
35923537 const tracked = switch (ip.indexToKey(ty.toIntern())) {
35933538 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
35943539 .declared => |d| d.zir_index,
35953540 .reified => |r| r.zir_index,
35963541 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3597 .empty_struct => return null,
35983542 },
35993543 else => return null,
36003544 };
......@@ -3603,13 +3547,17 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
36033547 assert(file.zir_loaded);
36043548 const zir = file.zir;
36053549 const inst = zir.instructions.get(@intFromEnum(info.inst));
3606 assert(inst.tag == .extended);
3607 return switch (inst.data.extended.opcode) {
3608 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_line,
3609 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,
3610 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,
3611 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,
3612 .reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.src_line,
3550 return switch (inst.tag) {
3551 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
3552 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_line,
3553 .extended => switch (inst.data.extended.opcode) {
3554 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_line,
3555 .union_decl => zir.extraData(Zir.Inst.UnionDecl, 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 },
36133561 else => unreachable,
36143562 };
36153563}
......@@ -3697,8 +3645,8 @@ pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void {
36973645 const ip = &zcu.intern_pool;
36983646 switch (ty.zigTypeTag(zcu)) {
36993647 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
3700 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {
3701 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);
3648 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |i| {
3649 const field_ty = Type.fromInterned(tuple_type.types.get(ip)[i]);
37023650 try field_ty.resolveLayout(pt);
37033651 },
37043652 .struct_type => return ty.resolveStructInner(pt, .layout),
......@@ -3796,7 +3744,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
37963744 .optional_noreturn_type,
37973745 .anyerror_void_error_union_type,
37983746 .generic_poison_type,
3799 .empty_struct_type,
3747 .empty_tuple_type,
38003748 => {},
38013749
38023750 .undef => unreachable,
......@@ -3813,7 +3761,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
38133761 .null_value => unreachable,
38143762 .bool_true => unreachable,
38153763 .bool_false => unreachable,
3816 .empty_struct => unreachable,
3764 .empty_tuple => unreachable,
38173765 .generic_poison => unreachable,
38183766
38193767 else => switch (ty_ip.unwrap(ip).getTag(ip)) {
......@@ -3868,8 +3816,8 @@ pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void {
38683816 },
38693817
38703818 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
3871 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {
3872 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);
3819 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |i| {
3820 const field_ty = Type.fromInterned(tuple_type.types.get(ip)[i]);
38733821 try field_ty.resolveFully(pt);
38743822 },
38753823 .struct_type => return ty.resolveStructInner(pt, .full),
......@@ -3903,7 +3851,7 @@ fn resolveStructInner(
39033851 const gpa = zcu.gpa;
39043852
39053853 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
39083856 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
39093857 return error.AnalysisFail;
......@@ -3915,7 +3863,7 @@ fn resolveStructInner(
39153863 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
39163864 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;
39193867 var sema: Sema = .{
39203868 .pt = pt,
39213869 .gpa = gpa,
......@@ -4196,7 +4144,7 @@ pub const single_const_pointer_to_comptime_int: Type = .{
41964144 .ip_index = .single_const_pointer_to_comptime_int_type,
41974145};
41984146pub 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
42014149pub 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 };
37043704
37053705pub const generic_poison: Value = .{ .ip_index = .generic_poison };
37063706pub 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
37093709pub fn makeBool(x: bool) Value {
37103710 return if (x) Value.true else Value.false;
src/Zcu.zig+33-2
......@@ -1497,6 +1497,20 @@ pub const SrcLoc = struct {
14971497 }
14981498 } else unreachable;
14991499 },
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 },
15001514 .init_elem => |init_elem| {
15011515 const tree = try src_loc.file_scope.getTree(gpa);
15021516 const init_node = src_loc.relativeToNodeIndex(init_elem.init_node_offset);
......@@ -1939,6 +1953,12 @@ pub const LazySrcLoc = struct {
19391953 container_field_type: u32,
19401954 /// Like `continer_field_name`, but points at the field's alignment.
19411955 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,
19421962 /// The source location points to the given element/field of a struct or
19431963 /// array initialization expression.
19441964 init_elem: struct {
......@@ -2016,13 +2036,20 @@ pub const LazySrcLoc = struct {
20162036 index: u31,
20172037 };
20182038
2019 const ArrayCat = struct {
2039 pub const ArrayCat = struct {
20202040 /// Points to the array concat AST node.
20212041 array_cat_offset: i32,
20222042 /// The index of the element the source location points to.
20232043 elem_index: u32,
20242044 };
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
20262053 pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
20272054
20282055 noinline fn nodeOffsetDebug(node_offset: i32) Offset {
......@@ -2052,6 +2079,8 @@ pub const LazySrcLoc = struct {
20522079
20532080 /// Returns `null` if the ZIR instruction has been lost across incremental updates.
20542081 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
20552084 const ip = &zcu.intern_pool;
20562085 const file_index, const zir_inst = inst: {
20572086 const info = base_node_inst.resolveFull(ip) orelse return null;
......@@ -2064,6 +2093,8 @@ pub const LazySrcLoc = struct {
20642093 const inst = zir.instructions.get(@intFromEnum(zir_inst));
20652094 const base_node: Ast.Node.Index = switch (inst.tag) {
20662095 .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,
20672098 .extended => switch (inst.data.extended.opcode) {
20682099 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_node,
20692100 .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
32153246
32163247 // If this type has a `Cau` for resolution, it's automatically referenced.
32173248 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(),
32193250 .union_type => ip.loadUnionType(ty).cau.toOptional(),
32203251 .enum_type => ip.loadEnumType(ty).cau,
32213252 .opaque_type => .none,
src/Zcu/PerThread.zig+7-15
......@@ -985,7 +985,6 @@ fn createFileRootStruct(
985985 .fields_len = fields_len,
986986 .known_non_opv = small.known_non_opv,
987987 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
988 .is_tuple = small.is_tuple,
989988 .any_comptime_fields = small.any_comptime_fields,
990989 .any_default_inits = small.any_default_inits,
991990 .inits_resolved = false,
......@@ -3191,7 +3190,7 @@ pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index, already_updat
31913190 .struct_type => |key| {
31923191 const struct_obj = ip.loadStructType(ty);
31933192 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 });
31953194 const o = zcu.outdated.swapRemove(anal_unit) or
31963195 zcu.potentially_outdated.swapRemove(anal_unit);
31973196 if (o) {
......@@ -3252,7 +3251,6 @@ fn recreateStructType(
32523251
32533252 const key = switch (full_key) {
32543253 .reified => unreachable, // never outdated
3255 .empty_struct => unreachable, // never outdated
32563254 .generated_tag => unreachable, // not a struct
32573255 .declared => |d| d,
32583256 };
......@@ -3283,16 +3281,13 @@ fn recreateStructType(
32833281 if (captures_len != key.captures.owned.len) return error.AnalysisFail;
32843282
32853283 // The old type will be unused, so drop its dependency information.
3286 ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap().? }));
3287
3288 const namespace_index = struct_obj.namespace.unwrap().?;
3284 ip.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .cau = struct_obj.cau }));
32893285
32903286 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
32913287 .layout = small.layout,
32923288 .fields_len = fields_len,
32933289 .known_non_opv = small.known_non_opv,
32943290 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
3295 .is_tuple = small.is_tuple,
32963291 .any_comptime_fields = small.any_comptime_fields,
32973292 .any_default_inits = small.any_default_inits,
32983293 .inits_resolved = false,
......@@ -3308,17 +3303,17 @@ fn recreateStructType(
33083303 errdefer wip_ty.cancel(ip, pt.tid);
33093304
33103305 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);
33123307 try ip.addDependency(
33133308 gpa,
33143309 AnalUnit.wrap(.{ .cau = new_cau_index }),
33153310 .{ .src_hash = key.zir_index },
33163311 );
3317 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;
3312 zcu.namespacePtr(struct_obj.namespace).owner_type = wip_ty.index;
33183313 // No need to re-scan the namespace -- `zirStructDecl` will ultimately do that if the type is still alive.
33193314 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);
33223317 if (inst_info.inst == .main_struct_inst) {
33233318 // This is the root type of a file! Update the reference.
33243319 zcu.setFileRootType(inst_info.file, new_ty);
......@@ -3337,7 +3332,6 @@ fn recreateUnionType(
33373332
33383333 const key = switch (full_key) {
33393334 .reified => unreachable, // never outdated
3340 .empty_struct => unreachable, // never outdated
33413335 .generated_tag => unreachable, // not a union
33423336 .declared => |d| d,
33433337 };
......@@ -3429,9 +3423,7 @@ fn recreateEnumType(
34293423 const ip = &zcu.intern_pool;
34303424
34313425 const key = switch (full_key) {
3432 .reified => unreachable, // never outdated
3433 .empty_struct => unreachable, // never outdated
3434 .generated_tag => unreachable, // never outdated
3426 .reified, .generated_tag => unreachable, // never outdated
34353427 .declared => |d| d,
34363428 };
34373429
......@@ -3575,7 +3567,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
35753567 };
35763568
35773569 const key = switch (full_key) {
3578 .reified, .empty_struct, .generated_tag => {
3570 .reified, .generated_tag => {
35793571 // Namespace always empty, so up-to-date.
35803572 namespace.generation = zcu.generation;
35813573 return;
src/arch/sparc64/CodeGen.zig+5-7
......@@ -3114,7 +3114,7 @@ fn binOpImmediate(
31143114 const reg = try self.register_manager.allocReg(track_inst, gp);
31153115
31163116 if (track_inst) |inst| {
3117 const mcv = .{ .register = reg };
3117 const mcv: MCValue = .{ .register = reg };
31183118 log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv });
31193119 branch.inst_table.putAssumeCapacity(inst, mcv);
31203120
......@@ -3252,7 +3252,7 @@ fn binOpRegister(
32523252
32533253 const reg = try self.register_manager.allocReg(track_inst, gp);
32543254 if (track_inst) |inst| {
3255 const mcv = .{ .register = reg };
3255 const mcv: MCValue = .{ .register = reg };
32563256 log.debug("binOpRegister move lhs %{d} to register: {} -> {}", .{ inst, lhs, mcv });
32573257 branch.inst_table.putAssumeCapacity(inst, mcv);
32583258
......@@ -3276,7 +3276,7 @@ fn binOpRegister(
32763276
32773277 const reg = try self.register_manager.allocReg(track_inst, gp);
32783278 if (track_inst) |inst| {
3279 const mcv = .{ .register = reg };
3279 const mcv: MCValue = .{ .register = reg };
32803280 log.debug("binOpRegister move rhs %{d} to register: {} -> {}", .{ inst, rhs, mcv });
32813281 branch.inst_table.putAssumeCapacity(inst, mcv);
32823282
......@@ -3650,7 +3650,6 @@ fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_ty
36503650 assert(off_type == Register or off_type == i13);
36513651
36523652 const is_imm = (off_type == i13);
3653 const rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off };
36543653
36553654 switch (abi_size) {
36563655 1, 2, 4, 8 => {
......@@ -3669,7 +3668,7 @@ fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_ty
36693668 .is_imm = is_imm,
36703669 .rd = value_reg,
36713670 .rs1 = addr_reg,
3672 .rs2_or_imm = rs2_or_imm,
3671 .rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off },
36733672 },
36743673 },
36753674 });
......@@ -4037,7 +4036,6 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t
40374036 assert(off_type == Register or off_type == i13);
40384037
40394038 const is_imm = (off_type == i13);
4040 const rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off };
40414039
40424040 switch (abi_size) {
40434041 1, 2, 4, 8 => {
......@@ -4056,7 +4054,7 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t
40564054 .is_imm = is_imm,
40574055 .rd = value_reg,
40584056 .rs1 = addr_reg,
4059 .rs2_or_imm = rs2_or_imm,
4057 .rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off },
40604058 },
40614059 },
40624060 });
src/arch/wasm/CodeGen.zig+3-3
......@@ -3259,7 +3259,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32593259 .error_union_type,
32603260 .simple_type,
32613261 .struct_type,
3262 .anon_struct_type,
3262 .tuple_type,
32633263 .union_type,
32643264 .opaque_type,
32653265 .enum_type,
......@@ -3273,7 +3273,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32733273 .undefined,
32743274 .void,
32753275 .null,
3276 .empty_struct,
3276 .empty_tuple,
32773277 .@"unreachable",
32783278 .generic_poison,
32793279 => unreachable, // non-runtime values
......@@ -3708,7 +3708,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37083708 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
37093709 const operand = try func.resolveInst(un_op);
37103710 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
37133713 try func.emitWValue(operand);
37143714 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 {
1368313683 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1368413684 const operand = try self.resolveInst(un_op);
1368513685 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)) {
1368713687 .eflags => |cc| .{ .eflags = cc.negate() },
1368813688 else => unreachable,
1368913689 };
src/codegen.zig+3-3
......@@ -216,7 +216,7 @@ pub fn generateSymbol(
216216 .error_union_type,
217217 .simple_type,
218218 .struct_type,
219 .anon_struct_type,
219 .tuple_type,
220220 .union_type,
221221 .opaque_type,
222222 .enum_type,
......@@ -230,7 +230,7 @@ pub fn generateSymbol(
230230 .undefined,
231231 .void,
232232 .null,
233 .empty_struct,
233 .empty_tuple,
234234 .@"unreachable",
235235 .generic_poison,
236236 => unreachable, // non-runtime values
......@@ -456,7 +456,7 @@ pub fn generateSymbol(
456456 if (padding > 0) try code.appendNTimes(0, padding);
457457 }
458458 },
459 .anon_struct_type => |tuple| {
459 .tuple_type => |tuple| {
460460 const struct_begin = code.items.len;
461461 for (
462462 tuple.types.get(ip),
src/codegen/c.zig+16-25
......@@ -891,7 +891,7 @@ pub const DeclGen = struct {
891891 .error_union_type,
892892 .simple_type,
893893 .struct_type,
894 .anon_struct_type,
894 .tuple_type,
895895 .union_type,
896896 .opaque_type,
897897 .enum_type,
......@@ -908,7 +908,7 @@ pub const DeclGen = struct {
908908 .undefined => unreachable,
909909 .void => unreachable,
910910 .null => unreachable,
911 .empty_struct => unreachable,
911 .empty_tuple => unreachable,
912912 .@"unreachable" => unreachable,
913913 .generic_poison => unreachable,
914914
......@@ -1194,7 +1194,7 @@ pub const DeclGen = struct {
11941194 try writer.writeByte('}');
11951195 }
11961196 },
1197 .anon_struct_type => |tuple| {
1197 .tuple_type => |tuple| {
11981198 if (!location.isInitializer()) {
11991199 try writer.writeByte('(');
12001200 try dg.renderCType(writer, ctype);
......@@ -1605,7 +1605,7 @@ pub const DeclGen = struct {
16051605 }),
16061606 }
16071607 },
1608 .anon_struct_type => |anon_struct_info| {
1608 .tuple_type => |tuple_info| {
16091609 if (!location.isInitializer()) {
16101610 try writer.writeByte('(');
16111611 try dg.renderCType(writer, ctype);
......@@ -1614,9 +1614,9 @@ pub const DeclGen = struct {
16141614
16151615 try writer.writeByte('{');
16161616 var need_comma = false;
1617 for (0..anon_struct_info.types.len) |field_index| {
1618 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
1619 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
1617 for (0..tuple_info.types.len) |field_index| {
1618 if (tuple_info.values.get(ip)[field_index] != .none) continue;
1619 const field_ty = Type.fromInterned(tuple_info.types.get(ip)[field_index]);
16201620 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
16211621
16221622 if (need_comma) try writer.writeByte(',');
......@@ -5411,9 +5411,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
54115411 const input_val = try f.resolveInst(input);
54125412 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
54135413 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;
54155415 locals_index += 1;
5416 break :local input_local;
5416 break :local .{ .local = input_local_idx };
54175417 } else input_val, .Other);
54185418 try writer.writeByte(')');
54195419 }
......@@ -5651,15 +5651,12 @@ fn fieldLocation(
56515651 .begin,
56525652 };
56535653 },
5654 .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
5654 .tuple_type => return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
56555655 .begin
56565656 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
56575657 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }
56585658 else
5659 .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|
5660 .{ .identifier = field_name.toSlice(ip) }
5661 else
5662 .{ .field = field_index } },
5659 .{ .field = .{ .field = field_index } },
56635660 .union_type => {
56645661 const loaded_union = ip.loadUnionType(container_ty.toIntern());
56655662 switch (loaded_union.flagsUnordered(ip).layout) {
......@@ -5892,10 +5889,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
58925889 },
58935890 }
58945891 },
5895 .anon_struct_type => |anon_struct_info| if (anon_struct_info.fieldName(ip, extra.field_index).unwrap()) |field_name|
5896 .{ .identifier = field_name.toSlice(ip) }
5897 else
5898 .{ .field = extra.field_index },
5892 .tuple_type => .{ .field = extra.field_index },
58995893 .union_type => field_name: {
59005894 const loaded_union = ip.loadUnionType(struct_ty.toIntern());
59015895 switch (loaded_union.flagsUnordered(ip).layout) {
......@@ -7366,16 +7360,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
73667360 },
73677361 }
73687362 },
7369 .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| {
7370 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
7371 const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
7363 .tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {
7364 if (tuple_info.values.get(ip)[field_index] != .none) continue;
7365 const field_ty = Type.fromInterned(tuple_info.types.get(ip)[field_index]);
73727366 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
73737367
73747368 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|
7376 .{ .identifier = field_name.toSlice(ip) }
7377 else
7378 .{ .field = field_index });
7369 try f.writeCValueMember(writer, local, .{ .field = field_index });
73797370 try a.assign(f, writer);
73807371 try f.writeCValue(writer, resolved_elements[field_index], .Other);
73817372 try a.end(f, writer);
src/codegen/c/Type.zig+8-12
......@@ -1350,7 +1350,7 @@ pub const Pool = struct {
13501350 .i0_type,
13511351 .anyopaque_type,
13521352 .void_type,
1353 .empty_struct_type,
1353 .empty_tuple_type,
13541354 .type_type,
13551355 .comptime_int_type,
13561356 .comptime_float_type,
......@@ -1450,7 +1450,7 @@ pub const Pool = struct {
14501450 .null_value,
14511451 .bool_true,
14521452 .bool_false,
1453 .empty_struct,
1453 .empty_tuple,
14541454 .generic_poison,
14551455 .none,
14561456 => unreachable,
......@@ -1730,16 +1730,16 @@ pub const Pool = struct {
17301730 ),
17311731 }
17321732 },
1733 .anon_struct_type => |anon_struct_info| {
1733 .tuple_type => |tuple_info| {
17341734 const scratch_top = scratch.items.len;
17351735 defer scratch.shrinkRetainingCapacity(scratch_top);
1736 try scratch.ensureUnusedCapacity(allocator, anon_struct_info.types.len *
1736 try scratch.ensureUnusedCapacity(allocator, tuple_info.types.len *
17371737 @typeInfo(Field).@"struct".fields.len);
17381738 var hasher = Hasher.init;
1739 for (0..anon_struct_info.types.len) |field_index| {
1740 if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
1739 for (0..tuple_info.types.len) |field_index| {
1740 if (tuple_info.values.get(ip)[field_index] != .none) continue;
17411741 const field_type = Type.fromInterned(
1742 anon_struct_info.types.get(ip)[field_index],
1742 tuple_info.types.get(ip)[field_index],
17431743 );
17441744 const field_ctype = try pool.fromType(
17451745 allocator,
......@@ -1750,11 +1750,7 @@ pub const Pool = struct {
17501750 kind.noParameter(),
17511751 );
17521752 if (field_ctype.index == .void) continue;
1753 const field_name = if (anon_struct_info.fieldName(ip, @intCast(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});
1753 const field_name = try pool.fmt(allocator, "f{d}", .{field_index});
17581754 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
17591755 .name = field_name.index,
17601756 .ctype = field_ctype.index,
src/codegen/llvm.zig+14-17
......@@ -2563,7 +2563,7 @@ pub const Object = struct {
25632563 }
25642564
25652565 switch (ip.indexToKey(ty.toIntern())) {
2566 .anon_struct_type => |tuple| {
2566 .tuple_type => |tuple| {
25672567 var fields: std.ArrayListUnmanaged(Builder.Metadata) = .empty;
25682568 defer fields.deinit(gpa);
25692569
......@@ -2582,11 +2582,8 @@ pub const Object = struct {
25822582 const field_offset = field_align.forward(offset);
25832583 offset = field_offset + field_size;
25842584
2585 const field_name = if (tuple.names.len != 0)
2586 tuple.names.get(ip)[i].toSlice(ip)
2587 else
2588 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
2589 defer if (tuple.names.len == 0) gpa.free(field_name);
2585 var name_buf: [32]u8 = undefined;
2586 const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{i}) catch unreachable;
25902587
25912588 fields.appendAssumeCapacity(try o.builder.debugMemberType(
25922589 try o.builder.metadataString(field_name),
......@@ -3426,7 +3423,7 @@ pub const Object = struct {
34263423 .adhoc_inferred_error_set_type,
34273424 => try o.errorIntType(),
34283425 .generic_poison_type,
3429 .empty_struct_type,
3426 .empty_tuple_type,
34303427 => unreachable,
34313428 // values, not types
34323429 .undef,
......@@ -3443,7 +3440,7 @@ pub const Object = struct {
34433440 .null_value,
34443441 .bool_true,
34453442 .bool_false,
3446 .empty_struct,
3443 .empty_tuple,
34473444 .generic_poison,
34483445 .none,
34493446 => unreachable,
......@@ -3610,13 +3607,13 @@ pub const Object = struct {
36103607 );
36113608 return ty;
36123609 },
3613 .anon_struct_type => |anon_struct_type| {
3610 .tuple_type => |tuple_type| {
36143611 var llvm_field_types: std.ArrayListUnmanaged(Builder.Type) = .empty;
36153612 defer llvm_field_types.deinit(o.gpa);
36163613 // Although we can estimate how much capacity to add, these cannot be
36173614 // relied upon because of the recursive calls to lowerType below.
3618 try llvm_field_types.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len);
3619 try o.struct_field_map.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len);
3615 try llvm_field_types.ensureUnusedCapacity(o.gpa, tuple_type.types.len);
3616 try o.struct_field_map.ensureUnusedCapacity(o.gpa, tuple_type.types.len);
36203617
36213618 comptime assert(struct_layout_version == 2);
36223619 var offset: u64 = 0;
......@@ -3625,8 +3622,8 @@ pub const Object = struct {
36253622 const struct_size = t.abiSize(zcu);
36263623
36273624 for (
3628 anon_struct_type.types.get(ip),
3629 anon_struct_type.values.get(ip),
3625 tuple_type.types.get(ip),
3626 tuple_type.values.get(ip),
36303627 0..,
36313628 ) |field_ty, field_val, field_index| {
36323629 if (field_val != .none) continue;
......@@ -3979,7 +3976,7 @@ pub const Object = struct {
39793976 .error_union_type,
39803977 .simple_type,
39813978 .struct_type,
3982 .anon_struct_type,
3979 .tuple_type,
39833980 .union_type,
39843981 .opaque_type,
39853982 .enum_type,
......@@ -3993,7 +3990,7 @@ pub const Object = struct {
39933990 .undefined => unreachable, // non-runtime value
39943991 .void => unreachable, // non-runtime value
39953992 .null => unreachable, // non-runtime value
3996 .empty_struct => unreachable, // non-runtime value
3993 .empty_tuple => unreachable, // non-runtime value
39973994 .@"unreachable" => unreachable, // non-runtime value
39983995 .generic_poison => unreachable, // non-runtime value
39993996
......@@ -4232,7 +4229,7 @@ pub const Object = struct {
42324229 ),
42334230 }
42344231 },
4235 .anon_struct_type => |tuple| {
4232 .tuple_type => |tuple| {
42364233 const struct_ty = try o.lowerType(ty);
42374234 const llvm_len = struct_ty.aggregateLen(&o.builder);
42384235
......@@ -12516,7 +12513,7 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {
1251612513 .array, .frame => return ty.hasRuntimeBits(zcu),
1251712514 .@"struct" => {
1251812515 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
12519 .anon_struct_type => |tuple| {
12516 .tuple_type => |tuple| {
1252012517 var count: usize = 0;
1252112518 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
1252212519 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 {
731731 .direct => {
732732 const result_ty_id = try self.resolveType(Type.bool, .direct);
733733 const result_id = self.spv.allocId();
734 const operands = .{
735 .id_result_type = result_ty_id,
736 .id_result = result_id,
737 };
738734 switch (value) {
739 true => try section.emit(self.spv.gpa, .OpConstantTrue, operands),
740 false => try section.emit(self.spv.gpa, .OpConstantFalse, operands),
735 inline else => |val_ct| try section.emit(
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 ),
741743 }
742744 return result_id;
743745 },
......@@ -915,7 +917,7 @@ const NavGen = struct {
915917 .error_union_type,
916918 .simple_type,
917919 .struct_type,
918 .anon_struct_type,
920 .tuple_type,
919921 .union_type,
920922 .opaque_type,
921923 .enum_type,
......@@ -937,7 +939,7 @@ const NavGen = struct {
937939 .undefined,
938940 .void,
939941 .null,
940 .empty_struct,
942 .empty_tuple,
941943 .@"unreachable",
942944 .generic_poison,
943945 => unreachable, // non-runtime values
......@@ -1125,7 +1127,7 @@ const NavGen = struct {
11251127
11261128 return try self.constructStruct(ty, types.items, constituents.items);
11271129 },
1128 .anon_struct_type => unreachable, // TODO
1130 .tuple_type => unreachable, // TODO
11291131 else => unreachable,
11301132 },
11311133 .un => |un| {
......@@ -1718,7 +1720,7 @@ const NavGen = struct {
17181720 },
17191721 .@"struct" => {
17201722 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
1721 .anon_struct_type => |tuple| {
1723 .tuple_type => |tuple| {
17221724 const member_types = try self.gpa.alloc(IdRef, tuple.values.len);
17231725 defer self.gpa.free(member_types);
17241726
......@@ -2831,18 +2833,12 @@ const NavGen = struct {
28312833 }
28322834 },
28332835 .vulkan => {
2834 const op_result_ty = blk: {
2835 // Operations return a struct{T, T}
2836 // where T is maybe vectorized.
2837 const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() };
2838 const values = [2]InternPool.Index{ .none, .none };
2839 const index = try ip.getAnonStructType(zcu.gpa, pt.tid, .{
2840 .types = &types,
2841 .values = &values,
2842 .names = &.{},
2843 });
2844 break :blk Type.fromInterned(index);
2845 };
2836 // Operations return a struct{T, T}
2837 // where T is maybe vectorized.
2838 const op_result_ty: Type = .fromInterned(try ip.getTupleType(zcu.gpa, pt.tid, .{
2839 .types = &.{ arith_op_ty.toIntern(), arith_op_ty.toIntern() },
2840 .values = &.{ .none, .none },
2841 }));
28462842 const op_result_ty_id = try self.resolveType(op_result_ty, .direct);
28472843
28482844 const opcode: Opcode = switch (op) {
......@@ -4867,7 +4863,7 @@ const NavGen = struct {
48674863 var index: usize = 0;
48684864
48694865 switch (ip.indexToKey(result_ty.toIntern())) {
4870 .anon_struct_type => |tuple| {
4866 .tuple_type => |tuple| {
48714867 for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {
48724868 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
48734869 assert(Type.fromInterned(field_ty).hasRuntimeBits(zcu));
......@@ -6216,15 +6212,20 @@ const NavGen = struct {
62166212 try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
62176213
62186214 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 };
62256215 switch (pred) {
6226 .is_err => try self.func.body.emit(self.spv.gpa, .OpINotEqual, operands),
6227 .is_non_err => try self.func.body.emit(self.spv.gpa, .OpIEqual, operands),
6216 inline else => |pred_ct| try self.func.body.emit(
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 ),
62286229 }
62296230 return result_id;
62306231 }
src/link/Dwarf.zig+29-20
......@@ -2599,16 +2599,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
25992599 .anyframe_type,
26002600 .error_union_type,
26012601 .simple_type,
2602 .anon_struct_type,
2602 .tuple_type,
26032603 .func_type,
26042604 .error_set_type,
26052605 .inferred_error_set_type,
26062606 => .decl_alias,
26072607 .struct_type => tag: {
26082608 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).?;
26122611 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
26132612
26142613 const value_inst = value_inst: {
......@@ -3349,7 +3348,7 @@ fn updateType(
33493348 .union_type,
33503349 .opaque_type,
33513350 => 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) {
33533352 try wip_nav.abbrevCode(.namespace_struct_type);
33543353 try wip_nav.strp(name);
33553354 try diw.writeByte(@intFromBool(false));
......@@ -3359,15 +3358,15 @@ fn updateType(
33593358 try uleb128(diw, ty.abiSize(zcu));
33603359 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
33613360 var field_byte_offset: u64 = 0;
3362 for (0..anon_struct_type.types.len) |field_index| {
3363 const comptime_value = anon_struct_type.values.get(ip)[field_index];
3361 for (0..tuple_type.types.len) |field_index| {
3362 const comptime_value = tuple_type.values.get(ip)[field_index];
33643363 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 {
3366 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
3367 defer dwarf.gpa.free(field_name);
3364 {
3365 var name_buf: [32]u8 = undefined;
3366 const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{field_index}) catch unreachable;
33683367 try wip_nav.strp(field_name);
33693368 }
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]);
33713370 try wip_nav.refType(field_type);
33723371 if (comptime_value != .none) try wip_nav.blockValue(
33733372 src_loc,
......@@ -3595,16 +3594,26 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
35953594 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
35963595 try wip_nav.flush(ty_src_loc);
35973596 } else {
3598 const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
3599 assert(decl_inst.tag == .extended);
3600 if (switch (decl_inst.data.extended.opcode) {
3601 .struct_decl => @as(Zir.Inst.StructDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3602 .enum_decl => @as(Zir.Inst.EnumDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3603 .union_decl => @as(Zir.Inst.UnionDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3604 .opaque_decl => @as(Zir.Inst.OpaqueDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
3605 .reify => @as(Zir.Inst.NameStrategy, @enumFromInt(decl_inst.data.extended.small)),
3606 else => unreachable,
3607 } == .parent) return;
3597 {
3598 // Note that changes to ZIR instruction tracking only need to update this code
3599 // if a newly-tracked instruction can be a type's owner `zir_index`.
3600 comptime assert(Zir.inst_tracking_version == 0);
3601
3602 const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
3603 const name_strat: Zir.Inst.NameStrategy = switch (decl_inst.tag) {
3604 .struct_init, .struct_init_ref, .struct_init_anon => .anon,
3605 .extended => switch (decl_inst.data.extended.opcode) {
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
36093618 const unit = try dwarf.getUnit(file.mod);
36103619 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
src/link/Plan9.zig+1-1
......@@ -931,7 +931,7 @@ fn addNavExports(
931931 break;
932932 }
933933 }
934 const sym = .{
934 const sym: aout.Sym = .{
935935 .value = atom.offset.?,
936936 .type = atom.type.toGlobal(),
937937 .name = try gpa.dupe(u8, exp_name),
src/main.zig+1-1
......@@ -34,7 +34,7 @@ const Zcu = @import("Zcu.zig");
3434const mingw = @import("mingw.zig");
3535const dev = @import("dev.zig");
3636
37pub const std_options = .{
37pub const std_options: std.Options = .{
3838 .wasiCwd = wasi_cwd,
3939 .logFn = log,
4040 .enable_segfault_handler = false,
src/print_value.zig+2-2
......@@ -74,7 +74,7 @@ pub fn print(
7474 .error_union_type,
7575 .simple_type,
7676 .struct_type,
77 .anon_struct_type,
77 .tuple_type,
7878 .union_type,
7979 .opaque_type,
8080 .enum_type,
......@@ -85,7 +85,7 @@ pub fn print(
8585 .undef => try writer.writeAll("undefined"),
8686 .simple_value => |simple_value| switch (simple_value) {
8787 .void => try writer.writeAll("{}"),
88 .empty_struct => try writer.writeAll(".{}"),
88 .empty_tuple => try writer.writeAll(".{}"),
8989 .generic_poison => try writer.writeAll("(generic poison)"),
9090 else => try writer.writeAll(@tagName(simple_value)),
9191 },
src/print_zir.zig+30-6
......@@ -563,6 +563,8 @@ const Writer = struct {
563563 .enum_decl => try self.writeEnumDecl(stream, extended),
564564 .opaque_decl => try self.writeOpaqueDecl(stream, extended),
565565
566 .tuple_decl => try self.writeTupleDecl(stream, extended),
567
566568 .await_nosuspend,
567569 .c_undef,
568570 .c_include,
......@@ -1421,7 +1423,6 @@ const Writer = struct {
14211423
14221424 try self.writeFlag(stream, "known_non_opv, ", small.known_non_opv);
14231425 try self.writeFlag(stream, "known_comptime_only, ", small.known_comptime_only);
1424 try self.writeFlag(stream, "tuple, ", small.is_tuple);
14251426
14261427 try stream.print("{s}, ", .{@tagName(small.name_strategy)});
14271428
......@@ -1506,11 +1507,8 @@ const Writer = struct {
15061507 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
15071508 cur_bit_bag >>= 1;
15081509
1509 var field_name_index: Zir.NullTerminatedString = .empty;
1510 if (!small.is_tuple) {
1511 field_name_index = @enumFromInt(self.code.extra[extra_index]);
1512 extra_index += 1;
1513 }
1510 const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1511 extra_index += 1;
15141512 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
15151513 extra_index += 1;
15161514
......@@ -1948,6 +1946,32 @@ const Writer = struct {
19481946 try self.writeSrcNode(stream, 0);
19491947 }
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
19511975 fn writeErrorSetDecl(
19521976 self: *Writer,
19531977 stream: anytype,
src/translate_c.zig+8-5
......@@ -2314,8 +2314,11 @@ fn transStringLiteralInitializer(
23142314 while (i < num_inits) : (i += 1) {
23152315 init_list[i] = try transCreateCharLitNode(c, false, stmt.getCodeUnit(i));
23162316 }
2317 const init_args = .{ .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);
2317 const init_args: ast.Payload.Array.ArrayTypeInfo = .{ .len = num_inits, .elem_type = elem_type };
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);
23192322 break :blk try Tag.array_init.create(c.arena, .{
23202323 .cond = init_array_type,
23212324 .cases = init_list,
......@@ -3910,7 +3913,7 @@ fn transCreateCompoundAssign(
39103913
39113914 if ((is_mod or is_div) and is_signed) {
39123915 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 };
39143917 const builtin = if (is_mod)
39153918 try Tag.signed_remainder.create(c.arena, operands)
39163919 else
......@@ -3949,7 +3952,7 @@ fn transCreateCompoundAssign(
39493952 if (is_ptr_op_signed) rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node);
39503953 if ((is_mod or is_div) and is_signed) {
39513954 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 };
39533956 const builtin = if (is_mod)
39543957 try Tag.signed_remainder.create(c.arena, operands)
39553958 else
......@@ -4777,7 +4780,7 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
47774780 const is_const = is_fn_proto or child_qt.isConstQualified();
47784781 const is_volatile = child_qt.isVolatileQualified();
47794782 const elem_type = try transQualType(c, scope, child_qt, source_loc);
4780 const ptr_info = .{
4783 const ptr_info: @FieldType(ast.Payload.Pointer, "data") = .{
47814784 .is_const = is_const,
47824785 .is_volatile = is_volatile,
47834786 .elem_type = elem_type,
test/behavior.zig-1
......@@ -26,7 +26,6 @@ test {
2626 _ = @import("behavior/duplicated_test_names.zig");
2727 _ = @import("behavior/defer.zig");
2828 _ = @import("behavior/destructure.zig");
29 _ = @import("behavior/empty_tuple_fields.zig");
3029 _ = @import("behavior/empty_union.zig");
3130 _ = @import("behavior/enum.zig");
3231 _ = @import("behavior/error.zig");
test/behavior/array.zig+1-35
......@@ -596,7 +596,7 @@ test "type coercion of anon struct literal to array" {
596596
597597 var x2: U = .{ .a = 42 };
598598 _ = &x2;
599 const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } };
599 const t2 = .{ x2, U{ .b = true }, U{ .c = "hello" } };
600600 const arr2: [3]U = t2;
601601 try expect(arr2[0].a == 42);
602602 try expect(arr2[1].b == true);
......@@ -607,40 +607,6 @@ test "type coercion of anon struct literal to array" {
607607 try comptime S.doTheTest();
608608}
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
644610test "array with comptime-only element type" {
645611 const a = [_]type{ u32, i32 };
646612 try testing.expect(a[0] == u32);
test/behavior/cast.zig-26
......@@ -2600,32 +2600,6 @@ test "result type is preserved into comptime block" {
26002600 try expect(x == 123);
26012601}
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
26292603test "bitcast vector" {
26302604 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
26312605 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" {
10131013 try expectEqual(@as(usize, 0), s.zero_length.len);
10141014}
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
10941016test "packed struct with undefined initializers" {
10951017 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10961018 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
......@@ -2183,3 +2105,20 @@ test "extern struct @FieldType" {
21832105 comptime assert(@FieldType(S, "b") == f64);
21842106 comptime assert(@FieldType(S, "c") == *S);
21852107}
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" {
150150 .type = u8,
151151 .default_value = null,
152152 .is_comptime = false,
153 .alignment = @alignOf(i32),
153 .alignment = @alignOf(u8),
154154 },
155155 },
156156 },
......@@ -566,16 +566,28 @@ test "comptime fields in tuple can be initialized" {
566566 _ = &a;
567567}
568568
569test "tuple default values" {
570 const T = struct {
571 usize,
572 usize = 123,
573 usize = 456,
574 };
569test "empty struct in tuple" {
570 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
571 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
572 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
573 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
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]);
579 try expectEqual(123, t[1]);
580 try expectEqual(456, t[2]);
588 const T = struct { union {} };
589 const info = @typeInfo(T);
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");
581593}
test/behavior/tuple_declarations.zig+3-3
......@@ -9,7 +9,7 @@ test "tuple declaration type info" {
99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1010
1111 {
12 const T = struct { comptime u32 align(2) = 1, []const u8 };
12 const T = struct { comptime u32 = 1, []const u8 };
1313 const info = @typeInfo(T).@"struct";
1414
1515 try expect(info.layout == .auto);
......@@ -22,7 +22,7 @@ test "tuple declaration type info" {
2222 try expect(info.fields[0].type == u32);
2323 try expect(@as(*const u32, @ptrCast(@alignCast(info.fields[0].default_value))).* == 1);
2424 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
2727 try expectEqualStrings(info.fields[1].name, "1");
2828 try expect(info.fields[1].type == []const u8);
......@@ -32,7 +32,7 @@ test "tuple declaration type info" {
3232 }
3333}
3434
35test "Tuple declaration usage" {
35test "tuple declaration usage" {
3636 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
3737 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" {
986986 try comptime S.doTheTest();
987987}
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
1059989test "switching on non exhaustive union" {
1060990 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1061991 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 @@
11export fn foo() void {
22 const S = struct { a: u32 };
3 const sentinel: S = .{ .a = 1 };
34 var arr = [_]S{ .{ .a = 1 }, .{ .a = 2 } };
4 const s = arr[0..1 :.{ .a = 1 }];
5 const s = arr[0..1 :sentinel];
56 _ = s;
67}
78
......@@ -9,5 +10,5 @@ export fn foo() void {
910// backend=stage2
1011// target=native
1112//
12// :4:26: error: non-scalar sentinel type 'tmp.foo.S'
13// :5:25: error: non-scalar sentinel type 'tmp.foo.S'
1314// :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 {
1818//
1919// :3:6: error: no field or member function named 'copy' in '[]const u8'
2020// :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 {
1010// backend=stage2
1111// target=native
1212//
13// :4:28: error: type 'anyerror!tmp.entry.Foo' cannot be destructured
13// :4:28: error: type 'anyerror!struct { u8, u8 }' cannot be destructured
1414// :4:26: note: result destructured here
1515// :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 {
1010 _ = .{ &x, &y };
1111 _ = @TypeOf(x, y);
1212}
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}
1813export fn incompatiblePointers() void {
1914 const x: []const u8 = "foo";
2015 const y: [*:0]const u8 = "bar";
......@@ -39,14 +34,9 @@ export fn incompatiblePointers4() void {
3934// :11:9: note: incompatible types: 'u32' and '*const [5:0]u8'
4035// :11:17: note: type 'u32' here
4136// :11:20: note: type '*const [5:0]u8' here
42// :16:9: error: struct field 'bar' has conflicting types
43// :16:9: note: struct field '1' has conflicting types
44// :16:9: note: incompatible types: 'comptime_int' and '*const [2:0]u8'
45// :16:17: note: type 'comptime_int' here
46// :16:20: note: type '*const [2:0]u8' here
47// :21:9: error: incompatible types: '[]const u8' and '[*:0]const u8'
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
37// :16:9: error: incompatible types: '[]const u8' and '[*:0]const u8'
38// :16:17: note: type '[]const u8' here
39// :16:20: note: type '[*:0]const u8' here
40// :23:9: error: incompatible types: '[]const u8' and '[*]const u8'
41// :23:23: note: type '[]const u8' here
42// :23: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 {
2929// :9:16: error: missing struct field: x
3030// :1:11: note: struct declared here
3131// :18:16: error: missing tuple field with index 1
32// :16:11: note: struct declared here
3332// :22:16: error: missing tuple field with index 0
3433// :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 {
2121// :14:5: note: also here
2222//
2323// Compile Log Output:
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 } })
26// @as(struct{@Vector(3, u8), @Vector(3, u1)}, .{ .{ 1, 64, 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 } })
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 {
7272// :18:14: error: missing tuple field with index 1
7373// :25:14: error: missing tuple field with index 1
7474// :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 }'
7676// :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 {
77// backend=stage2
88// target=native
99//
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 {
440440 cases.add("std.log per scope log level override",
441441 \\const std = @import("std");
442442 \\
443 \\pub const std_options = .{
443 \\pub const std_options: std.Options = .{
444444 \\ .log_level = .debug,
445445 \\
446446 \\ .log_scope_levels = &.{
......@@ -497,7 +497,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
497497 cases.add("std.heap.LoggingAllocator logs to std.log",
498498 \\const std = @import("std");
499499 \\
500 \\pub const std_options = .{
500 \\pub const std_options: std.Options = .{
501501 \\ .log_level = .debug,
502502 \\ .logFn = log,
503503 \\};
test/src/Debugger.zig+14-14
......@@ -1532,18 +1532,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
15321532 ,
15331533 &.{
15341534 \\(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 {
1536 \\ (root.main.Elem0) [0] = {
1535 \\(std.multi_array_list.MultiArrayList(struct { u32, u8, u16 })) list0 = len=3 capacity=8 {
1536 \\ (std.struct { u32, u8, u16 }) [0] = {
15371537 \\ (u32) .@"0" = 1
15381538 \\ (u8) .@"1" = 2
15391539 \\ (u16) .@"2" = 3
15401540 \\ }
1541 \\ (root.main.Elem0) [1] = {
1541 \\ (std.struct { u32, u8, u16 }) [1] = {
15421542 \\ (u32) .@"0" = 4
15431543 \\ (u8) .@"1" = 5
15441544 \\ (u16) .@"2" = 6
15451545 \\ }
1546 \\ (root.main.Elem0) [2] = {
1546 \\ (std.struct { u32, u8, u16 }) [2] = {
15471547 \\ (u32) .@"0" = 7
15481548 \\ (u8) .@"1" = 8
15491549 \\ (u16) .@"2" = 9
......@@ -1551,17 +1551,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
15511551 \\}
15521552 \\(usize) list0.len = 3
15531553 \\(usize) list0.capacity = 8
1554 \\(root.main.Elem0) list0[0] = {
1554 \\(std.struct { u32, u8, u16 }) list0[0] = {
15551555 \\ (u32) .@"0" = 1
15561556 \\ (u8) .@"1" = 2
15571557 \\ (u16) .@"2" = 3
15581558 \\}
1559 \\(root.main.Elem0) list0[1] = {
1559 \\(std.struct { u32, u8, u16 }) list0[1] = {
15601560 \\ (u32) .@"0" = 4
15611561 \\ (u8) .@"1" = 5
15621562 \\ (u16) .@"2" = 6
15631563 \\}
1564 \\(root.main.Elem0) list0[2] = {
1564 \\(std.struct { u32, u8, u16 }) list0[2] = {
15651565 \\ (u32) .@"0" = 7
15661566 \\ (u8) .@"1" = 8
15671567 \\ (u16) .@"2" = 9
......@@ -1582,18 +1582,18 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
15821582 \\ (u16) [2] = 9
15831583 \\}
15841584 \\(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 {
1586 \\ (root.main.Elem0) [0] = {
1585 \\(std.multi_array_list.MultiArrayList(struct { u32, u8, u16 }).Slice) slice0 = len=3 capacity=8 {
1586 \\ (std.struct { u32, u8, u16 }) [0] = {
15871587 \\ (u32) .@"0" = 1
15881588 \\ (u8) .@"1" = 2
15891589 \\ (u16) .@"2" = 3
15901590 \\ }
1591 \\ (root.main.Elem0) [1] = {
1591 \\ (std.struct { u32, u8, u16 }) [1] = {
15921592 \\ (u32) .@"0" = 4
15931593 \\ (u8) .@"1" = 5
15941594 \\ (u16) .@"2" = 6
15951595 \\ }
1596 \\ (root.main.Elem0) [2] = {
1596 \\ (std.struct { u32, u8, u16 }) [2] = {
15971597 \\ (u32) .@"0" = 7
15981598 \\ (u8) .@"1" = 8
15991599 \\ (u16) .@"2" = 9
......@@ -1601,17 +1601,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
16011601 \\}
16021602 \\(usize) slice0.len = 3
16031603 \\(usize) slice0.capacity = 8
1604 \\(root.main.Elem0) slice0[0] = {
1604 \\(std.struct { u32, u8, u16 }) slice0[0] = {
16051605 \\ (u32) .@"0" = 1
16061606 \\ (u8) .@"1" = 2
16071607 \\ (u16) .@"2" = 3
16081608 \\}
1609 \\(root.main.Elem0) slice0[1] = {
1609 \\(std.struct { u32, u8, u16 }) slice0[1] = {
16101610 \\ (u32) .@"0" = 4
16111611 \\ (u8) .@"1" = 5
16121612 \\ (u16) .@"2" = 6
16131613 \\}
1614 \\(root.main.Elem0) slice0[2] = {
1614 \\(std.struct { u32, u8, u16 }) slice0[2] = {
16151615 \\ (u32) .@"0" = 7
16161616 \\ (u8) .@"1" = 8
16171617 \\ (u16) .@"2" = 9
test/standalone/sigpipe/breakpipe.zig+1-1
......@@ -1,7 +1,7 @@
11const std = @import("std");
22const build_options = @import("build_options");
33
4pub const std_options = .{
4pub const std_options: std.Options = .{
55 .keep_sigpipe = build_options.keep_sigpipe,
66};
77
test/standalone/simple/issue_7030.zig+1-1
......@@ -1,6 +1,6 @@
11const std = @import("std");
22
3pub const std_options = .{
3pub const std_options: std.Options = .{
44 .logFn = log,
55};
66