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