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

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

compiler: remove anonymous struct types, unify all tuples

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

lib/compiler/aro/aro/Builtins.zig+1-1
......@@ -157,7 +157,7 @@ fn createType(desc: TypeDescription, it: *TypeDescription.TypeIterator, comp: *c
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/mem.zig+3-1
......@@ -3965,7 +3965,9 @@ fn CopyPtrAttrs(
39653965}
39663966
39673967fn AsBytesReturnType(comptime P: type) type {
3968 const size = @sizeOf(std.meta.Child(P));
3968 const pointer = @typeInfo(P).pointer;
3969 assert(pointer.size == .One);
3970 const size = @sizeOf(pointer.child);
39693971 return CopyPtrAttrs(P, .One, [size]u8);
39703972}
39713973
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