authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-20 12:09:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:53-07:00
log9ff514b6a35b7201f45f8bff31c61b4f8cfa7a7a
treedda74acc00690d1b3d31fd6e43d7ec0aa4acc882
parent7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2

compiler: move error union types and error set types to InternPool

One change worth noting in this commit is that `module.global_error_set` is no longer kept strictly up-to-date. The previous code reserved integer error values when dealing with error set types, but this is no longer needed because the integer values are not needed for semantic analysis unless `@errorToInt` or `@intToError` are used and therefore may be assigned lazily.

21 files changed, 1195 insertions(+), 1582 deletions(-)

src/Air.zig+1-1
...@@ -1411,7 +1411,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {...@@ -1411,7 +1411,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
14111411
1412 .@"try" => {1412 .@"try" => {
1413 const err_union_ty = air.typeOf(datas[inst].pl_op.operand, ip);1413 const err_union_ty = air.typeOf(datas[inst].pl_op.operand, ip);
1414 return err_union_ty.errorUnionPayload();1414 return ip.indexToKey(err_union_ty.ip_index).error_union_type.payload_type.toType();
1415 },1415 },
14161416
1417 .work_item_id,1417 .work_item_id,
src/InternPool.zig+160-16
...@@ -34,6 +34,14 @@ allocated_unions: std.SegmentedList(Module.Union, 0) = .{},...@@ -34,6 +34,14 @@ allocated_unions: std.SegmentedList(Module.Union, 0) = .{},
34/// When a Union object is freed from `allocated_unions`, it is pushed into this stack.34/// When a Union object is freed from `allocated_unions`, it is pushed into this stack.
35unions_free_list: std.ArrayListUnmanaged(Module.Union.Index) = .{},35unions_free_list: std.ArrayListUnmanaged(Module.Union.Index) = .{},
3636
37/// InferredErrorSet objects are stored in this data structure because:
38/// * They contain pointers such as the errors map and the set of other inferred error sets.
39/// * They need to be mutated after creation.
40allocated_inferred_error_sets: std.SegmentedList(Module.Fn.InferredErrorSet, 0) = .{},
41/// When a Struct object is freed from `allocated_inferred_error_sets`, it is
42/// pushed into this stack.
43inferred_error_sets_free_list: std.ArrayListUnmanaged(Module.Fn.InferredErrorSet.Index) = .{},
44
37/// Some types such as enums, structs, and unions need to store mappings from field names45/// Some types such as enums, structs, and unions need to store mappings from field names
38/// to field index, or value to field index. In such cases, they will store the underlying46/// to field index, or value to field index. In such cases, they will store the underlying
39/// field names and values directly, relying on one of these maps, stored separately,47/// field names and values directly, relying on one of these maps, stored separately,
...@@ -113,6 +121,12 @@ pub const NullTerminatedString = enum(u32) {...@@ -113,6 +121,12 @@ pub const NullTerminatedString = enum(u32) {
113 return std.hash.uint32(@enumToInt(a));121 return std.hash.uint32(@enumToInt(a));
114 }122 }
115 };123 };
124
125 /// Compare based on integer value alone, ignoring the string contents.
126 pub fn indexLessThan(ctx: void, a: NullTerminatedString, b: NullTerminatedString) bool {
127 _ = ctx;
128 return @enumToInt(a) < @enumToInt(b);
129 }
116};130};
117131
118/// An index into `string_bytes` which might be `none`.132/// An index into `string_bytes` which might be `none`.
...@@ -135,10 +149,7 @@ pub const Key = union(enum) {...@@ -135,10 +149,7 @@ pub const Key = union(enum) {
135 /// `anyframe->T`. The payload is the child type, which may be `none` to indicate149 /// `anyframe->T`. The payload is the child type, which may be `none` to indicate
136 /// `anyframe`.150 /// `anyframe`.
137 anyframe_type: Index,151 anyframe_type: Index,
138 error_union_type: struct {152 error_union_type: ErrorUnionType,
139 error_set_type: Index,
140 payload_type: Index,
141 },
142 simple_type: SimpleType,153 simple_type: SimpleType,
143 /// This represents a struct that has been explicitly declared in source code,154 /// This represents a struct that has been explicitly declared in source code,
144 /// or was created with `@Type`. It is unique and based on a declaration.155 /// or was created with `@Type`. It is unique and based on a declaration.
...@@ -152,6 +163,8 @@ pub const Key = union(enum) {...@@ -152,6 +163,8 @@ pub const Key = union(enum) {
152 opaque_type: OpaqueType,163 opaque_type: OpaqueType,
153 enum_type: EnumType,164 enum_type: EnumType,
154 func_type: FuncType,165 func_type: FuncType,
166 error_set_type: ErrorSetType,
167 inferred_error_set_type: Module.Fn.InferredErrorSet.Index,
155168
156 /// Typed `undefined`. This will never be `none`; untyped `undefined` is represented169 /// Typed `undefined`. This will never be `none`; untyped `undefined` is represented
157 /// via `simple_value` and has a named `Index` tag for it.170 /// via `simple_value` and has a named `Index` tag for it.
...@@ -183,6 +196,26 @@ pub const Key = union(enum) {...@@ -183,6 +196,26 @@ pub const Key = union(enum) {
183196
184 pub const IntType = std.builtin.Type.Int;197 pub const IntType = std.builtin.Type.Int;
185198
199 pub const ErrorUnionType = struct {
200 error_set_type: Index,
201 payload_type: Index,
202 };
203
204 pub const ErrorSetType = struct {
205 /// Set of error names, sorted by null terminated string index.
206 names: []const NullTerminatedString,
207 /// This is ignored by `get` but will always be provided by `indexToKey`.
208 names_map: OptionalMapIndex = .none,
209
210 /// Look up field index based on field name.
211 pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
212 const map = &ip.maps.items[@enumToInt(self.names_map.unwrap().?)];
213 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names };
214 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
215 return @intCast(u32, field_index);
216 }
217 };
218
186 pub const PtrType = struct {219 pub const PtrType = struct {
187 elem_type: Index,220 elem_type: Index,
188 sentinel: Index = .none,221 sentinel: Index = .none,
...@@ -507,6 +540,7 @@ pub const Key = union(enum) {...@@ -507,6 +540,7 @@ pub const Key = union(enum) {
507 .un,540 .un,
508 .undef,541 .undef,
509 .enum_tag,542 .enum_tag,
543 .inferred_error_set_type,
510 => |info| std.hash.autoHash(hasher, info),544 => |info| std.hash.autoHash(hasher, info),
511545
512 .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),546 .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl),
...@@ -535,7 +569,7 @@ pub const Key = union(enum) {...@@ -535,7 +569,7 @@ pub const Key = union(enum) {
535 .ptr => |ptr| {569 .ptr => |ptr| {
536 std.hash.autoHash(hasher, ptr.ty);570 std.hash.autoHash(hasher, ptr.ty);
537 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.571 // Int-to-ptr pointers are hashed separately than decl-referencing pointers.
538 // This is sound due to pointer province rules.572 // This is sound due to pointer provenance rules.
539 switch (ptr.addr) {573 switch (ptr.addr) {
540 .int => |int| std.hash.autoHash(hasher, int),574 .int => |int| std.hash.autoHash(hasher, int),
541 .decl => @panic("TODO"),575 .decl => @panic("TODO"),
...@@ -547,6 +581,10 @@ pub const Key = union(enum) {...@@ -547,6 +581,10 @@ pub const Key = union(enum) {
547 for (aggregate.fields) |field| std.hash.autoHash(hasher, field);581 for (aggregate.fields) |field| std.hash.autoHash(hasher, field);
548 },582 },
549583
584 .error_set_type => |error_set_type| {
585 for (error_set_type.names) |elem| std.hash.autoHash(hasher, elem);
586 },
587
550 .anon_struct_type => |anon_struct_type| {588 .anon_struct_type => |anon_struct_type| {
551 for (anon_struct_type.types) |elem| std.hash.autoHash(hasher, elem);589 for (anon_struct_type.types) |elem| std.hash.autoHash(hasher, elem);
552 for (anon_struct_type.values) |elem| std.hash.autoHash(hasher, elem);590 for (anon_struct_type.values) |elem| std.hash.autoHash(hasher, elem);
...@@ -726,6 +764,14 @@ pub const Key = union(enum) {...@@ -726,6 +764,14 @@ pub const Key = union(enum) {
726 std.mem.eql(Index, a_info.values, b_info.values) and764 std.mem.eql(Index, a_info.values, b_info.values) and
727 std.mem.eql(NullTerminatedString, a_info.names, b_info.names);765 std.mem.eql(NullTerminatedString, a_info.names, b_info.names);
728 },766 },
767 .error_set_type => |a_info| {
768 const b_info = b.error_set_type;
769 return std.mem.eql(NullTerminatedString, a_info.names, b_info.names);
770 },
771 .inferred_error_set_type => |a_info| {
772 const b_info = b.inferred_error_set_type;
773 return a_info == b_info;
774 },
729775
730 .func_type => |a_info| {776 .func_type => |a_info| {
731 const b_info = b.func_type;777 const b_info = b.func_type;
...@@ -752,6 +798,8 @@ pub const Key = union(enum) {...@@ -752,6 +798,8 @@ pub const Key = union(enum) {
752 .opt_type,798 .opt_type,
753 .anyframe_type,799 .anyframe_type,
754 .error_union_type,800 .error_union_type,
801 .error_set_type,
802 .inferred_error_set_type,
755 .simple_type,803 .simple_type,
756 .struct_type,804 .struct_type,
757 .union_type,805 .union_type,
...@@ -1207,8 +1255,14 @@ pub const Tag = enum(u8) {...@@ -1207,8 +1255,14 @@ pub const Tag = enum(u8) {
1207 /// If the child type is `none`, the type is `anyframe`.1255 /// If the child type is `none`, the type is `anyframe`.
1208 type_anyframe,1256 type_anyframe,
1209 /// An error union type.1257 /// An error union type.
1210 /// data is payload to ErrorUnion.1258 /// data is payload to `Key.ErrorUnionType`.
1211 type_error_union,1259 type_error_union,
1260 /// An error set type.
1261 /// data is payload to `ErrorSet`.
1262 type_error_set,
1263 /// The inferred error set type of a function.
1264 /// data is `Module.Fn.InferredErrorSet.Index`.
1265 type_inferred_error_set,
1212 /// An enum type with auto-numbered tag values.1266 /// An enum type with auto-numbered tag values.
1213 /// The enum is exhaustive.1267 /// The enum is exhaustive.
1214 /// data is payload index to `EnumAuto`.1268 /// data is payload index to `EnumAuto`.
...@@ -1355,6 +1409,12 @@ pub const Tag = enum(u8) {...@@ -1355,6 +1409,12 @@ pub const Tag = enum(u8) {
1355 aggregate,1409 aggregate,
1356};1410};
13571411
1412/// Trailing:
1413/// 0. name: NullTerminatedString for each names_len
1414pub const ErrorSet = struct {
1415 names_len: u32,
1416};
1417
1358/// Trailing:1418/// Trailing:
1359/// 0. param_type: Index for each params_len1419/// 0. param_type: Index for each params_len
1360pub const TypeFunction = struct {1420pub const TypeFunction = struct {
...@@ -1539,11 +1599,6 @@ pub const Array = struct {...@@ -1539,11 +1599,6 @@ pub const Array = struct {
1539 }1599 }
1540};1600};
15411601
1542pub const ErrorUnion = struct {
1543 error_set_type: Index,
1544 payload_type: Index,
1545};
1546
1547/// Trailing:1602/// Trailing:
1548/// 0. field name: NullTerminatedString for each fields_len; declaration order1603/// 0. field name: NullTerminatedString for each fields_len; declaration order
1549/// 1. tag value: Index for each fields_len; declaration order1604/// 1. tag value: Index for each fields_len; declaration order
...@@ -1719,6 +1774,9 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -1719,6 +1774,9 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
1719 ip.unions_free_list.deinit(gpa);1774 ip.unions_free_list.deinit(gpa);
1720 ip.allocated_unions.deinit(gpa);1775 ip.allocated_unions.deinit(gpa);
17211776
1777 ip.inferred_error_sets_free_list.deinit(gpa);
1778 ip.allocated_inferred_error_sets.deinit(gpa);
1779
1722 for (ip.maps.items) |*map| map.deinit(gpa);1780 for (ip.maps.items) |*map| map.deinit(gpa);
1723 ip.maps.deinit(gpa);1781 ip.maps.deinit(gpa);
17241782
...@@ -1798,7 +1856,18 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -1798,7 +1856,18 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
1798 .type_optional => .{ .opt_type = @intToEnum(Index, data) },1856 .type_optional => .{ .opt_type = @intToEnum(Index, data) },
1799 .type_anyframe => .{ .anyframe_type = @intToEnum(Index, data) },1857 .type_anyframe => .{ .anyframe_type = @intToEnum(Index, data) },
18001858
1801 .type_error_union => @panic("TODO"),1859 .type_error_union => .{ .error_union_type = ip.extraData(Key.ErrorUnionType, data) },
1860 .type_error_set => {
1861 const error_set = ip.extraDataTrail(ErrorSet, data);
1862 const names_len = error_set.data.names_len;
1863 const names = ip.extra.items[error_set.end..][0..names_len];
1864 return .{ .error_set_type = .{
1865 .names = @ptrCast([]const NullTerminatedString, names),
1866 } };
1867 },
1868 .type_inferred_error_set => .{
1869 .inferred_error_set_type = @intToEnum(Module.Fn.InferredErrorSet.Index, data),
1870 },
18021871
1803 .type_opaque => .{ .opaque_type = ip.extraData(Key.OpaqueType, data) },1872 .type_opaque => .{ .opaque_type = ip.extraData(Key.OpaqueType, data) },
1804 .type_struct => {1873 .type_struct => {
...@@ -2179,11 +2248,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -2179,11 +2248,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2179 .error_union_type => |error_union_type| {2248 .error_union_type => |error_union_type| {
2180 ip.items.appendAssumeCapacity(.{2249 ip.items.appendAssumeCapacity(.{
2181 .tag = .type_error_union,2250 .tag = .type_error_union,
2182 .data = try ip.addExtra(gpa, ErrorUnion{2251 .data = try ip.addExtra(gpa, error_union_type),
2183 .error_set_type = error_union_type.error_set_type,2252 });
2184 .payload_type = error_union_type.payload_type,2253 },
2254 .error_set_type => |error_set_type| {
2255 assert(error_set_type.names_map == .none);
2256 assert(std.sort.isSorted(NullTerminatedString, error_set_type.names, {}, NullTerminatedString.indexLessThan));
2257 const names_map = try ip.addMap(gpa);
2258 try addStringsToMap(ip, gpa, names_map, error_set_type.names);
2259 const names_len = @intCast(u32, error_set_type.names.len);
2260 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(ErrorSet).Struct.fields.len + names_len);
2261 ip.items.appendAssumeCapacity(.{
2262 .tag = .type_error_set,
2263 .data = ip.addExtraAssumeCapacity(ErrorSet{
2264 .names_len = names_len,
2185 }),2265 }),
2186 });2266 });
2267 ip.extra.appendSliceAssumeCapacity(@ptrCast([]const u32, error_set_type.names));
2268 },
2269 .inferred_error_set_type => |ies_index| {
2270 ip.items.appendAssumeCapacity(.{
2271 .tag = .type_inferred_error_set,
2272 .data = @enumToInt(ies_index),
2273 });
2187 },2274 },
2188 .simple_type => |simple_type| {2275 .simple_type => |simple_type| {
2189 ip.items.appendAssumeCapacity(.{2276 ip.items.appendAssumeCapacity(.{
...@@ -3192,12 +3279,26 @@ pub fn indexToFuncType(ip: InternPool, val: Index) ?Key.FuncType {...@@ -3192,12 +3279,26 @@ pub fn indexToFuncType(ip: InternPool, val: Index) ?Key.FuncType {
3192 }3279 }
3193}3280}
31943281
3282pub fn indexToInferredErrorSetType(ip: InternPool, val: Index) Module.Fn.InferredErrorSet.OptionalIndex {
3283 assert(val != .none);
3284 const tags = ip.items.items(.tag);
3285 if (tags[@enumToInt(val)] != .type_inferred_error_set) return .none;
3286 const datas = ip.items.items(.data);
3287 return @intToEnum(Module.Fn.InferredErrorSet.Index, datas[@enumToInt(val)]).toOptional();
3288}
3289
3195pub fn isOptionalType(ip: InternPool, ty: Index) bool {3290pub fn isOptionalType(ip: InternPool, ty: Index) bool {
3196 const tags = ip.items.items(.tag);3291 const tags = ip.items.items(.tag);
3197 if (ty == .none) return false;3292 if (ty == .none) return false;
3198 return tags[@enumToInt(ty)] == .type_optional;3293 return tags[@enumToInt(ty)] == .type_optional;
3199}3294}
32003295
3296pub fn isInferredErrorSetType(ip: InternPool, ty: Index) bool {
3297 const tags = ip.items.items(.tag);
3298 assert(ty != .none);
3299 return tags[@enumToInt(ty)] == .type_inferred_error_set;
3300}
3301
3201pub fn dump(ip: InternPool) void {3302pub fn dump(ip: InternPool) void {
3202 dumpFallible(ip, std.heap.page_allocator) catch return;3303 dumpFallible(ip, std.heap.page_allocator) catch return;
3203}3304}
...@@ -3258,7 +3359,12 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {...@@ -3258,7 +3359,12 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
3258 .type_slice => 0,3359 .type_slice => 0,
3259 .type_optional => 0,3360 .type_optional => 0,
3260 .type_anyframe => 0,3361 .type_anyframe => 0,
3261 .type_error_union => @sizeOf(ErrorUnion),3362 .type_error_union => @sizeOf(Key.ErrorUnionType),
3363 .type_error_set => b: {
3364 const info = ip.extraData(ErrorSet, data);
3365 break :b @sizeOf(ErrorSet) + (@sizeOf(u32) * info.names_len);
3366 },
3367 .type_inferred_error_set => @sizeOf(Module.Fn.InferredErrorSet),
3262 .type_enum_explicit, .type_enum_nonexhaustive => @sizeOf(EnumExplicit),3368 .type_enum_explicit, .type_enum_nonexhaustive => @sizeOf(EnumExplicit),
3263 .type_enum_auto => @sizeOf(EnumAuto),3369 .type_enum_auto => @sizeOf(EnumAuto),
3264 .type_opaque => @sizeOf(Key.OpaqueType),3370 .type_opaque => @sizeOf(Key.OpaqueType),
...@@ -3359,6 +3465,14 @@ pub fn unionPtr(ip: *InternPool, index: Module.Union.Index) *Module.Union {...@@ -3359,6 +3465,14 @@ pub fn unionPtr(ip: *InternPool, index: Module.Union.Index) *Module.Union {
3359 return ip.allocated_unions.at(@enumToInt(index));3465 return ip.allocated_unions.at(@enumToInt(index));
3360}3466}
33613467
3468pub fn inferredErrorSetPtr(ip: *InternPool, index: Module.Fn.InferredErrorSet.Index) *Module.Fn.InferredErrorSet {
3469 return ip.allocated_inferred_error_sets.at(@enumToInt(index));
3470}
3471
3472pub fn inferredErrorSetPtrConst(ip: InternPool, index: Module.Fn.InferredErrorSet.Index) *const Module.Fn.InferredErrorSet {
3473 return ip.allocated_inferred_error_sets.at(@enumToInt(index));
3474}
3475
3362pub fn createStruct(3476pub fn createStruct(
3363 ip: *InternPool,3477 ip: *InternPool,
3364 gpa: Allocator,3478 gpa: Allocator,
...@@ -3397,6 +3511,25 @@ pub fn destroyUnion(ip: *InternPool, gpa: Allocator, index: Module.Union.Index)...@@ -3397,6 +3511,25 @@ pub fn destroyUnion(ip: *InternPool, gpa: Allocator, index: Module.Union.Index)
3397 };3511 };
3398}3512}
33993513
3514pub fn createInferredErrorSet(
3515 ip: *InternPool,
3516 gpa: Allocator,
3517 initialization: Module.Fn.InferredErrorSet,
3518) Allocator.Error!Module.Fn.InferredErrorSet.Index {
3519 if (ip.inferred_error_sets_free_list.popOrNull()) |index| return index;
3520 const ptr = try ip.allocated_inferred_error_sets.addOne(gpa);
3521 ptr.* = initialization;
3522 return @intToEnum(Module.Fn.InferredErrorSet.Index, ip.allocated_inferred_error_sets.len - 1);
3523}
3524
3525pub fn destroyInferredErrorSet(ip: *InternPool, gpa: Allocator, index: Module.Fn.InferredErrorSet.Index) void {
3526 ip.inferredErrorSetPtr(index).* = undefined;
3527 ip.inferred_error_sets_free_list.append(gpa, index) catch {
3528 // In order to keep `destroyInferredErrorSet` a non-fallible function, we ignore memory
3529 // allocation failures here, instead leaking the InferredErrorSet until garbage collection.
3530 };
3531}
3532
3400pub fn getOrPutString(3533pub fn getOrPutString(
3401 ip: *InternPool,3534 ip: *InternPool,
3402 gpa: Allocator,3535 gpa: Allocator,
...@@ -3459,3 +3592,14 @@ pub fn aggregateTypeLen(ip: InternPool, ty: Index) u64 {...@@ -3459,3 +3592,14 @@ pub fn aggregateTypeLen(ip: InternPool, ty: Index) u64 {
3459 else => unreachable,3592 else => unreachable,
3460 };3593 };
3461}3594}
3595
3596pub fn isNoReturn(ip: InternPool, ty: InternPool.Index) bool {
3597 return switch (ty) {
3598 .noreturn_type => true,
3599 else => switch (ip.indexToKey(ty)) {
3600 .error_set_type => |error_set_type| error_set_type.names.len == 0,
3601 .enum_type => |enum_type| enum_type.names.len == 0,
3602 else => false,
3603 },
3604 };
3605}
src/Liveness.zig+1-1
...@@ -1416,7 +1416,7 @@ fn analyzeInstBlock(...@@ -1416,7 +1416,7 @@ fn analyzeInstBlock(
14161416
1417 // If the block is noreturn, block deaths not only aren't useful, they're impossible to1417 // If the block is noreturn, block deaths not only aren't useful, they're impossible to
1418 // find: there could be more stuff alive after the block than before it!1418 // find: there could be more stuff alive after the block than before it!
1419 if (!a.air.getRefType(ty_pl.ty).isNoReturn()) {1419 if (!a.intern_pool.isNoReturn(a.air.getRefType(ty_pl.ty).ip_index)) {
1420 // The block kills the difference in the live sets1420 // The block kills the difference in the live sets
1421 const block_scope = data.block_scopes.get(inst).?;1421 const block_scope = data.block_scopes.get(inst).?;
1422 const num_deaths = data.live_set.count() - block_scope.live_set.count();1422 const num_deaths = data.live_set.count() - block_scope.live_set.count();
src/Liveness/Verify.zig+1-1
...@@ -453,7 +453,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {...@@ -453,7 +453,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
453453
454 for (block_liveness.deaths) |death| try self.verifyDeath(inst, death);454 for (block_liveness.deaths) |death| try self.verifyDeath(inst, death);
455455
456 if (block_ty.isNoReturn()) {456 if (ip.isNoReturn(block_ty.toIntern())) {
457 assert(!self.blocks.contains(inst));457 assert(!self.blocks.contains(inst));
458 } else {458 } else {
459 var live = self.blocks.fetchRemove(inst).?.value;459 var live = self.blocks.fetchRemove(inst).?.value;
src/Module.zig+94-75
...@@ -960,38 +960,6 @@ pub const EmitH = struct {...@@ -960,38 +960,6 @@ pub const EmitH = struct {
960 fwd_decl: ArrayListUnmanaged(u8) = .{},960 fwd_decl: ArrayListUnmanaged(u8) = .{},
961};961};
962962
963/// Represents the data that an explicit error set syntax provides.
964pub const ErrorSet = struct {
965 /// The Decl that corresponds to the error set itself.
966 owner_decl: Decl.Index,
967 /// The string bytes are stored in the owner Decl arena.
968 /// These must be in sorted order. See sortNames.
969 names: NameMap,
970
971 pub const NameMap = std.StringArrayHashMapUnmanaged(void);
972
973 pub fn srcLoc(self: ErrorSet, mod: *Module) SrcLoc {
974 const owner_decl = mod.declPtr(self.owner_decl);
975 return .{
976 .file_scope = owner_decl.getFileScope(mod),
977 .parent_decl_node = owner_decl.src_node,
978 .lazy = LazySrcLoc.nodeOffset(0),
979 };
980 }
981
982 /// sort the NameMap. This should be called whenever the map is modified.
983 /// alloc should be the allocator used for the NameMap data.
984 pub fn sortNames(names: *NameMap) void {
985 const Context = struct {
986 keys: [][]const u8,
987 pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool {
988 return std.mem.lessThan(u8, ctx.keys[a_index], ctx.keys[b_index]);
989 }
990 };
991 names.sort(Context{ .keys = names.keys() });
992 }
993};
994
995pub const PropertyBoolean = enum { no, yes, unknown, wip };963pub const PropertyBoolean = enum { no, yes, unknown, wip };
996964
997/// Represents the data that a struct declaration provides.965/// Represents the data that a struct declaration provides.
...@@ -1530,13 +1498,6 @@ pub const Fn = struct {...@@ -1530,13 +1498,6 @@ pub const Fn = struct {
1530 is_noinline: bool,1498 is_noinline: bool,
1531 calls_or_awaits_errorable_fn: bool = false,1499 calls_or_awaits_errorable_fn: bool = false,
15321500
1533 /// Any inferred error sets that this function owns, both its own inferred error set and
1534 /// inferred error sets of any inline/comptime functions called. Not to be confused
1535 /// with inferred error sets of generic instantiations of this function, which are
1536 /// *not* tracked here - they are tracked in the new `Fn` object created for the
1537 /// instantiations.
1538 inferred_error_sets: InferredErrorSetList = .{},
1539
1540 pub const Analysis = enum {1501 pub const Analysis = enum {
1541 /// This function has not yet undergone analysis, because we have not1502 /// This function has not yet undergone analysis, because we have not
1542 /// seen a potential runtime call. It may be analyzed in future.1503 /// seen a potential runtime call. It may be analyzed in future.
...@@ -1568,10 +1529,10 @@ pub const Fn = struct {...@@ -1568,10 +1529,10 @@ pub const Fn = struct {
1568 /// direct additions via `return error.Foo;`, and possibly also errors that1529 /// direct additions via `return error.Foo;`, and possibly also errors that
1569 /// are returned from any dependent functions. When the inferred error set is1530 /// are returned from any dependent functions. When the inferred error set is
1570 /// fully resolved, this map contains all the errors that the function might return.1531 /// fully resolved, this map contains all the errors that the function might return.
1571 errors: ErrorSet.NameMap = .{},1532 errors: NameMap = .{},
15721533
1573 /// Other inferred error sets which this inferred error set should include.1534 /// Other inferred error sets which this inferred error set should include.
1574 inferred_error_sets: std.AutoArrayHashMapUnmanaged(*InferredErrorSet, void) = .{},1535 inferred_error_sets: std.AutoArrayHashMapUnmanaged(InferredErrorSet.Index, void) = .{},
15751536
1576 /// Whether the function returned anyerror. This is true if either of1537 /// Whether the function returned anyerror. This is true if either of
1577 /// the dependent functions returns anyerror.1538 /// the dependent functions returns anyerror.
...@@ -1581,51 +1542,59 @@ pub const Fn = struct {...@@ -1581,51 +1542,59 @@ pub const Fn = struct {
1581 /// can skip resolving any dependents of this inferred error set.1542 /// can skip resolving any dependents of this inferred error set.
1582 is_resolved: bool = false,1543 is_resolved: bool = false,
15831544
1584 pub fn addErrorSet(self: *InferredErrorSet, gpa: Allocator, err_set_ty: Type) !void {1545 pub const NameMap = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
1546
1547 pub const Index = enum(u32) {
1548 _,
1549
1550 pub fn toOptional(i: Index) OptionalIndex {
1551 return @intToEnum(OptionalIndex, @enumToInt(i));
1552 }
1553 };
1554
1555 pub const OptionalIndex = enum(u32) {
1556 none = std.math.maxInt(u32),
1557 _,
1558
1559 pub fn init(oi: ?Index) OptionalIndex {
1560 return @intToEnum(OptionalIndex, @enumToInt(oi orelse return .none));
1561 }
1562
1563 pub fn unwrap(oi: OptionalIndex) ?Index {
1564 if (oi == .none) return null;
1565 return @intToEnum(Index, @enumToInt(oi));
1566 }
1567 };
1568
1569 pub fn addErrorSet(
1570 self: *InferredErrorSet,
1571 err_set_ty: Type,
1572 ip: *InternPool,
1573 gpa: Allocator,
1574 ) !void {
1585 switch (err_set_ty.ip_index) {1575 switch (err_set_ty.ip_index) {
1586 .anyerror_type => {1576 .anyerror_type => {
1587 self.is_anyerror = true;1577 self.is_anyerror = true;
1588 },1578 },
1589 .none => switch (err_set_ty.tag()) {1579 else => switch (ip.indexToKey(err_set_ty.ip_index)) {
1590 .error_set => {1580 .error_set_type => |error_set_type| {
1591 const names = err_set_ty.castTag(.error_set).?.data.names.keys();1581 for (error_set_type.names) |name| {
1592 for (names) |name| {
1593 try self.errors.put(gpa, name, {});1582 try self.errors.put(gpa, name, {});
1594 }1583 }
1595 },1584 },
1596 .error_set_single => {1585 .inferred_error_set_type => |ies_index| {
1597 const name = err_set_ty.castTag(.error_set_single).?.data;1586 try self.inferred_error_sets.put(gpa, ies_index, {});
1598 try self.errors.put(gpa, name, {});
1599 },
1600 .error_set_inferred => {
1601 const ies = err_set_ty.castTag(.error_set_inferred).?.data;
1602 try self.inferred_error_sets.put(gpa, ies, {});
1603 },
1604 .error_set_merged => {
1605 const names = err_set_ty.castTag(.error_set_merged).?.data.keys();
1606 for (names) |name| {
1607 try self.errors.put(gpa, name, {});
1608 }
1609 },1587 },
1610 else => unreachable,1588 else => unreachable,
1611 },1589 },
1612 else => @panic("TODO"),
1613 }1590 }
1614 }1591 }
1615 };1592 };
16161593
1617 pub const InferredErrorSetList = std.SinglyLinkedList(InferredErrorSet);1594 /// TODO: remove this function
1618 pub const InferredErrorSetListNode = InferredErrorSetList.Node;
1619
1620 pub fn deinit(func: *Fn, gpa: Allocator) void {1595 pub fn deinit(func: *Fn, gpa: Allocator) void {
1621 var it = func.inferred_error_sets.first;1596 _ = func;
1622 while (it) |node| {1597 _ = gpa;
1623 const next = node.next;
1624 node.data.errors.deinit(gpa);
1625 node.data.inferred_error_sets.deinit(gpa);
1626 gpa.destroy(node);
1627 it = next;
1628 }
1629 }1598 }
16301599
1631 pub fn isAnytypeParam(func: Fn, mod: *Module, index: u32) bool {1600 pub fn isAnytypeParam(func: Fn, mod: *Module, index: u32) bool {
...@@ -3508,6 +3477,10 @@ pub fn structPtr(mod: *Module, index: Struct.Index) *Struct {...@@ -3508,6 +3477,10 @@ pub fn structPtr(mod: *Module, index: Struct.Index) *Struct {
3508 return mod.intern_pool.structPtr(index);3477 return mod.intern_pool.structPtr(index);
3509}3478}
35103479
3480pub fn inferredErrorSetPtr(mod: *Module, index: Fn.InferredErrorSet.Index) *Fn.InferredErrorSet {
3481 return mod.intern_pool.inferredErrorSetPtr(index);
3482}
3483
3511/// This one accepts an index from the InternPool and asserts that it is not3484/// This one accepts an index from the InternPool and asserts that it is not
3512/// the anonymous empty struct type.3485/// the anonymous empty struct type.
3513pub fn structPtrUnwrap(mod: *Module, index: Struct.OptionalIndex) ?*Struct {3486pub fn structPtrUnwrap(mod: *Module, index: Struct.OptionalIndex) ?*Struct {
...@@ -4722,7 +4695,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4722,7 +4695,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4722 decl_tv.ty.fmt(mod),4695 decl_tv.ty.fmt(mod),
4723 });4696 });
4724 }4697 }
4725 const ty = try decl_tv.val.toType().copy(decl_arena_allocator);4698 const ty = decl_tv.val.toType();
4726 if (ty.getNamespace(mod) == null) {4699 if (ty.getNamespace(mod) == null) {
4727 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});4700 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
4728 }4701 }
...@@ -4756,7 +4729,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4756,7 +4729,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4756 }4729 }
4757 decl.clearValues(mod);4730 decl.clearValues(mod);
47584731
4759 decl.ty = try decl_tv.ty.copy(decl_arena_allocator);4732 decl.ty = decl_tv.ty;
4760 decl.val = try decl_tv.val.copy(decl_arena_allocator);4733 decl.val = try decl_tv.val.copy(decl_arena_allocator);
4761 // linksection, align, and addrspace were already set by Sema4734 // linksection, align, and addrspace were already set by Sema
4762 decl.has_tv = true;4735 decl.has_tv = true;
...@@ -4823,7 +4796,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4823,7 +4796,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4823 },4796 },
4824 }4797 }
48254798
4826 decl.ty = try decl_tv.ty.copy(decl_arena_allocator);4799 decl.ty = decl_tv.ty;
4827 decl.val = try decl_tv.val.copy(decl_arena_allocator);4800 decl.val = try decl_tv.val.copy(decl_arena_allocator);
4828 decl.@"align" = blk: {4801 decl.@"align" = blk: {
4829 const align_ref = decl.zirAlignRef(mod);4802 const align_ref = decl.zirAlignRef(mod);
...@@ -6599,7 +6572,7 @@ pub fn populateTestFunctions(...@@ -6599,7 +6572,7 @@ pub fn populateTestFunctions(
6599 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.6572 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.
6600 const new_ty = try Type.ptr(arena, mod, .{6573 const new_ty = try Type.ptr(arena, mod, .{
6601 .size = .Slice,6574 .size = .Slice,
6602 .pointee_type = try tmp_test_fn_ty.copy(arena),6575 .pointee_type = tmp_test_fn_ty,
6603 .mutable = false,6576 .mutable = false,
6604 .@"addrspace" = .generic,6577 .@"addrspace" = .generic,
6605 });6578 });
...@@ -6877,6 +6850,42 @@ pub fn anyframeType(mod: *Module, payload_ty: Type) Allocator.Error!Type {...@@ -6877,6 +6850,42 @@ pub fn anyframeType(mod: *Module, payload_ty: Type) Allocator.Error!Type {
6877 return (try intern(mod, .{ .anyframe_type = payload_ty.toIntern() })).toType();6850 return (try intern(mod, .{ .anyframe_type = payload_ty.toIntern() })).toType();
6878}6851}
68796852
6853pub fn errorUnionType(mod: *Module, error_set_ty: Type, payload_ty: Type) Allocator.Error!Type {
6854 return (try intern(mod, .{ .error_union_type = .{
6855 .error_set_type = error_set_ty.toIntern(),
6856 .payload_type = payload_ty.toIntern(),
6857 } })).toType();
6858}
6859
6860pub fn singleErrorSetType(mod: *Module, name: []const u8) Allocator.Error!Type {
6861 const gpa = mod.gpa;
6862 const ip = &mod.intern_pool;
6863 return singleErrorSetTypeNts(mod, try ip.getOrPutString(gpa, name));
6864}
6865
6866pub fn singleErrorSetTypeNts(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type {
6867 const gpa = mod.gpa;
6868 const ip = &mod.intern_pool;
6869 const names = [1]InternPool.NullTerminatedString{name};
6870 const i = try ip.get(gpa, .{ .error_set_type = .{ .names = &names } });
6871 return i.toType();
6872}
6873
6874/// Sorts `names` in place.
6875pub fn errorSetFromUnsortedNames(
6876 mod: *Module,
6877 names: []InternPool.NullTerminatedString,
6878) Allocator.Error!Type {
6879 std.mem.sort(
6880 InternPool.NullTerminatedString,
6881 names,
6882 {},
6883 InternPool.NullTerminatedString.indexLessThan,
6884 );
6885 const new_ty = try mod.intern(.{ .error_set_type = .{ .names = names } });
6886 return new_ty.toType();
6887}
6888
6880/// Supports optionals in addition to pointers.6889/// Supports optionals in addition to pointers.
6881pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {6890pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value {
6882 if (ty.isPtrLikeOptional(mod)) {6891 if (ty.isPtrLikeOptional(mod)) {
...@@ -7240,6 +7249,16 @@ pub fn typeToFunc(mod: *Module, ty: Type) ?InternPool.Key.FuncType {...@@ -7240,6 +7249,16 @@ pub fn typeToFunc(mod: *Module, ty: Type) ?InternPool.Key.FuncType {
7240 return mod.intern_pool.indexToFuncType(ty.ip_index);7249 return mod.intern_pool.indexToFuncType(ty.ip_index);
7241}7250}
72427251
7252pub fn typeToInferredErrorSet(mod: *Module, ty: Type) ?*Fn.InferredErrorSet {
7253 const index = typeToInferredErrorSetIndex(mod, ty).unwrap() orelse return null;
7254 return mod.inferredErrorSetPtr(index);
7255}
7256
7257pub fn typeToInferredErrorSetIndex(mod: *Module, ty: Type) Fn.InferredErrorSet.OptionalIndex {
7258 if (ty.ip_index == .none) return .none;
7259 return mod.intern_pool.indexToInferredErrorSetType(ty.ip_index);
7260}
7261
7243pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQuery) SrcLoc {7262pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQuery) SrcLoc {
7244 @setCold(true);7263 @setCold(true);
7245 const owner_decl = mod.declPtr(owner_decl_index);7264 const owner_decl = mod.declPtr(owner_decl_index);
src/Sema.zig+377-444
...@@ -825,12 +825,13 @@ pub fn analyzeBodyBreak(...@@ -825,12 +825,13 @@ pub fn analyzeBodyBreak(
825 block: *Block,825 block: *Block,
826 body: []const Zir.Inst.Index,826 body: []const Zir.Inst.Index,
827) CompileError!?BreakData {827) CompileError!?BreakData {
828 const mod = sema.mod;
828 const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {829 const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
829 error.ComptimeBreak => sema.comptime_break_inst,830 error.ComptimeBreak => sema.comptime_break_inst,
830 else => |e| return e,831 else => |e| return e,
831 };832 };
832 if (block.instructions.items.len != 0 and833 if (block.instructions.items.len != 0 and
833 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())834 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn(mod))
834 return null;835 return null;
835 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";836 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
836 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;837 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
...@@ -1701,7 +1702,7 @@ fn analyzeBodyInner(...@@ -1701,7 +1702,7 @@ fn analyzeBodyInner(
1701 break :blk Air.Inst.Ref.void_value;1702 break :blk Air.Inst.Ref.void_value;
1702 },1703 },
1703 };1704 };
1704 if (sema.typeOf(air_inst).isNoReturn())1705 if (sema.typeOf(air_inst).isNoReturn(mod))
1705 break always_noreturn;1706 break always_noreturn;
1706 map.putAssumeCapacity(inst, air_inst);1707 map.putAssumeCapacity(inst, air_inst);
1707 i += 1;1708 i += 1;
...@@ -1796,8 +1797,7 @@ fn analyzeAsType(...@@ -1796,8 +1797,7 @@ fn analyzeAsType(
1796 const wanted_type = Type.type;1797 const wanted_type = Type.type;
1797 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1798 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1798 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");1799 const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");
1799 const ty = val.toType();1800 return val.toType();
1800 return ty.copy(sema.arena);
1801}1801}
18021802
1803pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {1803pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
...@@ -2004,7 +2004,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(...@@ -2004,7 +2004,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(
2004 if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true;2004 if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true;
2005 return val;2005 return val;
2006 },2006 },
2007 .const_ty => return try air_datas[i].ty.toValue(sema.arena),2007 .const_ty => return air_datas[i].ty.toValue(),
2008 .interned => return air_datas[i].interned.toValue(),2008 .interned => return air_datas[i].interned.toValue(),
2009 else => return null,2009 else => return null,
2010 }2010 }
...@@ -2131,7 +2131,7 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec...@@ -2131,7 +2131,7 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
2131 };2131 };
2132 return sema.failWithOwnedErrorMsg(msg);2132 return sema.failWithOwnedErrorMsg(msg);
2133 } else if (inner_ty.zigTypeTag(mod) == .ErrorUnion) err: {2133 } else if (inner_ty.zigTypeTag(mod) == .ErrorUnion) err: {
2134 const child_ty = inner_ty.errorUnionPayload();2134 const child_ty = inner_ty.errorUnionPayload(mod);
2135 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;2135 if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;
2136 const msg = msg: {2136 const msg = msg: {
2137 const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2137 const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
...@@ -2473,7 +2473,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2473,7 +2473,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2473 var anon_decl = try block.startAnonDecl();2473 var anon_decl = try block.startAnonDecl();
2474 defer anon_decl.deinit();2474 defer anon_decl.deinit();
2475 iac.data.decl_index = try anon_decl.finish(2475 iac.data.decl_index = try anon_decl.finish(
2476 try pointee_ty.copy(anon_decl.arena()),2476 pointee_ty,
2477 Value.undef,2477 Value.undef,
2478 iac.data.alignment,2478 iac.data.alignment,
2479 );2479 );
...@@ -3250,47 +3250,35 @@ fn zirErrorSetDecl(...@@ -3250,47 +3250,35 @@ fn zirErrorSetDecl(
3250 const tracy = trace(@src());3250 const tracy = trace(@src());
3251 defer tracy.end();3251 defer tracy.end();
32523252
3253 const mod = sema.mod;
3253 const gpa = sema.gpa;3254 const gpa = sema.gpa;
3254 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;3255 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
3255 const src = inst_data.src();3256 const src = inst_data.src();
3256 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);3257 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
32573258
3258 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);3259 var names: Module.Fn.InferredErrorSet.NameMap = .{};
3259 errdefer new_decl_arena.deinit();3260 try names.ensureUnusedCapacity(sema.arena, extra.data.fields_len);
3260 const new_decl_arena_allocator = new_decl_arena.allocator();
3261
3262 const error_set = try new_decl_arena_allocator.create(Module.ErrorSet);
3263 const error_set_ty = try Type.Tag.error_set.create(new_decl_arena_allocator, error_set);
3264 const error_set_val = try Value.Tag.ty.create(new_decl_arena_allocator, error_set_ty);
3265 const mod = sema.mod;
3266 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3267 .ty = Type.type,
3268 .val = error_set_val,
3269 }, name_strategy, "error", inst);
3270 const new_decl = mod.declPtr(new_decl_index);
3271 new_decl.owns_tv = true;
3272 errdefer mod.abortAnonDecl(new_decl_index);
3273
3274 var names = Module.ErrorSet.NameMap{};
3275 try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len);
32763261
3277 var extra_index = @intCast(u32, extra.end);3262 var extra_index = @intCast(u32, extra.end);
3278 const extra_index_end = extra_index + (extra.data.fields_len * 2);3263 const extra_index_end = extra_index + (extra.data.fields_len * 2);
3279 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string3264 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
3280 const str_index = sema.code.extra[extra_index];3265 const str_index = sema.code.extra[extra_index];
3281 const kv = try mod.getErrorValue(sema.code.nullTerminatedString(str_index));3266 const name = sema.code.nullTerminatedString(str_index);
3282 const result = names.getOrPutAssumeCapacity(kv.key);3267 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
3268 const result = names.getOrPutAssumeCapacity(name_ip);
3283 assert(!result.found_existing); // verified in AstGen3269 assert(!result.found_existing); // verified in AstGen
3284 }3270 }
32853271
3286 // names must be sorted.3272 const error_set_ty = try mod.errorSetFromUnsortedNames(names.keys());
3287 Module.ErrorSet.sortNames(&names);3273
3274 const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
3275 .ty = Type.type,
3276 .val = error_set_ty.toValue(),
3277 }, name_strategy, "error", inst);
3278 const new_decl = mod.declPtr(new_decl_index);
3279 new_decl.owns_tv = true;
3280 errdefer mod.abortAnonDecl(new_decl_index);
32883281
3289 error_set.* = .{
3290 .owner_decl = new_decl_index,
3291 .names = names,
3292 };
3293 try new_decl.finalizeNewArena(&new_decl_arena);
3294 return sema.analyzeDeclVal(block, src, new_decl_index);3282 return sema.analyzeDeclVal(block, src, new_decl_index);
3295}3283}
32963284
...@@ -3407,7 +3395,7 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index...@@ -3407,7 +3395,7 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
3407 else3395 else
3408 operand_ty;3396 operand_ty;
3409 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return;3397 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return;
3410 const payload_ty = err_union_ty.errorUnionPayload().zigTypeTag(mod);3398 const payload_ty = err_union_ty.errorUnionPayload(mod).zigTypeTag(mod);
3411 if (payload_ty != .Void and payload_ty != .NoReturn) {3399 if (payload_ty != .Void and payload_ty != .NoReturn) {
3412 const msg = msg: {3400 const msg = msg: {
3413 const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});3401 const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});
...@@ -3590,7 +3578,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3590,7 +3578,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3590 var anon_decl = try block.startAnonDecl();3578 var anon_decl = try block.startAnonDecl();
3591 defer anon_decl.deinit();3579 defer anon_decl.deinit();
3592 return sema.analyzeDeclRef(try anon_decl.finish(3580 return sema.analyzeDeclRef(try anon_decl.finish(
3593 try elem_ty.copy(anon_decl.arena()),3581 elem_ty,
3594 try store_val.copy(anon_decl.arena()),3582 try store_val.copy(anon_decl.arena()),
3595 ptr_info.@"align",3583 ptr_info.@"align",
3596 ));3584 ));
...@@ -3722,7 +3710,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3722,7 +3710,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3722 const var_is_mut = switch (sema.typeOf(ptr).tag()) {3710 const var_is_mut = switch (sema.typeOf(ptr).tag()) {
3723 .inferred_alloc_const => false,3711 .inferred_alloc_const => false,
3724 .inferred_alloc_mut => true,3712 .inferred_alloc_mut => true,
3725 else => unreachable,
3726 };3713 };
3727 const target = sema.mod.getTarget();3714 const target = sema.mod.getTarget();
37283715
...@@ -3733,7 +3720,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3733,7 +3720,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3733 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);3720 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
37343721
3735 const decl = sema.mod.declPtr(decl_index);3722 const decl = sema.mod.declPtr(decl_index);
3736 const final_elem_ty = try decl.ty.copy(sema.arena);3723 const final_elem_ty = decl.ty;
3737 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{3724 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
3738 .pointee_type = final_elem_ty,3725 .pointee_type = final_elem_ty,
3739 .mutable = true,3726 .mutable = true,
...@@ -3833,7 +3820,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3833,7 +3820,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3833 var anon_decl = try block.startAnonDecl();3820 var anon_decl = try block.startAnonDecl();
3834 defer anon_decl.deinit();3821 defer anon_decl.deinit();
3835 const new_decl_index = try anon_decl.finish(3822 const new_decl_index = try anon_decl.finish(
3836 try final_elem_ty.copy(anon_decl.arena()),3823 final_elem_ty,
3837 try store_val.copy(anon_decl.arena()),3824 try store_val.copy(anon_decl.arena()),
3838 inferred_alloc.data.alignment,3825 inferred_alloc.data.alignment,
3839 );3826 );
...@@ -5042,7 +5029,7 @@ fn storeToInferredAllocComptime(...@@ -5042,7 +5029,7 @@ fn storeToInferredAllocComptime(
5042 var anon_decl = try block.startAnonDecl();5029 var anon_decl = try block.startAnonDecl();
5043 defer anon_decl.deinit();5030 defer anon_decl.deinit();
5044 iac.data.decl_index = try anon_decl.finish(5031 iac.data.decl_index = try anon_decl.finish(
5045 try operand_ty.copy(anon_decl.arena()),5032 operand_ty,
5046 try operand_val.copy(anon_decl.arena()),5033 try operand_val.copy(anon_decl.arena()),
5047 iac.data.alignment,5034 iac.data.alignment,
5048 );5035 );
...@@ -5286,6 +5273,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5286,6 +5273,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5286 const tracy = trace(@src());5273 const tracy = trace(@src());
5287 defer tracy.end();5274 defer tracy.end();
52885275
5276 const mod = sema.mod;
5289 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;5277 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
5290 const src = inst_data.src();5278 const src = inst_data.src();
5291 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);5279 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
...@@ -5335,7 +5323,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5335,7 +5323,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5335 try sema.analyzeBody(&loop_block, body);5323 try sema.analyzeBody(&loop_block, body);
53365324
5337 const loop_block_len = loop_block.instructions.items.len;5325 const loop_block_len = loop_block.instructions.items.len;
5338 if (loop_block_len > 0 and sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block_len - 1])).isNoReturn()) {5326 if (loop_block_len > 0 and sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block_len - 1])).isNoReturn(mod)) {
5339 // If the loop ended with a noreturn terminator, then there is no way for it to loop,5327 // If the loop ended with a noreturn terminator, then there is no way for it to loop,
5340 // so we can just use the block instead.5328 // so we can just use the block instead.
5341 try child_block.instructions.appendSlice(gpa, loop_block.instructions.items);5329 try child_block.instructions.appendSlice(gpa, loop_block.instructions.items);
...@@ -5588,7 +5576,7 @@ fn analyzeBlockBody(...@@ -5588,7 +5576,7 @@ fn analyzeBlockBody(
55885576
5589 // Blocks must terminate with noreturn instruction.5577 // Blocks must terminate with noreturn instruction.
5590 assert(child_block.instructions.items.len != 0);5578 assert(child_block.instructions.items.len != 0);
5591 assert(sema.typeOf(Air.indexToRef(child_block.instructions.items[child_block.instructions.items.len - 1])).isNoReturn());5579 assert(sema.typeOf(Air.indexToRef(child_block.instructions.items[child_block.instructions.items.len - 1])).isNoReturn(mod));
55925580
5593 if (merges.results.items.len == 0) {5581 if (merges.results.items.len == 0) {
5594 // No need for a block instruction. We can put the new instructions5582 // No need for a block instruction. We can put the new instructions
...@@ -5755,7 +5743,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5755,7 +5743,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
5755 var anon_decl = try block.startAnonDecl();5743 var anon_decl = try block.startAnonDecl();
5756 defer anon_decl.deinit();5744 defer anon_decl.deinit();
5757 break :blk try anon_decl.finish(5745 break :blk try anon_decl.finish(
5758 try operand.ty.copy(anon_decl.arena()),5746 operand.ty,
5759 try operand.val.copy(anon_decl.arena()),5747 try operand.val.copy(anon_decl.arena()),
5760 0,5748 0,
5761 );5749 );
...@@ -6434,7 +6422,7 @@ fn zirCall(...@@ -6434,7 +6422,7 @@ fn zirCall(
6434 };6422 };
64356423
6436 const return_ty = sema.typeOf(call_inst);6424 const return_ty = sema.typeOf(call_inst);
6437 if (modifier != .always_tail and return_ty.isNoReturn())6425 if (modifier != .always_tail and return_ty.isNoReturn(mod))
6438 return call_inst; // call to "fn(...) noreturn", don't pop6426 return call_inst; // call to "fn(...) noreturn", don't pop
64396427
6440 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only6428 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
...@@ -6957,17 +6945,11 @@ fn analyzeCall(...@@ -6957,17 +6945,11 @@ fn analyzeCall(
6957 // Create a fresh inferred error set type for inline/comptime calls.6945 // Create a fresh inferred error set type for inline/comptime calls.
6958 const fn_ret_ty = blk: {6946 const fn_ret_ty = blk: {
6959 if (module_fn.hasInferredErrorSet(mod)) {6947 if (module_fn.hasInferredErrorSet(mod)) {
6960 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);6948 const ies_index = try mod.intern_pool.createInferredErrorSet(gpa, .{
6961 node.data = .{ .func = module_fn };6949 .func = module_fn,
6962 if (parent_func) |some| {
6963 some.inferred_error_sets.prepend(node);
6964 }
6965
6966 const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data);
6967 break :blk try Type.Tag.error_union.create(sema.arena, .{
6968 .error_set = error_set_ty,
6969 .payload = bare_return_type,
6970 });6950 });
6951 const error_set_ty = try mod.intern(.{ .inferred_error_set_type = ies_index });
6952 break :blk try mod.errorUnionType(error_set_ty.toType(), bare_return_type);
6971 }6953 }
6972 break :blk bare_return_type;6954 break :blk bare_return_type;
6973 };6955 };
...@@ -7843,21 +7825,21 @@ fn resolveGenericInstantiationType(...@@ -7843,21 +7825,21 @@ fn resolveGenericInstantiationType(
7843 // `GenericCallAdapter.eql` as well as function body analysis.7825 // `GenericCallAdapter.eql` as well as function body analysis.
7844 // Whether it is anytype is communicated by `isAnytypeParam`.7826 // Whether it is anytype is communicated by `isAnytypeParam`.
7845 const arg = child_sema.inst_map.get(inst).?;7827 const arg = child_sema.inst_map.get(inst).?;
7846 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);7828 const arg_ty = child_sema.typeOf(arg);
78477829
7848 if (try sema.typeRequiresComptime(copied_arg_ty)) {7830 if (try sema.typeRequiresComptime(arg_ty)) {
7849 is_comptime = true;7831 is_comptime = true;
7850 }7832 }
78517833
7852 if (is_comptime) {7834 if (is_comptime) {
7853 const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?;7835 const arg_val = (child_sema.resolveMaybeUndefValAllowVariables(arg) catch unreachable).?;
7854 child_sema.comptime_args[arg_i] = .{7836 child_sema.comptime_args[arg_i] = .{
7855 .ty = copied_arg_ty,7837 .ty = arg_ty,
7856 .val = try arg_val.copy(new_decl_arena_allocator),7838 .val = try arg_val.copy(new_decl_arena_allocator),
7857 };7839 };
7858 } else {7840 } else {
7859 child_sema.comptime_args[arg_i] = .{7841 child_sema.comptime_args[arg_i] = .{
7860 .ty = copied_arg_ty,7842 .ty = arg_ty,
7861 .val = Value.generic_poison,7843 .val = Value.generic_poison,
7862 };7844 };
7863 }7845 }
...@@ -7868,7 +7850,7 @@ fn resolveGenericInstantiationType(...@@ -7868,7 +7850,7 @@ fn resolveGenericInstantiationType(
7868 try wip_captures.finalize();7850 try wip_captures.finalize();
78697851
7870 // Populate the Decl ty/val with the function and its type.7852 // Populate the Decl ty/val with the function and its type.
7871 new_decl.ty = try child_sema.typeOf(new_func_inst).copy(new_decl_arena_allocator);7853 new_decl.ty = child_sema.typeOf(new_func_inst);
7872 // If the call evaluated to a return type that requires comptime, never mind7854 // If the call evaluated to a return type that requires comptime, never mind
7873 // our generic instantiation. Instead we need to perform a comptime call.7855 // our generic instantiation. Instead we need to perform a comptime call.
7874 const new_fn_info = mod.typeToFunc(new_decl.ty).?;7856 const new_fn_info = mod.typeToFunc(new_decl.ty).?;
...@@ -8068,7 +8050,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8068,7 +8050,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8068 });8050 });
8069 }8051 }
8070 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);8052 try sema.validateErrorUnionPayloadType(block, payload, rhs_src);
8071 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, sema.mod);8053 const err_union_ty = try mod.errorUnionType(error_set, payload);
8072 return sema.addType(err_union_ty);8054 return sema.addType(err_union_ty);
8073}8055}
80748056
...@@ -8087,16 +8069,13 @@ fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, p...@@ -8087,16 +8069,13 @@ fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, p
80878069
8088fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {8070fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
8089 _ = block;8071 _ = block;
8090 const tracy = trace(@src());8072 const mod = sema.mod;
8091 defer tracy.end();
8092
8093 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;8073 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
80948074 const name = inst_data.get(sema.code);
8095 // Create an anonymous error set type with only this error value, and return the value.8075 // Create an error set type with only this error value, and return the value.
8096 const kv = try sema.mod.getErrorValue(inst_data.get(sema.code));8076 const kv = try sema.mod.getErrorValue(name);
8097 const result_type = try Type.Tag.error_set_single.create(sema.arena, kv.key);
8098 return sema.addConstant(8077 return sema.addConstant(
8099 result_type,8078 try mod.singleErrorSetType(kv.key),
8100 try Value.Tag.@"error".create(sema.arena, .{8079 try Value.Tag.@"error".create(sema.arena, .{
8101 .name = kv.key,8080 .name = kv.key,
8102 }),8081 }),
...@@ -8139,11 +8118,14 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8139,11 +8118,14 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81398118
8140 const op_ty = sema.typeOf(uncasted_operand);8119 const op_ty = sema.typeOf(uncasted_operand);
8141 try sema.resolveInferredErrorSetTy(block, src, op_ty);8120 try sema.resolveInferredErrorSetTy(block, src, op_ty);
8142 if (!op_ty.isAnyError()) {8121 if (!op_ty.isAnyError(mod)) {
8143 const names = op_ty.errorSetNames();8122 const names = op_ty.errorSetNames(mod);
8144 switch (names.len) {8123 switch (names.len) {
8145 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),8124 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),
8146 1 => return sema.addIntUnsigned(Type.err_int, sema.mod.global_error_set.get(names[0]).?),8125 1 => {
8126 const name = mod.intern_pool.stringToSlice(names[0]);
8127 return sema.addIntUnsigned(Type.err_int, mod.global_error_set.get(name).?);
8128 },
8147 else => {},8129 else => {},
8148 }8130 }
8149 }8131 }
...@@ -8224,22 +8206,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -8224,22 +8206,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
8224 return Air.Inst.Ref.anyerror_type;8206 return Air.Inst.Ref.anyerror_type;
8225 }8207 }
82268208
8227 if (lhs_ty.castTag(.error_set_inferred)) |payload| {8209 if (mod.typeToInferredErrorSetIndex(lhs_ty).unwrap()) |ies_index| {
8228 try sema.resolveInferredErrorSet(block, src, payload.data);8210 try sema.resolveInferredErrorSet(block, src, ies_index);
8229 // isAnyError might have changed from a false negative to a true positive after resolution.8211 // isAnyError might have changed from a false negative to a true positive after resolution.
8230 if (lhs_ty.isAnyError()) {8212 if (lhs_ty.isAnyError(mod)) {
8231 return Air.Inst.Ref.anyerror_type;8213 return Air.Inst.Ref.anyerror_type;
8232 }8214 }
8233 }8215 }
8234 if (rhs_ty.castTag(.error_set_inferred)) |payload| {8216 if (mod.typeToInferredErrorSetIndex(rhs_ty).unwrap()) |ies_index| {
8235 try sema.resolveInferredErrorSet(block, src, payload.data);8217 try sema.resolveInferredErrorSet(block, src, ies_index);
8236 // isAnyError might have changed from a false negative to a true positive after resolution.8218 // isAnyError might have changed from a false negative to a true positive after resolution.
8237 if (rhs_ty.isAnyError()) {8219 if (rhs_ty.isAnyError(mod)) {
8238 return Air.Inst.Ref.anyerror_type;8220 return Air.Inst.Ref.anyerror_type;
8239 }8221 }
8240 }8222 }
82418223
8242 const err_set_ty = try lhs_ty.errorSetMerge(sema.arena, rhs_ty);8224 const err_set_ty = try sema.errorSetMerge(lhs_ty, rhs_ty);
8243 return sema.addType(err_set_ty);8225 return sema.addType(err_set_ty);
8244}8226}
82458227
...@@ -8484,7 +8466,7 @@ fn zirOptionalPayload(...@@ -8484,7 +8466,7 @@ fn zirOptionalPayload(
8484 if (true) break :t operand_ty;8466 if (true) break :t operand_ty;
8485 const ptr_info = operand_ty.ptrInfo(mod);8467 const ptr_info = operand_ty.ptrInfo(mod);
8486 break :t try Type.ptr(sema.arena, sema.mod, .{8468 break :t try Type.ptr(sema.arena, sema.mod, .{
8487 .pointee_type = try ptr_info.pointee_type.copy(sema.arena),8469 .pointee_type = ptr_info.pointee_type,
8488 .@"align" = ptr_info.@"align",8470 .@"align" = ptr_info.@"align",
8489 .@"addrspace" = ptr_info.@"addrspace",8471 .@"addrspace" = ptr_info.@"addrspace",
8490 .mutable = ptr_info.mutable,8472 .mutable = ptr_info.mutable,
...@@ -8547,7 +8529,7 @@ fn analyzeErrUnionPayload(...@@ -8547,7 +8529,7 @@ fn analyzeErrUnionPayload(
8547 safety_check: bool,8529 safety_check: bool,
8548) CompileError!Air.Inst.Ref {8530) CompileError!Air.Inst.Ref {
8549 const mod = sema.mod;8531 const mod = sema.mod;
8550 const payload_ty = err_union_ty.errorUnionPayload();8532 const payload_ty = err_union_ty.errorUnionPayload(mod);
8551 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {8533 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
8552 if (val.getError()) |name| {8534 if (val.getError()) |name| {
8553 return sema.fail(block, src, "caught unexpected error '{s}'", .{name});8535 return sema.fail(block, src, "caught unexpected error '{s}'", .{name});
...@@ -8560,7 +8542,7 @@ fn analyzeErrUnionPayload(...@@ -8560,7 +8542,7 @@ fn analyzeErrUnionPayload(
85608542
8561 // If the error set has no fields then no safety check is needed.8543 // If the error set has no fields then no safety check is needed.
8562 if (safety_check and block.wantSafety() and8544 if (safety_check and block.wantSafety() and
8563 !err_union_ty.errorUnionSet().errorSetIsEmpty(mod))8545 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
8564 {8546 {
8565 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err);8547 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err);
8566 }8548 }
...@@ -8603,7 +8585,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -8603,7 +8585,7 @@ fn analyzeErrUnionPayloadPtr(
8603 }8585 }
86048586
8605 const err_union_ty = operand_ty.childType(mod);8587 const err_union_ty = operand_ty.childType(mod);
8606 const payload_ty = err_union_ty.errorUnionPayload();8588 const payload_ty = err_union_ty.errorUnionPayload(mod);
8607 const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{8589 const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{
8608 .pointee_type = payload_ty,8590 .pointee_type = payload_ty,
8609 .mutable = !operand_ty.isConstPtr(mod),8591 .mutable = !operand_ty.isConstPtr(mod),
...@@ -8646,7 +8628,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -8646,7 +8628,7 @@ fn analyzeErrUnionPayloadPtr(
86468628
8647 // If the error set has no fields then no safety check is needed.8629 // If the error set has no fields then no safety check is needed.
8648 if (safety_check and block.wantSafety() and8630 if (safety_check and block.wantSafety() and
8649 !err_union_ty.errorUnionSet().errorSetIsEmpty(mod))8631 !err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod))
8650 {8632 {
8651 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);8633 try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);
8652 }8634 }
...@@ -8678,7 +8660,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air...@@ -8678,7 +8660,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air
8678 });8660 });
8679 }8661 }
86808662
8681 const result_ty = operand_ty.errorUnionSet();8663 const result_ty = operand_ty.errorUnionSet(mod);
86828664
8683 if (try sema.resolveDefinedValue(block, src, operand)) |val| {8665 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
8684 assert(val.getError() != null);8666 assert(val.getError() != null);
...@@ -8707,7 +8689,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -8707,7 +8689,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
8707 });8689 });
8708 }8690 }
87098691
8710 const result_ty = operand_ty.childType(mod).errorUnionSet();8692 const result_ty = operand_ty.childType(mod).errorUnionSet(mod);
87118693
8712 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {8694 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
8713 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {8695 if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| {
...@@ -8755,7 +8737,7 @@ fn zirFunc(...@@ -8755,7 +8737,7 @@ fn zirFunc(
8755 extra_index += ret_ty_body.len;8737 extra_index += ret_ty_body.len;
87568738
8757 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime-known");8739 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime-known");
8758 break :blk try ret_ty_val.toType().copy(sema.arena);8740 break :blk ret_ty_val.toType();
8759 },8741 },
8760 };8742 };
87618743
...@@ -8927,6 +8909,7 @@ fn funcCommon(...@@ -8927,6 +8909,7 @@ fn funcCommon(
8927 is_noinline: bool,8909 is_noinline: bool,
8928) CompileError!Air.Inst.Ref {8910) CompileError!Air.Inst.Ref {
8929 const mod = sema.mod;8911 const mod = sema.mod;
8912 const gpa = sema.gpa;
8930 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };8913 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
8931 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };8914 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
8932 const func_src = LazySrcLoc.nodeOffset(src_node_offset);8915 const func_src = LazySrcLoc.nodeOffset(src_node_offset);
...@@ -8955,16 +8938,12 @@ fn funcCommon(...@@ -8955,16 +8938,12 @@ fn funcCommon(
8955 break :new_func new_func;8938 break :new_func new_func;
8956 }8939 }
8957 destroy_fn_on_error = true;8940 destroy_fn_on_error = true;
8958 const new_func = try sema.gpa.create(Module.Fn);8941 const new_func = try gpa.create(Module.Fn);
8959 // Set this here so that the inferred return type can be printed correctly if it appears in an error.8942 // Set this here so that the inferred return type can be printed correctly if it appears in an error.
8960 new_func.owner_decl = sema.owner_decl_index;8943 new_func.owner_decl = sema.owner_decl_index;
8961 break :new_func new_func;8944 break :new_func new_func;
8962 };8945 };
8963 errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);8946 errdefer if (destroy_fn_on_error) gpa.destroy(new_func);
8964
8965 var maybe_inferred_error_set_node: ?*Module.Fn.InferredErrorSetListNode = null;
8966 errdefer if (maybe_inferred_error_set_node) |node| sema.gpa.destroy(node);
8967 // Note: no need to errdefer since this will still be in its default state at the end of the function.
89688947
8969 const target = sema.mod.getTarget();8948 const target = sema.mod.getTarget();
8970 const fn_ty: Type = fn_ty: {8949 const fn_ty: Type = fn_ty: {
...@@ -9027,15 +9006,11 @@ fn funcCommon(...@@ -9027,15 +9006,11 @@ fn funcCommon(
9027 bare_return_type9006 bare_return_type
9028 else blk: {9007 else blk: {
9029 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9008 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9030 const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode);9009 const ies_index = try mod.intern_pool.createInferredErrorSet(gpa, .{
9031 node.data = .{ .func = new_func };9010 .func = new_func,
9032 maybe_inferred_error_set_node = node;
9033
9034 const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data);
9035 break :blk try Type.Tag.error_union.create(sema.arena, .{
9036 .error_set = error_set_ty,
9037 .payload = bare_return_type,
9038 });9011 });
9012 const error_set_ty = try mod.intern(.{ .inferred_error_set_type = ies_index });
9013 break :blk try mod.errorUnionType(error_set_ty.toType(), bare_return_type);
9039 };9014 };
90409015
9041 if (!return_type.isValidReturnType(mod)) {9016 if (!return_type.isValidReturnType(mod)) {
...@@ -9044,7 +9019,7 @@ fn funcCommon(...@@ -9044,7 +9019,7 @@ fn funcCommon(
9044 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{9019 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
9045 opaque_str, return_type.fmt(sema.mod),9020 opaque_str, return_type.fmt(sema.mod),
9046 });9021 });
9047 errdefer msg.destroy(sema.gpa);9022 errdefer msg.destroy(gpa);
90489023
9049 try sema.addDeclaredHereNote(msg, return_type);9024 try sema.addDeclaredHereNote(msg, return_type);
9050 break :msg msg;9025 break :msg msg;
...@@ -9058,7 +9033,7 @@ fn funcCommon(...@@ -9058,7 +9033,7 @@ fn funcCommon(
9058 const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{9033 const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
9059 return_type.fmt(sema.mod), @tagName(cc_resolved),9034 return_type.fmt(sema.mod), @tagName(cc_resolved),
9060 });9035 });
9061 errdefer msg.destroy(sema.gpa);9036 errdefer msg.destroy(gpa);
90629037
9063 const src_decl = sema.mod.declPtr(block.src_decl);9038 const src_decl = sema.mod.declPtr(block.src_decl);
9064 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src.toSrcLoc(src_decl, mod), return_type, .ret_ty);9039 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src.toSrcLoc(src_decl, mod), return_type, .ret_ty);
...@@ -9182,8 +9157,8 @@ fn funcCommon(...@@ -9182,8 +9157,8 @@ fn funcCommon(
9182 sema.owner_decl.@"addrspace" = address_space orelse .generic;9157 sema.owner_decl.@"addrspace" = address_space orelse .generic;
91839158
9184 if (is_extern) {9159 if (is_extern) {
9185 const new_extern_fn = try sema.gpa.create(Module.ExternFn);9160 const new_extern_fn = try gpa.create(Module.ExternFn);
9186 errdefer sema.gpa.destroy(new_extern_fn);9161 errdefer gpa.destroy(new_extern_fn);
91879162
9188 new_extern_fn.* = Module.ExternFn{9163 new_extern_fn.* = Module.ExternFn{
9189 .owner_decl = sema.owner_decl_index,9164 .owner_decl = sema.owner_decl_index,
...@@ -9232,10 +9207,6 @@ fn funcCommon(...@@ -9232,10 +9207,6 @@ fn funcCommon(
9232 .branch_quota = default_branch_quota,9207 .branch_quota = default_branch_quota,
9233 .is_noinline = is_noinline,9208 .is_noinline = is_noinline,
9234 };9209 };
9235 if (maybe_inferred_error_set_node) |node| {
9236 new_func.inferred_error_sets.prepend(node);
9237 }
9238 maybe_inferred_error_set_node = null;
9239 fn_payload.* = .{9210 fn_payload.* = .{
9240 .base = .{ .tag = .function },9211 .base = .{ .tag = .function },
9241 .data = new_func,9212 .data = new_func,
...@@ -10139,6 +10110,7 @@ fn zirSwitchCapture(...@@ -10139,6 +10110,7 @@ fn zirSwitchCapture(
10139 defer tracy.end();10110 defer tracy.end();
1014010111
10141 const mod = sema.mod;10112 const mod = sema.mod;
10113 const gpa = sema.gpa;
10142 const zir_datas = sema.code.instructions.items(.data);10114 const zir_datas = sema.code.instructions.items(.data);
10143 const capture_info = zir_datas[inst].switch_capture;10115 const capture_info = zir_datas[inst].switch_capture;
10144 const switch_info = zir_datas[capture_info.switch_inst].pl_node;10116 const switch_info = zir_datas[capture_info.switch_inst].pl_node;
...@@ -10248,7 +10220,7 @@ fn zirSwitchCapture(...@@ -10248,7 +10220,7 @@ fn zirSwitchCapture(
10248 const capture_src = raw_capture_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);10220 const capture_src = raw_capture_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
1024910221
10250 const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{});10222 const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{});
10251 errdefer msg.destroy(sema.gpa);10223 errdefer msg.destroy(gpa);
1025210224
10253 const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } };10225 const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } };
10254 const first_item_src = raw_first_item_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);10226 const first_item_src = raw_first_item_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first);
...@@ -10294,20 +10266,16 @@ fn zirSwitchCapture(...@@ -10294,20 +10266,16 @@ fn zirSwitchCapture(
10294 },10266 },
10295 .ErrorSet => {10267 .ErrorSet => {
10296 if (is_multi) {10268 if (is_multi) {
10297 var names: Module.ErrorSet.NameMap = .{};10269 var names: Module.Fn.InferredErrorSet.NameMap = .{};
10298 try names.ensureUnusedCapacity(sema.arena, items.len);10270 try names.ensureUnusedCapacity(sema.arena, items.len);
10299 for (items) |item| {10271 for (items) |item| {
10300 const item_ref = try sema.resolveInst(item);10272 const item_ref = try sema.resolveInst(item);
10301 // Previous switch validation ensured this will succeed10273 // Previous switch validation ensured this will succeed
10302 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;10274 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
10303 names.putAssumeCapacityNoClobber(10275 const name_ip = try mod.intern_pool.getOrPutString(gpa, item_val.getError().?);
10304 item_val.getError().?,10276 names.putAssumeCapacityNoClobber(name_ip, {});
10305 {},
10306 );
10307 }10277 }
10308 // names must be sorted10278 const else_error_ty = try mod.errorSetFromUnsortedNames(names.keys());
10309 Module.ErrorSet.sortNames(&names);
10310 const else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
1031110279
10312 return sema.bitCast(block, else_error_ty, operand, operand_src, null);10280 return sema.bitCast(block, else_error_ty, operand, operand_src, null);
10313 } else {10281 } else {
...@@ -10315,7 +10283,7 @@ fn zirSwitchCapture(...@@ -10315,7 +10283,7 @@ fn zirSwitchCapture(
10315 // Previous switch validation ensured this will succeed10283 // Previous switch validation ensured this will succeed
10316 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;10284 const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable;
1031710285
10318 const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?);10286 const item_ty = try mod.singleErrorSetType(item_val.getError().?);
10319 return sema.bitCast(block, item_ty, operand, operand_src, null);10287 return sema.bitCast(block, item_ty, operand, operand_src, null);
10320 }10288 }
10321 },10289 },
...@@ -10678,7 +10646,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10678,7 +10646,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1067810646
10679 try sema.resolveInferredErrorSetTy(block, src, operand_ty);10647 try sema.resolveInferredErrorSetTy(block, src, operand_ty);
1068010648
10681 if (operand_ty.isAnyError()) {10649 if (operand_ty.isAnyError(mod)) {
10682 if (special_prong != .@"else") {10650 if (special_prong != .@"else") {
10683 return sema.fail(10651 return sema.fail(
10684 block,10652 block,
...@@ -10692,7 +10660,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10692,7 +10660,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10692 var maybe_msg: ?*Module.ErrorMsg = null;10660 var maybe_msg: ?*Module.ErrorMsg = null;
10693 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);10661 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
1069410662
10695 for (operand_ty.errorSetNames()) |error_name| {10663 for (operand_ty.errorSetNames(mod)) |error_name_ip| {
10664 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
10696 if (!seen_errors.contains(error_name) and special_prong != .@"else") {10665 if (!seen_errors.contains(error_name) and special_prong != .@"else") {
10697 const msg = maybe_msg orelse blk: {10666 const msg = maybe_msg orelse blk: {
10698 maybe_msg = try sema.errMsg(10667 maybe_msg = try sema.errMsg(
...@@ -10720,7 +10689,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10720,7 +10689,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10720 return sema.failWithOwnedErrorMsg(msg);10689 return sema.failWithOwnedErrorMsg(msg);
10721 }10690 }
1072210691
10723 if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) {10692 if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames(mod).len) {
10724 // In order to enable common patterns for generic code allow simple else bodies10693 // In order to enable common patterns for generic code allow simple else bodies
10725 // else => unreachable,10694 // else => unreachable,
10726 // else => return,10695 // else => return,
...@@ -10757,18 +10726,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10757,18 +10726,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10757 );10726 );
10758 }10727 }
1075910728
10760 const error_names = operand_ty.errorSetNames();10729 const error_names = operand_ty.errorSetNames(mod);
10761 var names: Module.ErrorSet.NameMap = .{};10730 var names: Module.Fn.InferredErrorSet.NameMap = .{};
10762 try names.ensureUnusedCapacity(sema.arena, error_names.len);10731 try names.ensureUnusedCapacity(sema.arena, error_names.len);
10763 for (error_names) |error_name| {10732 for (error_names) |error_name_ip| {
10733 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
10764 if (seen_errors.contains(error_name)) continue;10734 if (seen_errors.contains(error_name)) continue;
1076510735
10766 names.putAssumeCapacityNoClobber(error_name, {});10736 names.putAssumeCapacityNoClobber(error_name_ip, {});
10767 }10737 }
1076810738 // No need to keep the hash map metadata correct; here we
10769 // names must be sorted10739 // extract the (sorted) keys only.
10770 Module.ErrorSet.sortNames(&names);10740 else_error_ty = try mod.errorSetFromUnsortedNames(names.keys());
10771 else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
10772 }10741 }
10773 },10742 },
10774 .Int, .ComptimeInt => {10743 .Int, .ComptimeInt => {
...@@ -11513,12 +11482,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -11513,12 +11482,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
11513 }11482 }
11514 },11483 },
11515 .ErrorSet => {11484 .ErrorSet => {
11516 if (operand_ty.isAnyError()) {11485 if (operand_ty.isAnyError(mod)) {
11517 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{11486 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
11518 operand_ty.fmt(mod),11487 operand_ty.fmt(mod),
11519 });11488 });
11520 }11489 }
11521 for (operand_ty.errorSetNames()) |error_name| {11490 for (operand_ty.errorSetNames(mod)) |error_name_ip| {
11491 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
11522 if (seen_errors.contains(error_name)) continue;11492 if (seen_errors.contains(error_name)) continue;
11523 cases_len += 1;11493 cases_len += 1;
1152411494
...@@ -11931,7 +11901,8 @@ fn validateSwitchNoRange(...@@ -11931,7 +11901,8 @@ fn validateSwitchNoRange(
11931}11901}
1193211902
11933fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool {11903fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool {
11934 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) return false;11904 const mod = sema.mod;
11905 if (!mod.backendSupportsFeature(.panic_unwrap_error)) return false;
1193511906
11936 const tags = sema.code.instructions.items(.tag);11907 const tags = sema.code.instructions.items(.tag);
11937 for (body) |inst| {11908 for (body) |inst| {
...@@ -11967,7 +11938,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -11967,7 +11938,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
11967 .as_node => try sema.zirAsNode(block, inst),11938 .as_node => try sema.zirAsNode(block, inst),
11968 .field_val => try sema.zirFieldVal(block, inst),11939 .field_val => try sema.zirFieldVal(block, inst),
11969 .@"unreachable" => {11940 .@"unreachable" => {
11970 if (!sema.mod.comp.formatted_panics) {11941 if (!mod.comp.formatted_panics) {
11971 try sema.safetyPanic(block, .unwrap_error);11942 try sema.safetyPanic(block, .unwrap_error);
11972 return true;11943 return true;
11973 }11944 }
...@@ -11990,7 +11961,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -11990,7 +11961,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
11990 },11961 },
11991 else => unreachable,11962 else => unreachable,
11992 };11963 };
11993 if (sema.typeOf(air_inst).isNoReturn())11964 if (sema.typeOf(air_inst).isNoReturn(mod))
11994 return true;11965 return true;
11995 sema.inst_map.putAssumeCapacity(inst, air_inst);11966 sema.inst_map.putAssumeCapacity(inst, air_inst);
11996 }11967 }
...@@ -12194,13 +12165,14 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -12194,13 +12165,14 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12194}12165}
1219512166
12196fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {12167fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
12168 const mod = sema.mod;
12197 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;12169 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
12198 const err_name = inst_data.get(sema.code);12170 const err_name = inst_data.get(sema.code);
1219912171
12200 // Return the error code from the function.12172 // Return the error code from the function.
12201 const kv = try sema.mod.getErrorValue(err_name);12173 const kv = try mod.getErrorValue(err_name);
12202 const result_inst = try sema.addConstant(12174 const result_inst = try sema.addConstant(
12203 try Type.Tag.error_set_single.create(sema.arena, kv.key),12175 try mod.singleErrorSetType(kv.key),
12204 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),12176 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
12205 );12177 );
12206 return result_inst;12178 return result_inst;
...@@ -15737,7 +15709,7 @@ fn zirClosureCapture(...@@ -15737,7 +15709,7 @@ fn zirClosureCapture(
15737 Value.@"unreachable";15709 Value.@"unreachable";
1573815710
15739 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{15711 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, .{
15740 .ty = try sema.typeOf(operand).copy(sema.perm_arena),15712 .ty = sema.typeOf(operand),
15741 .val = try val.copy(sema.perm_arena),15713 .val = try val.copy(sema.perm_arena),
15742 });15714 });
15743}15715}
...@@ -16223,10 +16195,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16223,10 +16195,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16223 try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);16195 try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
16224 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);16196 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
16225 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);16197 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);
16226 break :t try set_field_ty_decl.val.toType().copy(fields_anon_decl.arena());16198 break :t set_field_ty_decl.val.toType();
16227 };16199 };
1622816200
16229 try sema.queueFullTypeResolution(try error_field_ty.copy(sema.arena));16201 try sema.queueFullTypeResolution(error_field_ty);
1623016202
16231 // If the error set is inferred it must be resolved at this point16203 // If the error set is inferred it must be resolved at this point
16232 try sema.resolveInferredErrorSetTy(block, src, ty);16204 try sema.resolveInferredErrorSetTy(block, src, ty);
...@@ -16234,11 +16206,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16234,11 +16206,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16234 // Build our list of Error values16206 // Build our list of Error values
16235 // Optional value is only null if anyerror16207 // Optional value is only null if anyerror
16236 // Value can be zero-length slice otherwise16208 // Value can be zero-length slice otherwise
16237 const error_field_vals: ?[]Value = if (ty.isAnyError()) null else blk: {16209 const error_field_vals: ?[]Value = if (ty.isAnyError(mod)) null else blk: {
16238 const names = ty.errorSetNames();16210 const names = ty.errorSetNames(mod);
16239 const vals = try fields_anon_decl.arena().alloc(Value, names.len);16211 const vals = try fields_anon_decl.arena().alloc(Value, names.len);
16240 for (vals, 0..) |*field_val, i| {16212 for (vals, names) |*field_val, name_ip| {
16241 const name = names[i];16213 const name = mod.intern_pool.stringToSlice(name_ip);
16242 const name_val = v: {16214 const name_val = v: {
16243 var anon_decl = try block.startAnonDecl();16215 var anon_decl = try block.startAnonDecl();
16244 defer anon_decl.deinit();16216 defer anon_decl.deinit();
...@@ -16301,9 +16273,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16301,9 +16273,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16301 .ErrorUnion => {16273 .ErrorUnion => {
16302 const field_values = try sema.arena.alloc(Value, 2);16274 const field_values = try sema.arena.alloc(Value, 2);
16303 // error_set: type,16275 // error_set: type,
16304 field_values[0] = try Value.Tag.ty.create(sema.arena, ty.errorUnionSet());16276 field_values[0] = try Value.Tag.ty.create(sema.arena, ty.errorUnionSet(mod));
16305 // payload: type,16277 // payload: type,
16306 field_values[1] = try Value.Tag.ty.create(sema.arena, ty.errorUnionPayload());16278 field_values[1] = try Value.Tag.ty.create(sema.arena, ty.errorUnionPayload(mod));
1630716279
16308 return sema.addConstant(16280 return sema.addConstant(
16309 type_info_ty,16281 type_info_ty,
...@@ -16332,7 +16304,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16332,7 +16304,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16332 try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);16304 try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
16333 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);16305 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
16334 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);16306 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);
16335 break :t try enum_field_ty_decl.val.toType().copy(fields_anon_decl.arena());16307 break :t enum_field_ty_decl.val.toType();
16336 };16308 };
1633716309
16338 const enum_field_vals = try fields_anon_decl.arena().alloc(Value, enum_type.names.len);16310 const enum_field_vals = try fields_anon_decl.arena().alloc(Value, enum_type.names.len);
...@@ -16416,7 +16388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16416,7 +16388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16416 try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);16388 try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
16417 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);16389 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
16418 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);16390 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);
16419 break :t try union_field_ty_decl.val.toType().copy(fields_anon_decl.arena());16391 break :t union_field_ty_decl.val.toType();
16420 };16392 };
1642116393
16422 const union_ty = try sema.resolveTypeFields(ty);16394 const union_ty = try sema.resolveTypeFields(ty);
...@@ -16523,7 +16495,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16523,7 +16495,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16523 try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);16495 try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
16524 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);16496 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
16525 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);16497 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);
16526 break :t try struct_field_ty_decl.val.toType().copy(fields_anon_decl.arena());16498 break :t struct_field_ty_decl.val.toType();
16527 };16499 };
16528 const struct_ty = try sema.resolveTypeFields(ty);16500 const struct_ty = try sema.resolveTypeFields(ty);
16529 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout16501 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
...@@ -16733,9 +16705,9 @@ fn typeInfoDecls(...@@ -16733,9 +16705,9 @@ fn typeInfoDecls(
16733 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);16705 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
16734 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);16706 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
16735 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);16707 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
16736 break :t try declaration_ty_decl.val.toType().copy(decls_anon_decl.arena());16708 break :t declaration_ty_decl.val.toType();
16737 };16709 };
16738 try sema.queueFullTypeResolution(try declaration_ty.copy(sema.arena));16710 try sema.queueFullTypeResolution(declaration_ty);
1673916711
16740 var decl_vals = std.ArrayList(Value).init(sema.gpa);16712 var decl_vals = std.ArrayList(Value).init(sema.gpa);
16741 defer decl_vals.deinit();16713 defer decl_vals.deinit();
...@@ -17018,12 +16990,12 @@ fn zirBoolBr(...@@ -17018,12 +16990,12 @@ fn zirBoolBr(
17018 _ = try lhs_block.addBr(block_inst, lhs_result);16990 _ = try lhs_block.addBr(block_inst, lhs_result);
1701916991
17020 const rhs_result = try sema.resolveBody(rhs_block, body, inst);16992 const rhs_result = try sema.resolveBody(rhs_block, body, inst);
17021 if (!sema.typeOf(rhs_result).isNoReturn()) {16993 if (!sema.typeOf(rhs_result).isNoReturn(mod)) {
17022 _ = try rhs_block.addBr(block_inst, rhs_result);16994 _ = try rhs_block.addBr(block_inst, rhs_result);
17023 }16995 }
1702416996
17025 const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst);16997 const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst);
17026 if (!sema.typeOf(rhs_result).isNoReturn()) {16998 if (!sema.typeOf(rhs_result).isNoReturn(mod)) {
17027 if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| {16999 if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| {
17028 if (is_bool_or and rhs_val.toBool(mod)) {17000 if (is_bool_or and rhs_val.toBool(mod)) {
17029 return Air.Inst.Ref.bool_true;17001 return Air.Inst.Ref.bool_true;
...@@ -17211,7 +17183,7 @@ fn zirCondbr(...@@ -17211,7 +17183,7 @@ fn zirCondbr(
17211 const err_operand = try sema.resolveInst(err_inst_data.operand);17183 const err_operand = try sema.resolveInst(err_inst_data.operand);
17212 const operand_ty = sema.typeOf(err_operand);17184 const operand_ty = sema.typeOf(err_operand);
17213 assert(operand_ty.zigTypeTag(mod) == .ErrorUnion);17185 assert(operand_ty.zigTypeTag(mod) == .ErrorUnion);
17214 const result_ty = operand_ty.errorUnionSet();17186 const result_ty = operand_ty.errorUnionSet(mod);
17215 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);17187 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
17216 };17188 };
1721717189
...@@ -17318,7 +17290,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -17318,7 +17290,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
17318 const operand_ty = sema.typeOf(operand);17290 const operand_ty = sema.typeOf(operand);
17319 const ptr_info = operand_ty.ptrInfo(mod);17291 const ptr_info = operand_ty.ptrInfo(mod);
17320 const res_ty = try Type.ptr(sema.arena, sema.mod, .{17292 const res_ty = try Type.ptr(sema.arena, sema.mod, .{
17321 .pointee_type = err_union_ty.errorUnionPayload(),17293 .pointee_type = err_union_ty.errorUnionPayload(mod),
17322 .@"addrspace" = ptr_info.@"addrspace",17294 .@"addrspace" = ptr_info.@"addrspace",
17323 .mutable = ptr_info.mutable,17295 .mutable = ptr_info.mutable,
17324 .@"allowzero" = ptr_info.@"allowzero",17296 .@"allowzero" = ptr_info.@"allowzero",
...@@ -17414,14 +17386,15 @@ fn zirRetErrValue(...@@ -17414,14 +17386,15 @@ fn zirRetErrValue(
17414 block: *Block,17386 block: *Block,
17415 inst: Zir.Inst.Index,17387 inst: Zir.Inst.Index,
17416) CompileError!Zir.Inst.Index {17388) CompileError!Zir.Inst.Index {
17389 const mod = sema.mod;
17417 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;17390 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
17418 const err_name = inst_data.get(sema.code);17391 const err_name = inst_data.get(sema.code);
17419 const src = inst_data.src();17392 const src = inst_data.src();
1742017393
17421 // Return the error code from the function.17394 // Return the error code from the function.
17422 const kv = try sema.mod.getErrorValue(err_name);17395 const kv = try mod.getErrorValue(err_name);
17423 const result_inst = try sema.addConstant(17396 const result_inst = try sema.addConstant(
17424 try Type.Tag.error_set_single.create(sema.arena, kv.key),17397 try mod.singleErrorSetType(err_name),
17425 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),17398 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
17426 );17399 );
17427 return sema.analyzeRet(block, result_inst, src);17400 return sema.analyzeRet(block, result_inst, src);
...@@ -17632,17 +17605,15 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)...@@ -17632,17 +17605,15 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
1763217605
17633fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {17606fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
17634 const mod = sema.mod;17607 const mod = sema.mod;
17608 const gpa = sema.gpa;
17609 const ip = &mod.intern_pool;
17635 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);17610 assert(sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion);
1763617611
17637 if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| {17612 if (mod.typeToInferredErrorSet(sema.fn_ret_ty.errorUnionSet(mod))) |ies| {
17638 const op_ty = sema.typeOf(uncasted_operand);17613 const op_ty = sema.typeOf(uncasted_operand);
17639 switch (op_ty.zigTypeTag(mod)) {17614 switch (op_ty.zigTypeTag(mod)) {
17640 .ErrorSet => {17615 .ErrorSet => try ies.addErrorSet(op_ty, ip, gpa),
17641 try payload.data.addErrorSet(sema.gpa, op_ty);17616 .ErrorUnion => try ies.addErrorSet(op_ty.errorUnionSet(mod), ip, gpa),
17642 },
17643 .ErrorUnion => {
17644 try payload.data.addErrorSet(sema.gpa, op_ty.errorUnionSet());
17645 },
17646 else => {},17617 else => {},
17647 }17618 }
17648 }17619 }
...@@ -18521,7 +18492,7 @@ fn addConstantMaybeRef(...@@ -18521,7 +18492,7 @@ fn addConstantMaybeRef(
18521 var anon_decl = try block.startAnonDecl();18492 var anon_decl = try block.startAnonDecl();
18522 defer anon_decl.deinit();18493 defer anon_decl.deinit();
18523 const decl = try anon_decl.finish(18494 const decl = try anon_decl.finish(
18524 try ty.copy(anon_decl.arena()),18495 ty,
18525 try val.copy(anon_decl.arena()),18496 try val.copy(anon_decl.arena()),
18526 0, // default alignment18497 0, // default alignment
18527 );18498 );
...@@ -18595,7 +18566,7 @@ fn fieldType(...@@ -18595,7 +18566,7 @@ fn fieldType(
18595 continue;18566 continue;
18596 },18567 },
18597 .ErrorUnion => {18568 .ErrorUnion => {
18598 cur_ty = cur_ty.errorUnionPayload();18569 cur_ty = cur_ty.errorUnionPayload(mod);
18599 continue;18570 continue;
18600 },18571 },
18601 else => {},18572 else => {},
...@@ -18641,7 +18612,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -18641,7 +18612,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
18641 const inst_data = sema.code.instructions.items(.data)[inst].un_node;18612 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
18642 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };18613 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
18643 const ty = try sema.resolveType(block, operand_src, inst_data.operand);18614 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
18644 if (ty.isNoReturn()) {18615 if (ty.isNoReturn(mod)) {
18645 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});18616 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
18646 }18617 }
18647 const val = try ty.lazyAbiAlignment(mod, sema.arena);18618 const val = try ty.lazyAbiAlignment(mod, sema.arena);
...@@ -18929,7 +18900,7 @@ fn zirReify(...@@ -18929,7 +18900,7 @@ fn zirReify(
18929 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;18900 const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;
18930 const ptr_ty = try Type.ptr(sema.arena, mod, .{18901 const ptr_ty = try Type.ptr(sema.arena, mod, .{
18931 .@"addrspace" = .generic,18902 .@"addrspace" = .generic,
18932 .pointee_type = try elem_ty.copy(sema.arena),18903 .pointee_type = elem_ty,
18933 });18904 });
18934 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;18905 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
18935 break :s sent_val.toIntern();18906 break :s sent_val.toIntern();
...@@ -18993,7 +18964,7 @@ fn zirReify(...@@ -18993,7 +18964,7 @@ fn zirReify(
18993 const sentinel_val = struct_val[2];18964 const sentinel_val = struct_val[2];
1899418965
18995 const len = len_val.toUnsignedInt(mod);18966 const len = len_val.toUnsignedInt(mod);
18996 const child_ty = try child_val.toType().copy(sema.arena);18967 const child_ty = child_val.toType();
18997 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {18968 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
18998 const ptr_ty = try Type.ptr(sema.arena, mod, .{18969 const ptr_ty = try Type.ptr(sema.arena, mod, .{
18999 .@"addrspace" = .generic,18970 .@"addrspace" = .generic,
...@@ -19011,7 +18982,7 @@ fn zirReify(...@@ -19011,7 +18982,7 @@ fn zirReify(
19011 // child: type,18982 // child: type,
19012 const child_val = struct_val[0];18983 const child_val = struct_val[0];
1901318984
19014 const child_ty = try child_val.toType().copy(sema.arena);18985 const child_ty = child_val.toType();
1901518986
19016 const ty = try Type.optional(sema.arena, child_ty, mod);18987 const ty = try Type.optional(sema.arena, child_ty, mod);
19017 return sema.addType(ty);18988 return sema.addType(ty);
...@@ -19024,17 +18995,14 @@ fn zirReify(...@@ -19024,17 +18995,14 @@ fn zirReify(
19024 // payload: type,18995 // payload: type,
19025 const payload_val = struct_val[1];18996 const payload_val = struct_val[1];
1902618997
19027 const error_set_ty = try error_set_val.toType().copy(sema.arena);18998 const error_set_ty = error_set_val.toType();
19028 const payload_ty = try payload_val.toType().copy(sema.arena);18999 const payload_ty = payload_val.toType();
1902919000
19030 if (error_set_ty.zigTypeTag(mod) != .ErrorSet) {19001 if (error_set_ty.zigTypeTag(mod) != .ErrorSet) {
19031 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});19002 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
19032 }19003 }
1903319004
19034 const ty = try Type.Tag.error_union.create(sema.arena, .{19005 const ty = try mod.errorUnionType(error_set_ty, payload_ty);
19035 .error_set = error_set_ty,
19036 .payload = payload_ty,
19037 });
19038 return sema.addType(ty);19006 return sema.addType(ty);
19039 },19007 },
19040 .ErrorSet => {19008 .ErrorSet => {
...@@ -19043,27 +19011,23 @@ fn zirReify(...@@ -19043,27 +19011,23 @@ fn zirReify(
19043 const slice_val = payload_val.castTag(.slice).?.data;19011 const slice_val = payload_val.castTag(.slice).?.data;
1904419012
19045 const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod));19013 const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod));
19046 var names: Module.ErrorSet.NameMap = .{};19014 var names: Module.Fn.InferredErrorSet.NameMap = .{};
19047 try names.ensureUnusedCapacity(sema.arena, len);19015 try names.ensureUnusedCapacity(sema.arena, len);
19048 var i: usize = 0;19016 for (0..len) |i| {
19049 while (i < len) : (i += 1) {
19050 const elem_val = try slice_val.ptr.elemValue(mod, i);19017 const elem_val = try slice_val.ptr.elemValue(mod, i);
19051 const struct_val = elem_val.castTag(.aggregate).?.data;19018 const struct_val = elem_val.castTag(.aggregate).?.data;
19052 // TODO use reflection instead of magic numbers here19019 // TODO use reflection instead of magic numbers here
19053 // error_set: type,19020 // error_set: type,
19054 const name_val = struct_val[0];19021 const name_val = struct_val[0];
19055 const name_str = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, mod);19022 const name_str = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, mod);
1905619023 const name_ip = try mod.intern_pool.getOrPutString(gpa, name_str);
19057 const kv = try mod.getErrorValue(name_str);19024 const gop = names.getOrPutAssumeCapacity(name_ip);
19058 const gop = names.getOrPutAssumeCapacity(kv.key);
19059 if (gop.found_existing) {19025 if (gop.found_existing) {
19060 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});19026 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});
19061 }19027 }
19062 }19028 }
1906319029
19064 // names must be sorted19030 const ty = try mod.errorSetFromUnsortedNames(names.keys());
19065 Module.ErrorSet.sortNames(&names);
19066 const ty = try Type.Tag.error_set_merged.create(sema.arena, names);
19067 return sema.addType(ty);19031 return sema.addType(ty);
19068 },19032 },
19069 .Struct => {19033 .Struct => {
...@@ -19378,7 +19342,7 @@ fn zirReify(...@@ -19378,7 +19342,7 @@ fn zirReify(
19378 return sema.fail(block, src, "duplicate union field {s}", .{field_name});19342 return sema.fail(block, src, "duplicate union field {s}", .{field_name});
19379 }19343 }
1938019344
19381 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);19345 const field_ty = type_val.toType();
19382 gop.value_ptr.* = .{19346 gop.value_ptr.* = .{
19383 .ty = field_ty,19347 .ty = field_ty,
19384 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),19348 .abi_align = @intCast(u32, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?),
...@@ -19673,7 +19637,7 @@ fn reifyStruct(...@@ -19673,7 +19637,7 @@ fn reifyStruct(
19673 return sema.fail(block, src, "comptime field without default initialization value", .{});19637 return sema.fail(block, src, "comptime field without default initialization value", .{});
19674 }19638 }
1967519639
19676 const field_ty = try type_val.toType().copy(new_decl_arena_allocator);19640 const field_ty = type_val.toType();
19677 gop.value_ptr.* = .{19641 gop.value_ptr.* = .{
19678 .ty = field_ty,19642 .ty = field_ty,
19679 .abi_align = abi_align,19643 .abi_align = abi_align,
...@@ -19751,7 +19715,7 @@ fn reifyStruct(...@@ -19751,7 +19715,7 @@ fn reifyStruct(
19751 if (backing_int_val.optionalValue(mod)) |payload| {19715 if (backing_int_val.optionalValue(mod)) |payload| {
19752 const backing_int_ty = payload.toType();19716 const backing_int_ty = payload.toType();
19753 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);19717 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
19754 struct_obj.backing_int_ty = try backing_int_ty.copy(new_decl_arena_allocator);19718 struct_obj.backing_int_ty = backing_int_ty;
19755 } else {19719 } else {
19756 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));19720 struct_obj.backing_int_ty = try mod.intType(.unsigned, @intCast(u16, fields_bit_sum));
19757 }19721 }
...@@ -20035,6 +19999,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -20035,6 +19999,8 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
20035}19999}
2003620000
20037fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {20001fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
20002 const mod = sema.mod;
20003 const ip = &mod.intern_pool;
20038 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;20004 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
20039 const src = LazySrcLoc.nodeOffset(extra.node);20005 const src = LazySrcLoc.nodeOffset(extra.node);
20040 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };20006 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
...@@ -20050,22 +20016,27 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -20050,22 +20016,27 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2005020016
20051 if (disjoint: {20017 if (disjoint: {
20052 // Try avoiding resolving inferred error sets if we can20018 // Try avoiding resolving inferred error sets if we can
20053 if (!dest_ty.isAnyError() and dest_ty.errorSetNames().len == 0) break :disjoint true;20019 if (!dest_ty.isAnyError(mod) and dest_ty.errorSetNames(mod).len == 0) break :disjoint true;
20054 if (!operand_ty.isAnyError() and operand_ty.errorSetNames().len == 0) break :disjoint true;20020 if (!operand_ty.isAnyError(mod) and operand_ty.errorSetNames(mod).len == 0) break :disjoint true;
20055 if (dest_ty.isAnyError()) break :disjoint false;20021 if (dest_ty.isAnyError(mod)) break :disjoint false;
20056 if (operand_ty.isAnyError()) break :disjoint false;20022 if (operand_ty.isAnyError(mod)) break :disjoint false;
20057 for (dest_ty.errorSetNames()) |dest_err_name|20023 for (dest_ty.errorSetNames(mod)) |dest_err_name| {
20058 if (operand_ty.errorSetHasField(dest_err_name))20024 if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
20059 break :disjoint false;20025 break :disjoint false;
20026 }
2006020027
20061 if (dest_ty.tag() != .error_set_inferred and operand_ty.tag() != .error_set_inferred)20028 if (!ip.isInferredErrorSetType(dest_ty.ip_index) and
20029 !ip.isInferredErrorSetType(operand_ty.ip_index))
20030 {
20062 break :disjoint true;20031 break :disjoint true;
20032 }
2006320033
20064 try sema.resolveInferredErrorSetTy(block, dest_ty_src, dest_ty);20034 try sema.resolveInferredErrorSetTy(block, dest_ty_src, dest_ty);
20065 try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty);20035 try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty);
20066 for (dest_ty.errorSetNames()) |dest_err_name|20036 for (dest_ty.errorSetNames(mod)) |dest_err_name| {
20067 if (operand_ty.errorSetHasField(dest_err_name))20037 if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
20068 break :disjoint false;20038 break :disjoint false;
20039 }
2006920040
20070 break :disjoint true;20041 break :disjoint true;
20071 }) {20042 }) {
...@@ -20085,9 +20056,9 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -20085,9 +20056,9 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
20085 }20056 }
2008620057
20087 if (maybe_operand_val) |val| {20058 if (maybe_operand_val) |val| {
20088 if (!dest_ty.isAnyError()) {20059 if (!dest_ty.isAnyError(mod)) {
20089 const error_name = val.castTag(.@"error").?.data.name;20060 const error_name = val.castTag(.@"error").?.data.name;
20090 if (!dest_ty.errorSetHasField(error_name)) {20061 if (!dest_ty.errorSetHasField(error_name, mod)) {
20091 const msg = msg: {20062 const msg = msg: {
20092 const msg = try sema.errMsg(20063 const msg = try sema.errMsg(
20093 block,20064 block,
...@@ -20107,7 +20078,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -20107,7 +20078,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
20107 }20078 }
2010820079
20109 try sema.requireRuntimeBlock(block, src, operand_src);20080 try sema.requireRuntimeBlock(block, src, operand_src);
20110 if (block.wantSafety() and !dest_ty.isAnyError() and sema.mod.backendSupportsFeature(.error_set_has_value)) {20081 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
20111 const err_int_inst = try block.addBitCast(Type.err_int, operand);20082 const err_int_inst = try block.addBitCast(Type.err_int, operand);
20112 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);20083 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);
20113 try sema.addSafetyCheck(block, ok, .invalid_error_code);20084 try sema.addSafetyCheck(block, ok, .invalid_error_code);
...@@ -22862,7 +22833,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22862,7 +22833,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22862 extra_index += body.len;22833 extra_index += body.len;
2286322834
22864 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime-known");22835 const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime-known");
22865 const ty = try val.toType().copy(sema.arena);22836 const ty = val.toType();
22866 break :blk ty;22837 break :blk ty;
22867 } else if (extra.data.bits.has_ret_ty_ref) blk: {22838 } else if (extra.data.bits.has_ret_ty_ref) blk: {
22868 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);22839 const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
...@@ -22873,7 +22844,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -22873,7 +22844,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
22873 },22844 },
22874 else => |e| return e,22845 else => |e| return e,
22875 };22846 };
22876 const ty = try ret_ty_tv.val.toType().copy(sema.arena);22847 const ty = ret_ty_tv.val.toType();
22877 break :blk ty;22848 break :blk ty;
22878 } else Type.void;22849 } else Type.void;
2287922850
...@@ -23360,7 +23331,7 @@ fn validateRunTimeType(...@@ -23360,7 +23331,7 @@ fn validateRunTimeType(
23360 },23331 },
23361 .Array, .Vector => ty = ty.childType(mod),23332 .Array, .Vector => ty = ty.childType(mod),
2336223333
23363 .ErrorUnion => ty = ty.errorUnionPayload(),23334 .ErrorUnion => ty = ty.errorUnionPayload(mod),
2336423335
23365 .Struct, .Union => {23336 .Struct, .Union => {
23366 const resolved_ty = try sema.resolveTypeFields(ty);23337 const resolved_ty = try sema.resolveTypeFields(ty);
...@@ -23452,7 +23423,7 @@ fn explainWhyTypeIsComptimeInner(...@@ -23452,7 +23423,7 @@ fn explainWhyTypeIsComptimeInner(
23452 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(mod), type_set);23423 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(mod), type_set);
23453 },23424 },
23454 .ErrorUnion => {23425 .ErrorUnion => {
23455 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(), type_set);23426 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(mod), type_set);
23456 },23427 },
2345723428
23458 .Struct => {23429 .Struct => {
...@@ -24065,7 +24036,9 @@ fn fieldVal(...@@ -24065,7 +24036,9 @@ fn fieldVal(
24065 // in `fieldPtr`. This function takes a value and returns a value.24036 // in `fieldPtr`. This function takes a value and returns a value.
2406624037
24067 const mod = sema.mod;24038 const mod = sema.mod;
24039 const gpa = sema.gpa;
24068 const arena = sema.arena;24040 const arena = sema.arena;
24041 const ip = &mod.intern_pool;
24069 const object_src = src; // TODO better source location24042 const object_src = src; // TODO better source location
24070 const object_ty = sema.typeOf(object);24043 const object_ty = sema.typeOf(object);
2407124044
...@@ -24147,27 +24120,33 @@ fn fieldVal(...@@ -24147,27 +24120,33 @@ fn fieldVal(
2414724120
24148 switch (try child_type.zigTypeTagOrPoison(mod)) {24121 switch (try child_type.zigTypeTagOrPoison(mod)) {
24149 .ErrorSet => {24122 .ErrorSet => {
24150 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {24123 const name = try ip.getOrPutString(gpa, field_name);
24151 if (payload.data.names.getEntry(field_name)) |entry| {24124 switch (ip.indexToKey(child_type.ip_index)) {
24152 break :blk entry.key_ptr.*;24125 .error_set_type => |error_set_type| blk: {
24153 }24126 if (error_set_type.nameIndex(ip, name) != null) break :blk;
24154 const msg = msg: {24127 const msg = msg: {
24155 const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{24128 const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{
24156 field_name, child_type.fmt(mod),24129 field_name, child_type.fmt(mod),
24157 });24130 });
24158 errdefer msg.destroy(sema.gpa);24131 errdefer msg.destroy(sema.gpa);
24159 try sema.addDeclaredHereNote(msg, child_type);24132 try sema.addDeclaredHereNote(msg, child_type);
24160 break :msg msg;24133 break :msg msg;
24161 };24134 };
24162 return sema.failWithOwnedErrorMsg(msg);24135 return sema.failWithOwnedErrorMsg(msg);
24163 } else (try mod.getErrorValue(field_name)).key;24136 },
24137 .inferred_error_set_type => {
24138 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
24139 },
24140 .simple_type => |t| assert(t == .anyerror),
24141 else => unreachable,
24142 }
2416424143
24165 return sema.addConstant(24144 return sema.addConstant(
24166 if (!child_type.isAnyError())24145 if (!child_type.isAnyError(mod))
24167 try child_type.copy(arena)24146 child_type
24168 else24147 else
24169 try Type.Tag.error_set_single.create(arena, name),24148 try mod.singleErrorSetTypeNts(name),
24170 try Value.Tag.@"error".create(arena, .{ .name = name }),24149 try Value.Tag.@"error".create(arena, .{ .name = ip.stringToSlice(name) }),
24171 );24150 );
24172 },24151 },
24173 .Union => {24152 .Union => {
...@@ -24252,6 +24231,8 @@ fn fieldPtr(...@@ -24252,6 +24231,8 @@ fn fieldPtr(
24252 // in `fieldVal`. This function takes a pointer and returns a pointer.24231 // in `fieldVal`. This function takes a pointer and returns a pointer.
2425324232
24254 const mod = sema.mod;24233 const mod = sema.mod;
24234 const gpa = sema.gpa;
24235 const ip = &mod.intern_pool;
24255 const object_ptr_src = src; // TODO better source location24236 const object_ptr_src = src; // TODO better source location
24256 const object_ptr_ty = sema.typeOf(object_ptr);24237 const object_ptr_ty = sema.typeOf(object_ptr);
24257 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {24238 const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) {
...@@ -24362,24 +24343,33 @@ fn fieldPtr(...@@ -24362,24 +24343,33 @@ fn fieldPtr(
2436224343
24363 switch (child_type.zigTypeTag(mod)) {24344 switch (child_type.zigTypeTag(mod)) {
24364 .ErrorSet => {24345 .ErrorSet => {
24365 // TODO resolve inferred error sets24346 const name = try ip.getOrPutString(gpa, field_name);
24366 const name: []const u8 = if (child_type.castTag(.error_set)) |payload| blk: {24347 switch (ip.indexToKey(child_type.ip_index)) {
24367 if (payload.data.names.getEntry(field_name)) |entry| {24348 .error_set_type => |error_set_type| blk: {
24368 break :blk entry.key_ptr.*;24349 if (error_set_type.nameIndex(ip, name) != null) {
24369 }24350 break :blk;
24370 return sema.fail(block, src, "no error named '{s}' in '{}'", .{24351 }
24371 field_name, child_type.fmt(mod),24352 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
24372 });24353 field_name, child_type.fmt(mod),
24373 } else (try mod.getErrorValue(field_name)).key;24354 });
24355 },
24356 .inferred_error_set_type => {
24357 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
24358 },
24359 .simple_type => |t| assert(t == .anyerror),
24360 else => unreachable,
24361 }
2437424362
24375 var anon_decl = try block.startAnonDecl();24363 var anon_decl = try block.startAnonDecl();
24376 defer anon_decl.deinit();24364 defer anon_decl.deinit();
24377 return sema.analyzeDeclRef(try anon_decl.finish(24365 return sema.analyzeDeclRef(try anon_decl.finish(
24378 if (!child_type.isAnyError())24366 if (!child_type.isAnyError(mod))
24379 try child_type.copy(anon_decl.arena())24367 child_type
24380 else24368 else
24381 try Type.Tag.error_set_single.create(anon_decl.arena(), name),24369 try mod.singleErrorSetTypeNts(name),
24382 try Value.Tag.@"error".create(anon_decl.arena(), .{ .name = name }),24370 try Value.Tag.@"error".create(anon_decl.arena(), .{
24371 .name = ip.stringToSlice(name),
24372 }),
24383 0, // default alignment24373 0, // default alignment
24384 ));24374 ));
24385 },24375 },
...@@ -24589,7 +24579,7 @@ fn fieldCallBind(...@@ -24589,7 +24579,7 @@ fn fieldCallBind(
24589 } };24579 } };
24590 }24580 }
24591 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and24581 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and
24592 first_param_type.errorUnionPayload().eql(concrete_ty, mod))24582 first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod))
24593 {24583 {
24594 const deref = try sema.analyzeLoad(block, src, object_ptr, src);24584 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
24595 return .{ .method = .{24585 return .{ .method = .{
...@@ -24832,7 +24822,7 @@ fn structFieldPtrByIndex(...@@ -24832,7 +24822,7 @@ fn structFieldPtrByIndex(
2483224822
24833 if (field.is_comptime) {24823 if (field.is_comptime) {
24834 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{24824 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
24835 .field_ty = try field.ty.copy(sema.arena),24825 .field_ty = field.ty,
24836 .field_val = try field.default_val.copy(sema.arena),24826 .field_val = try field.default_val.copy(sema.arena),
24837 });24827 });
24838 return sema.addConstant(ptr_field_ty, val);24828 return sema.addConstant(ptr_field_ty, val);
...@@ -26227,7 +26217,7 @@ fn coerceExtra(...@@ -26227,7 +26217,7 @@ fn coerceExtra(
26227 .none => switch (inst_val.tag()) {26217 .none => switch (inst_val.tag()) {
26228 .eu_payload => {26218 .eu_payload => {
26229 const payload = try sema.addConstant(26219 const payload = try sema.addConstant(
26230 inst_ty.errorUnionPayload(),26220 inst_ty.errorUnionPayload(mod),
26231 inst_val.castTag(.eu_payload).?.data,26221 inst_val.castTag(.eu_payload).?.data,
26232 );26222 );
26233 return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src) catch |err| switch (err) {26223 return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src) catch |err| switch (err) {
...@@ -26240,7 +26230,7 @@ fn coerceExtra(...@@ -26240,7 +26230,7 @@ fn coerceExtra(
26240 else => {},26230 else => {},
26241 }26231 }
26242 const error_set = try sema.addConstant(26232 const error_set = try sema.addConstant(
26243 inst_ty.errorUnionSet(),26233 inst_ty.errorUnionSet(mod),
26244 inst_val,26234 inst_val,
26245 );26235 );
26246 return sema.wrapErrorUnionSet(block, dest_ty, error_set, inst_src);26236 return sema.wrapErrorUnionSet(block, dest_ty, error_set, inst_src);
...@@ -26342,7 +26332,7 @@ fn coerceExtra(...@@ -26342,7 +26332,7 @@ fn coerceExtra(
2634226332
26343 // E!T to T26333 // E!T to T
26344 if (inst_ty.zigTypeTag(mod) == .ErrorUnion and26334 if (inst_ty.zigTypeTag(mod) == .ErrorUnion and
26345 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)26335 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(mod), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
26346 {26336 {
26347 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});26337 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});
26348 try sema.errNote(block, inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});26338 try sema.errNote(block, inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
...@@ -26393,7 +26383,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -26393,7 +26383,7 @@ const InMemoryCoercionResult = union(enum) {
26393 optional_shape: Pair,26383 optional_shape: Pair,
26394 optional_child: PairAndChild,26384 optional_child: PairAndChild,
26395 from_anyerror,26385 from_anyerror,
26396 missing_error: []const []const u8,26386 missing_error: []const InternPool.NullTerminatedString,
26397 /// true if wanted is var args26387 /// true if wanted is var args
26398 fn_var_args: bool,26388 fn_var_args: bool,
26399 /// true if wanted is generic26389 /// true if wanted is generic
...@@ -26567,7 +26557,8 @@ const InMemoryCoercionResult = union(enum) {...@@ -26567,7 +26557,8 @@ const InMemoryCoercionResult = union(enum) {
26567 break;26557 break;
26568 },26558 },
26569 .missing_error => |missing_errors| {26559 .missing_error => |missing_errors| {
26570 for (missing_errors) |err| {26560 for (missing_errors) |err_index| {
26561 const err = mod.intern_pool.stringToSlice(err_index);
26571 try sema.errNote(block, src, msg, "'error.{s}' not a member of destination error set", .{err});26562 try sema.errNote(block, src, msg, "'error.{s}' not a member of destination error set", .{err});
26572 }26563 }
26573 break;26564 break;
...@@ -26813,8 +26804,8 @@ fn coerceInMemoryAllowed(...@@ -26813,8 +26804,8 @@ fn coerceInMemoryAllowed(
2681326804
26814 // Error Unions26805 // Error Unions
26815 if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) {26806 if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) {
26816 const dest_payload = dest_ty.errorUnionPayload();26807 const dest_payload = dest_ty.errorUnionPayload(mod);
26817 const src_payload = src_ty.errorUnionPayload();26808 const src_payload = src_ty.errorUnionPayload(mod);
26818 const child = try sema.coerceInMemoryAllowed(block, dest_payload, src_payload, dest_is_mut, target, dest_src, src_src);26809 const child = try sema.coerceInMemoryAllowed(block, dest_payload, src_payload, dest_is_mut, target, dest_src, src_src);
26819 if (child != .ok) {26810 if (child != .ok) {
26820 return InMemoryCoercionResult{ .error_union_payload = .{26811 return InMemoryCoercionResult{ .error_union_payload = .{
...@@ -26823,7 +26814,7 @@ fn coerceInMemoryAllowed(...@@ -26823,7 +26814,7 @@ fn coerceInMemoryAllowed(
26823 .wanted = dest_payload,26814 .wanted = dest_payload,
26824 } };26815 } };
26825 }26816 }
26826 return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(), src_ty.errorUnionSet(), dest_is_mut, target, dest_src, src_src);26817 return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(mod), src_ty.errorUnionSet(mod), dest_is_mut, target, dest_src, src_src);
26827 }26818 }
2682826819
26829 // Error Sets26820 // Error Sets
...@@ -26903,8 +26894,8 @@ fn coerceInMemoryAllowed(...@@ -26903,8 +26894,8 @@ fn coerceInMemoryAllowed(
26903 if (child != .ok) {26894 if (child != .ok) {
26904 return InMemoryCoercionResult{ .optional_child = .{26895 return InMemoryCoercionResult{ .optional_child = .{
26905 .child = try child.dupe(sema.arena),26896 .child = try child.dupe(sema.arena),
26906 .actual = try src_child_type.copy(sema.arena),26897 .actual = src_child_type,
26907 .wanted = try dest_child_type.copy(sema.arena),26898 .wanted = dest_child_type,
26908 } };26899 } };
26909 }26900 }
2691026901
...@@ -26926,133 +26917,100 @@ fn coerceInMemoryAllowedErrorSets(...@@ -26926,133 +26917,100 @@ fn coerceInMemoryAllowedErrorSets(
26926 src_src: LazySrcLoc,26917 src_src: LazySrcLoc,
26927) !InMemoryCoercionResult {26918) !InMemoryCoercionResult {
26928 const mod = sema.mod;26919 const mod = sema.mod;
26920 const gpa = sema.gpa;
26921 const ip = &mod.intern_pool;
2692926922
26930 // Coercion to `anyerror`. Note that this check can return false negatives26923 // Coercion to `anyerror`. Note that this check can return false negatives
26931 // in case the error sets did not get resolved.26924 // in case the error sets did not get resolved.
26932 if (dest_ty.isAnyError()) {26925 if (dest_ty.isAnyError(mod)) {
26933 return .ok;26926 return .ok;
26934 }26927 }
2693526928
26936 if (dest_ty.castTag(.error_set_inferred)) |dst_payload| {26929 if (mod.typeToInferredErrorSetIndex(dest_ty).unwrap()) |dst_ies_index| {
26937 const dst_ies = dst_payload.data;26930 const dst_ies = mod.inferredErrorSetPtr(dst_ies_index);
26938 // We will make an effort to return `ok` without resolving either error set, to26931 // We will make an effort to return `ok` without resolving either error set, to
26939 // avoid unnecessary "unable to resolve error set" dependency loop errors.26932 // avoid unnecessary "unable to resolve error set" dependency loop errors.
26940 switch (src_ty.ip_index) {26933 switch (src_ty.ip_index) {
26941 .none => switch (src_ty.tag()) {26934 .anyerror_type => {},
26942 .error_set_inferred => {26935 else => switch (ip.indexToKey(src_ty.ip_index)) {
26936 .inferred_error_set_type => |src_index| {
26943 // If both are inferred error sets of functions, and26937 // If both are inferred error sets of functions, and
26944 // the dest includes the source function, the coercion is OK.26938 // the dest includes the source function, the coercion is OK.
26945 // This check is important because it works without forcing a full resolution26939 // This check is important because it works without forcing a full resolution
26946 // of inferred error sets.26940 // of inferred error sets.
26947 const src_ies = src_ty.castTag(.error_set_inferred).?.data;26941 if (dst_ies.inferred_error_sets.contains(src_index)) {
26948
26949 if (dst_ies.inferred_error_sets.contains(src_ies)) {
26950 return .ok;26942 return .ok;
26951 }26943 }
26952 },26944 },
26953 .error_set_single => {26945 .error_set_type => |error_set_type| {
26954 const name = src_ty.castTag(.error_set_single).?.data;26946 for (error_set_type.names) |name| {
26955 if (dst_ies.errors.contains(name)) return .ok;
26956 },
26957 .error_set_merged => {
26958 const names = src_ty.castTag(.error_set_merged).?.data.keys();
26959 for (names) |name| {
26960 if (!dst_ies.errors.contains(name)) break;
26961 } else return .ok;
26962 },
26963 .error_set => {
26964 const names = src_ty.castTag(.error_set).?.data.names.keys();
26965 for (names) |name| {
26966 if (!dst_ies.errors.contains(name)) break;26947 if (!dst_ies.errors.contains(name)) break;
26967 } else return .ok;26948 } else return .ok;
26968 },26949 },
26969 else => unreachable,26950 else => unreachable,
26970 },26951 },
26971 .anyerror_type => {},
26972 else => switch (mod.intern_pool.indexToKey(src_ty.ip_index)) {
26973 else => @panic("TODO"),
26974 },
26975 }26952 }
2697626953
26977 if (dst_ies.func == sema.owner_func) {26954 if (dst_ies.func == sema.owner_func) {
26978 // We are trying to coerce an error set to the current function's26955 // We are trying to coerce an error set to the current function's
26979 // inferred error set.26956 // inferred error set.
26980 try dst_ies.addErrorSet(sema.gpa, src_ty);26957 try dst_ies.addErrorSet(src_ty, ip, gpa);
26981 return .ok;26958 return .ok;
26982 }26959 }
2698326960
26984 try sema.resolveInferredErrorSet(block, dest_src, dst_payload.data);26961 try sema.resolveInferredErrorSet(block, dest_src, dst_ies_index);
26985 // isAnyError might have changed from a false negative to a true positive after resolution.26962 // isAnyError might have changed from a false negative to a true positive after resolution.
26986 if (dest_ty.isAnyError()) {26963 if (dest_ty.isAnyError(mod)) {
26987 return .ok;26964 return .ok;
26988 }26965 }
26989 }26966 }
2699026967
26991 var missing_error_buf = std.ArrayList([]const u8).init(sema.gpa);26968 var missing_error_buf = std.ArrayList(InternPool.NullTerminatedString).init(gpa);
26992 defer missing_error_buf.deinit();26969 defer missing_error_buf.deinit();
2699326970
26994 switch (src_ty.ip_index) {26971 switch (src_ty.ip_index) {
26995 .none => switch (src_ty.tag()) {26972 .anyerror_type => switch (ip.indexToKey(dest_ty.ip_index)) {
26996 .error_set_inferred => {26973 .inferred_error_set_type => unreachable, // Caught by dest_ty.isAnyError(mod) above.
26997 const src_data = src_ty.castTag(.error_set_inferred).?.data;26974 .simple_type => unreachable, // filtered out above
26975 .error_set_type => return .from_anyerror,
26976 else => unreachable,
26977 },
26978
26979 else => switch (ip.indexToKey(src_ty.ip_index)) {
26980 .inferred_error_set_type => |src_index| {
26981 const src_data = mod.inferredErrorSetPtr(src_index);
2699826982
26999 try sema.resolveInferredErrorSet(block, src_src, src_data);26983 try sema.resolveInferredErrorSet(block, src_src, src_index);
27000 // src anyerror status might have changed after the resolution.26984 // src anyerror status might have changed after the resolution.
27001 if (src_ty.isAnyError()) {26985 if (src_ty.isAnyError(mod)) {
27002 // dest_ty.isAnyError() == true is already checked for at this point.26986 // dest_ty.isAnyError(mod) == true is already checked for at this point.
27003 return .from_anyerror;26987 return .from_anyerror;
27004 }26988 }
2700526989
27006 for (src_data.errors.keys()) |key| {26990 for (src_data.errors.keys()) |key| {
27007 if (!dest_ty.errorSetHasField(key)) {26991 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), key)) {
27008 try missing_error_buf.append(key);26992 try missing_error_buf.append(key);
27009 }26993 }
27010 }26994 }
2701126995
27012 if (missing_error_buf.items.len != 0) {26996 if (missing_error_buf.items.len != 0) {
27013 return InMemoryCoercionResult{26997 return InMemoryCoercionResult{
27014 .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),26998 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
27015 };
27016 }
27017
27018 return .ok;
27019 },
27020 .error_set_single => {
27021 const name = src_ty.castTag(.error_set_single).?.data;
27022 if (dest_ty.errorSetHasField(name)) {
27023 return .ok;
27024 }
27025 const list = try sema.arena.alloc([]const u8, 1);
27026 list[0] = name;
27027 return InMemoryCoercionResult{ .missing_error = list };
27028 },
27029 .error_set_merged => {
27030 const names = src_ty.castTag(.error_set_merged).?.data.keys();
27031 for (names) |name| {
27032 if (!dest_ty.errorSetHasField(name)) {
27033 try missing_error_buf.append(name);
27034 }
27035 }
27036
27037 if (missing_error_buf.items.len != 0) {
27038 return InMemoryCoercionResult{
27039 .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
27040 };26999 };
27041 }27000 }
2704227001
27043 return .ok;27002 return .ok;
27044 },27003 },
27045 .error_set => {27004 .error_set_type => |error_set_type| {
27046 const names = src_ty.castTag(.error_set).?.data.names.keys();27005 for (error_set_type.names) |name| {
27047 for (names) |name| {27006 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), name)) {
27048 if (!dest_ty.errorSetHasField(name)) {
27049 try missing_error_buf.append(name);27007 try missing_error_buf.append(name);
27050 }27008 }
27051 }27009 }
2705227010
27053 if (missing_error_buf.items.len != 0) {27011 if (missing_error_buf.items.len != 0) {
27054 return InMemoryCoercionResult{27012 return InMemoryCoercionResult{
27055 .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),27013 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
27056 };27014 };
27057 }27015 }
2705827016
...@@ -27060,18 +27018,6 @@ fn coerceInMemoryAllowedErrorSets(...@@ -27060,18 +27018,6 @@ fn coerceInMemoryAllowedErrorSets(
27060 },27018 },
27061 else => unreachable,27019 else => unreachable,
27062 },27020 },
27063
27064 .anyerror_type => switch (dest_ty.ip_index) {
27065 .none => switch (dest_ty.tag()) {
27066 .error_set_inferred => unreachable, // Caught by dest_ty.isAnyError() above.
27067 .error_set_single, .error_set_merged, .error_set => return .from_anyerror,
27068 else => unreachable,
27069 },
27070 .anyerror_type => unreachable, // Filtered out above.
27071 else => @panic("TODO"),
27072 },
27073
27074 else => @panic("TODO"),
27075 }27021 }
2707627022
27077 unreachable;27023 unreachable;
...@@ -28029,7 +27975,7 @@ fn beginComptimePtrMutation(...@@ -28029,7 +27975,7 @@ fn beginComptimePtrMutation(
28029 var parent = try sema.beginComptimePtrMutation(block, src, eu_ptr.container_ptr, eu_ptr.container_ty);27975 var parent = try sema.beginComptimePtrMutation(block, src, eu_ptr.container_ptr, eu_ptr.container_ty);
28030 switch (parent.pointee) {27976 switch (parent.pointee) {
28031 .direct => |val_ptr| {27977 .direct => |val_ptr| {
28032 const payload_ty = parent.ty.errorUnionPayload();27978 const payload_ty = parent.ty.errorUnionPayload(mod);
28033 if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) {27979 if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) {
28034 return ComptimePtrMutationKit{27980 return ComptimePtrMutationKit{
28035 .decl_ref_mut = parent.decl_ref_mut,27981 .decl_ref_mut = parent.decl_ref_mut,
...@@ -28402,7 +28348,7 @@ fn beginComptimePtrLoad(...@@ -28402,7 +28348,7 @@ fn beginComptimePtrLoad(
28402 => blk: {28348 => blk: {
28403 const payload_ptr = ptr_val.cast(Value.Payload.PayloadPtr).?.data;28349 const payload_ptr = ptr_val.cast(Value.Payload.PayloadPtr).?.data;
28404 const payload_ty = switch (ptr_val.tag()) {28350 const payload_ty = switch (ptr_val.tag()) {
28405 .eu_payload_ptr => payload_ptr.container_ty.errorUnionPayload(),28351 .eu_payload_ptr => payload_ptr.container_ty.errorUnionPayload(mod),
28406 .opt_payload_ptr => payload_ptr.container_ty.optionalChild(mod),28352 .opt_payload_ptr => payload_ptr.container_ty.optionalChild(mod),
28407 else => unreachable,28353 else => unreachable,
28408 };28354 };
...@@ -29301,7 +29247,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {...@@ -29301,7 +29247,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
29301 var anon_decl = try block.startAnonDecl();29247 var anon_decl = try block.startAnonDecl();
29302 defer anon_decl.deinit();29248 defer anon_decl.deinit();
29303 const decl = try anon_decl.finish(29249 const decl = try anon_decl.finish(
29304 try ty.copy(anon_decl.arena()),29250 ty,
29305 try val.copy(anon_decl.arena()),29251 try val.copy(anon_decl.arena()),
29306 0, // default alignment29252 0, // default alignment
29307 );29253 );
...@@ -29387,7 +29333,7 @@ fn analyzeRef(...@@ -29387,7 +29333,7 @@ fn analyzeRef(
29387 var anon_decl = try block.startAnonDecl();29333 var anon_decl = try block.startAnonDecl();
29388 defer anon_decl.deinit();29334 defer anon_decl.deinit();
29389 return sema.analyzeDeclRef(try anon_decl.finish(29335 return sema.analyzeDeclRef(try anon_decl.finish(
29390 try operand_ty.copy(anon_decl.arena()),29336 operand_ty,
29391 try val.copy(anon_decl.arena()),29337 try val.copy(anon_decl.arena()),
29392 0, // default alignment29338 0, // default alignment
29393 ));29339 ));
...@@ -29555,7 +29501,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29555,7 +29501,7 @@ fn analyzeIsNonErrComptimeOnly(
29555 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;29501 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
29556 assert(ot == .ErrorUnion);29502 assert(ot == .ErrorUnion);
2955729503
29558 const payload_ty = operand_ty.errorUnionPayload();29504 const payload_ty = operand_ty.errorUnionPayload(mod);
29559 if (payload_ty.zigTypeTag(mod) == .NoReturn) {29505 if (payload_ty.zigTypeTag(mod) == .NoReturn) {
29560 return Air.Inst.Ref.bool_false;29506 return Air.Inst.Ref.bool_false;
29561 }29507 }
...@@ -29577,23 +29523,28 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29577,23 +29523,28 @@ fn analyzeIsNonErrComptimeOnly(
2957729523
29578 // exception if the error union error set is known to be empty,29524 // exception if the error union error set is known to be empty,
29579 // we allow the comparison but always make it comptime-known.29525 // we allow the comparison but always make it comptime-known.
29580 const set_ty = operand_ty.errorUnionSet();29526 const set_ty = operand_ty.errorUnionSet(mod);
29581 switch (set_ty.ip_index) {29527 switch (set_ty.ip_index) {
29582 .none => switch (set_ty.tag()) {29528 .anyerror_type => {},
29583 .error_set_inferred => blk: {29529 else => switch (mod.intern_pool.indexToKey(set_ty.ip_index)) {
29530 .error_set_type => |error_set_type| {
29531 if (error_set_type.names.len == 0) return Air.Inst.Ref.bool_true;
29532 },
29533 .inferred_error_set_type => |ies_index| blk: {
29584 // If the error set is empty, we must return a comptime true or false.29534 // If the error set is empty, we must return a comptime true or false.
29585 // However we want to avoid unnecessarily resolving an inferred error set29535 // However we want to avoid unnecessarily resolving an inferred error set
29586 // in case it is already non-empty.29536 // in case it is already non-empty.
29587 const ies = set_ty.castTag(.error_set_inferred).?.data;29537 const ies = mod.inferredErrorSetPtr(ies_index);
29588 if (ies.is_anyerror) break :blk;29538 if (ies.is_anyerror) break :blk;
29589 if (ies.errors.count() != 0) break :blk;29539 if (ies.errors.count() != 0) break :blk;
29590 if (maybe_operand_val == null) {29540 if (maybe_operand_val == null) {
29591 // Try to avoid resolving inferred error set if possible.29541 // Try to avoid resolving inferred error set if possible.
29592 if (ies.errors.count() != 0) break :blk;29542 if (ies.errors.count() != 0) break :blk;
29593 if (ies.is_anyerror) break :blk;29543 if (ies.is_anyerror) break :blk;
29594 for (ies.inferred_error_sets.keys()) |other_ies| {29544 for (ies.inferred_error_sets.keys()) |other_ies_index| {
29595 if (ies == other_ies) continue;29545 if (ies_index == other_ies_index) continue;
29596 try sema.resolveInferredErrorSet(block, src, other_ies);29546 try sema.resolveInferredErrorSet(block, src, other_ies_index);
29547 const other_ies = mod.inferredErrorSetPtr(other_ies_index);
29597 if (other_ies.is_anyerror) {29548 if (other_ies.is_anyerror) {
29598 ies.is_anyerror = true;29549 ies.is_anyerror = true;
29599 ies.is_resolved = true;29550 ies.is_resolved = true;
...@@ -29608,18 +29559,12 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29608,18 +29559,12 @@ fn analyzeIsNonErrComptimeOnly(
29608 // so far with this type can't contain errors either.29559 // so far with this type can't contain errors either.
29609 return Air.Inst.Ref.bool_true;29560 return Air.Inst.Ref.bool_true;
29610 }29561 }
29611 try sema.resolveInferredErrorSet(block, src, ies);29562 try sema.resolveInferredErrorSet(block, src, ies_index);
29612 if (ies.is_anyerror) break :blk;29563 if (ies.is_anyerror) break :blk;
29613 if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;29564 if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
29614 }29565 }
29615 },29566 },
29616 else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true,29567 else => unreachable,
29617 },
29618
29619 .anyerror_type => {},
29620
29621 else => switch (mod.intern_pool.indexToKey(set_ty.ip_index)) {
29622 else => @panic("TODO"),
29623 },29568 },
29624 }29569 }
2962529570
...@@ -30516,7 +30461,8 @@ fn wrapErrorUnionPayload(...@@ -30516,7 +30461,8 @@ fn wrapErrorUnionPayload(
30516 inst: Air.Inst.Ref,30461 inst: Air.Inst.Ref,
30517 inst_src: LazySrcLoc,30462 inst_src: LazySrcLoc,
30518) !Air.Inst.Ref {30463) !Air.Inst.Ref {
30519 const dest_payload_ty = dest_ty.errorUnionPayload();30464 const mod = sema.mod;
30465 const dest_payload_ty = dest_ty.errorUnionPayload(mod);
30520 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });30466 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });
30521 if (try sema.resolveMaybeUndefVal(coerced)) |val| {30467 if (try sema.resolveMaybeUndefVal(coerced)) |val| {
30522 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));30468 return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
...@@ -30533,51 +30479,41 @@ fn wrapErrorUnionSet(...@@ -30533,51 +30479,41 @@ fn wrapErrorUnionSet(
30533 inst: Air.Inst.Ref,30479 inst: Air.Inst.Ref,
30534 inst_src: LazySrcLoc,30480 inst_src: LazySrcLoc,
30535) !Air.Inst.Ref {30481) !Air.Inst.Ref {
30482 const mod = sema.mod;
30483 const ip = &mod.intern_pool;
30536 const inst_ty = sema.typeOf(inst);30484 const inst_ty = sema.typeOf(inst);
30537 const dest_err_set_ty = dest_ty.errorUnionSet();30485 const dest_err_set_ty = dest_ty.errorUnionSet(mod);
30538 if (try sema.resolveMaybeUndefVal(inst)) |val| {30486 if (try sema.resolveMaybeUndefVal(inst)) |val| {
30539 switch (dest_err_set_ty.ip_index) {30487 switch (dest_err_set_ty.ip_index) {
30540 .anyerror_type => {},30488 .anyerror_type => {},
3054130489 else => switch (ip.indexToKey(dest_err_set_ty.ip_index)) {
30542 .none => switch (dest_err_set_ty.tag()) {30490 .error_set_type => |error_set_type| ok: {
30543 .error_set_single => ok: {
30544 const expected_name = val.castTag(.@"error").?.data.name;
30545 const n = dest_err_set_ty.castTag(.error_set_single).?.data;
30546 if (mem.eql(u8, expected_name, n)) break :ok;
30547 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30548 },
30549 .error_set => {
30550 const expected_name = val.castTag(.@"error").?.data.name;30491 const expected_name = val.castTag(.@"error").?.data.name;
30551 const error_set = dest_err_set_ty.castTag(.error_set).?.data;30492 if (ip.getString(expected_name).unwrap()) |expected_name_interned| {
30552 if (!error_set.names.contains(expected_name)) {30493 if (error_set_type.nameIndex(ip, expected_name_interned) != null)
30553 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);30494 break :ok;
30554 }30495 }
30496 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30555 },30497 },
30556 .error_set_inferred => ok: {30498 .inferred_error_set_type => |ies_index| ok: {
30499 const ies = mod.inferredErrorSetPtr(ies_index);
30557 const expected_name = val.castTag(.@"error").?.data.name;30500 const expected_name = val.castTag(.@"error").?.data.name;
30558 const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data;
3055930501
30560 // We carefully do this in an order that avoids unnecessarily30502 // We carefully do this in an order that avoids unnecessarily
30561 // resolving the destination error set type.30503 // resolving the destination error set type.
30562 if (ies.is_anyerror) break :ok;30504 if (ies.is_anyerror) break :ok;
30563 if (ies.errors.contains(expected_name)) break :ok;30505
30506 if (ip.getString(expected_name).unwrap()) |expected_name_interned| {
30507 if (ies.errors.contains(expected_name_interned)) break :ok;
30508 }
30564 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {30509 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
30565 break :ok;30510 break :ok;
30566 }30511 }
3056730512
30568 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);30513 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30569 },30514 },
30570 .error_set_merged => {
30571 const expected_name = val.castTag(.@"error").?.data.name;
30572 const error_set = dest_err_set_ty.castTag(.error_set_merged).?.data;
30573 if (!error_set.contains(expected_name)) {
30574 return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
30575 }
30576 },
30577 else => unreachable,30515 else => unreachable,
30578 },30516 },
30579
30580 else => @panic("TODO"),
30581 }30517 }
30582 return sema.addConstant(dest_ty, val);30518 return sema.addConstant(dest_ty, val);
30583 }30519 }
...@@ -30743,11 +30679,11 @@ fn resolvePeerTypes(...@@ -30743,11 +30679,11 @@ fn resolvePeerTypes(
30743 continue;30679 continue;
30744 }30680 }
3074530681
30746 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);30682 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_ty);
30747 continue;30683 continue;
30748 },30684 },
30749 .ErrorUnion => {30685 .ErrorUnion => {
30750 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet();30686 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(mod);
3075130687
30752 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_ty, src, src)) {30688 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_ty, src, src)) {
30753 continue;30689 continue;
...@@ -30757,7 +30693,7 @@ fn resolvePeerTypes(...@@ -30757,7 +30693,7 @@ fn resolvePeerTypes(
30757 continue;30693 continue;
30758 }30694 }
3075930695
30760 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);30696 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_ty);
30761 continue;30697 continue;
30762 },30698 },
30763 else => {30699 else => {
...@@ -30770,7 +30706,7 @@ fn resolvePeerTypes(...@@ -30770,7 +30706,7 @@ fn resolvePeerTypes(
30770 continue;30706 continue;
30771 }30707 }
3077230708
30773 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty);30709 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_ty);
30774 continue;30710 continue;
30775 } else {30711 } else {
30776 err_set_ty = candidate_ty;30712 err_set_ty = candidate_ty;
...@@ -30781,14 +30717,14 @@ fn resolvePeerTypes(...@@ -30781,14 +30717,14 @@ fn resolvePeerTypes(
30781 .ErrorUnion => switch (chosen_ty_tag) {30717 .ErrorUnion => switch (chosen_ty_tag) {
30782 .ErrorSet => {30718 .ErrorSet => {
30783 const chosen_set_ty = err_set_ty orelse chosen_ty;30719 const chosen_set_ty = err_set_ty orelse chosen_ty;
30784 const candidate_set_ty = candidate_ty.errorUnionSet();30720 const candidate_set_ty = candidate_ty.errorUnionSet(mod);
3078530721
30786 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {30722 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {
30787 err_set_ty = chosen_set_ty;30723 err_set_ty = chosen_set_ty;
30788 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {30724 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {
30789 err_set_ty = null;30725 err_set_ty = null;
30790 } else {30726 } else {
30791 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);30727 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_set_ty);
30792 }30728 }
30793 chosen = candidate;30729 chosen = candidate;
30794 chosen_i = candidate_i + 1;30730 chosen_i = candidate_i + 1;
...@@ -30796,8 +30732,8 @@ fn resolvePeerTypes(...@@ -30796,8 +30732,8 @@ fn resolvePeerTypes(
30796 },30732 },
3079730733
30798 .ErrorUnion => {30734 .ErrorUnion => {
30799 const chosen_payload_ty = chosen_ty.errorUnionPayload();30735 const chosen_payload_ty = chosen_ty.errorUnionPayload(mod);
30800 const candidate_payload_ty = candidate_ty.errorUnionPayload();30736 const candidate_payload_ty = candidate_ty.errorUnionPayload(mod);
3080130737
30802 const coerce_chosen = (try sema.coerceInMemoryAllowed(block, chosen_payload_ty, candidate_payload_ty, false, target, src, src)) == .ok;30738 const coerce_chosen = (try sema.coerceInMemoryAllowed(block, chosen_payload_ty, candidate_payload_ty, false, target, src, src)) == .ok;
30803 const coerce_candidate = (try sema.coerceInMemoryAllowed(block, candidate_payload_ty, chosen_payload_ty, false, target, src, src)) == .ok;30739 const coerce_candidate = (try sema.coerceInMemoryAllowed(block, candidate_payload_ty, chosen_payload_ty, false, target, src, src)) == .ok;
...@@ -30811,15 +30747,15 @@ fn resolvePeerTypes(...@@ -30811,15 +30747,15 @@ fn resolvePeerTypes(
30811 chosen_i = candidate_i + 1;30747 chosen_i = candidate_i + 1;
30812 }30748 }
3081330749
30814 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet();30750 const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(mod);
30815 const candidate_set_ty = candidate_ty.errorUnionSet();30751 const candidate_set_ty = candidate_ty.errorUnionSet(mod);
3081630752
30817 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {30753 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {
30818 err_set_ty = chosen_set_ty;30754 err_set_ty = chosen_set_ty;
30819 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {30755 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {
30820 err_set_ty = candidate_set_ty;30756 err_set_ty = candidate_set_ty;
30821 } else {30757 } else {
30822 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);30758 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_set_ty);
30823 }30759 }
30824 continue;30760 continue;
30825 }30761 }
...@@ -30827,13 +30763,13 @@ fn resolvePeerTypes(...@@ -30827,13 +30763,13 @@ fn resolvePeerTypes(
3082730763
30828 else => {30764 else => {
30829 if (err_set_ty) |chosen_set_ty| {30765 if (err_set_ty) |chosen_set_ty| {
30830 const candidate_set_ty = candidate_ty.errorUnionSet();30766 const candidate_set_ty = candidate_ty.errorUnionSet(mod);
30831 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {30767 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) {
30832 err_set_ty = chosen_set_ty;30768 err_set_ty = chosen_set_ty;
30833 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {30769 } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, candidate_set_ty, chosen_set_ty, src, src)) {
30834 err_set_ty = null;30770 err_set_ty = null;
30835 } else {30771 } else {
30836 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);30772 err_set_ty = try sema.errorSetMerge(chosen_set_ty, candidate_set_ty);
30837 }30773 }
30838 }30774 }
30839 seen_const = seen_const or chosen_ty.isConstPtr(mod);30775 seen_const = seen_const or chosen_ty.isConstPtr(mod);
...@@ -30963,7 +30899,7 @@ fn resolvePeerTypes(...@@ -30963,7 +30899,7 @@ fn resolvePeerTypes(
30963 }30899 }
30964 },30900 },
30965 .ErrorUnion => {30901 .ErrorUnion => {
30966 const chosen_ptr_ty = chosen_ty.errorUnionPayload();30902 const chosen_ptr_ty = chosen_ty.errorUnionPayload(mod);
30967 if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) {30903 if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) {
30968 const chosen_info = chosen_ptr_ty.ptrInfo(mod);30904 const chosen_info = chosen_ptr_ty.ptrInfo(mod);
3096930905
...@@ -31073,7 +31009,7 @@ fn resolvePeerTypes(...@@ -31073,7 +31009,7 @@ fn resolvePeerTypes(
31073 }31009 }
31074 },31010 },
31075 .ErrorUnion => {31011 .ErrorUnion => {
31076 const payload_ty = chosen_ty.errorUnionPayload();31012 const payload_ty = chosen_ty.errorUnionPayload(mod);
31077 if ((try sema.coerceInMemoryAllowed(block, payload_ty, candidate_ty, false, target, src, src)) == .ok) {31013 if ((try sema.coerceInMemoryAllowed(block, payload_ty, candidate_ty, false, target, src, src)) == .ok) {
31078 continue;31014 continue;
31079 }31015 }
...@@ -31090,7 +31026,7 @@ fn resolvePeerTypes(...@@ -31090,7 +31026,7 @@ fn resolvePeerTypes(
31090 continue;31026 continue;
31091 }31027 }
3109231028
31093 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, chosen_ty);31029 err_set_ty = try sema.errorSetMerge(chosen_set_ty, chosen_ty);
31094 continue;31030 continue;
31095 } else {31031 } else {
31096 err_set_ty = chosen_ty;31032 err_set_ty = chosen_ty;
...@@ -31148,14 +31084,14 @@ fn resolvePeerTypes(...@@ -31148,14 +31084,14 @@ fn resolvePeerTypes(
31148 else31084 else
31149 new_ptr_ty;31085 new_ptr_ty;
31150 const set_ty = err_set_ty orelse return opt_ptr_ty;31086 const set_ty = err_set_ty orelse return opt_ptr_ty;
31151 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);31087 return try mod.errorUnionType(set_ty, opt_ptr_ty);
31152 }31088 }
3115331089
31154 if (seen_const) {31090 if (seen_const) {
31155 // turn []T => []const T31091 // turn []T => []const T
31156 switch (chosen_ty.zigTypeTag(mod)) {31092 switch (chosen_ty.zigTypeTag(mod)) {
31157 .ErrorUnion => {31093 .ErrorUnion => {
31158 const ptr_ty = chosen_ty.errorUnionPayload();31094 const ptr_ty = chosen_ty.errorUnionPayload(mod);
31159 var info = ptr_ty.ptrInfo(mod);31095 var info = ptr_ty.ptrInfo(mod);
31160 info.mutable = false;31096 info.mutable = false;
31161 const new_ptr_ty = try Type.ptr(sema.arena, mod, info);31097 const new_ptr_ty = try Type.ptr(sema.arena, mod, info);
...@@ -31163,8 +31099,8 @@ fn resolvePeerTypes(...@@ -31163,8 +31099,8 @@ fn resolvePeerTypes(
31163 try Type.optional(sema.arena, new_ptr_ty, mod)31099 try Type.optional(sema.arena, new_ptr_ty, mod)
31164 else31100 else
31165 new_ptr_ty;31101 new_ptr_ty;
31166 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();31102 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet(mod);
31167 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);31103 return try mod.errorUnionType(set_ty, opt_ptr_ty);
31168 },31104 },
31169 .Pointer => {31105 .Pointer => {
31170 var info = chosen_ty.ptrInfo(mod);31106 var info = chosen_ty.ptrInfo(mod);
...@@ -31175,7 +31111,7 @@ fn resolvePeerTypes(...@@ -31175,7 +31111,7 @@ fn resolvePeerTypes(
31175 else31111 else
31176 new_ptr_ty;31112 new_ptr_ty;
31177 const set_ty = err_set_ty orelse return opt_ptr_ty;31113 const set_ty = err_set_ty orelse return opt_ptr_ty;
31178 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod);31114 return try mod.errorUnionType(set_ty, opt_ptr_ty);
31179 },31115 },
31180 else => return chosen_ty,31116 else => return chosen_ty,
31181 }31117 }
...@@ -31187,16 +31123,16 @@ fn resolvePeerTypes(...@@ -31187,16 +31123,16 @@ fn resolvePeerTypes(
31187 else => try Type.optional(sema.arena, chosen_ty, mod),31123 else => try Type.optional(sema.arena, chosen_ty, mod),
31188 };31124 };
31189 const set_ty = err_set_ty orelse return opt_ty;31125 const set_ty = err_set_ty orelse return opt_ty;
31190 return try Type.errorUnion(sema.arena, set_ty, opt_ty, mod);31126 return try mod.errorUnionType(set_ty, opt_ty);
31191 }31127 }
3119231128
31193 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag(mod)) {31129 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag(mod)) {
31194 .ErrorSet => return ty,31130 .ErrorSet => return ty,
31195 .ErrorUnion => {31131 .ErrorUnion => {
31196 const payload_ty = chosen_ty.errorUnionPayload();31132 const payload_ty = chosen_ty.errorUnionPayload(mod);
31197 return try Type.errorUnion(sema.arena, ty, payload_ty, mod);31133 return try mod.errorUnionType(ty, payload_ty);
31198 },31134 },
31199 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, mod),31135 else => return try mod.errorUnionType(ty, chosen_ty),
31200 };31136 };
3120131137
31202 return chosen_ty;31138 return chosen_ty;
...@@ -31279,7 +31215,7 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31279,7 +31215,7 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
31279 return sema.resolveTypeLayout(payload_ty);31215 return sema.resolveTypeLayout(payload_ty);
31280 },31216 },
31281 .ErrorUnion => {31217 .ErrorUnion => {
31282 const payload_ty = ty.errorUnionPayload();31218 const payload_ty = ty.errorUnionPayload(mod);
31283 return sema.resolveTypeLayout(payload_ty);31219 return sema.resolveTypeLayout(payload_ty);
31284 },31220 },
31285 .Fn => {31221 .Fn => {
...@@ -31465,7 +31401,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31465,7 +31401,7 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31465 };31401 };
3146631402
31467 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);31403 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
31468 struct_obj.backing_int_ty = try backing_int_ty.copy(decl_arena_allocator);31404 struct_obj.backing_int_ty = backing_int_ty;
31469 try wip_captures.finalize();31405 try wip_captures.finalize();
31470 } else {31406 } else {
31471 if (fields_bit_sum > std.math.maxInt(u16)) {31407 if (fields_bit_sum > std.math.maxInt(u16)) {
...@@ -31605,18 +31541,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31605,18 +31541,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3160531541
31606 return switch (ty.ip_index) {31542 return switch (ty.ip_index) {
31607 .empty_struct_type => false,31543 .empty_struct_type => false,
31608 .none => switch (ty.tag()) {
31609 .error_set,
31610 .error_set_single,
31611 .error_set_inferred,
31612 .error_set_merged,
31613 => false,
31614
31615 .inferred_alloc_mut => unreachable,
31616 .inferred_alloc_const => unreachable,
31617
31618 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
31619 },
31620 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {31544 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
31621 .int_type => false,31545 .int_type => false,
31622 .ptr_type => |ptr_type| {31546 .ptr_type => |ptr_type| {
...@@ -31635,6 +31559,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31635,6 +31559,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31635 .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()),31559 .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()),
31636 .opt_type => |child| return sema.resolveTypeRequiresComptime(child.toType()),31560 .opt_type => |child| return sema.resolveTypeRequiresComptime(child.toType()),
31637 .error_union_type => |error_union_type| return sema.resolveTypeRequiresComptime(error_union_type.payload_type.toType()),31561 .error_union_type => |error_union_type| return sema.resolveTypeRequiresComptime(error_union_type.payload_type.toType()),
31562 .error_set_type, .inferred_error_set_type => false,
31563
31638 .func_type => true,31564 .func_type => true,
3163931565
31640 .simple_type => |t| switch (t) {31566 .simple_type => |t| switch (t) {
...@@ -31780,7 +31706,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {...@@ -31780,7 +31706,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
31780 .Optional => {31706 .Optional => {
31781 return sema.resolveTypeFully(ty.optionalChild(mod));31707 return sema.resolveTypeFully(ty.optionalChild(mod));
31782 },31708 },
31783 .ErrorUnion => return sema.resolveTypeFully(ty.errorUnionPayload()),31709 .ErrorUnion => return sema.resolveTypeFully(ty.errorUnionPayload(mod)),
31784 .Fn => {31710 .Fn => {
31785 const info = mod.typeToFunc(ty).?;31711 const info = mod.typeToFunc(ty).?;
31786 if (info.is_generic) {31712 if (info.is_generic) {
...@@ -32048,16 +31974,17 @@ fn resolveInferredErrorSet(...@@ -32048,16 +31974,17 @@ fn resolveInferredErrorSet(
32048 sema: *Sema,31974 sema: *Sema,
32049 block: *Block,31975 block: *Block,
32050 src: LazySrcLoc,31976 src: LazySrcLoc,
32051 ies: *Module.Fn.InferredErrorSet,31977 ies_index: Module.Fn.InferredErrorSet.Index,
32052) CompileError!void {31978) CompileError!void {
31979 const mod = sema.mod;
31980 const ies = mod.inferredErrorSetPtr(ies_index);
31981
32053 if (ies.is_resolved) return;31982 if (ies.is_resolved) return;
3205431983
32055 if (ies.func.state == .in_progress) {31984 if (ies.func.state == .in_progress) {
32056 return sema.fail(block, src, "unable to resolve inferred error set", .{});31985 return sema.fail(block, src, "unable to resolve inferred error set", .{});
32057 }31986 }
3205831987
32059 const mod = sema.mod;
32060
32061 // In order to ensure that all dependencies are properly added to the set, we31988 // In order to ensure that all dependencies are properly added to the set, we
32062 // need to ensure the function body is analyzed of the inferred error set.31989 // need to ensure the function body is analyzed of the inferred error set.
32063 // However, in the case of comptime/inline function calls with inferred error sets,31990 // However, in the case of comptime/inline function calls with inferred error sets,
...@@ -32072,7 +31999,7 @@ fn resolveInferredErrorSet(...@@ -32072,7 +31999,7 @@ fn resolveInferredErrorSet(
32072 // so here we can simply skip this case.31999 // so here we can simply skip this case.
32073 if (ies_func_info.return_type == .generic_poison_type) {32000 if (ies_func_info.return_type == .generic_poison_type) {
32074 assert(ies_func_info.cc == .Inline);32001 assert(ies_func_info.cc == .Inline);
32075 } else if (ies_func_info.return_type.toType().errorUnionSet().castTag(.error_set_inferred).?.data == ies) {32002 } else if (mod.typeToInferredErrorSet(ies_func_info.return_type.toType().errorUnionSet(mod)).? == ies) {
32076 if (ies_func_info.is_generic) {32003 if (ies_func_info.is_generic) {
32077 const msg = msg: {32004 const msg = msg: {
32078 const msg = try sema.errMsg(block, src, "unable to resolve inferred error set of generic function", .{});32005 const msg = try sema.errMsg(block, src, "unable to resolve inferred error set of generic function", .{});
...@@ -32090,10 +32017,11 @@ fn resolveInferredErrorSet(...@@ -32090,10 +32017,11 @@ fn resolveInferredErrorSet(
3209032017
32091 ies.is_resolved = true;32018 ies.is_resolved = true;
3209232019
32093 for (ies.inferred_error_sets.keys()) |other_ies| {32020 for (ies.inferred_error_sets.keys()) |other_ies_index| {
32094 if (ies == other_ies) continue;32021 if (ies_index == other_ies_index) continue;
32095 try sema.resolveInferredErrorSet(block, src, other_ies);32022 try sema.resolveInferredErrorSet(block, src, other_ies_index);
3209632023
32024 const other_ies = mod.inferredErrorSetPtr(other_ies_index);
32097 for (other_ies.errors.keys()) |key| {32025 for (other_ies.errors.keys()) |key| {
32098 try ies.errors.put(sema.gpa, key, {});32026 try ies.errors.put(sema.gpa, key, {});
32099 }32027 }
...@@ -32108,8 +32036,9 @@ fn resolveInferredErrorSetTy(...@@ -32108,8 +32036,9 @@ fn resolveInferredErrorSetTy(
32108 src: LazySrcLoc,32036 src: LazySrcLoc,
32109 ty: Type,32037 ty: Type,
32110) CompileError!void {32038) CompileError!void {
32111 if (ty.castTag(.error_set_inferred)) |inferred| {32039 const mod = sema.mod;
32112 try sema.resolveInferredErrorSet(block, src, inferred.data);32040 if (mod.typeToInferredErrorSetIndex(ty).unwrap()) |ies_index| {
32041 try sema.resolveInferredErrorSet(block, src, ies_index);
32113 }32042 }
32114}32043}
3211532044
...@@ -32333,7 +32262,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32333,7 +32262,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32333 }32262 }
3233432263
32335 const field = &struct_obj.fields.values()[field_i];32264 const field = &struct_obj.fields.values()[field_i];
32336 field.ty = try field_ty.copy(decl_arena_allocator);32265 field.ty = field_ty;
3233732266
32338 if (field_ty.zigTypeTag(mod) == .Opaque) {32267 if (field_ty.zigTypeTag(mod) == .Opaque) {
32339 const msg = msg: {32268 const msg = msg: {
...@@ -32809,7 +32738,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32809,7 +32738,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32809 }32738 }
3281032739
32811 gop.value_ptr.* = .{32740 gop.value_ptr.* = .{
32812 .ty = try field_ty.copy(decl_arena_allocator),32741 .ty = field_ty,
32813 .abi_align = 0,32742 .abi_align = 0,
32814 };32743 };
3281532744
...@@ -33038,13 +32967,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33038,13 +32967,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33038 .empty_struct_type => return Value.empty_struct,32967 .empty_struct_type => return Value.empty_struct,
3303932968
33040 .none => switch (ty.tag()) {32969 .none => switch (ty.tag()) {
33041 .error_set_single,
33042 .error_set,
33043 .error_set_merged,
33044 .error_union,
33045 .error_set_inferred,
33046 => return null,
33047
33048 .inferred_alloc_const => unreachable,32970 .inferred_alloc_const => unreachable,
33049 .inferred_alloc_mut => unreachable,32971 .inferred_alloc_mut => unreachable,
33050 },32972 },
...@@ -33062,6 +32984,8 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33062,6 +32984,8 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33062 .error_union_type,32984 .error_union_type,
33063 .func_type,32985 .func_type,
33064 .anyframe_type,32986 .anyframe_type,
32987 .error_set_type,
32988 .inferred_error_set_type,
33065 => null,32989 => null,
3306632990
33067 .array_type => |array_type| {32991 .array_type => |array_type| {
...@@ -33389,7 +33313,7 @@ fn analyzeComptimeAlloc(...@@ -33389,7 +33313,7 @@ fn analyzeComptimeAlloc(
33389 defer anon_decl.deinit();33313 defer anon_decl.deinit();
3339033314
33391 const decl_index = try anon_decl.finish(33315 const decl_index = try anon_decl.finish(
33392 try var_type.copy(anon_decl.arena()),33316 var_type,
33393 // There will be stores before the first load, but they may be to sub-elements or33317 // There will be stores before the first load, but they may be to sub-elements or
33394 // sub-fields. So we need to initialize with undef to allow the mechanism to expand33318 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
33395 // into fields/elements and have those overridden with stored values.33319 // into fields/elements and have those overridden with stored values.
...@@ -33600,8 +33524,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {...@@ -33600,8 +33524,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
33600 switch (ty.tag()) {33524 switch (ty.tag()) {
33601 .inferred_alloc_const => unreachable,33525 .inferred_alloc_const => unreachable,
33602 .inferred_alloc_mut => unreachable,33526 .inferred_alloc_mut => unreachable,
33603
33604 else => return null,
33605 }33527 }
33606}33528}
3360733529
...@@ -33616,18 +33538,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33616,18 +33538,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33616 return switch (ty.ip_index) {33538 return switch (ty.ip_index) {
33617 .empty_struct_type => false,33539 .empty_struct_type => false,
3361833540
33619 .none => switch (ty.tag()) {
33620 .error_set,
33621 .error_set_single,
33622 .error_set_inferred,
33623 .error_set_merged,
33624 => false,
33625
33626 .inferred_alloc_mut => unreachable,
33627 .inferred_alloc_const => unreachable,
33628
33629 .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()),
33630 },
33631 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {33541 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
33632 .int_type => return false,33542 .int_type => return false,
33633 .ptr_type => |ptr_type| {33543 .ptr_type => |ptr_type| {
...@@ -33649,6 +33559,9 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33649,6 +33559,9 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33649 .error_union_type => |error_union_type| {33559 .error_union_type => |error_union_type| {
33650 return sema.typeRequiresComptime(error_union_type.payload_type.toType());33560 return sema.typeRequiresComptime(error_union_type.payload_type.toType());
33651 },33561 },
33562
33563 .error_set_type, .inferred_error_set_type => false,
33564
33652 .func_type => true,33565 .func_type => true,
3365333566
33654 .simple_type => |t| return switch (t) {33567 .simple_type => |t| return switch (t) {
...@@ -34410,3 +34323,23 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {...@@ -34410,3 +34323,23 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
34410 .vector_index = vector_info.vector_index,34323 .vector_index = vector_info.vector_index,
34411 });34324 });
34412}34325}
34326
34327/// Merge lhs with rhs.
34328/// Asserts that lhs and rhs are both error sets and are resolved.
34329fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
34330 const mod = sema.mod;
34331 const arena = sema.arena;
34332 const lhs_names = lhs.errorSetNames(mod);
34333 const rhs_names = rhs.errorSetNames(mod);
34334 var names: Module.Fn.InferredErrorSet.NameMap = .{};
34335 try names.ensureUnusedCapacity(arena, lhs_names.len);
34336
34337 for (lhs_names) |name| {
34338 names.putAssumeCapacityNoClobber(name, {});
34339 }
34340 for (rhs_names) |name| {
34341 try names.put(arena, name, {});
34342 }
34343
34344 return mod.errorSetFromUnsortedNames(names.keys());
34345}
src/TypedValue.zig+3-3
...@@ -27,13 +27,13 @@ pub const Managed = struct {...@@ -27,13 +27,13 @@ pub const Managed = struct {
27/// Assumes arena allocation. Does a recursive copy.27/// Assumes arena allocation. Does a recursive copy.
28pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {28pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
29 return TypedValue{29 return TypedValue{
30 .ty = try self.ty.copy(arena),30 .ty = self.ty,
31 .val = try self.val.copy(arena),31 .val = try self.val.copy(arena),
32 };32 };
33}33}
3434
35pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool {35pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool {
36 if (!a.ty.eql(b.ty, mod)) return false;36 if (a.ty.ip_index != b.ty.ip_index) return false;
37 return a.val.eql(b.val, a.ty, mod);37 return a.val.eql(b.val, a.ty, mod);
38}38}
3939
...@@ -286,7 +286,7 @@ pub fn print(...@@ -286,7 +286,7 @@ pub fn print(
286 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),286 .@"error" => return writer.print("error.{s}", .{val.castTag(.@"error").?.data.name}),
287 .eu_payload => {287 .eu_payload => {
288 val = val.castTag(.eu_payload).?.data;288 val = val.castTag(.eu_payload).?.data;
289 ty = ty.errorUnionPayload();289 ty = ty.errorUnionPayload(mod);
290 },290 },
291 .opt_payload => {291 .opt_payload => {
292 val = val.castTag(.opt_payload).?.data;292 val = val.castTag(.opt_payload).?.data;
src/arch/aarch64/CodeGen.zig+9-9
...@@ -3065,8 +3065,8 @@ fn errUnionErr(...@@ -3065,8 +3065,8 @@ fn errUnionErr(
3065 maybe_inst: ?Air.Inst.Index,3065 maybe_inst: ?Air.Inst.Index,
3066) !MCValue {3066) !MCValue {
3067 const mod = self.bin_file.options.module.?;3067 const mod = self.bin_file.options.module.?;
3068 const err_ty = error_union_ty.errorUnionSet();3068 const err_ty = error_union_ty.errorUnionSet(mod);
3069 const payload_ty = error_union_ty.errorUnionPayload();3069 const payload_ty = error_union_ty.errorUnionPayload(mod);
3070 if (err_ty.errorSetIsEmpty(mod)) {3070 if (err_ty.errorSetIsEmpty(mod)) {
3071 return MCValue{ .immediate = 0 };3071 return MCValue{ .immediate = 0 };
3072 }3072 }
...@@ -3145,8 +3145,8 @@ fn errUnionPayload(...@@ -3145,8 +3145,8 @@ fn errUnionPayload(
3145 maybe_inst: ?Air.Inst.Index,3145 maybe_inst: ?Air.Inst.Index,
3146) !MCValue {3146) !MCValue {
3147 const mod = self.bin_file.options.module.?;3147 const mod = self.bin_file.options.module.?;
3148 const err_ty = error_union_ty.errorUnionSet();3148 const err_ty = error_union_ty.errorUnionSet(mod);
3149 const payload_ty = error_union_ty.errorUnionPayload();3149 const payload_ty = error_union_ty.errorUnionPayload(mod);
3150 if (err_ty.errorSetIsEmpty(mod)) {3150 if (err_ty.errorSetIsEmpty(mod)) {
3151 return try error_union_bind.resolveToMcv(self);3151 return try error_union_bind.resolveToMcv(self);
3152 }3152 }
...@@ -3305,8 +3305,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3305,8 +3305,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3305 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3305 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3306 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3306 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3307 const error_union_ty = self.air.getRefType(ty_op.ty);3307 const error_union_ty = self.air.getRefType(ty_op.ty);
3308 const error_ty = error_union_ty.errorUnionSet();3308 const error_ty = error_union_ty.errorUnionSet(mod);
3309 const payload_ty = error_union_ty.errorUnionPayload();3309 const payload_ty = error_union_ty.errorUnionPayload(mod);
3310 const operand = try self.resolveInst(ty_op.operand);3310 const operand = try self.resolveInst(ty_op.operand);
3311 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;3311 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
33123312
...@@ -3329,8 +3329,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3329,8 +3329,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3329 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3329 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3330 const mod = self.bin_file.options.module.?;3330 const mod = self.bin_file.options.module.?;
3331 const error_union_ty = self.air.getRefType(ty_op.ty);3331 const error_union_ty = self.air.getRefType(ty_op.ty);
3332 const error_ty = error_union_ty.errorUnionSet();3332 const error_ty = error_union_ty.errorUnionSet(mod);
3333 const payload_ty = error_union_ty.errorUnionPayload();3333 const payload_ty = error_union_ty.errorUnionPayload(mod);
3334 const operand = try self.resolveInst(ty_op.operand);3334 const operand = try self.resolveInst(ty_op.operand);
3335 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;3335 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
33363336
...@@ -4893,7 +4893,7 @@ fn isErr(...@@ -4893,7 +4893,7 @@ fn isErr(
4893 error_union_ty: Type,4893 error_union_ty: Type,
4894) !MCValue {4894) !MCValue {
4895 const mod = self.bin_file.options.module.?;4895 const mod = self.bin_file.options.module.?;
4896 const error_type = error_union_ty.errorUnionSet();4896 const error_type = error_union_ty.errorUnionSet(mod);
48974897
4898 if (error_type.errorSetIsEmpty(mod)) {4898 if (error_type.errorSetIsEmpty(mod)) {
4899 return MCValue{ .immediate = 0 }; // always false4899 return MCValue{ .immediate = 0 }; // always false
src/arch/arm/CodeGen.zig+9-9
...@@ -2042,8 +2042,8 @@ fn errUnionErr(...@@ -2042,8 +2042,8 @@ fn errUnionErr(
2042 maybe_inst: ?Air.Inst.Index,2042 maybe_inst: ?Air.Inst.Index,
2043) !MCValue {2043) !MCValue {
2044 const mod = self.bin_file.options.module.?;2044 const mod = self.bin_file.options.module.?;
2045 const err_ty = error_union_ty.errorUnionSet();2045 const err_ty = error_union_ty.errorUnionSet(mod);
2046 const payload_ty = error_union_ty.errorUnionPayload();2046 const payload_ty = error_union_ty.errorUnionPayload(mod);
2047 if (err_ty.errorSetIsEmpty(mod)) {2047 if (err_ty.errorSetIsEmpty(mod)) {
2048 return MCValue{ .immediate = 0 };2048 return MCValue{ .immediate = 0 };
2049 }2049 }
...@@ -2119,8 +2119,8 @@ fn errUnionPayload(...@@ -2119,8 +2119,8 @@ fn errUnionPayload(
2119 maybe_inst: ?Air.Inst.Index,2119 maybe_inst: ?Air.Inst.Index,
2120) !MCValue {2120) !MCValue {
2121 const mod = self.bin_file.options.module.?;2121 const mod = self.bin_file.options.module.?;
2122 const err_ty = error_union_ty.errorUnionSet();2122 const err_ty = error_union_ty.errorUnionSet(mod);
2123 const payload_ty = error_union_ty.errorUnionPayload();2123 const payload_ty = error_union_ty.errorUnionPayload(mod);
2124 if (err_ty.errorSetIsEmpty(mod)) {2124 if (err_ty.errorSetIsEmpty(mod)) {
2125 return try error_union_bind.resolveToMcv(self);2125 return try error_union_bind.resolveToMcv(self);
2126 }2126 }
...@@ -2232,8 +2232,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2232,8 +2232,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2232 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2232 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2233 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2233 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2234 const error_union_ty = self.air.getRefType(ty_op.ty);2234 const error_union_ty = self.air.getRefType(ty_op.ty);
2235 const error_ty = error_union_ty.errorUnionSet();2235 const error_ty = error_union_ty.errorUnionSet(mod);
2236 const payload_ty = error_union_ty.errorUnionPayload();2236 const payload_ty = error_union_ty.errorUnionPayload(mod);
2237 const operand = try self.resolveInst(ty_op.operand);2237 const operand = try self.resolveInst(ty_op.operand);
2238 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;2238 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
22392239
...@@ -2256,8 +2256,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2256,8 +2256,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2256 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2256 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2257 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2257 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2258 const error_union_ty = self.air.getRefType(ty_op.ty);2258 const error_union_ty = self.air.getRefType(ty_op.ty);
2259 const error_ty = error_union_ty.errorUnionSet();2259 const error_ty = error_union_ty.errorUnionSet(mod);
2260 const payload_ty = error_union_ty.errorUnionPayload();2260 const payload_ty = error_union_ty.errorUnionPayload(mod);
2261 const operand = try self.resolveInst(ty_op.operand);2261 const operand = try self.resolveInst(ty_op.operand);
2262 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;2262 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
22632263
...@@ -4871,7 +4871,7 @@ fn isErr(...@@ -4871,7 +4871,7 @@ fn isErr(
4871 error_union_ty: Type,4871 error_union_ty: Type,
4872) !MCValue {4872) !MCValue {
4873 const mod = self.bin_file.options.module.?;4873 const mod = self.bin_file.options.module.?;
4874 const error_type = error_union_ty.errorUnionSet();4874 const error_type = error_union_ty.errorUnionSet(mod);
48754875
4876 if (error_type.errorSetIsEmpty(mod)) {4876 if (error_type.errorSetIsEmpty(mod)) {
4877 return MCValue{ .immediate = 0 }; // always false4877 return MCValue{ .immediate = 0 }; // always false
src/arch/sparc64/CodeGen.zig+10-10
...@@ -2707,12 +2707,12 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -2707,12 +2707,12 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
2707}2707}
27082708
2709fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {2709fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2710 const mod = self.bin_file.options.module.?;
2710 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2711 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2711 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2712 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2712 const error_union_ty = self.typeOf(ty_op.operand);2713 const error_union_ty = self.typeOf(ty_op.operand);
2713 const payload_ty = error_union_ty.errorUnionPayload();2714 const payload_ty = error_union_ty.errorUnionPayload(mod);
2714 const mcv = try self.resolveInst(ty_op.operand);2715 const mcv = try self.resolveInst(ty_op.operand);
2715 const mod = self.bin_file.options.module.?;
2716 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;2716 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
27172717
2718 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});2718 return self.fail("TODO implement unwrap error union error for non-empty payloads", .{});
...@@ -2721,11 +2721,11 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2721,11 +2721,11 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2721}2721}
27222722
2723fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {2723fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2724 const mod = self.bin_file.options.module.?;
2724 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2725 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2725 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2726 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2726 const error_union_ty = self.typeOf(ty_op.operand);2727 const error_union_ty = self.typeOf(ty_op.operand);
2727 const payload_ty = error_union_ty.errorUnionPayload();2728 const payload_ty = error_union_ty.errorUnionPayload(mod);
2728 const mod = self.bin_file.options.module.?;
2729 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;2729 if (!payload_ty.hasRuntimeBits(mod)) break :result MCValue.none;
27302730
2731 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});2731 return self.fail("TODO implement unwrap error union payload for non-empty payloads", .{});
...@@ -2735,12 +2735,12 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -2735,12 +2735,12 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
27352735
2736/// E to E!T2736/// E to E!T
2737fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {2737fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2738 const mod = self.bin_file.options.module.?;
2738 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2739 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2739 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2740 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2740 const error_union_ty = self.air.getRefType(ty_op.ty);2741 const error_union_ty = self.air.getRefType(ty_op.ty);
2741 const payload_ty = error_union_ty.errorUnionPayload();2742 const payload_ty = error_union_ty.errorUnionPayload(mod);
2742 const mcv = try self.resolveInst(ty_op.operand);2743 const mcv = try self.resolveInst(ty_op.operand);
2743 const mod = self.bin_file.options.module.?;
2744 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;2744 if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
27452745
2746 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});2746 return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
...@@ -3529,8 +3529,8 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {...@@ -3529,8 +3529,8 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
3529/// Given an error union, returns the payload3529/// Given an error union, returns the payload
3530fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {3530fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
3531 const mod = self.bin_file.options.module.?;3531 const mod = self.bin_file.options.module.?;
3532 const err_ty = error_union_ty.errorUnionSet();3532 const err_ty = error_union_ty.errorUnionSet(mod);
3533 const payload_ty = error_union_ty.errorUnionPayload();3533 const payload_ty = error_union_ty.errorUnionPayload(mod);
3534 if (err_ty.errorSetIsEmpty(mod)) {3534 if (err_ty.errorSetIsEmpty(mod)) {
3535 return error_union_mcv;3535 return error_union_mcv;
3536 }3536 }
...@@ -4168,8 +4168,8 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {...@@ -4168,8 +4168,8 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
41684168
4169fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {4169fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
4170 const mod = self.bin_file.options.module.?;4170 const mod = self.bin_file.options.module.?;
4171 const error_type = ty.errorUnionSet();4171 const error_type = ty.errorUnionSet(mod);
4172 const payload_type = ty.errorUnionPayload();4172 const payload_type = ty.errorUnionPayload(mod);
41734173
4174 if (!error_type.hasRuntimeBits(mod)) {4174 if (!error_type.hasRuntimeBits(mod)) {
4175 return MCValue{ .immediate = 0 }; // always false4175 return MCValue{ .immediate = 0 }; // always false
src/arch/wasm/CodeGen.zig+21-20
...@@ -1264,7 +1264,7 @@ fn genFunc(func: *CodeGen) InnerError!void {...@@ -1264,7 +1264,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
1264 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {1264 if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
1265 const inst = @intCast(u32, func.air.instructions.len - 1);1265 const inst = @intCast(u32, func.air.instructions.len - 1);
1266 const last_inst_ty = func.typeOfIndex(inst);1266 const last_inst_ty = func.typeOfIndex(inst);
1267 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn()) {1267 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn(mod)) {
1268 try func.addTag(.@"unreachable");1268 try func.addTag(.@"unreachable");
1269 }1269 }
1270 }1270 }
...@@ -1757,7 +1757,7 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -1757,7 +1757,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
1757 .Int => return ty.intInfo(mod).bits > 64,1757 .Int => return ty.intInfo(mod).bits > 64,
1758 .Float => return ty.floatBits(target) > 64,1758 .Float => return ty.floatBits(target) > 64,
1759 .ErrorUnion => {1759 .ErrorUnion => {
1760 const pl_ty = ty.errorUnionPayload();1760 const pl_ty = ty.errorUnionPayload(mod);
1761 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {1761 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1762 return false;1762 return false;
1763 }1763 }
...@@ -2256,7 +2256,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2256,7 +2256,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2256 const result_value = result_value: {2256 const result_value = result_value: {
2257 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {2257 if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
2258 break :result_value WValue{ .none = {} };2258 break :result_value WValue{ .none = {} };
2259 } else if (ret_ty.isNoReturn()) {2259 } else if (ret_ty.isNoReturn(mod)) {
2260 try func.addTag(.@"unreachable");2260 try func.addTag(.@"unreachable");
2261 break :result_value WValue{ .none = {} };2261 break :result_value WValue{ .none = {} };
2262 } else if (first_param_sret) {2262 } else if (first_param_sret) {
...@@ -2346,7 +2346,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2346,7 +2346,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2346 const abi_size = ty.abiSize(mod);2346 const abi_size = ty.abiSize(mod);
2347 switch (ty.zigTypeTag(mod)) {2347 switch (ty.zigTypeTag(mod)) {
2348 .ErrorUnion => {2348 .ErrorUnion => {
2349 const pl_ty = ty.errorUnionPayload();2349 const pl_ty = ty.errorUnionPayload(mod);
2350 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {2350 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2351 return func.store(lhs, rhs, Type.anyerror, 0);2351 return func.store(lhs, rhs, Type.anyerror, 0);
2352 }2352 }
...@@ -3111,8 +3111,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3111,8 +3111,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3111 else => return WValue{ .imm32 = 0 },3111 else => return WValue{ .imm32 = 0 },
3112 },3112 },
3113 .ErrorUnion => {3113 .ErrorUnion => {
3114 const error_type = ty.errorUnionSet();3114 const error_type = ty.errorUnionSet(mod);
3115 const payload_type = ty.errorUnionPayload();3115 const payload_type = ty.errorUnionPayload(mod);
3116 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3116 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3117 // We use the error type directly as the type.3117 // We use the error type directly as the type.
3118 const is_pl = val.errorUnionIsPayload();3118 const is_pl = val.errorUnionIsPayload();
...@@ -3916,10 +3916,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro...@@ -3916,10 +3916,10 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
3916 const un_op = func.air.instructions.items(.data)[inst].un_op;3916 const un_op = func.air.instructions.items(.data)[inst].un_op;
3917 const operand = try func.resolveInst(un_op);3917 const operand = try func.resolveInst(un_op);
3918 const err_union_ty = func.typeOf(un_op);3918 const err_union_ty = func.typeOf(un_op);
3919 const pl_ty = err_union_ty.errorUnionPayload();3919 const pl_ty = err_union_ty.errorUnionPayload(mod);
39203920
3921 const result = result: {3921 const result = result: {
3922 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {3922 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
3923 switch (opcode) {3923 switch (opcode) {
3924 .i32_ne => break :result WValue{ .imm32 = 0 },3924 .i32_ne => break :result WValue{ .imm32 = 0 },
3925 .i32_eq => break :result WValue{ .imm32 = 1 },3925 .i32_eq => break :result WValue{ .imm32 = 1 },
...@@ -3953,7 +3953,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -3953,7 +3953,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
3953 const operand = try func.resolveInst(ty_op.operand);3953 const operand = try func.resolveInst(ty_op.operand);
3954 const op_ty = func.typeOf(ty_op.operand);3954 const op_ty = func.typeOf(ty_op.operand);
3955 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;3955 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
3956 const payload_ty = err_ty.errorUnionPayload();3956 const payload_ty = err_ty.errorUnionPayload(mod);
39573957
3958 const result = result: {3958 const result = result: {
3959 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3959 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -3981,10 +3981,10 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -3981,10 +3981,10 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
3981 const operand = try func.resolveInst(ty_op.operand);3981 const operand = try func.resolveInst(ty_op.operand);
3982 const op_ty = func.typeOf(ty_op.operand);3982 const op_ty = func.typeOf(ty_op.operand);
3983 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;3983 const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
3984 const payload_ty = err_ty.errorUnionPayload();3984 const payload_ty = err_ty.errorUnionPayload(mod);
39853985
3986 const result = result: {3986 const result = result: {
3987 if (err_ty.errorUnionSet().errorSetIsEmpty(mod)) {3987 if (err_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
3988 break :result WValue{ .imm32 = 0 };3988 break :result WValue{ .imm32 = 0 };
3989 }3989 }
39903990
...@@ -4031,7 +4031,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4031,7 +4031,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40314031
4032 const operand = try func.resolveInst(ty_op.operand);4032 const operand = try func.resolveInst(ty_op.operand);
4033 const err_ty = func.air.getRefType(ty_op.ty);4033 const err_ty = func.air.getRefType(ty_op.ty);
4034 const pl_ty = err_ty.errorUnionPayload();4034 const pl_ty = err_ty.errorUnionPayload(mod);
40354035
4036 const result = result: {4036 const result = result: {
4037 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {4037 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -4044,7 +4044,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4044,7 +4044,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40444044
4045 // write 'undefined' to the payload4045 // write 'undefined' to the payload
4046 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, mod)), .new);4046 const payload_ptr = try func.buildPointerOffset(err_union, @intCast(u32, errUnionPayloadOffset(pl_ty, mod)), .new);
4047 const len = @intCast(u32, err_ty.errorUnionPayload().abiSize(mod));4047 const len = @intCast(u32, err_ty.errorUnionPayload(mod).abiSize(mod));
4048 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });4048 try func.memset(Type.u8, payload_ptr, .{ .imm32 = len }, .{ .imm32 = 0xaa });
40494049
4050 break :result err_union;4050 break :result err_union;
...@@ -5362,7 +5362,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi...@@ -5362,7 +5362,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
5362 const ty_op = func.air.instructions.items(.data)[inst].ty_op;5362 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
53635363
5364 const err_set_ty = func.typeOf(ty_op.operand).childType(mod);5364 const err_set_ty = func.typeOf(ty_op.operand).childType(mod);
5365 const payload_ty = err_set_ty.errorUnionPayload();5365 const payload_ty = err_set_ty.errorUnionPayload(mod);
5366 const operand = try func.resolveInst(ty_op.operand);5366 const operand = try func.resolveInst(ty_op.operand);
53675367
5368 // set error-tag to '0' to annotate error union is non-error5368 // set error-tag to '0' to annotate error union is non-error
...@@ -6177,10 +6177,10 @@ fn lowerTry(...@@ -6177,10 +6177,10 @@ fn lowerTry(
6177 return func.fail("TODO: lowerTry for pointers", .{});6177 return func.fail("TODO: lowerTry for pointers", .{});
6178 }6178 }
61796179
6180 const pl_ty = err_union_ty.errorUnionPayload();6180 const pl_ty = err_union_ty.errorUnionPayload(mod);
6181 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod);6181 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod);
61826182
6183 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {6183 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6184 // Block we can jump out of when error is not set6184 // Block we can jump out of when error is not set
6185 try func.startBlock(.block, wasm.block_empty);6185 try func.startBlock(.block, wasm.block_empty);
61866186
...@@ -6742,7 +6742,7 @@ fn callIntrinsic(...@@ -6742,7 +6742,7 @@ fn callIntrinsic(
67426742
6743 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {6743 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
6744 return WValue.none;6744 return WValue.none;
6745 } else if (return_type.isNoReturn()) {6745 } else if (return_type.isNoReturn(mod)) {
6746 try func.addTag(.@"unreachable");6746 try func.addTag(.@"unreachable");
6747 return WValue.none;6747 return WValue.none;
6748 } else if (want_sret_param) {6748 } else if (want_sret_param) {
...@@ -6941,20 +6941,21 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6941,20 +6941,21 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6941}6941}
69426942
6943fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {6943fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6944 const mod = func.bin_file.base.options.module.?;
6944 const ty_op = func.air.instructions.items(.data)[inst].ty_op;6945 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
69456946
6946 const operand = try func.resolveInst(ty_op.operand);6947 const operand = try func.resolveInst(ty_op.operand);
6947 const error_set_ty = func.air.getRefType(ty_op.ty);6948 const error_set_ty = func.air.getRefType(ty_op.ty);
6948 const result = try func.allocLocal(Type.bool);6949 const result = try func.allocLocal(Type.bool);
69496950
6950 const names = error_set_ty.errorSetNames();6951 const names = error_set_ty.errorSetNames(mod);
6951 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);6952 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);
6952 defer values.deinit();6953 defer values.deinit();
69536954
6954 const mod = func.bin_file.base.options.module.?;
6955 var lowest: ?u32 = null;6955 var lowest: ?u32 = null;
6956 var highest: ?u32 = null;6956 var highest: ?u32 = null;
6957 for (names) |name| {6957 for (names) |name_ip| {
6958 const name = mod.intern_pool.stringToSlice(name_ip);
6958 const err_int = mod.global_error_set.get(name).?;6959 const err_int = mod.global_error_set.get(name).?;
6959 if (lowest) |*l| {6960 if (lowest) |*l| {
6960 if (err_int < l.*) {6961 if (err_int < l.*) {
src/arch/x86_64/CodeGen.zig+14-14
...@@ -3612,8 +3612,8 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3612,8 +3612,8 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3612 const mod = self.bin_file.options.module.?;3612 const mod = self.bin_file.options.module.?;
3613 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3613 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3614 const err_union_ty = self.typeOf(ty_op.operand);3614 const err_union_ty = self.typeOf(ty_op.operand);
3615 const err_ty = err_union_ty.errorUnionSet();3615 const err_ty = err_union_ty.errorUnionSet(mod);
3616 const payload_ty = err_union_ty.errorUnionPayload();3616 const payload_ty = err_union_ty.errorUnionPayload(mod);
3617 const operand = try self.resolveInst(ty_op.operand);3617 const operand = try self.resolveInst(ty_op.operand);
36183618
3619 const result: MCValue = result: {3619 const result: MCValue = result: {
...@@ -3671,7 +3671,7 @@ fn genUnwrapErrorUnionPayloadMir(...@@ -3671,7 +3671,7 @@ fn genUnwrapErrorUnionPayloadMir(
3671 err_union: MCValue,3671 err_union: MCValue,
3672) !MCValue {3672) !MCValue {
3673 const mod = self.bin_file.options.module.?;3673 const mod = self.bin_file.options.module.?;
3674 const payload_ty = err_union_ty.errorUnionPayload();3674 const payload_ty = err_union_ty.errorUnionPayload(mod);
36753675
3676 const result: MCValue = result: {3676 const result: MCValue = result: {
3677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;3677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result .none;
...@@ -3731,8 +3731,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3731,8 +3731,8 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
3731 defer self.register_manager.unlockReg(dst_lock);3731 defer self.register_manager.unlockReg(dst_lock);
37323732
3733 const eu_ty = src_ty.childType(mod);3733 const eu_ty = src_ty.childType(mod);
3734 const pl_ty = eu_ty.errorUnionPayload();3734 const pl_ty = eu_ty.errorUnionPayload(mod);
3735 const err_ty = eu_ty.errorUnionSet();3735 const err_ty = eu_ty.errorUnionSet(mod);
3736 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));3736 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3737 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));3737 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
3738 try self.asmRegisterMemory(3738 try self.asmRegisterMemory(
...@@ -3771,7 +3771,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3771,7 +3771,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
3771 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);3771 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
37723772
3773 const eu_ty = src_ty.childType(mod);3773 const eu_ty = src_ty.childType(mod);
3774 const pl_ty = eu_ty.errorUnionPayload();3774 const pl_ty = eu_ty.errorUnionPayload(mod);
3775 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));3775 const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod));
3776 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));3776 const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod));
3777 try self.asmRegisterMemory(3777 try self.asmRegisterMemory(
...@@ -3797,8 +3797,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3797,8 +3797,8 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3797 defer self.register_manager.unlockReg(src_lock);3797 defer self.register_manager.unlockReg(src_lock);
37983798
3799 const eu_ty = src_ty.childType(mod);3799 const eu_ty = src_ty.childType(mod);
3800 const pl_ty = eu_ty.errorUnionPayload();3800 const pl_ty = eu_ty.errorUnionPayload(mod);
3801 const err_ty = eu_ty.errorUnionSet();3801 const err_ty = eu_ty.errorUnionSet(mod);
3802 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));3802 const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod));
3803 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));3803 const err_abi_size = @intCast(u32, err_ty.abiSize(mod));
3804 try self.asmMemoryImmediate(3804 try self.asmMemoryImmediate(
...@@ -3901,8 +3901,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {...@@ -3901,8 +3901,8 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3901 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3901 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39023902
3903 const eu_ty = self.air.getRefType(ty_op.ty);3903 const eu_ty = self.air.getRefType(ty_op.ty);
3904 const pl_ty = eu_ty.errorUnionPayload();3904 const pl_ty = eu_ty.errorUnionPayload(mod);
3905 const err_ty = eu_ty.errorUnionSet();3905 const err_ty = eu_ty.errorUnionSet(mod);
3906 const operand = try self.resolveInst(ty_op.operand);3906 const operand = try self.resolveInst(ty_op.operand);
39073907
3908 const result: MCValue = result: {3908 const result: MCValue = result: {
...@@ -3924,8 +3924,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3924,8 +3924,8 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
3924 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3924 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
39253925
3926 const eu_ty = self.air.getRefType(ty_op.ty);3926 const eu_ty = self.air.getRefType(ty_op.ty);
3927 const pl_ty = eu_ty.errorUnionPayload();3927 const pl_ty = eu_ty.errorUnionPayload(mod);
3928 const err_ty = eu_ty.errorUnionSet();3928 const err_ty = eu_ty.errorUnionSet(mod);
39293929
3930 const result: MCValue = result: {3930 const result: MCValue = result: {
3931 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);3931 if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result try self.resolveInst(ty_op.operand);
...@@ -8782,7 +8782,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -8782,7 +8782,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87828782
8783fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {8783fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue {
8784 const mod = self.bin_file.options.module.?;8784 const mod = self.bin_file.options.module.?;
8785 const err_type = ty.errorUnionSet();8785 const err_type = ty.errorUnionSet(mod);
87868786
8787 if (err_type.errorSetIsEmpty(mod)) {8787 if (err_type.errorSetIsEmpty(mod)) {
8788 return MCValue{ .immediate = 0 }; // always false8788 return MCValue{ .immediate = 0 }; // always false
...@@ -8793,7 +8793,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !...@@ -8793,7 +8793,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
8793 self.eflags_inst = inst;8793 self.eflags_inst = inst;
8794 }8794 }
87958795
8796 const err_off = errUnionErrorOffset(ty.errorUnionPayload(), mod);8796 const err_off = errUnionErrorOffset(ty.errorUnionPayload(mod), mod);
8797 switch (operand) {8797 switch (operand) {
8798 .register => |reg| {8798 .register => |reg| {
8799 const eu_lock = self.register_manager.lockReg(reg);8799 const eu_lock = self.register_manager.lockReg(reg);
src/codegen.zig+6-6
...@@ -139,7 +139,7 @@ pub fn generateLazySymbol(...@@ -139,7 +139,7 @@ pub fn generateLazySymbol(
139 return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);139 return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);
140 }140 }
141141
142 if (lazy_sym.ty.isAnyError()) {142 if (lazy_sym.ty.isAnyError(mod)) {
143 alignment.* = 4;143 alignment.* = 4;
144 const err_names = mod.error_name_list.items;144 const err_names = mod.error_name_list.items;
145 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);145 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
...@@ -670,8 +670,8 @@ pub fn generateSymbol(...@@ -670,8 +670,8 @@ pub fn generateSymbol(
670 return Result.ok;670 return Result.ok;
671 },671 },
672 .ErrorUnion => {672 .ErrorUnion => {
673 const error_ty = typed_value.ty.errorUnionSet();673 const error_ty = typed_value.ty.errorUnionSet(mod);
674 const payload_ty = typed_value.ty.errorUnionPayload();674 const payload_ty = typed_value.ty.errorUnionPayload(mod);
675 const is_payload = typed_value.val.errorUnionIsPayload();675 const is_payload = typed_value.val.errorUnionIsPayload();
676676
677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {677 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -894,7 +894,7 @@ fn lowerParentPtr(...@@ -894,7 +894,7 @@ fn lowerParentPtr(
894 },894 },
895 .eu_payload_ptr => {895 .eu_payload_ptr => {
896 const eu_payload_ptr = parent_ptr.castTag(.eu_payload_ptr).?.data;896 const eu_payload_ptr = parent_ptr.castTag(.eu_payload_ptr).?.data;
897 const pl_ty = eu_payload_ptr.container_ty.errorUnionPayload();897 const pl_ty = eu_payload_ptr.container_ty.errorUnionPayload(mod);
898 return lowerParentPtr(898 return lowerParentPtr(
899 bin_file,899 bin_file,
900 src_loc,900 src_loc,
...@@ -1249,8 +1249,8 @@ pub fn genTypedValue(...@@ -1249,8 +1249,8 @@ pub fn genTypedValue(
1249 }1249 }
1250 },1250 },
1251 .ErrorUnion => {1251 .ErrorUnion => {
1252 const error_type = typed_value.ty.errorUnionSet();1252 const error_type = typed_value.ty.errorUnionSet(mod);
1253 const payload_type = typed_value.ty.errorUnionPayload();1253 const payload_type = typed_value.ty.errorUnionPayload(mod);
1254 const is_pl = typed_value.val.errorUnionIsPayload();1254 const is_pl = typed_value.val.errorUnionIsPayload();
12551255
1256 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {1256 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
src/codegen/c.zig+20-19
...@@ -465,7 +465,7 @@ pub const Function = struct {...@@ -465,7 +465,7 @@ pub const Function = struct {
465 }),465 }),
466 },466 },
467 .data = switch (key) {467 .data = switch (key) {
468 .tag_name => .{ .tag_name = try data.tag_name.copy(arena) },468 .tag_name => .{ .tag_name = data.tag_name },
469 .never_tail => .{ .never_tail = data.never_tail },469 .never_tail => .{ .never_tail = data.never_tail },
470 .never_inline => .{ .never_inline = data.never_inline },470 .never_inline => .{ .never_inline = data.never_inline },
471 },471 },
...@@ -862,8 +862,8 @@ pub const DeclGen = struct {...@@ -862,8 +862,8 @@ pub const DeclGen = struct {
862 return writer.writeByte('}');862 return writer.writeByte('}');
863 },863 },
864 .ErrorUnion => {864 .ErrorUnion => {
865 const payload_ty = ty.errorUnionPayload();865 const payload_ty = ty.errorUnionPayload(mod);
866 const error_ty = ty.errorUnionSet();866 const error_ty = ty.errorUnionSet(mod);
867867
868 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {868 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
869 return dg.renderValue(writer, error_ty, val, location);869 return dg.renderValue(writer, error_ty, val, location);
...@@ -1252,8 +1252,8 @@ pub const DeclGen = struct {...@@ -1252,8 +1252,8 @@ pub const DeclGen = struct {
1252 }1252 }
1253 },1253 },
1254 .ErrorUnion => {1254 .ErrorUnion => {
1255 const payload_ty = ty.errorUnionPayload();1255 const payload_ty = ty.errorUnionPayload(mod);
1256 const error_ty = ty.errorUnionSet();1256 const error_ty = ty.errorUnionSet(mod);
1257 const error_val = if (val.errorUnionIsPayload()) try mod.intValue(Type.anyerror, 0) else val;1257 const error_val = if (val.errorUnionIsPayload()) try mod.intValue(Type.anyerror, 0) else val;
12581258
1259 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1259 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -4252,6 +4252,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4252,6 +4252,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4252}4252}
42534253
4254fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {4254fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4255 const mod = f.object.dg.module;
4255 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4256 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4256 const extra = f.air.extraData(Air.Block, ty_pl.payload);4257 const extra = f.air.extraData(Air.Block, ty_pl.payload);
4257 const body = f.air.extra[extra.end..][0..extra.data.body_len];4258 const body = f.air.extra[extra.end..][0..extra.data.body_len];
...@@ -4284,7 +4285,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4284,7 +4285,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4284 try f.object.indent_writer.insertNewline();4285 try f.object.indent_writer.insertNewline();
42854286
4286 // noreturn blocks have no `br` instructions reaching them, so we don't want a label4287 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
4287 if (!f.typeOfIndex(inst).isNoReturn()) {4288 if (!f.typeOfIndex(inst).isNoReturn(mod)) {
4288 // label must be followed by an expression, include an empty one.4289 // label must be followed by an expression, include an empty one.
4289 try writer.print("zig_block_{d}:;\n", .{block_id});4290 try writer.print("zig_block_{d}:;\n", .{block_id});
4290 }4291 }
...@@ -4322,10 +4323,10 @@ fn lowerTry(...@@ -4322,10 +4323,10 @@ fn lowerTry(
4322 const inst_ty = f.typeOfIndex(inst);4323 const inst_ty = f.typeOfIndex(inst);
4323 const liveness_condbr = f.liveness.getCondBr(inst);4324 const liveness_condbr = f.liveness.getCondBr(inst);
4324 const writer = f.object.writer();4325 const writer = f.object.writer();
4325 const payload_ty = err_union_ty.errorUnionPayload();4326 const payload_ty = err_union_ty.errorUnionPayload(mod);
4326 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);4327 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
43274328
4328 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {4329 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
4329 try writer.writeAll("if (");4330 try writer.writeAll("if (");
4330 if (!payload_has_bits) {4331 if (!payload_has_bits) {
4331 if (is_ptr)4332 if (is_ptr)
...@@ -5500,8 +5501,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5500,8 +5501,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
55005501
5501 const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;5502 const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer;
5502 const error_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;5503 const error_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
5503 const error_ty = error_union_ty.errorUnionSet();5504 const error_ty = error_union_ty.errorUnionSet(mod);
5504 const payload_ty = error_union_ty.errorUnionPayload();5505 const payload_ty = error_union_ty.errorUnionPayload(mod);
5505 const local = try f.allocLocal(inst, inst_ty);5506 const local = try f.allocLocal(inst, inst_ty);
55065507
5507 if (!payload_ty.hasRuntimeBits(mod) and operand == .local and operand.local == local.new_local) {5508 if (!payload_ty.hasRuntimeBits(mod) and operand == .local and operand.local == local.new_local) {
...@@ -5539,7 +5540,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -5539,7 +5540,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
5539 const error_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;5540 const error_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
55405541
5541 const writer = f.object.writer();5542 const writer = f.object.writer();
5542 if (!error_union_ty.errorUnionPayload().hasRuntimeBits(mod)) {5543 if (!error_union_ty.errorUnionPayload(mod).hasRuntimeBits(mod)) {
5543 if (!is_ptr) return .none;5544 if (!is_ptr) return .none;
55445545
5545 const local = try f.allocLocal(inst, inst_ty);5546 const local = try f.allocLocal(inst, inst_ty);
...@@ -5601,9 +5602,9 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5601,9 +5602,9 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5601 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5602 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56025603
5603 const inst_ty = f.typeOfIndex(inst);5604 const inst_ty = f.typeOfIndex(inst);
5604 const payload_ty = inst_ty.errorUnionPayload();5605 const payload_ty = inst_ty.errorUnionPayload(mod);
5605 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);5606 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5606 const err_ty = inst_ty.errorUnionSet();5607 const err_ty = inst_ty.errorUnionSet(mod);
5607 const err = try f.resolveInst(ty_op.operand);5608 const err = try f.resolveInst(ty_op.operand);
5608 try reap(f, inst, &.{ty_op.operand});5609 try reap(f, inst, &.{ty_op.operand});
56095610
...@@ -5642,8 +5643,8 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5642,8 +5643,8 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5642 const operand = try f.resolveInst(ty_op.operand);5643 const operand = try f.resolveInst(ty_op.operand);
5643 const error_union_ty = f.typeOf(ty_op.operand).childType(mod);5644 const error_union_ty = f.typeOf(ty_op.operand).childType(mod);
56445645
5645 const error_ty = error_union_ty.errorUnionSet();5646 const error_ty = error_union_ty.errorUnionSet(mod);
5646 const payload_ty = error_union_ty.errorUnionPayload();5647 const payload_ty = error_union_ty.errorUnionPayload(mod);
56475648
5648 // First, set the non-error value.5649 // First, set the non-error value.
5649 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {5650 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -5691,10 +5692,10 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5691,10 +5692,10 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5691 const ty_op = f.air.instructions.items(.data)[inst].ty_op;5692 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
56925693
5693 const inst_ty = f.typeOfIndex(inst);5694 const inst_ty = f.typeOfIndex(inst);
5694 const payload_ty = inst_ty.errorUnionPayload();5695 const payload_ty = inst_ty.errorUnionPayload(mod);
5695 const payload = try f.resolveInst(ty_op.operand);5696 const payload = try f.resolveInst(ty_op.operand);
5696 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);5697 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5697 const err_ty = inst_ty.errorUnionSet();5698 const err_ty = inst_ty.errorUnionSet(mod);
5698 try reap(f, inst, &.{ty_op.operand});5699 try reap(f, inst, &.{ty_op.operand});
56995700
5700 const writer = f.object.writer();5701 const writer = f.object.writer();
...@@ -5729,8 +5730,8 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5729,8 +5730,8 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5729 const operand_ty = f.typeOf(un_op);5730 const operand_ty = f.typeOf(un_op);
5730 const local = try f.allocLocal(inst, Type.bool);5731 const local = try f.allocLocal(inst, Type.bool);
5731 const err_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;5732 const err_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
5732 const payload_ty = err_union_ty.errorUnionPayload();5733 const payload_ty = err_union_ty.errorUnionPayload(mod);
5733 const error_ty = err_union_ty.errorUnionSet();5734 const error_ty = err_union_ty.errorUnionSet(mod);
57345735
5735 try f.writeCValue(writer, local, .Other);5736 try f.writeCValue(writer, local, .Other);
5736 try writer.writeAll(" = ");5737 try writer.writeAll(" = ");
src/codegen/c/type.zig+2-2
...@@ -1680,14 +1680,14 @@ pub const CType = extern union {...@@ -1680,14 +1680,14 @@ pub const CType = extern union {
1680 .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),1680 .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward),
1681 .payload => unreachable,1681 .payload => unreachable,
1682 }) |fwd_idx| {1682 }) |fwd_idx| {
1683 const payload_ty = ty.errorUnionPayload();1683 const payload_ty = ty.errorUnionPayload(mod);
1684 if (try lookup.typeToIndex(payload_ty, switch (kind) {1684 if (try lookup.typeToIndex(payload_ty, switch (kind) {
1685 .forward, .forward_parameter => .forward,1685 .forward, .forward_parameter => .forward,
1686 .complete, .parameter => .complete,1686 .complete, .parameter => .complete,
1687 .global => .global,1687 .global => .global,
1688 .payload => unreachable,1688 .payload => unreachable,
1689 })) |payload_idx| {1689 })) |payload_idx| {
1690 const error_ty = ty.errorUnionSet();1690 const error_ty = ty.errorUnionSet(mod);
1691 if (payload_idx == Tag.void.toIndex()) {1691 if (payload_idx == Tag.void.toIndex()) {
1692 try self.initType(error_ty, kind, lookup);1692 try self.initType(error_ty, kind, lookup);
1693 } else if (try lookup.typeToIndex(error_ty, kind)) |error_idx| {1693 } else if (try lookup.typeToIndex(error_ty, kind)) |error_idx| {
src/codegen/llvm.zig+27-47
...@@ -362,15 +362,11 @@ pub const Object = struct {...@@ -362,15 +362,11 @@ pub const Object = struct {
362 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),362 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),
363 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.363 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.
364 named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),364 named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),
365 /// Maps Zig types to LLVM types. The table memory itself is backed by the GPA of365 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
366 /// the compiler, but the Type/Value memory here is backed by `type_map_arena`.366 /// the compiler.
367 /// TODO we need to remove entries from this map in response to incremental compilation367 /// TODO when InternPool garbage collection is implemented, this map needs
368 /// but I think the frontend won't tell us about types that get deleted because368 /// to be garbage collected as well.
369 /// hasRuntimeBits() is false for types.
370 type_map: TypeMap,369 type_map: TypeMap,
371 /// The backing memory for `type_map`. Periodically garbage collected after flush().
372 /// The code for doing the periodical GC is not yet implemented.
373 type_map_arena: std.heap.ArenaAllocator,
374 di_type_map: DITypeMap,370 di_type_map: DITypeMap,
375 /// The LLVM global table which holds the names corresponding to Zig errors.371 /// The LLVM global table which holds the names corresponding to Zig errors.
376 /// Note that the values are not added until flushModule, when all errors in372 /// Note that the values are not added until flushModule, when all errors in
...@@ -381,12 +377,7 @@ pub const Object = struct {...@@ -381,12 +377,7 @@ pub const Object = struct {
381 /// name collision.377 /// name collision.
382 extern_collisions: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void),378 extern_collisions: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void),
383379
384 pub const TypeMap = std.HashMapUnmanaged(380 pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, *llvm.Type);
385 Type,
386 *llvm.Type,
387 Type.HashContext64,
388 std.hash_map.default_max_load_percentage,
389 );
390381
391 /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we382 /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we
392 /// want to iterate over it while adding entries to it.383 /// want to iterate over it while adding entries to it.
...@@ -543,7 +534,6 @@ pub const Object = struct {...@@ -543,7 +534,6 @@ pub const Object = struct {
543 .decl_map = .{},534 .decl_map = .{},
544 .named_enum_map = .{},535 .named_enum_map = .{},
545 .type_map = .{},536 .type_map = .{},
546 .type_map_arena = std.heap.ArenaAllocator.init(gpa),
547 .di_type_map = .{},537 .di_type_map = .{},
548 .error_name_table = null,538 .error_name_table = null,
549 .extern_collisions = .{},539 .extern_collisions = .{},
...@@ -563,7 +553,6 @@ pub const Object = struct {...@@ -563,7 +553,6 @@ pub const Object = struct {
563 self.decl_map.deinit(gpa);553 self.decl_map.deinit(gpa);
564 self.named_enum_map.deinit(gpa);554 self.named_enum_map.deinit(gpa);
565 self.type_map.deinit(gpa);555 self.type_map.deinit(gpa);
566 self.type_map_arena.deinit();
567 self.extern_collisions.deinit(gpa);556 self.extern_collisions.deinit(gpa);
568 self.* = undefined;557 self.* = undefined;
569 }558 }
...@@ -1462,9 +1451,6 @@ pub const Object = struct {...@@ -1462,9 +1451,6 @@ pub const Object = struct {
1462 return o.lowerDebugTypeImpl(entry, resolve, di_type);1451 return o.lowerDebugTypeImpl(entry, resolve, di_type);
1463 }1452 }
1464 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .mod = o.module }));1453 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .mod = o.module }));
1465 // The Type memory is ephemeral; since we want to store a longer-lived
1466 // reference, we need to copy it here.
1467 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
1468 const entry: Object.DITypeMap.Entry = .{1454 const entry: Object.DITypeMap.Entry = .{
1469 .key_ptr = gop.key_ptr,1455 .key_ptr = gop.key_ptr,
1470 .value_ptr = gop.value_ptr,1456 .value_ptr = gop.value_ptr,
...@@ -1868,7 +1854,7 @@ pub const Object = struct {...@@ -1868,7 +1854,7 @@ pub const Object = struct {
1868 return full_di_ty;1854 return full_di_ty;
1869 },1855 },
1870 .ErrorUnion => {1856 .ErrorUnion => {
1871 const payload_ty = ty.errorUnionPayload();1857 const payload_ty = ty.errorUnionPayload(mod);
1872 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1858 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1873 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);1859 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);
1874 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1860 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
...@@ -2823,7 +2809,7 @@ pub const DeclGen = struct {...@@ -2823,7 +2809,7 @@ pub const DeclGen = struct {
2823 .Opaque => {2809 .Opaque => {
2824 if (t.ip_index == .anyopaque_type) return dg.context.intType(8);2810 if (t.ip_index == .anyopaque_type) return dg.context.intType(8);
28252811
2826 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });2812 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
2827 if (gop.found_existing) return gop.value_ptr.*;2813 if (gop.found_existing) return gop.value_ptr.*;
28282814
2829 const opaque_type = mod.intern_pool.indexToKey(t.ip_index).opaque_type;2815 const opaque_type = mod.intern_pool.indexToKey(t.ip_index).opaque_type;
...@@ -2869,7 +2855,7 @@ pub const DeclGen = struct {...@@ -2869,7 +2855,7 @@ pub const DeclGen = struct {
2869 return dg.context.structType(&fields_buf, 3, .False);2855 return dg.context.structType(&fields_buf, 3, .False);
2870 },2856 },
2871 .ErrorUnion => {2857 .ErrorUnion => {
2872 const payload_ty = t.errorUnionPayload();2858 const payload_ty = t.errorUnionPayload(mod);
2873 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {2859 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2874 return try dg.lowerType(Type.anyerror);2860 return try dg.lowerType(Type.anyerror);
2875 }2861 }
...@@ -2913,13 +2899,9 @@ pub const DeclGen = struct {...@@ -2913,13 +2899,9 @@ pub const DeclGen = struct {
2913 },2899 },
2914 .ErrorSet => return dg.context.intType(16),2900 .ErrorSet => return dg.context.intType(16),
2915 .Struct => {2901 .Struct => {
2916 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });2902 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
2917 if (gop.found_existing) return gop.value_ptr.*;2903 if (gop.found_existing) return gop.value_ptr.*;
29182904
2919 // The Type memory is ephemeral; since we want to store a longer-lived
2920 // reference, we need to copy it here.
2921 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
2922
2923 const struct_type = switch (mod.intern_pool.indexToKey(t.ip_index)) {2905 const struct_type = switch (mod.intern_pool.indexToKey(t.ip_index)) {
2924 .anon_struct_type => |tuple| {2906 .anon_struct_type => |tuple| {
2925 const llvm_struct_ty = dg.context.structCreateNamed("");2907 const llvm_struct_ty = dg.context.structCreateNamed("");
...@@ -3041,13 +3023,9 @@ pub const DeclGen = struct {...@@ -3041,13 +3023,9 @@ pub const DeclGen = struct {
3041 return llvm_struct_ty;3023 return llvm_struct_ty;
3042 },3024 },
3043 .Union => {3025 .Union => {
3044 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = mod });3026 const gop = try dg.object.type_map.getOrPut(gpa, t.toIntern());
3045 if (gop.found_existing) return gop.value_ptr.*;3027 if (gop.found_existing) return gop.value_ptr.*;
30463028
3047 // The Type memory is ephemeral; since we want to store a longer-lived
3048 // reference, we need to copy it here.
3049 gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
3050
3051 const layout = t.unionGetLayout(mod);3029 const layout = t.unionGetLayout(mod);
3052 const union_obj = mod.typeToUnion(t).?;3030 const union_obj = mod.typeToUnion(t).?;
30533031
...@@ -3571,7 +3549,7 @@ pub const DeclGen = struct {...@@ -3571,7 +3549,7 @@ pub const DeclGen = struct {
3571 }3549 }
3572 },3550 },
3573 .ErrorUnion => {3551 .ErrorUnion => {
3574 const payload_type = tv.ty.errorUnionPayload();3552 const payload_type = tv.ty.errorUnionPayload(mod);
3575 const is_pl = tv.val.errorUnionIsPayload();3553 const is_pl = tv.val.errorUnionIsPayload();
35763554
3577 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3555 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -4130,7 +4108,7 @@ pub const DeclGen = struct {...@@ -4130,7 +4108,7 @@ pub const DeclGen = struct {
4130 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;4108 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
4131 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);4109 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true);
41324110
4133 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();4111 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(mod);
4134 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {4112 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
4135 // In this case, we represent pointer to error union the same as pointer4113 // In this case, we represent pointer to error union the same as pointer
4136 // to the payload.4114 // to the payload.
...@@ -5368,7 +5346,7 @@ pub const FuncGen = struct {...@@ -5368,7 +5346,7 @@ pub const FuncGen = struct {
5368 const inst_ty = self.typeOfIndex(inst);5346 const inst_ty = self.typeOfIndex(inst);
5369 const parent_bb = self.context.createBasicBlock("Block");5347 const parent_bb = self.context.createBasicBlock("Block");
53705348
5371 if (inst_ty.isNoReturn()) {5349 if (inst_ty.isNoReturn(mod)) {
5372 try self.genBody(body);5350 try self.genBody(body);
5373 return null;5351 return null;
5374 }5352 }
...@@ -5490,11 +5468,11 @@ pub const FuncGen = struct {...@@ -5490,11 +5468,11 @@ pub const FuncGen = struct {
5490 is_unused: bool,5468 is_unused: bool,
5491 ) !?*llvm.Value {5469 ) !?*llvm.Value {
5492 const mod = fg.dg.module;5470 const mod = fg.dg.module;
5493 const payload_ty = err_union_ty.errorUnionPayload();5471 const payload_ty = err_union_ty.errorUnionPayload(mod);
5494 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);5472 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5495 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);5473 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
54965474
5497 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {5475 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
5498 const is_err = err: {5476 const is_err = err: {
5499 const err_set_ty = try fg.dg.lowerType(Type.anyerror);5477 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
5500 const zero = err_set_ty.constNull();5478 const zero = err_set_ty.constNull();
...@@ -5601,6 +5579,7 @@ pub const FuncGen = struct {...@@ -5601,6 +5579,7 @@ pub const FuncGen = struct {
5601 }5579 }
56025580
5603 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5581 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5582 const mod = self.dg.module;
5604 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5583 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5605 const loop = self.air.extraData(Air.Block, ty_pl.payload);5584 const loop = self.air.extraData(Air.Block, ty_pl.payload);
5606 const body = self.air.extra[loop.end..][0..loop.data.body_len];5585 const body = self.air.extra[loop.end..][0..loop.data.body_len];
...@@ -5616,7 +5595,7 @@ pub const FuncGen = struct {...@@ -5616,7 +5595,7 @@ pub const FuncGen = struct {
5616 // would have been emitted already. Also the main loop in genBody can5595 // would have been emitted already. Also the main loop in genBody can
5617 // be while(true) instead of for(body), which will eliminate 1 branch on5596 // be while(true) instead of for(body), which will eliminate 1 branch on
5618 // a hot path.5597 // a hot path.
5619 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn()) {5598 if (body.len == 0 or !self.typeOfIndex(body[body.len - 1]).isNoReturn(mod)) {
5620 _ = self.builder.buildBr(loop_block);5599 _ = self.builder.buildBr(loop_block);
5621 }5600 }
5622 return null;5601 return null;
...@@ -6674,11 +6653,11 @@ pub const FuncGen = struct {...@@ -6674,11 +6653,11 @@ pub const FuncGen = struct {
6674 const operand = try self.resolveInst(un_op);6653 const operand = try self.resolveInst(un_op);
6675 const operand_ty = self.typeOf(un_op);6654 const operand_ty = self.typeOf(un_op);
6676 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;6655 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6677 const payload_ty = err_union_ty.errorUnionPayload();6656 const payload_ty = err_union_ty.errorUnionPayload(mod);
6678 const err_set_ty = try self.dg.lowerType(Type.anyerror);6657 const err_set_ty = try self.dg.lowerType(Type.anyerror);
6679 const zero = err_set_ty.constNull();6658 const zero = err_set_ty.constNull();
66806659
6681 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {6660 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6682 const llvm_i1 = self.context.intType(1);6661 const llvm_i1 = self.context.intType(1);
6683 switch (op) {6662 switch (op) {
6684 .EQ => return llvm_i1.constInt(1, .False), // 0 == 06663 .EQ => return llvm_i1.constInt(1, .False), // 0 == 0
...@@ -6825,7 +6804,7 @@ pub const FuncGen = struct {...@@ -6825,7 +6804,7 @@ pub const FuncGen = struct {
6825 const operand = try self.resolveInst(ty_op.operand);6804 const operand = try self.resolveInst(ty_op.operand);
6826 const operand_ty = self.typeOf(ty_op.operand);6805 const operand_ty = self.typeOf(ty_op.operand);
6827 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;6806 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6828 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {6807 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6829 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);6808 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
6830 if (operand_is_ptr) {6809 if (operand_is_ptr) {
6831 return operand;6810 return operand;
...@@ -6836,7 +6815,7 @@ pub const FuncGen = struct {...@@ -6836,7 +6815,7 @@ pub const FuncGen = struct {
68366815
6837 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);6816 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
68386817
6839 const payload_ty = err_union_ty.errorUnionPayload();6818 const payload_ty = err_union_ty.errorUnionPayload(mod);
6840 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6819 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6841 if (!operand_is_ptr) return operand;6820 if (!operand_is_ptr) return operand;
6842 return self.builder.buildLoad(err_set_llvm_ty, operand, "");6821 return self.builder.buildLoad(err_set_llvm_ty, operand, "");
...@@ -6859,7 +6838,7 @@ pub const FuncGen = struct {...@@ -6859,7 +6838,7 @@ pub const FuncGen = struct {
6859 const operand = try self.resolveInst(ty_op.operand);6838 const operand = try self.resolveInst(ty_op.operand);
6860 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);6839 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
68616840
6862 const payload_ty = err_union_ty.errorUnionPayload();6841 const payload_ty = err_union_ty.errorUnionPayload(mod);
6863 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) });6842 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) });
6864 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6843 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6865 _ = self.builder.buildStore(non_error_val, operand);6844 _ = self.builder.buildStore(non_error_val, operand);
...@@ -6968,7 +6947,7 @@ pub const FuncGen = struct {...@@ -6968,7 +6947,7 @@ pub const FuncGen = struct {
6968 const mod = self.dg.module;6947 const mod = self.dg.module;
6969 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6948 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6970 const err_un_ty = self.typeOfIndex(inst);6949 const err_un_ty = self.typeOfIndex(inst);
6971 const payload_ty = err_un_ty.errorUnionPayload();6950 const payload_ty = err_un_ty.errorUnionPayload(mod);
6972 const operand = try self.resolveInst(ty_op.operand);6951 const operand = try self.resolveInst(ty_op.operand);
6973 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6952 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6974 return operand;6953 return operand;
...@@ -8787,13 +8766,14 @@ pub const FuncGen = struct {...@@ -8787,13 +8766,14 @@ pub const FuncGen = struct {
8787 const operand = try self.resolveInst(ty_op.operand);8766 const operand = try self.resolveInst(ty_op.operand);
8788 const error_set_ty = self.air.getRefType(ty_op.ty);8767 const error_set_ty = self.air.getRefType(ty_op.ty);
87898768
8790 const names = error_set_ty.errorSetNames();8769 const names = error_set_ty.errorSetNames(mod);
8791 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");8770 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");
8792 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");8771 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");
8793 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");8772 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
8794 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));8773 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87958774
8796 for (names) |name| {8775 for (names) |name_ip| {
8776 const name = mod.intern_pool.stringToSlice(name_ip);
8797 const err_int = mod.global_error_set.get(name).?;8777 const err_int = mod.global_error_set.get(name).?;
8798 const this_tag_int_value = try self.dg.lowerValue(.{8778 const this_tag_int_value = try self.dg.lowerValue(.{
8799 .ty = Type.err_int,8779 .ty = Type.err_int,
...@@ -11095,7 +11075,7 @@ fn isByRef(ty: Type, mod: *Module) bool {...@@ -11095,7 +11075,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
11095 else => return ty.hasRuntimeBits(mod),11075 else => return ty.hasRuntimeBits(mod),
11096 },11076 },
11097 .ErrorUnion => {11077 .ErrorUnion => {
11098 const payload_ty = ty.errorUnionPayload();11078 const payload_ty = ty.errorUnionPayload(mod);
11099 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {11079 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
11100 return false;11080 return false;
11101 }11081 }
src/codegen/spirv.zig+7-6
...@@ -801,7 +801,7 @@ pub const DeclGen = struct {...@@ -801,7 +801,7 @@ pub const DeclGen = struct {
801 },801 },
802 },802 },
803 .ErrorUnion => {803 .ErrorUnion => {
804 const payload_ty = ty.errorUnionPayload();804 const payload_ty = ty.errorUnionPayload(mod);
805 const is_pl = val.errorUnionIsPayload();805 const is_pl = val.errorUnionIsPayload();
806 const error_val = if (!is_pl) val else try mod.intValue(Type.anyerror, 0);806 const error_val = if (!is_pl) val else try mod.intValue(Type.anyerror, 0);
807807
...@@ -1365,7 +1365,7 @@ pub const DeclGen = struct {...@@ -1365,7 +1365,7 @@ pub const DeclGen = struct {
1365 .Union => return try self.resolveUnionType(ty, null),1365 .Union => return try self.resolveUnionType(ty, null),
1366 .ErrorSet => return try self.intType(.unsigned, 16),1366 .ErrorSet => return try self.intType(.unsigned, 16),
1367 .ErrorUnion => {1367 .ErrorUnion => {
1368 const payload_ty = ty.errorUnionPayload();1368 const payload_ty = ty.errorUnionPayload(mod);
1369 const error_ty_ref = try self.resolveType(Type.anyerror, .indirect);1369 const error_ty_ref = try self.resolveType(Type.anyerror, .indirect);
13701370
1371 const eu_layout = self.errorUnionLayout(payload_ty);1371 const eu_layout = self.errorUnionLayout(payload_ty);
...@@ -2875,7 +2875,7 @@ pub const DeclGen = struct {...@@ -2875,7 +2875,7 @@ pub const DeclGen = struct {
28752875
2876 const eu_layout = self.errorUnionLayout(payload_ty);2876 const eu_layout = self.errorUnionLayout(payload_ty);
28772877
2878 if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {2878 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
2879 const err_id = if (eu_layout.payload_has_bits)2879 const err_id = if (eu_layout.payload_has_bits)
2880 try self.extractField(Type.anyerror, err_union_id, eu_layout.errorFieldIndex())2880 try self.extractField(Type.anyerror, err_union_id, eu_layout.errorFieldIndex())
2881 else2881 else
...@@ -2929,12 +2929,12 @@ pub const DeclGen = struct {...@@ -2929,12 +2929,12 @@ pub const DeclGen = struct {
2929 const err_union_ty = self.typeOf(ty_op.operand);2929 const err_union_ty = self.typeOf(ty_op.operand);
2930 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);2930 const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
29312931
2932 if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {2932 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
2933 // No error possible, so just return undefined.2933 // No error possible, so just return undefined.
2934 return try self.spv.constUndef(err_ty_ref);2934 return try self.spv.constUndef(err_ty_ref);
2935 }2935 }
29362936
2937 const payload_ty = err_union_ty.errorUnionPayload();2937 const payload_ty = err_union_ty.errorUnionPayload(mod);
2938 const eu_layout = self.errorUnionLayout(payload_ty);2938 const eu_layout = self.errorUnionLayout(payload_ty);
29392939
2940 if (!eu_layout.payload_has_bits) {2940 if (!eu_layout.payload_has_bits) {
...@@ -2948,9 +2948,10 @@ pub const DeclGen = struct {...@@ -2948,9 +2948,10 @@ pub const DeclGen = struct {
2948 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2948 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2949 if (self.liveness.isUnused(inst)) return null;2949 if (self.liveness.isUnused(inst)) return null;
29502950
2951 const mod = self.module;
2951 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2952 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2952 const err_union_ty = self.typeOfIndex(inst);2953 const err_union_ty = self.typeOfIndex(inst);
2953 const payload_ty = err_union_ty.errorUnionPayload();2954 const payload_ty = err_union_ty.errorUnionPayload(mod);
2954 const operand_id = try self.resolve(ty_op.operand);2955 const operand_id = try self.resolve(ty_op.operand);
2955 const eu_layout = self.errorUnionLayout(payload_ty);2956 const eu_layout = self.errorUnionLayout(payload_ty);
29562957
src/link/Dwarf.zig+31-23
...@@ -18,6 +18,7 @@ const LinkBlock = File.LinkBlock;...@@ -18,6 +18,7 @@ const LinkBlock = File.LinkBlock;
18const LinkFn = File.LinkFn;18const LinkFn = File.LinkFn;
19const LinkerLoad = @import("../codegen.zig").LinkerLoad;19const LinkerLoad = @import("../codegen.zig").LinkerLoad;
20const Module = @import("../Module.zig");20const Module = @import("../Module.zig");
21const InternPool = @import("../InternPool.zig");
21const StringTable = @import("strtab.zig").StringTable;22const StringTable = @import("strtab.zig").StringTable;
22const Type = @import("../type.zig").Type;23const Type = @import("../type.zig").Type;
23const Value = @import("../value.zig").Value;24const Value = @import("../value.zig").Value;
...@@ -518,9 +519,9 @@ pub const DeclState = struct {...@@ -518,9 +519,9 @@ pub const DeclState = struct {
518 );519 );
519 },520 },
520 .ErrorUnion => {521 .ErrorUnion => {
521 const error_ty = ty.errorUnionSet();522 const error_ty = ty.errorUnionSet(mod);
522 const payload_ty = ty.errorUnionPayload();523 const payload_ty = ty.errorUnionPayload(mod);
523 const payload_align = if (payload_ty.isNoReturn()) 0 else payload_ty.abiAlignment(mod);524 const payload_align = if (payload_ty.isNoReturn(mod)) 0 else payload_ty.abiAlignment(mod);
524 const error_align = Type.anyerror.abiAlignment(mod);525 const error_align = Type.anyerror.abiAlignment(mod);
525 const abi_size = ty.abiSize(mod);526 const abi_size = ty.abiSize(mod);
526 const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(mod) else 0;527 const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(mod) else 0;
...@@ -534,7 +535,7 @@ pub const DeclState = struct {...@@ -534,7 +535,7 @@ pub const DeclState = struct {
534 const name = try ty.nameAllocArena(arena, mod);535 const name = try ty.nameAllocArena(arena, mod);
535 try dbg_info_buffer.writer().print("{s}\x00", .{name});536 try dbg_info_buffer.writer().print("{s}\x00", .{name});
536537
537 if (!payload_ty.isNoReturn()) {538 if (!payload_ty.isNoReturn(mod)) {
538 // DW.AT.member539 // DW.AT.member
539 try dbg_info_buffer.ensureUnusedCapacity(7);540 try dbg_info_buffer.ensureUnusedCapacity(7);
540 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));541 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -1266,10 +1267,11 @@ pub fn commitDeclState(...@@ -1266,10 +1267,11 @@ pub fn commitDeclState(
1266 const symbol = &decl_state.abbrev_table.items[sym_index];1267 const symbol = &decl_state.abbrev_table.items[sym_index];
1267 const ty = symbol.type;1268 const ty = symbol.type;
1268 const deferred: bool = blk: {1269 const deferred: bool = blk: {
1269 if (ty.isAnyError()) break :blk true;1270 if (ty.isAnyError(mod)) break :blk true;
1270 switch (ty.tag()) {1271 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1271 .error_set_inferred => {1272 .inferred_error_set_type => |ies_index| {
1272 if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;1273 const ies = mod.inferredErrorSetPtr(ies_index);
1274 if (!ies.is_resolved) break :blk true;
1273 },1275 },
1274 else => {},1276 else => {},
1275 }1277 }
...@@ -1290,10 +1292,11 @@ pub fn commitDeclState(...@@ -1290,10 +1292,11 @@ pub fn commitDeclState(
1290 const symbol = decl_state.abbrev_table.items[target];1292 const symbol = decl_state.abbrev_table.items[target];
1291 const ty = symbol.type;1293 const ty = symbol.type;
1292 const deferred: bool = blk: {1294 const deferred: bool = blk: {
1293 if (ty.isAnyError()) break :blk true;1295 if (ty.isAnyError(mod)) break :blk true;
1294 switch (ty.tag()) {1296 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1295 .error_set_inferred => {1297 .inferred_error_set_type => |ies_index| {
1296 if (!ty.castTag(.error_set_inferred).?.data.is_resolved) break :blk true;1298 const ies = mod.inferredErrorSetPtr(ies_index);
1299 if (!ies.is_resolved) break :blk true;
1297 },1300 },
1298 else => {},1301 else => {},
1299 }1302 }
...@@ -2529,18 +2532,22 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2529,18 +2532,22 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
2529 defer arena_alloc.deinit();2532 defer arena_alloc.deinit();
2530 const arena = arena_alloc.allocator();2533 const arena = arena_alloc.allocator();
25312534
2532 const error_set = try arena.create(Module.ErrorSet);2535 // TODO: don't create a zig type for this, just make the dwarf info
2533 const error_ty = try Type.Tag.error_set.create(arena, error_set);2536 // without touching the zig type system.
2534 var names = Module.ErrorSet.NameMap{};2537 const names = try arena.alloc(InternPool.NullTerminatedString, module.global_error_set.count());
2535 try names.ensureUnusedCapacity(arena, module.global_error_set.count());2538 {
2536 var it = module.global_error_set.keyIterator();2539 var it = module.global_error_set.keyIterator();
2537 while (it.next()) |key| {2540 var i: usize = 0;
2538 names.putAssumeCapacityNoClobber(key.*, {});2541 while (it.next()) |key| : (i += 1) {
2542 names[i] = module.intern_pool.getString(key.*).unwrap().?;
2543 }
2539 }2544 }
2540 error_set.names = names;
25412545
2546 std.mem.sort(InternPool.NullTerminatedString, names, {}, InternPool.NullTerminatedString.indexLessThan);
2547
2548 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
2542 var dbg_info_buffer = std.ArrayList(u8).init(arena);2549 var dbg_info_buffer = std.ArrayList(u8).init(arena);
2543 try addDbgInfoErrorSet(arena, module, error_ty, self.target, &dbg_info_buffer);2550 try addDbgInfoErrorSet(arena, module, error_ty.toType(), self.target, &dbg_info_buffer);
25442551
2545 const di_atom_index = try self.createAtom(.di_atom);2552 const di_atom_index = try self.createAtom(.di_atom);
2546 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});2553 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
...@@ -2684,8 +2691,9 @@ fn addDbgInfoErrorSet(...@@ -2684,8 +2691,9 @@ fn addDbgInfoErrorSet(
2684 // DW.AT.const_value, DW.FORM.data82691 // DW.AT.const_value, DW.FORM.data8
2685 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);2692 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);
26862693
2687 const error_names = ty.errorSetNames();2694 const error_names = ty.errorSetNames(mod);
2688 for (error_names) |error_name| {2695 for (error_names) |error_name_ip| {
2696 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
2689 const kv = mod.getErrorValue(error_name) catch unreachable;2697 const kv = mod.getErrorValue(error_name) catch unreachable;
2690 // DW.AT.enumerator2698 // DW.AT.enumerator
2691 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));2699 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
src/print_air.zig-1
...@@ -370,7 +370,6 @@ const Writer = struct {...@@ -370,7 +370,6 @@ const Writer = struct {
370 .none => switch (ty.tag()) {370 .none => switch (ty.tag()) {
371 .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"),371 .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"),
372 .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"),372 .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"),
373 else => try ty.print(s, w.module),
374 },373 },
375 else => try ty.print(s, w.module),374 else => try ty.print(s, w.module),
376 }375 }
src/type.zig+393-866
...@@ -36,17 +36,9 @@ pub const Type = struct {...@@ -36,17 +36,9 @@ pub const Type = struct {
36 pub fn zigTypeTagOrPoison(ty: Type, mod: *const Module) error{GenericPoison}!std.builtin.TypeId {36 pub fn zigTypeTagOrPoison(ty: Type, mod: *const Module) error{GenericPoison}!std.builtin.TypeId {
37 switch (ty.ip_index) {37 switch (ty.ip_index) {
38 .none => switch (ty.tag()) {38 .none => switch (ty.tag()) {
39 .error_set,
40 .error_set_single,
41 .error_set_inferred,
42 .error_set_merged,
43 => return .ErrorSet,
44
45 .inferred_alloc_const,39 .inferred_alloc_const,
46 .inferred_alloc_mut,40 .inferred_alloc_mut,
47 => return .Pointer,41 => return .Pointer,
48
49 .error_union => return .ErrorUnion,
50 },42 },
51 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {43 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
52 .int_type => .Int,44 .int_type => .Int,
...@@ -55,6 +47,7 @@ pub const Type = struct {...@@ -55,6 +47,7 @@ pub const Type = struct {
55 .vector_type => .Vector,47 .vector_type => .Vector,
56 .opt_type => .Optional,48 .opt_type => .Optional,
57 .error_union_type => .ErrorUnion,49 .error_union_type => .ErrorUnion,
50 .error_set_type, .inferred_error_set_type => .ErrorSet,
58 .struct_type, .anon_struct_type => .Struct,51 .struct_type, .anon_struct_type => .Struct,
59 .union_type => .Union,52 .union_type => .Union,
60 .opaque_type => .Opaque,53 .opaque_type => .Opaque,
...@@ -130,9 +123,9 @@ pub const Type = struct {...@@ -130,9 +123,9 @@ pub const Type = struct {
130 }123 }
131 }124 }
132125
133 pub fn baseZigTypeTag(self: Type, mod: *const Module) std.builtin.TypeId {126 pub fn baseZigTypeTag(self: Type, mod: *Module) std.builtin.TypeId {
134 return switch (self.zigTypeTag(mod)) {127 return switch (self.zigTypeTag(mod)) {
135 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(mod),128 .ErrorUnion => self.errorUnionPayload(mod).baseZigTypeTag(mod),
136 .Optional => {129 .Optional => {
137 return self.optionalChild(mod).baseZigTypeTag(mod);130 return self.optionalChild(mod).baseZigTypeTag(mod);
138 },131 },
...@@ -294,35 +287,6 @@ pub const Type = struct {...@@ -294,35 +287,6 @@ pub const Type = struct {
294 if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true;287 if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true;
295288
296 switch (a.tag()) {289 switch (a.tag()) {
297 .error_set_inferred => {
298 // Inferred error sets are only equal if both are inferred
299 // and they share the same pointer.
300 const a_ies = a.castTag(.error_set_inferred).?.data;
301 const b_ies = (b.castTag(.error_set_inferred) orelse return false).data;
302 return a_ies == b_ies;
303 },
304
305 .error_set,
306 .error_set_single,
307 .error_set_merged,
308 => {
309 switch (b.tag()) {
310 .error_set, .error_set_single, .error_set_merged => {},
311 else => return false,
312 }
313
314 // Two resolved sets match if their error set names match.
315 // Since they are pre-sorted we compare them element-wise.
316 const a_set = a.errorSetNames();
317 const b_set = b.errorSetNames();
318 if (a_set.len != b_set.len) return false;
319 for (a_set, 0..) |a_item, i| {
320 const b_item = b_set[i];
321 if (!std.mem.eql(u8, a_item, b_item)) return false;
322 }
323 return true;
324 },
325
326 .inferred_alloc_const,290 .inferred_alloc_const,
327 .inferred_alloc_mut,291 .inferred_alloc_mut,
328 => {292 => {
...@@ -367,20 +331,6 @@ pub const Type = struct {...@@ -367,20 +331,6 @@ pub const Type = struct {
367331
368 return true;332 return true;
369 },333 },
370
371 .error_union => {
372 if (b.zigTypeTag(mod) != .ErrorUnion) return false;
373
374 const a_set = a.errorUnionSet();
375 const b_set = b.errorUnionSet();
376 if (!a_set.eql(b_set, mod)) return false;
377
378 const a_payload = a.errorUnionPayload();
379 const b_payload = b.errorUnionPayload();
380 if (!a_payload.eql(b_payload, mod)) return false;
381
382 return true;
383 },
384 }334 }
385 }335 }
386336
...@@ -399,28 +349,6 @@ pub const Type = struct {...@@ -399,28 +349,6 @@ pub const Type = struct {
399 return;349 return;
400 }350 }
401 switch (ty.tag()) {351 switch (ty.tag()) {
402 .error_set,
403 .error_set_single,
404 .error_set_merged,
405 => {
406 // all are treated like an "error set" for hashing
407 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet);
408 std.hash.autoHash(hasher, Tag.error_set);
409
410 const names = ty.errorSetNames();
411 std.hash.autoHash(hasher, names.len);
412 assert(std.sort.isSorted([]const u8, names, u8, std.mem.lessThan));
413 for (names) |name| hasher.update(name);
414 },
415
416 .error_set_inferred => {
417 // inferred error sets are compared using their data pointer
418 const ies: *Module.Fn.InferredErrorSet = ty.castTag(.error_set_inferred).?.data;
419 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet);
420 std.hash.autoHash(hasher, Tag.error_set_inferred);
421 std.hash.autoHash(hasher, ies);
422 },
423
424 .inferred_alloc_const,352 .inferred_alloc_const,
425 .inferred_alloc_mut,353 .inferred_alloc_mut,
426 => {354 => {
...@@ -439,16 +367,6 @@ pub const Type = struct {...@@ -439,16 +367,6 @@ pub const Type = struct {
439 std.hash.autoHash(hasher, info.@"volatile");367 std.hash.autoHash(hasher, info.@"volatile");
440 std.hash.autoHash(hasher, info.size);368 std.hash.autoHash(hasher, info.size);
441 },369 },
442
443 .error_union => {
444 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
445
446 const set_ty = ty.errorUnionSet();
447 hashWithHasher(set_ty, hasher, mod);
448
449 const payload_ty = ty.errorUnionPayload();
450 hashWithHasher(payload_ty, hasher, mod);
451 },
452 }370 }
453 }371 }
454372
...@@ -484,52 +402,6 @@ pub const Type = struct {...@@ -484,52 +402,6 @@ pub const Type = struct {
484 }402 }
485 };403 };
486404
487 pub fn copy(self: Type, allocator: Allocator) error{OutOfMemory}!Type {
488 if (self.ip_index != .none) {
489 return Type{ .ip_index = self.ip_index, .legacy = undefined };
490 }
491 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
492 return Type{
493 .ip_index = .none,
494 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
495 };
496 } else switch (self.legacy.ptr_otherwise.tag) {
497 .inferred_alloc_const,
498 .inferred_alloc_mut,
499 => unreachable,
500
501 .error_union => {
502 const payload = self.castTag(.error_union).?.data;
503 return Tag.error_union.create(allocator, .{
504 .error_set = try payload.error_set.copy(allocator),
505 .payload = try payload.payload.copy(allocator),
506 });
507 },
508 .error_set_merged => {
509 const names = self.castTag(.error_set_merged).?.data.keys();
510 var duped_names = Module.ErrorSet.NameMap{};
511 try duped_names.ensureTotalCapacity(allocator, names.len);
512 for (names) |name| {
513 duped_names.putAssumeCapacityNoClobber(name, {});
514 }
515 return Tag.error_set_merged.create(allocator, duped_names);
516 },
517 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
518 .error_set_inferred => return self.copyPayloadShallow(allocator, Payload.ErrorSetInferred),
519 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
520 }
521 }
522
523 fn copyPayloadShallow(self: Type, allocator: Allocator, comptime T: type) error{OutOfMemory}!Type {
524 const payload = self.cast(T).?;
525 const new_payload = try allocator.create(T);
526 new_payload.* = payload.*;
527 return Type{
528 .ip_index = .none,
529 .legacy = .{ .ptr_otherwise = &new_payload.base },
530 };
531 }
532
533 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {405 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
534 _ = ty;406 _ = ty;
535 _ = unused_fmt_string;407 _ = unused_fmt_string;
...@@ -575,62 +447,7 @@ pub const Type = struct {...@@ -575,62 +447,7 @@ pub const Type = struct {
575 ) @TypeOf(writer).Error!void {447 ) @TypeOf(writer).Error!void {
576 _ = options;448 _ = options;
577 comptime assert(unused_format_string.len == 0);449 comptime assert(unused_format_string.len == 0);
578 if (start_type.ip_index != .none) {450 return writer.print("{any}", .{start_type.ip_index});
579 return writer.print("(intern index: {d})", .{@enumToInt(start_type.ip_index)});
580 }
581 if (true) {
582 // This is disabled to work around a stage2 bug where this function recursively
583 // causes more generic function instantiations resulting in an infinite loop
584 // in the compiler.
585 try writer.writeAll("[TODO fix internal compiler bug regarding dump]");
586 return;
587 }
588 var ty = start_type;
589 while (true) {
590 const t = ty.tag();
591 switch (t) {
592 .error_union => {
593 const payload = ty.castTag(.error_union).?.data;
594 try payload.error_set.dump("", .{}, writer);
595 try writer.writeAll("!");
596 ty = payload.payload;
597 continue;
598 },
599 .error_set => {
600 const names = ty.castTag(.error_set).?.data.names.keys();
601 try writer.writeAll("error{");
602 for (names, 0..) |name, i| {
603 if (i != 0) try writer.writeByte(',');
604 try writer.writeAll(name);
605 }
606 try writer.writeAll("}");
607 return;
608 },
609 .error_set_inferred => {
610 const func = ty.castTag(.error_set_inferred).?.data.func;
611 return writer.print("({s} func={d})", .{
612 @tagName(t), func.owner_decl,
613 });
614 },
615 .error_set_merged => {
616 const names = ty.castTag(.error_set_merged).?.data.keys();
617 try writer.writeAll("error{");
618 for (names, 0..) |name, i| {
619 if (i != 0) try writer.writeByte(',');
620 try writer.writeAll(name);
621 }
622 try writer.writeAll("}");
623 return;
624 },
625 .error_set_single => {
626 const name = ty.castTag(.error_set_single).?.data;
627 return writer.print("error{{{s}}}", .{name});
628 },
629 .inferred_alloc_const => return writer.writeAll("(inferred_alloc_const)"),
630 .inferred_alloc_mut => return writer.writeAll("(inferred_alloc_mut)"),
631 }
632 unreachable;
633 }
634 }451 }
635452
636 pub const nameAllocArena = nameAlloc;453 pub const nameAllocArena = nameAlloc;
...@@ -648,45 +465,6 @@ pub const Type = struct {...@@ -648,45 +465,6 @@ pub const Type = struct {
648 .none => switch (ty.tag()) {465 .none => switch (ty.tag()) {
649 .inferred_alloc_const => unreachable,466 .inferred_alloc_const => unreachable,
650 .inferred_alloc_mut => unreachable,467 .inferred_alloc_mut => unreachable,
651
652 .error_set_inferred => {
653 const func = ty.castTag(.error_set_inferred).?.data.func;
654
655 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
656 const owner_decl = mod.declPtr(func.owner_decl);
657 try owner_decl.renderFullyQualifiedName(mod, writer);
658 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
659 },
660
661 .error_union => {
662 const error_union = ty.castTag(.error_union).?.data;
663 try print(error_union.error_set, writer, mod);
664 try writer.writeAll("!");
665 try print(error_union.payload, writer, mod);
666 },
667
668 .error_set => {
669 const names = ty.castTag(.error_set).?.data.names.keys();
670 try writer.writeAll("error{");
671 for (names, 0..) |name, i| {
672 if (i != 0) try writer.writeByte(',');
673 try writer.writeAll(name);
674 }
675 try writer.writeAll("}");
676 },
677 .error_set_single => {
678 const name = ty.castTag(.error_set_single).?.data;
679 return writer.print("error{{{s}}}", .{name});
680 },
681 .error_set_merged => {
682 const names = ty.castTag(.error_set_merged).?.data.keys();
683 try writer.writeAll("error{");
684 for (names, 0..) |name, i| {
685 if (i != 0) try writer.writeByte(',');
686 try writer.writeAll(name);
687 }
688 try writer.writeAll("}");
689 },
690 },468 },
691 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {469 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
692 .int_type => |int_type| {470 .int_type => |int_type| {
...@@ -766,6 +544,24 @@ pub const Type = struct {...@@ -766,6 +544,24 @@ pub const Type = struct {
766 try print(error_union_type.payload_type.toType(), writer, mod);544 try print(error_union_type.payload_type.toType(), writer, mod);
767 return;545 return;
768 },546 },
547 .inferred_error_set_type => |index| {
548 const ies = mod.inferredErrorSetPtr(index);
549 const func = ies.func;
550
551 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
552 const owner_decl = mod.declPtr(func.owner_decl);
553 try owner_decl.renderFullyQualifiedName(mod, writer);
554 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
555 },
556 .error_set_type => |error_set_type| {
557 const names = error_set_type.names;
558 try writer.writeAll("error{");
559 for (names, 0..) |name, i| {
560 if (i != 0) try writer.writeByte(',');
561 try writer.writeAll(mod.intern_pool.stringToSlice(name));
562 }
563 try writer.writeAll("}");
564 },
769 .simple_type => |s| return writer.writeAll(@tagName(s)),565 .simple_type => |s| return writer.writeAll(@tagName(s)),
770 .struct_type => |struct_type| {566 .struct_type => |struct_type| {
771 if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {567 if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
...@@ -881,13 +677,8 @@ pub const Type = struct {...@@ -881,13 +677,8 @@ pub const Type = struct {
881 return ty.ip_index;677 return ty.ip_index;
882 }678 }
883679
884 pub fn toValue(self: Type, allocator: Allocator) Allocator.Error!Value {680 pub fn toValue(self: Type) Value {
885 if (self.ip_index != .none) return self.ip_index.toValue();681 return self.toIntern().toValue();
886 switch (self.tag()) {
887 .inferred_alloc_const => unreachable,
888 .inferred_alloc_mut => unreachable,
889 else => return Value.Tag.ty.create(allocator, self),
890 }
891 }682 }
892683
893 const RuntimeBitsError = Module.CompileError || error{NeedLazy};684 const RuntimeBitsError = Module.CompileError || error{NeedLazy};
...@@ -914,14 +705,6 @@ pub const Type = struct {...@@ -914,14 +705,6 @@ pub const Type = struct {
914 .empty_struct_type => return false,705 .empty_struct_type => return false,
915706
916 .none => switch (ty.tag()) {707 .none => switch (ty.tag()) {
917 .error_set_inferred,
918
919 .error_set_single,
920 .error_union,
921 .error_set,
922 .error_set_merged,
923 => return true,
924
925 .inferred_alloc_const => unreachable,708 .inferred_alloc_const => unreachable,
926 .inferred_alloc_mut => unreachable,709 .inferred_alloc_mut => unreachable,
927 },710 },
...@@ -951,7 +734,7 @@ pub const Type = struct {...@@ -951,7 +734,7 @@ pub const Type = struct {
951 },734 },
952 .opt_type => |child| {735 .opt_type => |child| {
953 const child_ty = child.toType();736 const child_ty = child.toType();
954 if (child_ty.isNoReturn()) {737 if (child_ty.isNoReturn(mod)) {
955 // Then the optional is comptime-known to be null.738 // Then the optional is comptime-known to be null.
956 return false;739 return false;
957 }740 }
...@@ -963,7 +746,10 @@ pub const Type = struct {...@@ -963,7 +746,10 @@ pub const Type = struct {
963 return !comptimeOnly(child_ty, mod);746 return !comptimeOnly(child_ty, mod);
964 }747 }
965 },748 },
966 .error_union_type => @panic("TODO"),749 .error_union_type,
750 .error_set_type,
751 .inferred_error_set_type,
752 => true,
967753
968 // These are function *bodies*, not pointers.754 // These are function *bodies*, not pointers.
969 // They return false here because they are comptime-only types.755 // They return false here because they are comptime-only types.
...@@ -1103,112 +889,99 @@ pub const Type = struct {...@@ -1103,112 +889,99 @@ pub const Type = struct {
1103 /// readFrom/writeToMemory are supported only for types with a well-889 /// readFrom/writeToMemory are supported only for types with a well-
1104 /// defined memory layout890 /// defined memory layout
1105 pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {891 pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
1106 return switch (ty.ip_index) {892 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1107 .empty_struct_type => false,893 .int_type,
894 .ptr_type,
895 .vector_type,
896 => true,
1108897
1109 .none => switch (ty.tag()) {898 .error_union_type,
1110 .error_set,899 .error_set_type,
1111 .error_set_single,900 .inferred_error_set_type,
1112 .error_set_inferred,901 .anon_struct_type,
1113 .error_set_merged,902 .opaque_type,
1114 .error_union,903 .anyframe_type,
1115 => false,904 // These are function bodies, not function pointers.
905 .func_type,
906 => false,
1116907
1117 .inferred_alloc_mut => unreachable,908 .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod),
1118 .inferred_alloc_const => unreachable,909 .opt_type => ty.isPtrLikeOptional(mod),
1119 },910
1120 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {911 .simple_type => |t| switch (t) {
1121 .int_type,912 .f16,
1122 .ptr_type,913 .f32,
1123 .vector_type,914 .f64,
915 .f80,
916 .f128,
917 .usize,
918 .isize,
919 .c_char,
920 .c_short,
921 .c_ushort,
922 .c_int,
923 .c_uint,
924 .c_long,
925 .c_ulong,
926 .c_longlong,
927 .c_ulonglong,
928 .c_longdouble,
929 .bool,
930 .void,
1124 => true,931 => true,
1125932
1126 .error_union_type,933 .anyerror,
1127 .anon_struct_type,934 .anyopaque,
1128 .opaque_type,935 .atomic_order,
1129 .anyframe_type,936 .atomic_rmw_op,
1130 // These are function bodies, not function pointers.937 .calling_convention,
1131 .func_type,938 .address_space,
939 .float_mode,
940 .reduce_op,
941 .call_modifier,
942 .prefetch_options,
943 .export_options,
944 .extern_options,
945 .type,
946 .comptime_int,
947 .comptime_float,
948 .noreturn,
949 .null,
950 .undefined,
951 .enum_literal,
952 .type_info,
953 .generic_poison,
1132 => false,954 => false,
1133955
1134 .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod),956 .var_args_param => unreachable,
1135 .opt_type => ty.isPtrLikeOptional(mod),957 },
1136958 .struct_type => |struct_type| {
1137 .simple_type => |t| switch (t) {959 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
1138 .f16,960 // Struct with no fields has a well-defined layout of no bits.
1139 .f32,961 return true;
1140 .f64,962 };
1141 .f80,963 return struct_obj.layout != .Auto;
1142 .f128,964 },
1143 .usize,965 .union_type => |union_type| switch (union_type.runtime_tag) {
1144 .isize,966 .none, .safety => mod.unionPtr(union_type.index).layout != .Auto,
1145 .c_char,967 .tagged => false,
1146 .c_short,
1147 .c_ushort,
1148 .c_int,
1149 .c_uint,
1150 .c_long,
1151 .c_ulong,
1152 .c_longlong,
1153 .c_ulonglong,
1154 .c_longdouble,
1155 .bool,
1156 .void,
1157 => true,
1158
1159 .anyerror,
1160 .anyopaque,
1161 .atomic_order,
1162 .atomic_rmw_op,
1163 .calling_convention,
1164 .address_space,
1165 .float_mode,
1166 .reduce_op,
1167 .call_modifier,
1168 .prefetch_options,
1169 .export_options,
1170 .extern_options,
1171 .type,
1172 .comptime_int,
1173 .comptime_float,
1174 .noreturn,
1175 .null,
1176 .undefined,
1177 .enum_literal,
1178 .type_info,
1179 .generic_poison,
1180 => false,
1181
1182 .var_args_param => unreachable,
1183 },
1184 .struct_type => |struct_type| {
1185 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
1186 // Struct with no fields has a well-defined layout of no bits.
1187 return true;
1188 };
1189 return struct_obj.layout != .Auto;
1190 },
1191 .union_type => |union_type| switch (union_type.runtime_tag) {
1192 .none, .safety => mod.unionPtr(union_type.index).layout != .Auto,
1193 .tagged => false,
1194 },
1195 .enum_type => |enum_type| switch (enum_type.tag_mode) {
1196 .auto => false,
1197 .explicit, .nonexhaustive => true,
1198 },
1199
1200 // values, not types
1201 .undef => unreachable,
1202 .un => unreachable,
1203 .simple_value => unreachable,
1204 .extern_func => unreachable,
1205 .int => unreachable,
1206 .float => unreachable,
1207 .ptr => unreachable,
1208 .opt => unreachable,
1209 .enum_tag => unreachable,
1210 .aggregate => unreachable,
1211 },968 },
969 .enum_type => |enum_type| switch (enum_type.tag_mode) {
970 .auto => false,
971 .explicit, .nonexhaustive => true,
972 },
973
974 // values, not types
975 .undef => unreachable,
976 .un => unreachable,
977 .simple_value => unreachable,
978 .extern_func => unreachable,
979 .int => unreachable,
980 .float => unreachable,
981 .ptr => unreachable,
982 .opt => unreachable,
983 .enum_tag => unreachable,
984 .aggregate => unreachable,
1212 };985 };
1213 }986 }
1214987
...@@ -1247,35 +1020,8 @@ pub const Type = struct {...@@ -1247,35 +1020,8 @@ pub const Type = struct {
1247 };1020 };
1248 }1021 }
12491022
1250 pub fn isNoReturn(ty: Type) bool {1023 pub fn isNoReturn(ty: Type, mod: *Module) bool {
1251 switch (@enumToInt(ty.ip_index)) {1024 return mod.intern_pool.isNoReturn(ty.ip_index);
1252 @enumToInt(InternPool.Index.first_type)...@enumToInt(InternPool.Index.noreturn_type) - 1 => return false,
1253
1254 @enumToInt(InternPool.Index.noreturn_type) => return true,
1255
1256 @enumToInt(InternPool.Index.noreturn_type) + 1...@enumToInt(InternPool.Index.last_type) => return false,
1257
1258 @enumToInt(InternPool.Index.first_value)...@enumToInt(InternPool.Index.last_value) => unreachable,
1259 @enumToInt(InternPool.Index.generic_poison) => unreachable,
1260
1261 // TODO add empty error sets here
1262 // TODO add enums with no fields here
1263 else => return false,
1264
1265 @enumToInt(InternPool.Index.none) => switch (ty.tag()) {
1266 .error_set => {
1267 const err_set_obj = ty.castTag(.error_set).?.data;
1268 const names = err_set_obj.names.keys();
1269 return names.len == 0;
1270 },
1271 .error_set_merged => {
1272 const name_map = ty.castTag(.error_set_merged).?.data;
1273 const names = name_map.keys();
1274 return names.len == 0;
1275 },
1276 else => return false,
1277 },
1278 }
1279 }1025 }
12801026
1281 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.1027 /// Returns 0 if the pointer is naturally aligned and the element type is 0-bit.
...@@ -1353,21 +1099,6 @@ pub const Type = struct {...@@ -1353,21 +1099,6 @@ pub const Type = struct {
13531099
1354 switch (ty.ip_index) {1100 switch (ty.ip_index) {
1355 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },1101 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },
1356 .none => switch (ty.tag()) {
1357
1358 // TODO revisit this when we have the concept of the error tag type
1359 .error_set_inferred,
1360 .error_set_single,
1361 .error_set,
1362 .error_set_merged,
1363 => return AbiAlignmentAdvanced{ .scalar = 2 },
1364
1365 .error_union => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
1366
1367 .inferred_alloc_const,
1368 .inferred_alloc_mut,
1369 => unreachable,
1370 },
1371 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {1102 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1372 .int_type => |int_type| {1103 .int_type => |int_type| {
1373 if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 };1104 if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 };
...@@ -1388,7 +1119,11 @@ pub const Type = struct {...@@ -1388,7 +1119,11 @@ pub const Type = struct {
1388 },1119 },
13891120
1390 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),1121 .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),
1391 .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),1122 .error_union_type => |info| return abiAlignmentAdvancedErrorUnion(ty, mod, strat, info.payload_type.toType()),
1123
1124 // TODO revisit this when we have the concept of the error tag type
1125 .error_set_type, .inferred_error_set_type => return AbiAlignmentAdvanced{ .scalar = 2 },
1126
1392 // represents machine code; not a pointer1127 // represents machine code; not a pointer
1393 .func_type => |func_type| return AbiAlignmentAdvanced{1128 .func_type => |func_type| return AbiAlignmentAdvanced{
1394 .scalar = if (func_type.alignment.toByteUnitsOptional()) |a|1129 .scalar = if (func_type.alignment.toByteUnitsOptional()) |a|
...@@ -1572,14 +1307,14 @@ pub const Type = struct {...@@ -1572,14 +1307,14 @@ pub const Type = struct {
1572 ty: Type,1307 ty: Type,
1573 mod: *Module,1308 mod: *Module,
1574 strat: AbiAlignmentAdvancedStrat,1309 strat: AbiAlignmentAdvancedStrat,
1310 payload_ty: Type,
1575 ) Module.CompileError!AbiAlignmentAdvanced {1311 ) Module.CompileError!AbiAlignmentAdvanced {
1576 // This code needs to be kept in sync with the equivalent switch prong1312 // This code needs to be kept in sync with the equivalent switch prong
1577 // in abiSizeAdvanced.1313 // in abiSizeAdvanced.
1578 const data = ty.castTag(.error_union).?.data;
1579 const code_align = abiAlignment(Type.anyerror, mod);1314 const code_align = abiAlignment(Type.anyerror, mod);
1580 switch (strat) {1315 switch (strat) {
1581 .eager, .sema => {1316 .eager, .sema => {
1582 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {1317 if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1583 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },1318 error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) },
1584 else => |e| return e,1319 else => |e| return e,
1585 })) {1320 })) {
...@@ -1587,11 +1322,11 @@ pub const Type = struct {...@@ -1587,11 +1322,11 @@ pub const Type = struct {
1587 }1322 }
1588 return AbiAlignmentAdvanced{ .scalar = @max(1323 return AbiAlignmentAdvanced{ .scalar = @max(
1589 code_align,1324 code_align,
1590 (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar,1325 (try payload_ty.abiAlignmentAdvanced(mod, strat)).scalar,
1591 ) };1326 ) };
1592 },1327 },
1593 .lazy => |arena| {1328 .lazy => |arena| {
1594 switch (try data.payload.abiAlignmentAdvanced(mod, strat)) {1329 switch (try payload_ty.abiAlignmentAdvanced(mod, strat)) {
1595 .scalar => |payload_align| {1330 .scalar => |payload_align| {
1596 return AbiAlignmentAdvanced{1331 return AbiAlignmentAdvanced{
1597 .scalar = @max(code_align, payload_align),1332 .scalar = @max(code_align, payload_align),
...@@ -1728,55 +1463,6 @@ pub const Type = struct {...@@ -1728,55 +1463,6 @@ pub const Type = struct {
1728 switch (ty.ip_index) {1463 switch (ty.ip_index) {
1729 .empty_struct_type => return AbiSizeAdvanced{ .scalar = 0 },1464 .empty_struct_type => return AbiSizeAdvanced{ .scalar = 0 },
17301465
1731 .none => switch (ty.tag()) {
1732 .inferred_alloc_const => unreachable,
1733 .inferred_alloc_mut => unreachable,
1734
1735 // TODO revisit this when we have the concept of the error tag type
1736 .error_set_inferred,
1737 .error_set,
1738 .error_set_merged,
1739 .error_set_single,
1740 => return AbiSizeAdvanced{ .scalar = 2 },
1741
1742 .error_union => {
1743 // This code needs to be kept in sync with the equivalent switch prong
1744 // in abiAlignmentAdvanced.
1745 const data = ty.castTag(.error_union).?.data;
1746 const code_size = abiSize(Type.anyerror, mod);
1747 if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1748 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
1749 else => |e| return e,
1750 })) {
1751 // Same as anyerror.
1752 return AbiSizeAdvanced{ .scalar = code_size };
1753 }
1754 const code_align = abiAlignment(Type.anyerror, mod);
1755 const payload_align = abiAlignment(data.payload, mod);
1756 const payload_size = switch (try data.payload.abiSizeAdvanced(mod, strat)) {
1757 .scalar => |elem_size| elem_size,
1758 .val => switch (strat) {
1759 .sema => unreachable,
1760 .eager => unreachable,
1761 .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
1762 },
1763 };
1764
1765 var size: u64 = 0;
1766 if (code_align > payload_align) {
1767 size += code_size;
1768 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1769 size += payload_size;
1770 size = std.mem.alignForwardGeneric(u64, size, code_align);
1771 } else {
1772 size += payload_size;
1773 size = std.mem.alignForwardGeneric(u64, size, code_align);
1774 size += code_size;
1775 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1776 }
1777 return AbiSizeAdvanced{ .scalar = size };
1778 },
1779 },
1780 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {1466 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1781 .int_type => |int_type| {1467 .int_type => |int_type| {
1782 if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 };1468 if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 };
...@@ -1816,12 +1502,52 @@ pub const Type = struct {...@@ -1816,12 +1502,52 @@ pub const Type = struct {
1816 .val = try Value.Tag.lazy_size.create(strat.lazy, ty),1502 .val = try Value.Tag.lazy_size.create(strat.lazy, ty),
1817 },1503 },
1818 };1504 };
1819 const result = std.mem.alignForwardGeneric(u32, total_bytes, alignment);1505 const result = std.mem.alignForwardGeneric(u32, total_bytes, alignment);
1820 return AbiSizeAdvanced{ .scalar = result };1506 return AbiSizeAdvanced{ .scalar = result };
1821 },1507 },
1508
1509 .opt_type => return ty.abiSizeAdvancedOptional(mod, strat),
1510
1511 // TODO revisit this when we have the concept of the error tag type
1512 .error_set_type, .inferred_error_set_type => return AbiSizeAdvanced{ .scalar = 2 },
1513
1514 .error_union_type => |error_union_type| {
1515 const payload_ty = error_union_type.payload_type.toType();
1516 // This code needs to be kept in sync with the equivalent switch prong
1517 // in abiAlignmentAdvanced.
1518 const code_size = abiSize(Type.anyerror, mod);
1519 if (!(payload_ty.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) {
1520 error.NeedLazy => return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(strat.lazy, ty) },
1521 else => |e| return e,
1522 })) {
1523 // Same as anyerror.
1524 return AbiSizeAdvanced{ .scalar = code_size };
1525 }
1526 const code_align = abiAlignment(Type.anyerror, mod);
1527 const payload_align = abiAlignment(payload_ty, mod);
1528 const payload_size = switch (try payload_ty.abiSizeAdvanced(mod, strat)) {
1529 .scalar => |elem_size| elem_size,
1530 .val => switch (strat) {
1531 .sema => unreachable,
1532 .eager => unreachable,
1533 .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
1534 },
1535 };
18221536
1823 .opt_type => return ty.abiSizeAdvancedOptional(mod, strat),1537 var size: u64 = 0;
1824 .error_union_type => @panic("TODO"),1538 if (code_align > payload_align) {
1539 size += code_size;
1540 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1541 size += payload_size;
1542 size = std.mem.alignForwardGeneric(u64, size, code_align);
1543 } else {
1544 size += payload_size;
1545 size = std.mem.alignForwardGeneric(u64, size, code_align);
1546 size += code_size;
1547 size = std.mem.alignForwardGeneric(u64, size, payload_align);
1548 }
1549 return AbiSizeAdvanced{ .scalar = size };
1550 },
1825 .func_type => unreachable, // represents machine code; not a pointer1551 .func_type => unreachable, // represents machine code; not a pointer
1826 .simple_type => |t| switch (t) {1552 .simple_type => |t| switch (t) {
1827 .bool,1553 .bool,
...@@ -1982,7 +1708,7 @@ pub const Type = struct {...@@ -1982,7 +1708,7 @@ pub const Type = struct {
1982 ) Module.CompileError!AbiSizeAdvanced {1708 ) Module.CompileError!AbiSizeAdvanced {
1983 const child_ty = ty.optionalChild(mod);1709 const child_ty = ty.optionalChild(mod);
19841710
1985 if (child_ty.isNoReturn()) {1711 if (child_ty.isNoReturn(mod)) {
1986 return AbiSizeAdvanced{ .scalar = 0 };1712 return AbiSizeAdvanced{ .scalar = 0 };
1987 }1713 }
19881714
...@@ -2041,147 +1767,137 @@ pub const Type = struct {...@@ -2041,147 +1767,137 @@ pub const Type = struct {
20411767
2042 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;1768 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;
20431769
2044 switch (ty.ip_index) {1770 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2045 .none => switch (ty.tag()) {1771 .int_type => |int_type| return int_type.bits,
2046 .inferred_alloc_const => unreachable,1772 .ptr_type => |ptr_type| switch (ptr_type.size) {
2047 .inferred_alloc_mut => unreachable,1773 .Slice => return target.ptrBitWidth() * 2,
20481774 else => return target.ptrBitWidth() * 2,
2049 .error_set,1775 },
2050 .error_set_single,1776 .anyframe_type => return target.ptrBitWidth(),
2051 .error_set_inferred,1777
2052 .error_set_merged,1778 .array_type => |array_type| {
2053 => return 16, // TODO revisit this when we have the concept of the error tag type1779 const len = array_type.len + @boolToInt(array_type.sentinel != .none);
1780 if (len == 0) return 0;
1781 const elem_ty = array_type.child.toType();
1782 const elem_size = std.math.max(elem_ty.abiAlignment(mod), elem_ty.abiSize(mod));
1783 if (elem_size == 0) return 0;
1784 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, opt_sema);
1785 return (len - 1) * 8 * elem_size + elem_bit_size;
1786 },
1787 .vector_type => |vector_type| {
1788 const child_ty = vector_type.child.toType();
1789 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
1790 return elem_bit_size * vector_type.len;
1791 },
1792 .opt_type => {
1793 // Optionals and error unions are not packed so their bitsize
1794 // includes padding bits.
1795 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
1796 },
1797
1798 // TODO revisit this when we have the concept of the error tag type
1799 .error_set_type, .inferred_error_set_type => return 16,
1800
1801 .error_union_type => {
1802 // Optionals and error unions are not packed so their bitsize
1803 // includes padding bits.
1804 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
1805 },
1806 .func_type => unreachable, // represents machine code; not a pointer
1807 .simple_type => |t| switch (t) {
1808 .f16 => return 16,
1809 .f32 => return 32,
1810 .f64 => return 64,
1811 .f80 => return 80,
1812 .f128 => return 128,
1813
1814 .usize,
1815 .isize,
1816 => return target.ptrBitWidth(),
1817
1818 .c_char => return target.c_type_bit_size(.char),
1819 .c_short => return target.c_type_bit_size(.short),
1820 .c_ushort => return target.c_type_bit_size(.ushort),
1821 .c_int => return target.c_type_bit_size(.int),
1822 .c_uint => return target.c_type_bit_size(.uint),
1823 .c_long => return target.c_type_bit_size(.long),
1824 .c_ulong => return target.c_type_bit_size(.ulong),
1825 .c_longlong => return target.c_type_bit_size(.longlong),
1826 .c_ulonglong => return target.c_type_bit_size(.ulonglong),
1827 .c_longdouble => return target.c_type_bit_size(.longdouble),
1828
1829 .bool => return 1,
1830 .void => return 0,
20541831
2055 .error_union => {1832 // TODO revisit this when we have the concept of the error tag type
2056 // Optionals and error unions are not packed so their bitsize1833 .anyerror => return 16,
2057 // includes padding bits.1834
2058 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;1835 .anyopaque => unreachable,
2059 },1836 .type => unreachable,
1837 .comptime_int => unreachable,
1838 .comptime_float => unreachable,
1839 .noreturn => unreachable,
1840 .null => unreachable,
1841 .undefined => unreachable,
1842 .enum_literal => unreachable,
1843 .generic_poison => unreachable,
1844 .var_args_param => unreachable,
1845
1846 .atomic_order => unreachable, // missing call to resolveTypeFields
1847 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
1848 .calling_convention => unreachable, // missing call to resolveTypeFields
1849 .address_space => unreachable, // missing call to resolveTypeFields
1850 .float_mode => unreachable, // missing call to resolveTypeFields
1851 .reduce_op => unreachable, // missing call to resolveTypeFields
1852 .call_modifier => unreachable, // missing call to resolveTypeFields
1853 .prefetch_options => unreachable, // missing call to resolveTypeFields
1854 .export_options => unreachable, // missing call to resolveTypeFields
1855 .extern_options => unreachable, // missing call to resolveTypeFields
1856 .type_info => unreachable, // missing call to resolveTypeFields
2060 },1857 },
2061 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {1858 .struct_type => |struct_type| {
2062 .int_type => |int_type| return int_type.bits,1859 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return 0;
2063 .ptr_type => |ptr_type| switch (ptr_type.size) {1860 if (struct_obj.layout != .Packed) {
2064 .Slice => return target.ptrBitWidth() * 2,
2065 else => return target.ptrBitWidth() * 2,
2066 },
2067 .anyframe_type => return target.ptrBitWidth(),
2068
2069 .array_type => |array_type| {
2070 const len = array_type.len + @boolToInt(array_type.sentinel != .none);
2071 if (len == 0) return 0;
2072 const elem_ty = array_type.child.toType();
2073 const elem_size = std.math.max(elem_ty.abiAlignment(mod), elem_ty.abiSize(mod));
2074 if (elem_size == 0) return 0;
2075 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, opt_sema);
2076 return (len - 1) * 8 * elem_size + elem_bit_size;
2077 },
2078 .vector_type => |vector_type| {
2079 const child_ty = vector_type.child.toType();
2080 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
2081 return elem_bit_size * vector_type.len;
2082 },
2083 .opt_type => {
2084 // Optionals and error unions are not packed so their bitsize
2085 // includes padding bits.
2086 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
2087 },
2088 .error_union_type => @panic("TODO"),
2089 .func_type => unreachable, // represents machine code; not a pointer
2090 .simple_type => |t| switch (t) {
2091 .f16 => return 16,
2092 .f32 => return 32,
2093 .f64 => return 64,
2094 .f80 => return 80,
2095 .f128 => return 128,
2096
2097 .usize,
2098 .isize,
2099 => return target.ptrBitWidth(),
2100
2101 .c_char => return target.c_type_bit_size(.char),
2102 .c_short => return target.c_type_bit_size(.short),
2103 .c_ushort => return target.c_type_bit_size(.ushort),
2104 .c_int => return target.c_type_bit_size(.int),
2105 .c_uint => return target.c_type_bit_size(.uint),
2106 .c_long => return target.c_type_bit_size(.long),
2107 .c_ulong => return target.c_type_bit_size(.ulong),
2108 .c_longlong => return target.c_type_bit_size(.longlong),
2109 .c_ulonglong => return target.c_type_bit_size(.ulonglong),
2110 .c_longdouble => return target.c_type_bit_size(.longdouble),
2111
2112 .bool => return 1,
2113 .void => return 0,
2114
2115 // TODO revisit this when we have the concept of the error tag type
2116 .anyerror => return 16,
2117
2118 .anyopaque => unreachable,
2119 .type => unreachable,
2120 .comptime_int => unreachable,
2121 .comptime_float => unreachable,
2122 .noreturn => unreachable,
2123 .null => unreachable,
2124 .undefined => unreachable,
2125 .enum_literal => unreachable,
2126 .generic_poison => unreachable,
2127 .var_args_param => unreachable,
2128
2129 .atomic_order => unreachable, // missing call to resolveTypeFields
2130 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
2131 .calling_convention => unreachable, // missing call to resolveTypeFields
2132 .address_space => unreachable, // missing call to resolveTypeFields
2133 .float_mode => unreachable, // missing call to resolveTypeFields
2134 .reduce_op => unreachable, // missing call to resolveTypeFields
2135 .call_modifier => unreachable, // missing call to resolveTypeFields
2136 .prefetch_options => unreachable, // missing call to resolveTypeFields
2137 .export_options => unreachable, // missing call to resolveTypeFields
2138 .extern_options => unreachable, // missing call to resolveTypeFields
2139 .type_info => unreachable, // missing call to resolveTypeFields
2140 },
2141 .struct_type => |struct_type| {
2142 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return 0;
2143 if (struct_obj.layout != .Packed) {
2144 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2145 }
2146 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
2147 assert(struct_obj.haveLayout());
2148 return try struct_obj.backing_int_ty.bitSizeAdvanced(mod, opt_sema);
2149 },
2150
2151 .anon_struct_type => {
2152 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
2153 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1861 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2154 },1862 }
1863 if (opt_sema) |sema| _ = try sema.resolveTypeLayout(ty);
1864 assert(struct_obj.haveLayout());
1865 return try struct_obj.backing_int_ty.bitSizeAdvanced(mod, opt_sema);
1866 },
21551867
2156 .union_type => |union_type| {1868 .anon_struct_type => {
2157 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);1869 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
2158 if (ty.containerLayout(mod) != .Packed) {1870 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2159 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1871 },
2160 }
2161 const union_obj = mod.unionPtr(union_type.index);
2162 assert(union_obj.haveFieldTypes());
21631872
2164 var size: u64 = 0;1873 .union_type => |union_type| {
2165 for (union_obj.fields.values()) |field| {1874 if (opt_sema) |sema| _ = try sema.resolveTypeFields(ty);
2166 size = @max(size, try bitSizeAdvanced(field.ty, mod, opt_sema));1875 if (ty.containerLayout(mod) != .Packed) {
2167 }1876 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
2168 return size;1877 }
2169 },1878 const union_obj = mod.unionPtr(union_type.index);
2170 .opaque_type => unreachable,1879 assert(union_obj.haveFieldTypes());
2171 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),
21721880
2173 // values, not types1881 var size: u64 = 0;
2174 .undef => unreachable,1882 for (union_obj.fields.values()) |field| {
2175 .un => unreachable,1883 size = @max(size, try bitSizeAdvanced(field.ty, mod, opt_sema));
2176 .simple_value => unreachable,1884 }
2177 .extern_func => unreachable,1885 return size;
2178 .int => unreachable,
2179 .float => unreachable,
2180 .ptr => unreachable,
2181 .opt => unreachable,
2182 .enum_tag => unreachable,
2183 .aggregate => unreachable,
2184 },1886 },
1887 .opaque_type => unreachable,
1888 .enum_type => |enum_type| return bitSizeAdvanced(enum_type.tag_ty.toType(), mod, opt_sema),
1889
1890 // values, not types
1891 .undef => unreachable,
1892 .un => unreachable,
1893 .simple_value => unreachable,
1894 .extern_func => unreachable,
1895 .int => unreachable,
1896 .float => unreachable,
1897 .ptr => unreachable,
1898 .opt => unreachable,
1899 .enum_tag => unreachable,
1900 .aggregate => unreachable,
2185 }1901 }
2186 }1902 }
21871903
...@@ -2210,7 +1926,7 @@ pub const Type = struct {...@@ -2210,7 +1926,7 @@ pub const Type = struct {
2210 return payload_ty.layoutIsResolved(mod);1926 return payload_ty.layoutIsResolved(mod);
2211 },1927 },
2212 .ErrorUnion => {1928 .ErrorUnion => {
2213 const payload_ty = ty.errorUnionPayload();1929 const payload_ty = ty.errorUnionPayload(mod);
2214 return payload_ty.layoutIsResolved(mod);1930 return payload_ty.layoutIsResolved(mod);
2215 },1931 },
2216 else => return true,1932 else => return true,
...@@ -2223,8 +1939,6 @@ pub const Type = struct {...@@ -2223,8 +1939,6 @@ pub const Type = struct {
2223 .inferred_alloc_const,1939 .inferred_alloc_const,
2224 .inferred_alloc_mut,1940 .inferred_alloc_mut,
2225 => true,1941 => true,
2226
2227 else => false,
2228 },1942 },
2229 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {1943 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2230 .ptr_type => |ptr_info| ptr_info.size == .One,1944 .ptr_type => |ptr_info| ptr_info.size == .One,
...@@ -2245,8 +1959,6 @@ pub const Type = struct {...@@ -2245,8 +1959,6 @@ pub const Type = struct {
2245 .inferred_alloc_const,1959 .inferred_alloc_const,
2246 .inferred_alloc_mut,1960 .inferred_alloc_mut,
2247 => .One,1961 => .One,
2248
2249 else => null,
2250 },1962 },
2251 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {1963 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2252 .ptr_type => |ptr_info| ptr_info.size,1964 .ptr_type => |ptr_info| ptr_info.size,
...@@ -2534,69 +2246,43 @@ pub const Type = struct {...@@ -2534,69 +2246,43 @@ pub const Type = struct {
2534 }2246 }
25352247
2536 /// Asserts that the type is an error union.2248 /// Asserts that the type is an error union.
2537 pub fn errorUnionPayload(ty: Type) Type {2249 pub fn errorUnionPayload(ty: Type, mod: *Module) Type {
2538 return switch (ty.ip_index) {2250 return mod.intern_pool.indexToKey(ty.ip_index).error_union_type.payload_type.toType();
2539 .anyerror_void_error_union_type => Type.void,
2540 .none => switch (ty.tag()) {
2541 .error_union => ty.castTag(.error_union).?.data.payload,
2542 else => unreachable,
2543 },
2544 else => @panic("TODO"),
2545 };
2546 }2251 }
25472252
2548 pub fn errorUnionSet(ty: Type) Type {2253 /// Asserts that the type is an error union.
2549 return switch (ty.ip_index) {2254 pub fn errorUnionSet(ty: Type, mod: *Module) Type {
2550 .anyerror_void_error_union_type => Type.anyerror,2255 return mod.intern_pool.indexToKey(ty.ip_index).error_union_type.error_set_type.toType();
2551 .none => switch (ty.tag()) {
2552 .error_union => ty.castTag(.error_union).?.data.error_set,
2553 else => unreachable,
2554 },
2555 else => @panic("TODO"),
2556 };
2557 }2256 }
25582257
2559 /// Returns false for unresolved inferred error sets.2258 /// Returns false for unresolved inferred error sets.
2560 pub fn errorSetIsEmpty(ty: Type, mod: *const Module) bool {2259 pub fn errorSetIsEmpty(ty: Type, mod: *Module) bool {
2561 switch (ty.ip_index) {2260 return switch (ty.ip_index) {
2562 .none => switch (ty.tag()) {2261 .anyerror_type => false,
2563 .error_set_inferred => {2262 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2564 const inferred_error_set = ty.castTag(.error_set_inferred).?.data;2263 .error_set_type => |error_set_type| error_set_type.names.len == 0,
2264 .inferred_error_set_type => |index| {
2265 const inferred_error_set = mod.inferredErrorSetPtr(index);
2565 // Can't know for sure.2266 // Can't know for sure.
2566 if (!inferred_error_set.is_resolved) return false;2267 if (!inferred_error_set.is_resolved) return false;
2567 if (inferred_error_set.is_anyerror) return false;2268 if (inferred_error_set.is_anyerror) return false;
2568 return inferred_error_set.errors.count() == 0;2269 return inferred_error_set.errors.count() == 0;
2569 },2270 },
2570 .error_set_single => return false,
2571 .error_set => {
2572 const err_set_obj = ty.castTag(.error_set).?.data;
2573 return err_set_obj.names.count() == 0;
2574 },
2575 .error_set_merged => {
2576 const name_map = ty.castTag(.error_set_merged).?.data;
2577 return name_map.count() == 0;
2578 },
2579 else => unreachable,2271 else => unreachable,
2580 },2272 },
2581 .anyerror_type => return false,2273 };
2582 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2583 else => @panic("TODO"),
2584 },
2585 }
2586 }2274 }
25872275
2588 /// Returns true if it is an error set that includes anyerror, false otherwise.2276 /// Returns true if it is an error set that includes anyerror, false otherwise.
2589 /// Note that the result may be a false negative if the type did not get error set2277 /// Note that the result may be a false negative if the type did not get error set
2590 /// resolution prior to this call.2278 /// resolution prior to this call.
2591 pub fn isAnyError(ty: Type) bool {2279 pub fn isAnyError(ty: Type, mod: *Module) bool {
2592 return switch (ty.ip_index) {2280 return switch (ty.ip_index) {
2593 .none => switch (ty.tag()) {2281 .anyerror_type => true,
2594 .error_set_inferred => ty.castTag(.error_set_inferred).?.data.is_anyerror,2282 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2283 .inferred_error_set_type => |i| mod.inferredErrorSetPtr(i).is_anyerror,
2595 else => false,2284 else => false,
2596 },2285 },
2597 .anyerror_type => true,
2598 // TODO handle error_set_inferred here
2599 else => false,
2600 };2286 };
2601 }2287 }
26022288
...@@ -2610,30 +2296,50 @@ pub const Type = struct {...@@ -2610,30 +2296,50 @@ pub const Type = struct {
2610 /// Returns whether ty, which must be an error set, includes an error `name`.2296 /// Returns whether ty, which must be an error set, includes an error `name`.
2611 /// Might return a false negative if `ty` is an inferred error set and not fully2297 /// Might return a false negative if `ty` is an inferred error set and not fully
2612 /// resolved yet.2298 /// resolved yet.
2613 pub fn errorSetHasField(ty: Type, name: []const u8) bool {2299 pub fn errorSetHasFieldIp(
2614 if (ty.isAnyError()) {2300 ip: *const InternPool,
2615 return true;2301 ty: InternPool.Index,
2616 }2302 name: InternPool.NullTerminatedString,
26172303 ) bool {
2618 switch (ty.tag()) {2304 return switch (ty) {
2619 .error_set_single => {2305 .anyerror_type => true,
2620 const data = ty.castTag(.error_set_single).?.data;2306 else => switch (ip.indexToKey(ty)) {
2621 return std.mem.eql(u8, data, name);2307 .error_set_type => |error_set_type| {
2622 },2308 return error_set_type.nameIndex(ip, name) != null;
2623 .error_set_inferred => {2309 },
2624 const data = ty.castTag(.error_set_inferred).?.data;2310 .inferred_error_set_type => |index| {
2625 return data.errors.contains(name);2311 const ies = ip.inferredErrorSetPtrConst(index);
2626 },2312 if (ies.is_anyerror) return true;
2627 .error_set_merged => {2313 return ies.errors.contains(name);
2628 const data = ty.castTag(.error_set_merged).?.data;2314 },
2629 return data.contains(name);2315 else => unreachable,
2630 },2316 },
2631 .error_set => {2317 };
2632 const data = ty.castTag(.error_set).?.data;2318 }
2633 return data.names.contains(name);2319
2320 /// Returns whether ty, which must be an error set, includes an error `name`.
2321 /// Might return a false negative if `ty` is an inferred error set and not fully
2322 /// resolved yet.
2323 pub fn errorSetHasField(ty: Type, name: []const u8, mod: *Module) bool {
2324 const ip = &mod.intern_pool;
2325 return switch (ty.ip_index) {
2326 .anyerror_type => true,
2327 else => switch (ip.indexToKey(ty.ip_index)) {
2328 .error_set_type => |error_set_type| {
2329 // If the string is not interned, then the field certainly is not present.
2330 const field_name_interned = ip.getString(name).unwrap() orelse return false;
2331 return error_set_type.nameIndex(ip, field_name_interned) != null;
2332 },
2333 .inferred_error_set_type => |index| {
2334 const ies = ip.inferredErrorSetPtr(index);
2335 if (ies.is_anyerror) return true;
2336 // If the string is not interned, then the field certainly is not present.
2337 const field_name_interned = ip.getString(name).unwrap() orelse return false;
2338 return ies.errors.contains(field_name_interned);
2339 },
2340 else => unreachable,
2634 },2341 },
2635 else => unreachable,2342 };
2636 }
2637 }2343 }
26382344
2639 /// Asserts the type is an array or vector or struct.2345 /// Asserts the type is an array or vector or struct.
...@@ -2727,14 +2433,6 @@ pub const Type = struct {...@@ -2727,14 +2433,6 @@ pub const Type = struct {
2727 var ty = starting_ty;2433 var ty = starting_ty;
27282434
2729 while (true) switch (ty.ip_index) {2435 while (true) switch (ty.ip_index) {
2730 .none => switch (ty.tag()) {
2731 .error_set, .error_set_single, .error_set_inferred, .error_set_merged => {
2732 // TODO revisit this when error sets support custom int types
2733 return .{ .signedness = .unsigned, .bits = 16 };
2734 },
2735
2736 else => unreachable,
2737 },
2738 .anyerror_type => {2436 .anyerror_type => {
2739 // TODO revisit this when error sets support custom int types2437 // TODO revisit this when error sets support custom int types
2740 return .{ .signedness = .unsigned, .bits = 16 };2438 return .{ .signedness = .unsigned, .bits = 16 };
...@@ -2760,6 +2458,9 @@ pub const Type = struct {...@@ -2760,6 +2458,9 @@ pub const Type = struct {
2760 .enum_type => |enum_type| ty = enum_type.tag_ty.toType(),2458 .enum_type => |enum_type| ty = enum_type.tag_ty.toType(),
2761 .vector_type => |vector_type| ty = vector_type.child.toType(),2459 .vector_type => |vector_type| ty = vector_type.child.toType(),
27622460
2461 // TODO revisit this when error sets support custom int types
2462 .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = 16 },
2463
2763 .anon_struct_type => unreachable,2464 .anon_struct_type => unreachable,
27642465
2765 .ptr_type => unreachable,2466 .ptr_type => unreachable,
...@@ -2932,13 +2633,6 @@ pub const Type = struct {...@@ -2932,13 +2633,6 @@ pub const Type = struct {
2932 .empty_struct_type => return Value.empty_struct,2633 .empty_struct_type => return Value.empty_struct,
29332634
2934 .none => switch (ty.tag()) {2635 .none => switch (ty.tag()) {
2935 .error_union,
2936 .error_set_single,
2937 .error_set,
2938 .error_set_merged,
2939 .error_set_inferred,
2940 => return null,
2941
2942 .inferred_alloc_const => unreachable,2636 .inferred_alloc_const => unreachable,
2943 .inferred_alloc_mut => unreachable,2637 .inferred_alloc_mut => unreachable,
2944 },2638 },
...@@ -2955,6 +2649,8 @@ pub const Type = struct {...@@ -2955,6 +2649,8 @@ pub const Type = struct {
2955 .error_union_type,2649 .error_union_type,
2956 .func_type,2650 .func_type,
2957 .anyframe_type,2651 .anyframe_type,
2652 .error_set_type,
2653 .inferred_error_set_type,
2958 => return null,2654 => return null,
29592655
2960 .array_type => |array_type| {2656 .array_type => |array_type| {
...@@ -3130,18 +2826,6 @@ pub const Type = struct {...@@ -3130,18 +2826,6 @@ pub const Type = struct {
3130 return switch (ty.ip_index) {2826 return switch (ty.ip_index) {
3131 .empty_struct_type => false,2827 .empty_struct_type => false,
31322828
3133 .none => switch (ty.tag()) {
3134 .error_set,
3135 .error_set_single,
3136 .error_set_inferred,
3137 .error_set_merged,
3138 => false,
3139
3140 .inferred_alloc_mut => unreachable,
3141 .inferred_alloc_const => unreachable,
3142
3143 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),
3144 },
3145 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2829 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3146 .int_type => false,2830 .int_type => false,
3147 .ptr_type => |ptr_type| {2831 .ptr_type => |ptr_type| {
...@@ -3160,6 +2844,11 @@ pub const Type = struct {...@@ -3160,6 +2844,11 @@ pub const Type = struct {
3160 .vector_type => |vector_type| vector_type.child.toType().comptimeOnly(mod),2844 .vector_type => |vector_type| vector_type.child.toType().comptimeOnly(mod),
3161 .opt_type => |child| child.toType().comptimeOnly(mod),2845 .opt_type => |child| child.toType().comptimeOnly(mod),
3162 .error_union_type => |error_union_type| error_union_type.payload_type.toType().comptimeOnly(mod),2846 .error_union_type => |error_union_type| error_union_type.payload_type.toType().comptimeOnly(mod),
2847
2848 .error_set_type,
2849 .inferred_error_set_type,
2850 => false,
2851
3163 // These are function bodies, not function pointers.2852 // These are function bodies, not function pointers.
3164 .func_type => true,2853 .func_type => true,
31652854
...@@ -3418,17 +3107,11 @@ pub const Type = struct {...@@ -3418,17 +3107,11 @@ pub const Type = struct {
3418 }3107 }
34193108
3420 // Asserts that `ty` is an error set and not `anyerror`.3109 // Asserts that `ty` is an error set and not `anyerror`.
3421 pub fn errorSetNames(ty: Type) []const []const u8 {3110 pub fn errorSetNames(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
3422 return switch (ty.tag()) {3111 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3423 .error_set_single => blk: {3112 .error_set_type => |x| x.names,
3424 // Work around coercion problems3113 .inferred_error_set_type => |index| {
3425 const tmp: *const [1][]const u8 = &ty.castTag(.error_set_single).?.data;3114 const inferred_error_set = mod.inferredErrorSetPtr(index);
3426 break :blk tmp;
3427 },
3428 .error_set_merged => ty.castTag(.error_set_merged).?.data.keys(),
3429 .error_set => ty.castTag(.error_set).?.data.names.keys(),
3430 .error_set_inferred => {
3431 const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
3432 assert(inferred_error_set.is_resolved);3115 assert(inferred_error_set.is_resolved);
3433 assert(!inferred_error_set.is_anyerror);3116 assert(!inferred_error_set.is_anyerror);
3434 return inferred_error_set.errors.keys();3117 return inferred_error_set.errors.keys();
...@@ -3437,26 +3120,6 @@ pub const Type = struct {...@@ -3437,26 +3120,6 @@ pub const Type = struct {
3437 };3120 };
3438 }3121 }
34393122
3440 /// Merge lhs with rhs.
3441 /// Asserts that lhs and rhs are both error sets and are resolved.
3442 pub fn errorSetMerge(lhs: Type, arena: Allocator, rhs: Type) !Type {
3443 const lhs_names = lhs.errorSetNames();
3444 const rhs_names = rhs.errorSetNames();
3445 var names: Module.ErrorSet.NameMap = .{};
3446 try names.ensureUnusedCapacity(arena, lhs_names.len);
3447 for (lhs_names) |name| {
3448 names.putAssumeCapacityNoClobber(name, {});
3449 }
3450 for (rhs_names) |name| {
3451 try names.put(arena, name, {});
3452 }
3453
3454 // names must be sorted
3455 Module.ErrorSet.sortNames(&names);
3456
3457 return try Tag.error_set_merged.create(arena, names);
3458 }
3459
3460 pub fn enumFields(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {3123 pub fn enumFields(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
3461 return mod.intern_pool.indexToKey(ty.ip_index).enum_type.names;3124 return mod.intern_pool.indexToKey(ty.ip_index).enum_type.names;
3462 }3125 }
...@@ -3748,30 +3411,19 @@ pub const Type = struct {...@@ -3748,30 +3411,19 @@ pub const Type = struct {
3748 }3411 }
37493412
3750 pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {3413 pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
3751 switch (ty.ip_index) {3414 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3752 .empty_struct_type => return null,3415 .struct_type => |struct_type| {
3753 .none => switch (ty.tag()) {3416 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3754 .error_set => {3417 return struct_obj.srcLoc(mod);
3755 const error_set = ty.castTag(.error_set).?.data;
3756 return error_set.srcLoc(mod);
3757 },
3758
3759 else => return null,
3760 },3418 },
3761 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {3419 .union_type => |union_type| {
3762 .struct_type => |struct_type| {3420 const union_obj = mod.unionPtr(union_type.index);
3763 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;3421 return union_obj.srcLoc(mod);
3764 return struct_obj.srcLoc(mod);
3765 },
3766 .union_type => |union_type| {
3767 const union_obj = mod.unionPtr(union_type.index);
3768 return union_obj.srcLoc(mod);
3769 },
3770 .opaque_type => |opaque_type| mod.opaqueSrcLoc(opaque_type),
3771 .enum_type => |enum_type| mod.declPtr(enum_type.decl).srcLoc(mod),
3772 else => null,
3773 },3422 },
3774 }3423 .opaque_type => |opaque_type| mod.opaqueSrcLoc(opaque_type),
3424 .enum_type => |enum_type| mod.declPtr(enum_type.decl).srcLoc(mod),
3425 else => null,
3426 };
3775 }3427 }
37763428
3777 pub fn getOwnerDecl(ty: Type, mod: *Module) Module.Decl.Index {3429 pub fn getOwnerDecl(ty: Type, mod: *Module) Module.Decl.Index {
...@@ -3779,39 +3431,25 @@ pub const Type = struct {...@@ -3779,39 +3431,25 @@ pub const Type = struct {
3779 }3431 }
37803432
3781 pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?Module.Decl.Index {3433 pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?Module.Decl.Index {
3782 switch (ty.ip_index) {3434 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3783 .none => switch (ty.tag()) {3435 .struct_type => |struct_type| {
3784 .error_set => {3436 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return null;
3785 const error_set = ty.castTag(.error_set).?.data;3437 return struct_obj.owner_decl;
3786 return error_set.owner_decl;
3787 },
3788
3789 else => return null,
3790 },3438 },
3791 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {3439 .union_type => |union_type| {
3792 .struct_type => |struct_type| {3440 const union_obj = mod.unionPtr(union_type.index);
3793 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return null;3441 return union_obj.owner_decl;
3794 return struct_obj.owner_decl;
3795 },
3796 .union_type => |union_type| {
3797 const union_obj = mod.unionPtr(union_type.index);
3798 return union_obj.owner_decl;
3799 },
3800 .opaque_type => |opaque_type| opaque_type.decl,
3801 .enum_type => |enum_type| enum_type.decl,
3802 else => null,
3803 },3442 },
3804 }3443 .opaque_type => |opaque_type| opaque_type.decl,
3444 .enum_type => |enum_type| enum_type.decl,
3445 else => null,
3446 };
3805 }3447 }
38063448
3807 pub fn isGenericPoison(ty: Type) bool {3449 pub fn isGenericPoison(ty: Type) bool {
3808 return ty.ip_index == .generic_poison_type;3450 return ty.ip_index == .generic_poison_type;
3809 }3451 }
38103452
3811 pub fn isBoundFn(ty: Type) bool {
3812 return ty.ip_index == .none and ty.tag() == .bound_fn;
3813 }
3814
3815 /// This enum does not directly correspond to `std.builtin.TypeId` because3453 /// This enum does not directly correspond to `std.builtin.TypeId` because
3816 /// it has extra enum tags in it, as a way of using less memory. For example,3454 /// it has extra enum tags in it, as a way of using less memory. For example,
3817 /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types3455 /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types
...@@ -3827,54 +3465,8 @@ pub const Type = struct {...@@ -3827,54 +3465,8 @@ pub const Type = struct {
3827 inferred_alloc_const, // See last_no_payload_tag below.3465 inferred_alloc_const, // See last_no_payload_tag below.
3828 // After this, the tag requires a payload.3466 // After this, the tag requires a payload.
38293467
3830 error_union,
3831 error_set,
3832 error_set_single,
3833 /// The type is the inferred error set of a specific function.
3834 error_set_inferred,
3835 error_set_merged,
3836
3837 pub const last_no_payload_tag = Tag.inferred_alloc_const;3468 pub const last_no_payload_tag = Tag.inferred_alloc_const;
3838 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;3469 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
3839
3840 pub fn Type(comptime t: Tag) type {
3841 return switch (t) {
3842 .inferred_alloc_const,
3843 .inferred_alloc_mut,
3844 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
3845
3846 .error_set => Payload.ErrorSet,
3847 .error_set_inferred => Payload.ErrorSetInferred,
3848 .error_set_merged => Payload.ErrorSetMerged,
3849
3850 .error_union => Payload.ErrorUnion,
3851 .error_set_single => Payload.Name,
3852 };
3853 }
3854
3855 pub fn init(comptime t: Tag) file_struct.Type {
3856 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
3857 return file_struct.Type{
3858 .ip_index = .none,
3859 .legacy = .{ .tag_if_small_enough = t },
3860 };
3861 }
3862
3863 pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {
3864 const p = try ally.create(t.Type());
3865 p.* = .{
3866 .base = .{ .tag = t },
3867 .data = data,
3868 };
3869 return file_struct.Type{
3870 .ip_index = .none,
3871 .legacy = .{ .ptr_otherwise = &p.base },
3872 };
3873 }
3874
3875 pub fn Data(comptime t: Tag) type {
3876 return std.meta.fieldInfo(t.Type(), .data).type;
3877 }
3878 };3470 };
38793471
3880 pub fn isTuple(ty: Type, mod: *Module) bool {3472 pub fn isTuple(ty: Type, mod: *Module) bool {
...@@ -3928,37 +3520,6 @@ pub const Type = struct {...@@ -3928,37 +3520,6 @@ pub const Type = struct {
3928 pub const Payload = struct {3520 pub const Payload = struct {
3929 tag: Tag,3521 tag: Tag,
39303522
3931 pub const Len = struct {
3932 base: Payload,
3933 data: u64,
3934 };
3935
3936 pub const Bits = struct {
3937 base: Payload,
3938 data: u16,
3939 };
3940
3941 pub const ErrorSet = struct {
3942 pub const base_tag = Tag.error_set;
3943
3944 base: Payload = Payload{ .tag = base_tag },
3945 data: *Module.ErrorSet,
3946 };
3947
3948 pub const ErrorSetMerged = struct {
3949 pub const base_tag = Tag.error_set_merged;
3950
3951 base: Payload = Payload{ .tag = base_tag },
3952 data: Module.ErrorSet.NameMap,
3953 };
3954
3955 pub const ErrorSetInferred = struct {
3956 pub const base_tag = Tag.error_set_inferred;
3957
3958 base: Payload = Payload{ .tag = base_tag },
3959 data: *Module.Fn.InferredErrorSet,
3960 };
3961
3962 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.3523 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
3963 pub const Pointer = struct {3524 pub const Pointer = struct {
3964 data: Data,3525 data: Data,
...@@ -4010,27 +3571,6 @@ pub const Type = struct {...@@ -4010,27 +3571,6 @@ pub const Type = struct {
4010 }3571 }
4011 };3572 };
4012 };3573 };
4013
4014 pub const ErrorUnion = struct {
4015 pub const base_tag = Tag.error_union;
4016
4017 base: Payload = Payload{ .tag = base_tag },
4018 data: struct {
4019 error_set: Type,
4020 payload: Type,
4021 },
4022 };
4023
4024 pub const Decl = struct {
4025 base: Payload,
4026 data: *Module.Decl,
4027 };
4028
4029 pub const Name = struct {
4030 base: Payload,
4031 /// memory is owned by `Module`
4032 data: []const u8,
4033 };
4034 };3574 };
40353575
4036 pub const @"u1": Type = .{ .ip_index = .u1_type, .legacy = undefined };3576 pub const @"u1": Type = .{ .ip_index = .u1_type, .legacy = undefined };
...@@ -4164,19 +3704,6 @@ pub const Type = struct {...@@ -4164,19 +3704,6 @@ pub const Type = struct {
4164 return mod.optionalType(child_type.ip_index);3704 return mod.optionalType(child_type.ip_index);
4165 }3705 }
41663706
4167 pub fn errorUnion(
4168 arena: Allocator,
4169 error_set: Type,
4170 payload: Type,
4171 mod: *Module,
4172 ) Allocator.Error!Type {
4173 assert(error_set.zigTypeTag(mod) == .ErrorSet);
4174 return Type.Tag.error_union.create(arena, .{
4175 .error_set = error_set,
4176 .payload = payload,
4177 });
4178 }
4179
4180 pub fn smallestUnsignedBits(max: u64) u16 {3707 pub fn smallestUnsignedBits(max: u64) u16 {
4181 if (max == 0) return 0;3708 if (max == 0) return 0;
4182 const base = std.math.log2(max);3709 const base = std.math.log2(max);
src/value.zig+9-9
...@@ -260,7 +260,7 @@ pub const Value = struct {...@@ -260,7 +260,7 @@ pub const Value = struct {
260 const new_payload = try arena.create(Payload.Ty);260 const new_payload = try arena.create(Payload.Ty);
261 new_payload.* = .{261 new_payload.* = .{
262 .base = payload.base,262 .base = payload.base,
263 .data = try payload.data.copy(arena),263 .data = payload.data,
264 };264 };
265 return Value{265 return Value{
266 .ip_index = .none,266 .ip_index = .none,
...@@ -281,7 +281,7 @@ pub const Value = struct {...@@ -281,7 +281,7 @@ pub const Value = struct {
281 .base = payload.base,281 .base = payload.base,
282 .data = .{282 .data = .{
283 .container_ptr = try payload.data.container_ptr.copy(arena),283 .container_ptr = try payload.data.container_ptr.copy(arena),
284 .container_ty = try payload.data.container_ty.copy(arena),284 .container_ty = payload.data.container_ty,
285 },285 },
286 };286 };
287 return Value{287 return Value{
...@@ -296,7 +296,7 @@ pub const Value = struct {...@@ -296,7 +296,7 @@ pub const Value = struct {
296 .base = payload.base,296 .base = payload.base,
297 .data = .{297 .data = .{
298 .field_val = try payload.data.field_val.copy(arena),298 .field_val = try payload.data.field_val.copy(arena),
299 .field_ty = try payload.data.field_ty.copy(arena),299 .field_ty = payload.data.field_ty,
300 },300 },
301 };301 };
302 return Value{302 return Value{
...@@ -311,7 +311,7 @@ pub const Value = struct {...@@ -311,7 +311,7 @@ pub const Value = struct {
311 .base = payload.base,311 .base = payload.base,
312 .data = .{312 .data = .{
313 .array_ptr = try payload.data.array_ptr.copy(arena),313 .array_ptr = try payload.data.array_ptr.copy(arena),
314 .elem_ty = try payload.data.elem_ty.copy(arena),314 .elem_ty = payload.data.elem_ty,
315 .index = payload.data.index,315 .index = payload.data.index,
316 },316 },
317 };317 };
...@@ -327,7 +327,7 @@ pub const Value = struct {...@@ -327,7 +327,7 @@ pub const Value = struct {
327 .base = payload.base,327 .base = payload.base,
328 .data = .{328 .data = .{
329 .container_ptr = try payload.data.container_ptr.copy(arena),329 .container_ptr = try payload.data.container_ptr.copy(arena),
330 .container_ty = try payload.data.container_ty.copy(arena),330 .container_ty = payload.data.container_ty,
331 .field_index = payload.data.field_index,331 .field_index = payload.data.field_index,
332 },332 },
333 };333 };
...@@ -1870,7 +1870,7 @@ pub const Value = struct {...@@ -1870,7 +1870,7 @@ pub const Value = struct {
1870 .eu_payload => {1870 .eu_payload => {
1871 const a_payload = a.castTag(.eu_payload).?.data;1871 const a_payload = a.castTag(.eu_payload).?.data;
1872 const b_payload = b.castTag(.eu_payload).?.data;1872 const b_payload = b.castTag(.eu_payload).?.data;
1873 const payload_ty = ty.errorUnionPayload();1873 const payload_ty = ty.errorUnionPayload(mod);
1874 return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, opt_sema);1874 return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, opt_sema);
1875 },1875 },
1876 .eu_payload_ptr => {1876 .eu_payload_ptr => {
...@@ -2163,14 +2163,14 @@ pub const Value = struct {...@@ -2163,14 +2163,14 @@ pub const Value = struct {
2163 .ErrorUnion => {2163 .ErrorUnion => {
2164 if (val.tag() == .@"error") {2164 if (val.tag() == .@"error") {
2165 std.hash.autoHash(hasher, false); // error2165 std.hash.autoHash(hasher, false); // error
2166 const sub_ty = ty.errorUnionSet();2166 const sub_ty = ty.errorUnionSet(mod);
2167 val.hash(sub_ty, hasher, mod);2167 val.hash(sub_ty, hasher, mod);
2168 return;2168 return;
2169 }2169 }
21702170
2171 if (val.castTag(.eu_payload)) |payload| {2171 if (val.castTag(.eu_payload)) |payload| {
2172 std.hash.autoHash(hasher, true); // payload2172 std.hash.autoHash(hasher, true); // payload
2173 const sub_ty = ty.errorUnionPayload();2173 const sub_ty = ty.errorUnionPayload(mod);
2174 payload.data.hash(sub_ty, hasher, mod);2174 payload.data.hash(sub_ty, hasher, mod);
2175 return;2175 return;
2176 } else unreachable;2176 } else unreachable;
...@@ -2272,7 +2272,7 @@ pub const Value = struct {...@@ -2272,7 +2272,7 @@ pub const Value = struct {
2272 payload.data.hashUncoerced(child_ty, hasher, mod);2272 payload.data.hashUncoerced(child_ty, hasher, mod);
2273 } else std.hash.autoHash(hasher, std.builtin.TypeId.Null),2273 } else std.hash.autoHash(hasher, std.builtin.TypeId.Null),
2274 .ErrorSet, .ErrorUnion => if (val.getError()) |err| hasher.update(err) else {2274 .ErrorSet, .ErrorUnion => if (val.getError()) |err| hasher.update(err) else {
2275 const pl_ty = ty.errorUnionPayload();2275 const pl_ty = ty.errorUnionPayload(mod);
2276 val.castTag(.eu_payload).?.data.hashUncoerced(pl_ty, hasher, mod);2276 val.castTag(.eu_payload).?.data.hashUncoerced(pl_ty, hasher, mod);
2277 },2277 },
2278 .Enum, .EnumLiteral, .Union => {2278 .Enum, .EnumLiteral, .Union => {