| author | |
| committer | |
| log | 9ff514b6a35b7201f45f8bff31c61b4f8cfa7a7a |
| tree | dda74acc00690d1b3d31fd6e43d7ec0aa4acc882 |
| parent | 7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2 |
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 { |
| 1411 | 1411 | ||
| 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 | }, |
| 1416 | 1416 | ||
| 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. |
| 35 | unions_free_list: std.ArrayListUnmanaged(Module.Union.Index) = .{}, | 35 | unions_free_list: std.ArrayListUnmanaged(Module.Union.Index) = .{}, |
| 36 | 36 | ||
| 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. | ||
| 40 | allocated_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. | ||
| 43 | inferred_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 names | 45 | /// 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 underlying | 46 | /// 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 | }; |
| 117 | 131 | ||
| 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 indicate | 149 | /// `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, | ||
| 155 | 168 | ||
| 156 | /// Typed `undefined`. This will never be `none`; untyped `undefined` is represented | 169 | /// 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) { |
| 183 | 196 | ||
| 184 | pub const IntType = std.builtin.Type.Int; | 197 | pub const IntType = std.builtin.Type.Int; |
| 185 | 198 | ||
| 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), |
| 511 | 545 | ||
| 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 | }, |
| 549 | 583 | ||
| 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) and | 764 | 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 | }, | ||
| 729 | 775 | ||
| 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 | }; |
| 1357 | 1411 | ||
| 1412 | /// Trailing: | ||
| 1413 | /// 0. name: NullTerminatedString for each names_len | ||
| 1414 | pub const ErrorSet = struct { | ||
| 1415 | names_len: u32, | ||
| 1416 | }; | ||
| 1417 | |||
| 1358 | /// Trailing: | 1418 | /// Trailing: |
| 1359 | /// 0. param_type: Index for each params_len | 1419 | /// 0. param_type: Index for each params_len |
| 1360 | pub const TypeFunction = struct { | 1420 | pub const TypeFunction = struct { |
| ... | @@ -1539,11 +1599,6 @@ pub const Array = struct { | ... | @@ -1539,11 +1599,6 @@ pub const Array = struct { |
| 1539 | } | 1599 | } |
| 1540 | }; | 1600 | }; |
| 1541 | 1601 | ||
| 1542 | pub 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 order | 1603 | /// 0. field name: NullTerminatedString for each fields_len; declaration order |
| 1549 | /// 1. tag value: Index for each fields_len; declaration order | 1604 | /// 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); |
| 1721 | 1776 | ||
| 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); |
| 1724 | 1782 | ||
| ... | @@ -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) }, |
| 1800 | 1858 | ||
| 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 | }, | ||
| 1802 | 1871 | ||
| 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 | } |
| 3194 | 3281 | ||
| 3282 | pub 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 | |||
| 3195 | pub fn isOptionalType(ip: InternPool, ty: Index) bool { | 3290 | pub 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 | } |
| 3200 | 3295 | ||
| 3296 | pub 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 | |||
| 3201 | pub fn dump(ip: InternPool) void { | 3302 | pub 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 | } |
| 3361 | 3467 | ||
| 3468 | pub fn inferredErrorSetPtr(ip: *InternPool, index: Module.Fn.InferredErrorSet.Index) *Module.Fn.InferredErrorSet { | ||
| 3469 | return ip.allocated_inferred_error_sets.at(@enumToInt(index)); | ||
| 3470 | } | ||
| 3471 | |||
| 3472 | pub 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 | |||
| 3362 | pub fn createStruct( | 3476 | pub 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 | } |
| 3399 | 3513 | ||
| 3514 | pub 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 | |||
| 3525 | pub 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 | |||
| 3400 | pub fn getOrPutString( | 3533 | pub 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 | |||
| 3596 | pub 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( |
| 1416 | 1416 | ||
| 1417 | // If the block is noreturn, block deaths not only aren't useful, they're impossible to | 1417 | // 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 sets | 1420 | // 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 { |
| 453 | 453 | ||
| 454 | for (block_liveness.deaths) |death| try self.verifyDeath(inst, death); | 454 | for (block_liveness.deaths) |death| try self.verifyDeath(inst, death); |
| 455 | 455 | ||
| 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 | }; |
| 962 | 962 | ||
| 963 | /// Represents the data that an explicit error set syntax provides. | ||
| 964 | pub 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 | |||
| 995 | pub const PropertyBoolean = enum { no, yes, unknown, wip }; | 963 | pub const PropertyBoolean = enum { no, yes, unknown, wip }; |
| 996 | 964 | ||
| 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, |
| 1532 | 1500 | ||
| 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 not | 1502 | /// 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 that | 1529 | /// direct additions via `return error.Foo;`, and possibly also errors that |
| 1569 | /// are returned from any dependent functions. When the inferred error set is | 1530 | /// 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 = .{}, |
| 1572 | 1533 | ||
| 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) = .{}, |
| 1575 | 1536 | ||
| 1576 | /// Whether the function returned anyerror. This is true if either of | 1537 | /// 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, |
| 1583 | 1544 | ||
| 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 | }; |
| 1616 | 1593 | ||
| 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 | } |
| 1630 | 1599 | ||
| 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 | } |
| 3510 | 3479 | ||
| 3480 | pub 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 not | 3484 | /// 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. |
| 3513 | pub fn structPtrUnwrap(mod: *Module, index: Struct.OptionalIndex) ?*Struct { | 3486 | pub 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); |
| 4758 | 4731 | ||
| 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 Sema | 4734 | // 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 | } |
| 4825 | 4798 | ||
| 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 | } |
| 6879 | 6852 | ||
| 6853 | pub 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 | |||
| 6860 | pub 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 | |||
| 6866 | pub 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. | ||
| 6875 | pub 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. |
| 6881 | pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value { | 6890 | pub 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 | } |
| 7242 | 7251 | ||
| 7252 | pub 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 | |||
| 7257 | pub 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 | |||
| 7243 | pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQuery) SrcLoc { | 7262 | pub 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 and | 833 | 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 | } |
| 1802 | 1802 | ||
| 1803 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { | 1803 | pub 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(); |
| 3252 | 3252 | ||
| 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); |
| 3257 | 3258 | ||
| 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); | ||
| 3276 | 3261 | ||
| 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_string | 3264 | 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 AstGen | 3269 | assert(!result.found_existing); // verified in AstGen |
| 3284 | } | 3270 | } |
| 3285 | 3271 | ||
| 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); | ||
| 3288 | 3281 | ||
| 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 | } |
| 3296 | 3284 | ||
| ... | @@ -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 | else | 3395 | 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(); |
| 3728 | 3715 | ||
| ... | @@ -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); |
| 3734 | 3721 | ||
| 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(); |
| 5288 | 5275 | ||
| 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); |
| 5336 | 5324 | ||
| 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( |
| 5588 | 5576 | ||
| 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)); |
| 5592 | 5580 | ||
| 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 instructions | 5582 | // 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 | }; |
| 6435 | 6423 | ||
| 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 pop | 6426 | return call_inst; // call to "fn(...) noreturn", don't pop |
| 6439 | 6427 | ||
| 6440 | // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only | 6428 | // 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); |
| 7847 | 7829 | ||
| 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 | } |
| 7851 | 7833 | ||
| 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(); |
| 7869 | 7851 | ||
| 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 mind | 7854 | // 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 | } |
| 8074 | 8056 | ||
| ... | @@ -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 |
| 8087 | 8069 | ||
| 8088 | fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8070 | fn 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; |
| 8094 | 8074 | 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 |
| 8139 | 8118 | ||
| 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 | } |
| 8226 | 8208 | ||
| 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 | } |
| 8241 | 8223 | ||
| 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 | } |
| 8245 | 8227 | ||
| ... | @@ -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( |
| 8560 | 8542 | ||
| 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() and | 8544 | 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 | } |
| 8604 | 8586 | ||
| 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( |
| 8646 | 8628 | ||
| 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() and | 8630 | 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 | } |
| 8680 | 8662 | ||
| 8681 | const result_ty = operand_ty.errorUnionSet(); | 8663 | const result_ty = operand_ty.errorUnionSet(mod); |
| 8682 | 8664 | ||
| 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 | } |
| 8709 | 8691 | ||
| 8710 | const result_ty = operand_ty.childType(mod).errorUnionSet(); | 8692 | const result_ty = operand_ty.childType(mod).errorUnionSet(mod); |
| 8711 | 8693 | ||
| 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; |
| 8756 | 8738 | ||
| 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 | }; |
| 8761 | 8743 | ||
| ... | @@ -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. | ||
| 8968 | 8947 | ||
| 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_type | 9006 | 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 | }; |
| 9040 | 9015 | ||
| 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); |
| 9048 | 9023 | ||
| 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); |
| 9062 | 9037 | ||
| 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; |
| 9183 | 9158 | ||
| 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); |
| 9187 | 9162 | ||
| 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(); |
| 10140 | 10111 | ||
| 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); |
| 10249 | 10221 | ||
| 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); |
| 10252 | 10224 | ||
| 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 succeed | 10273 | // 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 sorted | 10278 | 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); | ||
| 10311 | 10279 | ||
| 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 succeed | 10283 | // 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; |
| 10317 | 10285 | ||
| 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 |
| 10678 | 10646 | ||
| 10679 | try sema.resolveInferredErrorSetTy(block, src, operand_ty); | 10647 | try sema.resolveInferredErrorSetTy(block, src, operand_ty); |
| 10680 | 10648 | ||
| 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); |
| 10694 | 10662 | ||
| 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 | } |
| 10722 | 10691 | ||
| 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 bodies | 10693 | // 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 | } |
| 10759 | 10728 | ||
| 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; |
| 10765 | 10735 | ||
| 10766 | names.putAssumeCapacityNoClobber(error_name, {}); | 10736 | names.putAssumeCapacityNoClobber(error_name_ip, {}); |
| 10767 | } | 10737 | } |
| 10768 | 10738 | // No need to keep the hash map metadata correct; here we | |
| 10769 | // names must be sorted | 10739 | // 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; |
| 11524 | 11494 | ||
| ... | @@ -11931,7 +11901,8 @@ fn validateSwitchNoRange( | ... | @@ -11931,7 +11901,8 @@ fn validateSwitchNoRange( |
| 11931 | } | 11901 | } |
| 11932 | 11902 | ||
| 11933 | fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool { | 11903 | fn 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; | ||
| 11935 | 11906 | ||
| 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 | } |
| 12195 | 12166 | ||
| 12196 | fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 12167 | fn 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); |
| 12199 | 12171 | ||
| 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"; |
| 15738 | 15710 | ||
| 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 | }; |
| 16228 | 16200 | ||
| 16229 | try sema.queueFullTypeResolution(try error_field_ty.copy(sema.arena)); | 16201 | try sema.queueFullTypeResolution(error_field_ty); |
| 16230 | 16202 | ||
| 16231 | // If the error set is inferred it must be resolved at this point | 16203 | // 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 values | 16206 | // Build our list of Error values |
| 16235 | // Optional value is only null if anyerror | 16207 | // Optional value is only null if anyerror |
| 16236 | // Value can be zero-length slice otherwise | 16208 | // 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)); |
| 16307 | 16279 | ||
| 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 | }; |
| 16337 | 16309 | ||
| 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 | }; |
| 16421 | 16393 | ||
| 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 layout | 16501 | 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); |
| 16739 | 16711 | ||
| 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); |
| 17019 | 16991 | ||
| 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 | } |
| 17024 | 16996 | ||
| 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 | }; |
| 17217 | 17189 | ||
| ... | @@ -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(); |
| 17420 | 17393 | ||
| 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) |
| 17632 | 17605 | ||
| 17633 | fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { | 17606 | fn 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); |
| 17636 | 17611 | ||
| 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 alignment | 18497 | 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]; |
| 18994 | 18965 | ||
| 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]; |
| 19013 | 18984 | ||
| 19014 | const child_ty = try child_val.toType().copy(sema.arena); | 18985 | const child_ty = child_val.toType(); |
| 19015 | 18986 | ||
| 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]; |
| 19026 | 18997 | ||
| 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(); |
| 19029 | 19000 | ||
| 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 | } |
| 19033 | 19004 | ||
| 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; |
| 19044 | 19012 | ||
| 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 here | 19019 | // 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); |
| 19056 | 19023 | 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 | } |
| 19063 | 19029 | ||
| 19064 | // names must be sorted | 19030 | 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 | } |
| 19380 | 19344 | ||
| 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 | } |
| 19675 | 19639 | ||
| 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 | } |
| 20036 | 20000 | ||
| 20037 | fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 20001 | fn 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 |
| 20050 | 20016 | ||
| 20051 | if (disjoint: { | 20017 | if (disjoint: { |
| 20052 | // Try avoiding resolving inferred error sets if we can | 20018 | // 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 | } | ||
| 20060 | 20027 | ||
| 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 | } | ||
| 20063 | 20033 | ||
| 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 | } | ||
| 20069 | 20040 | ||
| 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 | } |
| 20086 | 20057 | ||
| 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 | } |
| 20108 | 20079 | ||
| 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; |
| 22863 | 22834 | ||
| 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; |
| 22879 | 22850 | ||
| ... | @@ -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), |
| 23362 | 23333 | ||
| 23363 | .ErrorUnion => ty = ty.errorUnionPayload(), | 23334 | .ErrorUnion => ty = ty.errorUnionPayload(mod), |
| 23364 | 23335 | ||
| 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 | }, |
| 23457 | 23428 | ||
| 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. |
| 24066 | 24037 | ||
| 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 location | 24042 | const object_src = src; // TODO better source location |
| 24070 | const object_ty = sema.typeOf(object); | 24043 | const object_ty = sema.typeOf(object); |
| 24071 | 24044 | ||
| ... | @@ -24147,27 +24120,33 @@ fn fieldVal( | ... | @@ -24147,27 +24120,33 @@ fn fieldVal( |
| 24147 | 24120 | ||
| 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 | } | ||
| 24164 | 24143 | ||
| 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 | else | 24147 | 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. |
| 24253 | 24232 | ||
| 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 location | 24236 | 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( |
| 24362 | 24343 | ||
| 24363 | switch (child_type.zigTypeTag(mod)) { | 24344 | switch (child_type.zigTypeTag(mod)) { |
| 24364 | .ErrorSet => { | 24345 | .ErrorSet => { |
| 24365 | // TODO resolve inferred error sets | 24346 | 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 | } | ||
| 24374 | 24362 | ||
| 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 | else | 24368 | 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 alignment | 24373 | 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 and | 24581 | } 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( |
| 24832 | 24822 | ||
| 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( |
| 26342 | 26332 | ||
| 26343 | // E!T to T | 26333 | // E!T to T |
| 26344 | if (inst_ty.zigTypeTag(mod) == .ErrorUnion and | 26334 | 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 args | 26387 | /// true if wanted is var args |
| 26398 | fn_var_args: bool, | 26388 | fn_var_args: bool, |
| 26399 | /// true if wanted is generic | 26389 | /// 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( |
| 26813 | 26804 | ||
| 26814 | // Error Unions | 26805 | // 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 | } |
| 26828 | 26819 | ||
| 26829 | // Error Sets | 26820 | // 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 | } |
| 26910 | 26901 | ||
| ... | @@ -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; | ||
| 26929 | 26922 | ||
| 26930 | // Coercion to `anyerror`. Note that this check can return false negatives | 26923 | // 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 | } |
| 26935 | 26928 | ||
| 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, to | 26931 | // 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, and | 26937 | // 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 resolution | 26939 | // 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 | } |
| 26976 | 26953 | ||
| 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's | 26955 | // 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 | } |
| 26983 | 26960 | ||
| 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 | } |
| 26990 | 26967 | ||
| 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(); |
| 26993 | 26970 | ||
| 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); | ||
| 26998 | 26982 | ||
| 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 | } |
| 27005 | 26989 | ||
| 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 | } |
| 27011 | 26995 | ||
| 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 | } |
| 27042 | 27001 | ||
| 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 | } |
| 27052 | 27010 | ||
| 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 | } |
| 27058 | 27016 | ||
| ... | @@ -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 | } |
| 27076 | 27022 | ||
| 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 alignment | 29252 | 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 alignment | 29338 | 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); |
| 29557 | 29503 | ||
| 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( |
| 29577 | 29523 | ||
| 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 set | 29535 | // 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 | } |
| 29625 | 29570 | ||
| ... | @@ -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 => {}, |
| 30541 | 30489 | 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; | ||
| 30559 | 30501 | ||
| 30560 | // We carefully do this in an order that avoids unnecessarily | 30502 | // 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 | } |
| 30567 | 30512 | ||
| 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 | } |
| 30745 | 30681 | ||
| 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); |
| 30751 | 30687 | ||
| 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 | } |
| 30759 | 30695 | ||
| 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 | } |
| 30772 | 30708 | ||
| 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); |
| 30785 | 30721 | ||
| 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 | }, |
| 30797 | 30733 | ||
| 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); |
| 30801 | 30737 | ||
| 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 | } |
| 30813 | 30749 | ||
| 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); |
| 30816 | 30752 | ||
| 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( |
| 30827 | 30763 | ||
| 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); |
| 30969 | 30905 | ||
| ... | @@ -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 | } |
| 31092 | 31028 | ||
| 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 | else | 31084 | 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 | } |
| 31153 | 31089 | ||
| 31154 | if (seen_const) { | 31090 | if (seen_const) { |
| 31155 | // turn []T => []const T | 31091 | // 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 | else | 31100 | 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 | else | 31111 | 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 | } |
| 31192 | 31128 | ||
| 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 | }; |
| 31201 | 31137 | ||
| 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 | }; |
| 31466 | 31402 | ||
| 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 { |
| 31605 | 31541 | ||
| 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, |
| 31639 | 31565 | ||
| 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; |
| 32054 | 31983 | ||
| 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 | } |
| 32058 | 31987 | ||
| 32059 | const mod = sema.mod; | ||
| 32060 | |||
| 32061 | // In order to ensure that all dependencies are properly added to the set, we | 31988 | // 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( |
| 32090 | 32017 | ||
| 32091 | ies.is_resolved = true; | 32018 | ies.is_resolved = true; |
| 32092 | 32019 | ||
| 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); |
| 32096 | 32023 | ||
| 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 | } |
| 32115 | 32044 | ||
| ... | @@ -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 | } |
| 32334 | 32263 | ||
| 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; |
| 32337 | 32266 | ||
| 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 | } |
| 32810 | 32739 | ||
| 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 | }; |
| 32815 | 32744 | ||
| ... | @@ -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, |
| 33039 | 32968 | ||
| 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, |
| 33066 | 32990 | ||
| 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(); |
| 33390 | 33314 | ||
| 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 or | 33317 | // 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 expand | 33318 | // 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 | } |
| 33607 | 33529 | ||
| ... | @@ -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, |
| 33618 | 33540 | ||
| 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, |
| 33653 | 33566 | ||
| 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. | ||
| 34329 | fn 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. |
| 28 | pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue { | 28 | pub 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 | } |
| 34 | 34 | ||
| 35 | pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool { | 35 | pub 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 | } |
| 39 | 39 | ||
| ... | @@ -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; |
| 3312 | 3312 | ||
| ... | @@ -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; |
| 3336 | 3336 | ||
| ... | @@ -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); |
| 4897 | 4897 | ||
| 4898 | if (error_type.errorSetIsEmpty(mod)) { | 4898 | if (error_type.errorSetIsEmpty(mod)) { |
| 4899 | return MCValue{ .immediate = 0 }; // always false | 4899 | 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; |
| 2239 | 2239 | ||
| ... | @@ -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; |
| 2263 | 2263 | ||
| ... | @@ -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); |
| 4875 | 4875 | ||
| 4876 | if (error_type.errorSetIsEmpty(mod)) { | 4876 | if (error_type.errorSetIsEmpty(mod)) { |
| 4877 | return MCValue{ .immediate = 0 }; // always false | 4877 | 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 | } |
| 2708 | 2708 | ||
| 2709 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { | 2709 | fn 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; |
| 2717 | 2717 | ||
| 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 | } |
| 2722 | 2722 | ||
| 2723 | fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { | 2723 | fn 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; |
| 2730 | 2730 | ||
| 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 { |
| 2735 | 2735 | ||
| 2736 | /// E to E!T | 2736 | /// E to E!T |
| 2737 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | 2737 | fn 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; |
| 2745 | 2745 | ||
| 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 payload | 3529 | /// Given an error union, returns the payload |
| 3530 | fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue { | 3530 | fn 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 { |
| 4168 | 4168 | ||
| 4169 | fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue { | 4169 | fn 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); |
| 4173 | 4173 | ||
| 4174 | if (!error_type.hasRuntimeBits(mod)) { | 4174 | if (!error_type.hasRuntimeBits(mod)) { |
| 4175 | return MCValue{ .immediate = 0 }; // always false | 4175 | 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); |
| 3920 | 3920 | ||
| 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); |
| 3957 | 3957 | ||
| 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); |
| 3985 | 3985 | ||
| 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 | } |
| 3990 | 3990 | ||
| ... | @@ -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 { |
| 4031 | 4031 | ||
| 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); |
| 4035 | 4035 | ||
| 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 { |
| 4044 | 4044 | ||
| 4045 | // write 'undefined' to the payload | 4045 | // 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 }); |
| 4049 | 4049 | ||
| 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; |
| 5363 | 5363 | ||
| 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); |
| 5367 | 5367 | ||
| 5368 | // set error-tag to '0' to annotate error union is non-error | 5368 | // 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 | } |
| 6179 | 6179 | ||
| 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); |
| 6182 | 6182 | ||
| 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 set | 6184 | // 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); |
| 6186 | 6186 | ||
| ... | @@ -6742,7 +6742,7 @@ fn callIntrinsic( | ... | @@ -6742,7 +6742,7 @@ fn callIntrinsic( |
| 6742 | 6742 | ||
| 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 | } |
| 6942 | 6942 | ||
| 6943 | fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 6943 | fn 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; |
| 6945 | 6946 | ||
| 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); |
| 6949 | 6950 | ||
| 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(); |
| 6953 | 6954 | ||
| 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); |
| 3618 | 3618 | ||
| 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); |
| 3675 | 3675 | ||
| 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); |
| 3732 | 3732 | ||
| 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); |
| 3772 | 3772 | ||
| 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); |
| 3798 | 3798 | ||
| 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; |
| 3902 | 3902 | ||
| 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); |
| 3907 | 3907 | ||
| 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; |
| 3925 | 3925 | ||
| 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); |
| 3929 | 3929 | ||
| 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) |
| 8782 | 8782 | ||
| 8783 | fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !MCValue { | 8783 | fn 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); |
| 8786 | 8786 | ||
| 8787 | if (err_type.errorSetIsEmpty(mod)) { | 8787 | if (err_type.errorSetIsEmpty(mod)) { |
| 8788 | return MCValue{ .immediate = 0 }; // always false | 8788 | 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 | } |
| 8795 | 8795 | ||
| 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 | } |
| 141 | 141 | ||
| 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(); |
| 676 | 676 | ||
| 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(); |
| 1255 | 1255 | ||
| 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); |
| 867 | 867 | ||
| 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; |
| 1258 | 1258 | ||
| 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 | } |
| 4253 | 4253 | ||
| 4254 | fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { | 4254 | fn 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(); |
| 4285 | 4286 | ||
| 4286 | // noreturn blocks have no `br` instructions reaching them, so we don't want a label | 4287 | // 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); |
| 4327 | 4328 | ||
| 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 { |
| 5500 | 5501 | ||
| 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); |
| 5506 | 5507 | ||
| 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; |
| 5540 | 5541 | ||
| 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; |
| 5544 | 5545 | ||
| 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; |
| 5602 | 5603 | ||
| 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}); |
| 5609 | 5610 | ||
| ... | @@ -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); |
| 5644 | 5645 | ||
| 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); |
| 5647 | 5648 | ||
| 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; |
| 5692 | 5693 | ||
| 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}); |
| 5699 | 5700 | ||
| 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); |
| 5734 | 5735 | ||
| 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 of | 365 | /// 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 compilation | 367 | /// 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 because | 368 | /// 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 in | 372 | /// 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), |
| 383 | 379 | ||
| 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 | ); | ||
| 390 | 381 | ||
| 391 | /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we | 382 | /// 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); |
| 2825 | 2811 | ||
| 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.*; |
| 2828 | 2814 | ||
| 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.*; |
| 2918 | 2904 | ||
| 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.*; |
| 3046 | 3028 | ||
| 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).?; |
| 3053 | 3031 | ||
| ... | @@ -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(); |
| 3576 | 3554 | ||
| 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); |
| 4132 | 4110 | ||
| 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 pointer | 4113 | // 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"); |
| 5370 | 5348 | ||
| 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); |
| 5496 | 5474 | ||
| 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 | } |
| 5602 | 5580 | ||
| 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 can | 5595 | // 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 on | 5596 | // 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(); |
| 6680 | 6659 | ||
| 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 == 0 | 6663 | .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 { |
| 6836 | 6815 | ||
| 6837 | const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror); | 6816 | const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror); |
| 6838 | 6817 | ||
| 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); |
| 6861 | 6840 | ||
| 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); |
| 8789 | 8768 | ||
| 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)); |
| 8795 | 8774 | ||
| 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); |
| 807 | 807 | ||
| ... | @@ -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); |
| 1370 | 1370 | ||
| 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 { |
| 2875 | 2875 | ||
| 2876 | const eu_layout = self.errorUnionLayout(payload_ty); | 2876 | const eu_layout = self.errorUnionLayout(payload_ty); |
| 2877 | 2877 | ||
| 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 | else | 2881 | 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); |
| 2931 | 2931 | ||
| 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 | } |
| 2936 | 2936 | ||
| 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); |
| 2939 | 2939 | ||
| 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; |
| 2950 | 2950 | ||
| 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); |
| 2956 | 2957 |
src/link/Dwarf.zig+31-23| ... | @@ -18,6 +18,7 @@ const LinkBlock = File.LinkBlock; | ... | @@ -18,6 +18,7 @@ const LinkBlock = File.LinkBlock; |
| 18 | const LinkFn = File.LinkFn; | 18 | const LinkFn = File.LinkFn; |
| 19 | const LinkerLoad = @import("../codegen.zig").LinkerLoad; | 19 | const LinkerLoad = @import("../codegen.zig").LinkerLoad; |
| 20 | const Module = @import("../Module.zig"); | 20 | const Module = @import("../Module.zig"); |
| 21 | const InternPool = @import("../InternPool.zig"); | ||
| 21 | const StringTable = @import("strtab.zig").StringTable; | 22 | const StringTable = @import("strtab.zig").StringTable; |
| 22 | const Type = @import("../type.zig").Type; | 23 | const Type = @import("../type.zig").Type; |
| 23 | const Value = @import("../value.zig").Value; | 24 | const 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}); |
| 536 | 537 | ||
| 537 | if (!payload_ty.isNoReturn()) { | 538 | if (!payload_ty.isNoReturn(mod)) { |
| 538 | // DW.AT.member | 539 | // 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(); |
| 2531 | 2534 | ||
| 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; | ||
| 2541 | 2545 | ||
| 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); |
| 2544 | 2551 | ||
| 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.data8 | 2691 | // 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); |
| 2686 | 2693 | ||
| 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.enumerator | 2698 | // 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 | } |
| 132 | 125 | ||
| 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; |
| 295 | 288 | ||
| 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 { |
| 367 | 331 | ||
| 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 | } |
| 386 | 336 | ||
| ... | @@ -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 | } |
| 454 | 372 | ||
| ... | @@ -484,52 +402,6 @@ pub const Type = struct { | ... | @@ -484,52 +402,6 @@ pub const Type = struct { |
| 484 | } | 402 | } |
| 485 | }; | 403 | }; |
| 486 | 404 | ||
| 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 | } |
| 635 | 452 | ||
| 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 | } |
| 883 | 679 | ||
| 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 | } |
| 892 | 683 | ||
| 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, |
| 915 | 706 | ||
| 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, | ||
| 967 | 753 | ||
| 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 layout | 890 | /// 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, | ||
| 1108 | 897 | ||
| 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, | ||
| 1116 | 907 | ||
| 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, |
| 1125 | 932 | ||
| 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, |
| 1133 | 955 | ||
| 1134 | .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod), | 956 | .var_args_param => unreachable, |
| 1135 | .opt_type => ty.isPtrLikeOptional(mod), | 957 | }, |
| 1136 | 958 | .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 | } |
| 1214 | 987 | ||
| ... | @@ -1247,35 +1020,8 @@ pub const Type = struct { | ... | @@ -1247,35 +1020,8 @@ pub const Type = struct { |
| 1247 | }; | 1020 | }; |
| 1248 | } | 1021 | } |
| 1249 | 1022 | ||
| 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 | } |
| 1280 | 1026 | ||
| 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 { |
| 1353 | 1099 | ||
| 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 | }, |
| 1389 | 1120 | ||
| 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 pointer | 1127 | // 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 prong | 1312 | // 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 }, |
| 1730 | 1465 | ||
| 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 | }; | ||
| 1822 | 1536 | ||
| 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 pointer | 1551 | .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); |
| 1984 | 1710 | ||
| 1985 | if (child_ty.isNoReturn()) { | 1711 | if (child_ty.isNoReturn(mod)) { |
| 1986 | return AbiSizeAdvanced{ .scalar = 0 }; | 1712 | return AbiSizeAdvanced{ .scalar = 0 }; |
| 1987 | } | 1713 | } |
| 1988 | 1714 | ||
| ... | @@ -2041,147 +1767,137 @@ pub const Type = struct { | ... | @@ -2041,147 +1767,137 @@ pub const Type = struct { |
| 2041 | 1767 | ||
| 2042 | const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager; | 1768 | const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager; |
| 2043 | 1769 | ||
| 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, |
| 2048 | 1774 | 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 type | 1779 | 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, | ||
| 2054 | 1831 | ||
| 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 bitsize | 1833 | .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 | }, | ||
| 2155 | 1867 | ||
| 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()); | ||
| 2163 | 1872 | ||
| 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), | ||
| 2172 | 1880 | ||
| 2173 | // values, not types | 1881 | 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 | } |
| 2187 | 1903 | ||
| ... | @@ -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 | } |
| 2535 | 2247 | ||
| 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 | } |
| 2547 | 2252 | ||
| 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 | } |
| 2558 | 2257 | ||
| 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 | } |
| 2587 | 2275 | ||
| 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 set | 2277 | /// 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 | } |
| 2602 | 2288 | ||
| ... | @@ -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 fully | 2297 | /// 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, |
| 2617 | 2303 | ) 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 | } |
| 2638 | 2344 | ||
| 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; |
| 2728 | 2434 | ||
| 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 types | 2437 | // 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(), |
| 2762 | 2460 | ||
| 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, |
| 2764 | 2465 | ||
| 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, |
| 2933 | 2634 | ||
| 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, |
| 2959 | 2655 | ||
| 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, |
| 3132 | 2828 | ||
| 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, |
| 3165 | 2854 | ||
| ... | @@ -3418,17 +3107,11 @@ pub const Type = struct { | ... | @@ -3418,17 +3107,11 @@ pub const Type = struct { |
| 3418 | } | 3107 | } |
| 3419 | 3108 | ||
| 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 problems | 3113 | .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 | } |
| 3439 | 3122 | ||
| 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 | } |
| 3749 | 3412 | ||
| 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 | } |
| 3776 | 3428 | ||
| 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 | } |
| 3780 | 3432 | ||
| 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 | } |
| 3806 | 3448 | ||
| 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 | } |
| 3810 | 3452 | ||
| 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` because | 3453 | /// 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 types | 3455 | /// 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. |
| 3829 | 3467 | ||
| 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 | }; |
| 3879 | 3471 | ||
| 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, |
| 3930 | 3522 | ||
| 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 | }; |
| 4035 | 3575 | ||
| 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 | } |
| 4166 | 3706 | ||
| 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); // error | 2165 | 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 | } |
| 2170 | 2170 | ||
| 2171 | if (val.castTag(.eu_payload)) |payload| { | 2171 | if (val.castTag(.eu_payload)) |payload| { |
| 2172 | std.hash.autoHash(hasher, true); // payload | 2172 | 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 => { |