| author | |
| committer | |
| log | 68b95a39b1fe734b938ec02fa2b16bbb63170f87 |
| tree | b86f3f97c04c23ad7e23d910d0fe65d5b06f27b4 |
| parent | fd674d95bee4815783bb282c80ba6af369296706 |
Also modify coercion in Sema to be InternPool-aware by calling
getCoerced.
The unnecessary comptime logic in mod.intValue is deleted too4 files changed, 212 insertions(+), 71 deletions(-)
src/InternPool.zig+135-45| ... | @@ -55,6 +55,7 @@ pub const Key = union(enum) { | ... | @@ -55,6 +55,7 @@ pub const Key = union(enum) { |
| 55 | lib_name: u32, | 55 | lib_name: u32, |
| 56 | }, | 56 | }, |
| 57 | int: Key.Int, | 57 | int: Key.Int, |
| 58 | ptr: Key.Ptr, | ||
| 58 | enum_tag: struct { | 59 | enum_tag: struct { |
| 59 | ty: Index, | 60 | ty: Index, |
| 60 | tag: BigIntConst, | 61 | tag: BigIntConst, |
| ... | @@ -140,6 +141,16 @@ pub const Key = union(enum) { | ... | @@ -140,6 +141,16 @@ pub const Key = union(enum) { |
| 140 | }; | 141 | }; |
| 141 | }; | 142 | }; |
| 142 | 143 | ||
| 144 | pub const Ptr = struct { | ||
| 145 | ty: Index, | ||
| 146 | addr: Addr, | ||
| 147 | |||
| 148 | pub const Addr = union(enum) { | ||
| 149 | decl: DeclIndex, | ||
| 150 | int: Index, | ||
| 151 | }; | ||
| 152 | }; | ||
| 153 | |||
| 143 | pub fn hash32(key: Key) u32 { | 154 | pub fn hash32(key: Key) u32 { |
| 144 | return @truncate(u32, key.hash64()); | 155 | return @truncate(u32, key.hash64()); |
| 145 | } | 156 | } |
| ... | @@ -176,6 +187,16 @@ pub const Key = union(enum) { | ... | @@ -176,6 +187,16 @@ pub const Key = union(enum) { |
| 176 | for (big_int.limbs) |limb| std.hash.autoHash(hasher, limb); | 187 | for (big_int.limbs) |limb| std.hash.autoHash(hasher, limb); |
| 177 | }, | 188 | }, |
| 178 | 189 | ||
| 190 | .ptr => |ptr| { | ||
| 191 | std.hash.autoHash(hasher, ptr.ty); | ||
| 192 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. | ||
| 193 | // This is sound due to pointer province rules. | ||
| 194 | switch (ptr.addr) { | ||
| 195 | .int => |int| std.hash.autoHash(hasher, int), | ||
| 196 | .decl => @panic("TODO"), | ||
| 197 | } | ||
| 198 | }, | ||
| 199 | |||
| 179 | .enum_tag => |enum_tag| { | 200 | .enum_tag => |enum_tag| { |
| 180 | std.hash.autoHash(hasher, enum_tag.ty); | 201 | std.hash.autoHash(hasher, enum_tag.ty); |
| 181 | std.hash.autoHash(hasher, enum_tag.tag.positive); | 202 | std.hash.autoHash(hasher, enum_tag.tag.positive); |
| ... | @@ -237,8 +258,30 @@ pub const Key = union(enum) { | ... | @@ -237,8 +258,30 @@ pub const Key = union(enum) { |
| 237 | return std.meta.eql(a_info, b_info); | 258 | return std.meta.eql(a_info, b_info); |
| 238 | }, | 259 | }, |
| 239 | 260 | ||
| 261 | .ptr => |a_info| { | ||
| 262 | const b_info = b.ptr; | ||
| 263 | |||
| 264 | if (a_info.ty != b_info.ty) | ||
| 265 | return false; | ||
| 266 | |||
| 267 | return switch (a_info.addr) { | ||
| 268 | .int => |a_int| switch (b_info.addr) { | ||
| 269 | .int => |b_int| a_int == b_int, | ||
| 270 | .decl => false, | ||
| 271 | }, | ||
| 272 | .decl => |a_decl| switch (b_info.addr) { | ||
| 273 | .int => false, | ||
| 274 | .decl => |b_decl| a_decl == b_decl, | ||
| 275 | }, | ||
| 276 | }; | ||
| 277 | }, | ||
| 278 | |||
| 240 | .int => |a_info| { | 279 | .int => |a_info| { |
| 241 | const b_info = b.int; | 280 | const b_info = b.int; |
| 281 | |||
| 282 | if (a_info.ty != b_info.ty) | ||
| 283 | return false; | ||
| 284 | |||
| 242 | return switch (a_info.storage) { | 285 | return switch (a_info.storage) { |
| 243 | .u64 => |aa| switch (b_info.storage) { | 286 | .u64 => |aa| switch (b_info.storage) { |
| 244 | .u64 => |bb| aa == bb, | 287 | .u64 => |bb| aa == bb, |
| ... | @@ -298,9 +341,11 @@ pub const Key = union(enum) { | ... | @@ -298,9 +341,11 @@ pub const Key = union(enum) { |
| 298 | .union_type, | 341 | .union_type, |
| 299 | => return .type_type, | 342 | => return .type_type, |
| 300 | 343 | ||
| 301 | .int => |x| return x.ty, | 344 | inline .ptr, |
| 302 | .extern_func => |x| return x.ty, | 345 | .int, |
| 303 | .enum_tag => |x| return x.ty, | 346 | .extern_func, |
| 347 | .enum_tag, | ||
| 348 | => |x| return x.ty, | ||
| 304 | 349 | ||
| 305 | .simple_value => |s| switch (s) { | 350 | .simple_value => |s| switch (s) { |
| 306 | .undefined => return .undefined_type, | 351 | .undefined => return .undefined_type, |
| ... | @@ -724,6 +769,9 @@ pub const Tag = enum(u8) { | ... | @@ -724,6 +769,9 @@ pub const Tag = enum(u8) { |
| 724 | /// only an enum tag, but will be presented via the API with a different Key. | 769 | /// only an enum tag, but will be presented via the API with a different Key. |
| 725 | /// data is SimpleInternal enum value. | 770 | /// data is SimpleInternal enum value. |
| 726 | simple_internal, | 771 | simple_internal, |
| 772 | /// A pointer to an integer value. | ||
| 773 | /// data is extra index of PtrInt, which contains the type and address. | ||
| 774 | ptr_int, | ||
| 727 | /// Type: u8 | 775 | /// Type: u8 |
| 728 | /// data is integer value | 776 | /// data is integer value |
| 729 | int_u8, | 777 | int_u8, |
| ... | @@ -897,16 +945,13 @@ pub const Array = struct { | ... | @@ -897,16 +945,13 @@ pub const Array = struct { |
| 897 | child: Index, | 945 | child: Index, |
| 898 | sentinel: Index, | 946 | sentinel: Index, |
| 899 | 947 | ||
| 900 | pub const Length = packed struct(u64) { | 948 | pub const Length = PackedU64; |
| 901 | len0: u32, | ||
| 902 | len1: u32, | ||
| 903 | }; | ||
| 904 | 949 | ||
| 905 | pub fn getLength(a: Array) u64 { | 950 | pub fn getLength(a: Array) u64 { |
| 906 | return @bitCast(u64, Length{ | 951 | return (PackedU64{ |
| 907 | .len0 = a.len0, | 952 | .a = a.len0, |
| 908 | .len1 = a.len1, | 953 | .b = a.len1, |
| 909 | }); | 954 | }).get(); |
| 910 | } | 955 | } |
| 911 | }; | 956 | }; |
| 912 | 957 | ||
| ... | @@ -929,6 +974,24 @@ pub const EnumSimple = struct { | ... | @@ -929,6 +974,24 @@ pub const EnumSimple = struct { |
| 929 | fields_len: u32, | 974 | fields_len: u32, |
| 930 | }; | 975 | }; |
| 931 | 976 | ||
| 977 | pub const PackedU64 = packed struct(u64) { | ||
| 978 | a: u32, | ||
| 979 | b: u32, | ||
| 980 | |||
| 981 | pub fn get(x: PackedU64) u64 { | ||
| 982 | return @bitCast(u64, x); | ||
| 983 | } | ||
| 984 | |||
| 985 | pub fn init(x: u64) PackedU64 { | ||
| 986 | return @bitCast(PackedU64, x); | ||
| 987 | } | ||
| 988 | }; | ||
| 989 | |||
| 990 | pub const PtrInt = struct { | ||
| 991 | ty: Index, | ||
| 992 | addr: Index, | ||
| 993 | }; | ||
| 994 | |||
| 932 | /// Trailing: Limb for every limbs_len | 995 | /// Trailing: Limb for every limbs_len |
| 933 | pub const Int = struct { | 996 | pub const Int = struct { |
| 934 | ty: Index, | 997 | ty: Index, |
| ... | @@ -1066,6 +1129,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { | ... | @@ -1066,6 +1129,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 1066 | .fields_len = 0, | 1129 | .fields_len = 0, |
| 1067 | } }, | 1130 | } }, |
| 1068 | }, | 1131 | }, |
| 1132 | .ptr_int => { | ||
| 1133 | const info = ip.extraData(PtrInt, data); | ||
| 1134 | return .{ .ptr = .{ | ||
| 1135 | .ty = info.ty, | ||
| 1136 | .addr = .{ .int = info.addr }, | ||
| 1137 | } }; | ||
| 1138 | }, | ||
| 1069 | .int_u8 => .{ .int = .{ | 1139 | .int_u8 => .{ .int = .{ |
| 1070 | .ty = .u8_type, | 1140 | .ty = .u8_type, |
| 1071 | .storage = .{ .u64 = data }, | 1141 | .storage = .{ .u64 = data }, |
| ... | @@ -1188,12 +1258,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -1188,12 +1258,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 1188 | } | 1258 | } |
| 1189 | } | 1259 | } |
| 1190 | 1260 | ||
| 1191 | const length = @bitCast(Array.Length, array_type.len); | 1261 | const length = Array.Length.init(array_type.len); |
| 1192 | ip.items.appendAssumeCapacity(.{ | 1262 | ip.items.appendAssumeCapacity(.{ |
| 1193 | .tag = .type_array_big, | 1263 | .tag = .type_array_big, |
| 1194 | .data = try ip.addExtra(gpa, Array{ | 1264 | .data = try ip.addExtra(gpa, Array{ |
| 1195 | .len0 = length.len0, | 1265 | .len0 = length.a, |
| 1196 | .len1 = length.len1, | 1266 | .len1 = length.b, |
| 1197 | .child = array_type.child, | 1267 | .child = array_type.child, |
| 1198 | .sentinel = array_type.sentinel, | 1268 | .sentinel = array_type.sentinel, |
| 1199 | }), | 1269 | }), |
| ... | @@ -1237,6 +1307,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -1237,6 +1307,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 1237 | }, | 1307 | }, |
| 1238 | .extern_func => @panic("TODO"), | 1308 | .extern_func => @panic("TODO"), |
| 1239 | 1309 | ||
| 1310 | .ptr => |ptr| switch (ptr.addr) { | ||
| 1311 | .decl => @panic("TODO"), | ||
| 1312 | .int => |int| { | ||
| 1313 | assert(ptr.ty != .none); | ||
| 1314 | ip.items.appendAssumeCapacity(.{ | ||
| 1315 | .tag = .ptr_int, | ||
| 1316 | .data = try ip.addExtra(gpa, PtrInt{ | ||
| 1317 | .ty = ptr.ty, | ||
| 1318 | .addr = int, | ||
| 1319 | }), | ||
| 1320 | }); | ||
| 1321 | }, | ||
| 1322 | }, | ||
| 1323 | |||
| 1240 | .int => |int| b: { | 1324 | .int => |int| b: { |
| 1241 | switch (int.ty) { | 1325 | switch (int.ty) { |
| 1242 | .none => unreachable, | 1326 | .none => unreachable, |
| ... | @@ -1620,38 +1704,43 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index { | ... | @@ -1620,38 +1704,43 @@ pub fn slicePtrType(ip: InternPool, i: Index) Index { |
| 1620 | } | 1704 | } |
| 1621 | } | 1705 | } |
| 1622 | 1706 | ||
| 1623 | /// Given an existing integer value, returns the same numerical value but with | 1707 | /// Given an existing value, returns the same value but with the supplied type. |
| 1624 | /// the supplied type. | 1708 | /// Only some combinations are allowed: |
| 1625 | pub fn getCoercedInt(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { | 1709 | /// * int to int |
| 1626 | const key = ip.indexToKey(val); | 1710 | pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index { |
| 1627 | // The key cannot be passed directly to `get`, otherwise in the case of | 1711 | switch (ip.indexToKey(val)) { |
| 1628 | // big_int storage, the limbs would be invalidated before they are read. | 1712 | .int => |int| { |
| 1629 | // Here we pre-reserve the limbs to ensure that the logic in `addInt` will | 1713 | // The key cannot be passed directly to `get`, otherwise in the case of |
| 1630 | // not use an invalidated limbs pointer. | 1714 | // big_int storage, the limbs would be invalidated before they are read. |
| 1631 | switch (key.int.storage) { | 1715 | // Here we pre-reserve the limbs to ensure that the logic in `addInt` will |
| 1632 | .u64 => |x| return ip.get(gpa, .{ .int = .{ | 1716 | // not use an invalidated limbs pointer. |
| 1633 | .ty = new_ty, | 1717 | switch (int.storage) { |
| 1634 | .storage = .{ .u64 = x }, | 1718 | .u64 => |x| return ip.get(gpa, .{ .int = .{ |
| 1635 | } }), | 1719 | .ty = new_ty, |
| 1636 | .i64 => |x| return ip.get(gpa, .{ .int = .{ | 1720 | .storage = .{ .u64 = x }, |
| 1637 | .ty = new_ty, | 1721 | } }), |
| 1638 | .storage = .{ .i64 = x }, | 1722 | .i64 => |x| return ip.get(gpa, .{ .int = .{ |
| 1639 | } }), | 1723 | .ty = new_ty, |
| 1640 | 1724 | .storage = .{ .i64 = x }, | |
| 1641 | .big_int => |big_int| { | 1725 | } }), |
| 1642 | const positive = big_int.positive; | 1726 | |
| 1643 | const limbs = ip.limbsSliceToIndex(big_int.limbs); | 1727 | .big_int => |big_int| { |
| 1644 | // This line invalidates the limbs slice, but the indexes computed in the | 1728 | const positive = big_int.positive; |
| 1645 | // previous line are still correct. | 1729 | const limbs = ip.limbsSliceToIndex(big_int.limbs); |
| 1646 | try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len); | 1730 | // This line invalidates the limbs slice, but the indexes computed in the |
| 1647 | return ip.get(gpa, .{ .int = .{ | 1731 | // previous line are still correct. |
| 1648 | .ty = new_ty, | 1732 | try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len); |
| 1649 | .storage = .{ .big_int = .{ | 1733 | return ip.get(gpa, .{ .int = .{ |
| 1650 | .limbs = ip.limbsIndexToSlice(limbs), | 1734 | .ty = new_ty, |
| 1651 | .positive = positive, | 1735 | .storage = .{ .big_int = .{ |
| 1652 | } }, | 1736 | .limbs = ip.limbsIndexToSlice(limbs), |
| 1653 | } }); | 1737 | .positive = positive, |
| 1738 | } }, | ||
| 1739 | } }); | ||
| 1740 | }, | ||
| 1741 | } | ||
| 1654 | }, | 1742 | }, |
| 1743 | else => unreachable, | ||
| 1655 | } | 1744 | } |
| 1656 | } | 1745 | } |
| 1657 | 1746 | ||
| ... | @@ -1708,6 +1797,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void { | ... | @@ -1708,6 +1797,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void { |
| 1708 | .simple_type => 0, | 1797 | .simple_type => 0, |
| 1709 | .simple_value => 0, | 1798 | .simple_value => 0, |
| 1710 | .simple_internal => 0, | 1799 | .simple_internal => 0, |
| 1800 | .ptr_int => @sizeOf(PtrInt), | ||
| 1711 | .int_u8 => 0, | 1801 | .int_u8 => 0, |
| 1712 | .int_u16 => 0, | 1802 | .int_u16 => 0, |
| 1713 | .int_u32 => 0, | 1803 | .int_u32 => 0, |
src/Module.zig+12-6| ... | @@ -6887,17 +6887,23 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | ... | @@ -6887,17 +6887,23 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6887 | return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true }); | 6887 | return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true }); |
| 6888 | } | 6888 | } |
| 6889 | 6889 | ||
| 6890 | pub fn ptrIntValue(mod: *Module, ty: Type, x: u64) Allocator.Error!Value { | ||
| 6891 | assert(ty.zigTypeTag(mod) == .Pointer); | ||
| 6892 | const i = try intern(mod, .{ .ptr = .{ | ||
| 6893 | .ty = ty.ip_index, | ||
| 6894 | .addr = .{ .int = try intern(mod, .{ .int = .{ | ||
| 6895 | .ty = ty.ip_index, | ||
| 6896 | .storage = .{ .u64 = x }, | ||
| 6897 | } }) }, | ||
| 6898 | } }); | ||
| 6899 | return i.toValue(); | ||
| 6900 | } | ||
| 6901 | |||
| 6890 | pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value { | 6902 | pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value { |
| 6891 | if (std.debug.runtime_safety) { | 6903 | if (std.debug.runtime_safety) { |
| 6892 | // TODO: decide if this also works for ABI int types like enums | ||
| 6893 | const tag = ty.zigTypeTag(mod); | 6904 | const tag = ty.zigTypeTag(mod); |
| 6894 | assert(tag == .Int or tag == .ComptimeInt); | 6905 | assert(tag == .Int or tag == .ComptimeInt); |
| 6895 | } | 6906 | } |
| 6896 | if (@TypeOf(x) == comptime_int) { | ||
| 6897 | if (comptime std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); | ||
| 6898 | if (comptime std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); | ||
| 6899 | @compileError("Out-of-range comptime_int passed to Module.intValue"); | ||
| 6900 | } | ||
| 6901 | if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); | 6907 | if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); |
| 6902 | if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); | 6908 | if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); |
| 6903 | var limbs_buffer: [4]usize = undefined; | 6909 | var limbs_buffer: [4]usize = undefined; |
src/Sema.zig+30-9| ... | @@ -15096,7 +15096,7 @@ fn analyzePtrArithmetic( | ... | @@ -15096,7 +15096,7 @@ fn analyzePtrArithmetic( |
| 15096 | .ptr_sub => addr - elem_size * offset_int, | 15096 | .ptr_sub => addr - elem_size * offset_int, |
| 15097 | else => unreachable, | 15097 | else => unreachable, |
| 15098 | }; | 15098 | }; |
| 15099 | const new_ptr_val = try mod.intValue(new_ptr_ty, new_addr); | 15099 | const new_ptr_val = try mod.ptrIntValue(new_ptr_ty, new_addr); |
| 15100 | return sema.addConstant(new_ptr_ty, new_ptr_val); | 15100 | return sema.addConstant(new_ptr_ty, new_ptr_val); |
| 15101 | } | 15101 | } |
| 15102 | if (air_tag == .ptr_sub) { | 15102 | if (air_tag == .ptr_sub) { |
| ... | @@ -19931,7 +19931,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -19931,7 +19931,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 19931 | if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0) | 19931 | if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0) |
| 19932 | return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)}); | 19932 | return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)}); |
| 19933 | 19933 | ||
| 19934 | return sema.addConstant(ptr_ty, try mod.intValue(ptr_ty, addr)); | 19934 | return sema.addConstant(ptr_ty, try mod.ptrIntValue(ptr_ty, addr)); |
| 19935 | } | 19935 | } |
| 19936 | 19936 | ||
| 19937 | try sema.requireRuntimeBlock(block, src, operand_src); | 19937 | try sema.requireRuntimeBlock(block, src, operand_src); |
| ... | @@ -25640,8 +25640,13 @@ fn coerceExtra( | ... | @@ -25640,8 +25640,13 @@ fn coerceExtra( |
| 25640 | var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); | 25640 | var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| 25641 | if (in_memory_result == .ok) { | 25641 | if (in_memory_result == .ok) { |
| 25642 | if (maybe_inst_val) |val| { | 25642 | if (maybe_inst_val) |val| { |
| 25643 | // Keep the comptime Value representation; take the new type. | 25643 | if (val.ip_index == .none or val.ip_index == .null_value) { |
| 25644 | return sema.addConstant(dest_ty, val); | 25644 | // Keep the comptime Value representation; take the new type. |
| 25645 | return sema.addConstant(dest_ty, val); | ||
| 25646 | } else { | ||
| 25647 | const new_val = try mod.intern_pool.getCoerced(mod.gpa, val.ip_index, dest_ty.ip_index); | ||
| 25648 | return sema.addConstant(dest_ty, new_val.toValue()); | ||
| 25649 | } | ||
| 25645 | } | 25650 | } |
| 25646 | try sema.requireRuntimeBlock(block, inst_src, null); | 25651 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 25647 | return block.addBitCast(dest_ty, inst); | 25652 | return block.addBitCast(dest_ty, inst); |
| ... | @@ -26014,7 +26019,7 @@ fn coerceExtra( | ... | @@ -26014,7 +26019,7 @@ fn coerceExtra( |
| 26014 | if (!opts.report_err) return error.NotCoercible; | 26019 | if (!opts.report_err) return error.NotCoercible; |
| 26015 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); | 26020 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); |
| 26016 | } | 26021 | } |
| 26017 | const new_val = try mod.intern_pool.getCoercedInt(sema.gpa, val.ip_index, dest_ty.ip_index); | 26022 | const new_val = try mod.intern_pool.getCoerced(sema.gpa, val.ip_index, dest_ty.ip_index); |
| 26018 | return try sema.addConstant(dest_ty, new_val.toValue()); | 26023 | return try sema.addConstant(dest_ty, new_val.toValue()); |
| 26019 | } | 26024 | } |
| 26020 | if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { | 26025 | if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { |
| ... | @@ -31673,10 +31678,13 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -31673,10 +31678,13 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 31673 | }, | 31678 | }, |
| 31674 | .struct_type => @panic("TODO"), | 31679 | .struct_type => @panic("TODO"), |
| 31675 | .union_type => @panic("TODO"), | 31680 | .union_type => @panic("TODO"), |
| 31681 | |||
| 31682 | // values, not types | ||
| 31676 | .simple_value => unreachable, | 31683 | .simple_value => unreachable, |
| 31677 | .extern_func => unreachable, | 31684 | .extern_func => unreachable, |
| 31678 | .int => unreachable, | 31685 | .int => unreachable, |
| 31679 | .enum_tag => unreachable, // it's a value, not a type | 31686 | .ptr => unreachable, |
| 31687 | .enum_tag => unreachable, | ||
| 31680 | }, | 31688 | }, |
| 31681 | }; | 31689 | }; |
| 31682 | } | 31690 | } |
| ... | @@ -33193,10 +33201,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33193,10 +33201,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33193 | }, | 33201 | }, |
| 33194 | .struct_type => @panic("TODO"), | 33202 | .struct_type => @panic("TODO"), |
| 33195 | .union_type => @panic("TODO"), | 33203 | .union_type => @panic("TODO"), |
| 33204 | |||
| 33205 | // values, not types | ||
| 33196 | .simple_value => unreachable, | 33206 | .simple_value => unreachable, |
| 33197 | .extern_func => unreachable, | 33207 | .extern_func => unreachable, |
| 33198 | .int => unreachable, | 33208 | .int => unreachable, |
| 33199 | .enum_tag => unreachable, // it's a value, not a type | 33209 | .ptr => unreachable, |
| 33210 | .enum_tag => unreachable, | ||
| 33200 | }, | 33211 | }, |
| 33201 | } | 33212 | } |
| 33202 | } | 33213 | } |
| ... | @@ -33253,7 +33264,14 @@ pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { | ... | @@ -33253,7 +33264,14 @@ pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { |
| 33253 | const result = Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); | 33264 | const result = Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); |
| 33254 | // This assertion can be removed when the `ty` parameter is removed from | 33265 | // This assertion can be removed when the `ty` parameter is removed from |
| 33255 | // this function thanks to the InternPool transition being complete. | 33266 | // this function thanks to the InternPool transition being complete. |
| 33256 | assert(Type.eql(sema.typeOf(result), ty, sema.mod)); | 33267 | if (std.debug.runtime_safety) { |
| 33268 | const val_ty = sema.typeOf(result); | ||
| 33269 | if (!Type.eql(val_ty, ty, sema.mod)) { | ||
| 33270 | std.debug.panic("addConstant type mismatch: '{}' vs '{}'\n", .{ | ||
| 33271 | ty.fmt(sema.mod), val_ty.fmt(sema.mod), | ||
| 33272 | }); | ||
| 33273 | } | ||
| 33274 | } | ||
| 33257 | return result; | 33275 | return result; |
| 33258 | } | 33276 | } |
| 33259 | const ty_inst = try sema.addType(ty); | 33277 | const ty_inst = try sema.addType(ty); |
| ... | @@ -33752,10 +33770,13 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -33752,10 +33770,13 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 33752 | }, | 33770 | }, |
| 33753 | .struct_type => @panic("TODO"), | 33771 | .struct_type => @panic("TODO"), |
| 33754 | .union_type => @panic("TODO"), | 33772 | .union_type => @panic("TODO"), |
| 33773 | |||
| 33774 | // values, not types | ||
| 33755 | .simple_value => unreachable, | 33775 | .simple_value => unreachable, |
| 33756 | .extern_func => unreachable, | 33776 | .extern_func => unreachable, |
| 33757 | .int => unreachable, | 33777 | .int => unreachable, |
| 33758 | .enum_tag => unreachable, // it's a value, not a type | 33778 | .ptr => unreachable, |
| 33779 | .enum_tag => unreachable, | ||
| 33759 | }, | 33780 | }, |
| 33760 | }; | 33781 | }; |
| 33761 | } | 33782 | } |
src/type.zig+35-11| ... | @@ -142,11 +142,12 @@ pub const Type = struct { | ... | @@ -142,11 +142,12 @@ pub const Type = struct { |
| 142 | .var_args_param => unreachable, | 142 | .var_args_param => unreachable, |
| 143 | }, | 143 | }, |
| 144 | 144 | ||
| 145 | .extern_func, | 145 | // values, not types |
| 146 | .int, | 146 | .extern_func => unreachable, |
| 147 | .enum_tag, | 147 | .int => unreachable, |
| 148 | .simple_value, | 148 | .ptr => unreachable, |
| 149 | => unreachable, // it's a value, not a type | 149 | .enum_tag => unreachable, |
| 150 | .simple_value => unreachable, | ||
| 150 | }, | 151 | }, |
| 151 | } | 152 | } |
| 152 | } | 153 | } |
| ... | @@ -1576,6 +1577,7 @@ pub const Type = struct { | ... | @@ -1576,6 +1577,7 @@ pub const Type = struct { |
| 1576 | .simple_value => unreachable, | 1577 | .simple_value => unreachable, |
| 1577 | .extern_func => unreachable, | 1578 | .extern_func => unreachable, |
| 1578 | .int => unreachable, | 1579 | .int => unreachable, |
| 1580 | .ptr => unreachable, | ||
| 1579 | .enum_tag => unreachable, | 1581 | .enum_tag => unreachable, |
| 1580 | }, | 1582 | }, |
| 1581 | } | 1583 | } |
| ... | @@ -1842,10 +1844,13 @@ pub const Type = struct { | ... | @@ -1842,10 +1844,13 @@ pub const Type = struct { |
| 1842 | }, | 1844 | }, |
| 1843 | .struct_type => @panic("TODO"), | 1845 | .struct_type => @panic("TODO"), |
| 1844 | .union_type => @panic("TODO"), | 1846 | .union_type => @panic("TODO"), |
| 1847 | |||
| 1848 | // values, not types | ||
| 1845 | .simple_value => unreachable, | 1849 | .simple_value => unreachable, |
| 1846 | .extern_func => unreachable, | 1850 | .extern_func => unreachable, |
| 1847 | .int => unreachable, | 1851 | .int => unreachable, |
| 1848 | .enum_tag => unreachable, // it's a value, not a type | 1852 | .ptr => unreachable, |
| 1853 | .enum_tag => unreachable, | ||
| 1849 | }, | 1854 | }, |
| 1850 | } | 1855 | } |
| 1851 | } | 1856 | } |
| ... | @@ -1950,10 +1955,13 @@ pub const Type = struct { | ... | @@ -1950,10 +1955,13 @@ pub const Type = struct { |
| 1950 | }, | 1955 | }, |
| 1951 | .struct_type => @panic("TODO"), | 1956 | .struct_type => @panic("TODO"), |
| 1952 | .union_type => @panic("TODO"), | 1957 | .union_type => @panic("TODO"), |
| 1958 | |||
| 1959 | // values, not types | ||
| 1953 | .simple_value => unreachable, | 1960 | .simple_value => unreachable, |
| 1954 | .extern_func => unreachable, | 1961 | .extern_func => unreachable, |
| 1955 | .int => unreachable, | 1962 | .int => unreachable, |
| 1956 | .enum_tag => unreachable, // it's a value, not a type | 1963 | .ptr => unreachable, |
| 1964 | .enum_tag => unreachable, | ||
| 1957 | }, | 1965 | }, |
| 1958 | }; | 1966 | }; |
| 1959 | } | 1967 | } |
| ... | @@ -2348,10 +2356,13 @@ pub const Type = struct { | ... | @@ -2348,10 +2356,13 @@ pub const Type = struct { |
| 2348 | }, | 2356 | }, |
| 2349 | .struct_type => @panic("TODO"), | 2357 | .struct_type => @panic("TODO"), |
| 2350 | .union_type => @panic("TODO"), | 2358 | .union_type => @panic("TODO"), |
| 2359 | |||
| 2360 | // values, not types | ||
| 2351 | .simple_value => unreachable, | 2361 | .simple_value => unreachable, |
| 2352 | .extern_func => unreachable, | 2362 | .extern_func => unreachable, |
| 2353 | .int => unreachable, | 2363 | .int => unreachable, |
| 2354 | .enum_tag => unreachable, // it's a value, not a type | 2364 | .ptr => unreachable, |
| 2365 | .enum_tag => unreachable, | ||
| 2355 | }, | 2366 | }, |
| 2356 | } | 2367 | } |
| 2357 | } | 2368 | } |
| ... | @@ -2759,10 +2770,13 @@ pub const Type = struct { | ... | @@ -2759,10 +2770,13 @@ pub const Type = struct { |
| 2759 | }, | 2770 | }, |
| 2760 | .struct_type => @panic("TODO"), | 2771 | .struct_type => @panic("TODO"), |
| 2761 | .union_type => @panic("TODO"), | 2772 | .union_type => @panic("TODO"), |
| 2773 | |||
| 2774 | // values, not types | ||
| 2762 | .simple_value => unreachable, | 2775 | .simple_value => unreachable, |
| 2763 | .extern_func => unreachable, | 2776 | .extern_func => unreachable, |
| 2764 | .int => unreachable, | 2777 | .int => unreachable, |
| 2765 | .enum_tag => unreachable, // it's a value, not a type | 2778 | .ptr => unreachable, |
| 2779 | .enum_tag => unreachable, | ||
| 2766 | }, | 2780 | }, |
| 2767 | } | 2781 | } |
| 2768 | } | 2782 | } |
| ... | @@ -2926,10 +2940,13 @@ pub const Type = struct { | ... | @@ -2926,10 +2940,13 @@ pub const Type = struct { |
| 2926 | }, | 2940 | }, |
| 2927 | .struct_type => @panic("TODO"), | 2941 | .struct_type => @panic("TODO"), |
| 2928 | .union_type => @panic("TODO"), | 2942 | .union_type => @panic("TODO"), |
| 2943 | |||
| 2944 | // values, not types | ||
| 2929 | .simple_value => unreachable, | 2945 | .simple_value => unreachable, |
| 2930 | .extern_func => unreachable, | 2946 | .extern_func => unreachable, |
| 2931 | .int => unreachable, | 2947 | .int => unreachable, |
| 2932 | .enum_tag => unreachable, // it's a value, not a type | 2948 | .ptr => unreachable, |
| 2949 | .enum_tag => unreachable, | ||
| 2933 | }; | 2950 | }; |
| 2934 | 2951 | ||
| 2935 | const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager; | 2952 | const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager; |
| ... | @@ -3780,9 +3797,12 @@ pub const Type = struct { | ... | @@ -3780,9 +3797,12 @@ pub const Type = struct { |
| 3780 | .simple_type => unreachable, // handled via Index enum tag above | 3797 | .simple_type => unreachable, // handled via Index enum tag above |
| 3781 | .struct_type => @panic("TODO"), | 3798 | .struct_type => @panic("TODO"), |
| 3782 | .union_type => unreachable, | 3799 | .union_type => unreachable, |
| 3800 | |||
| 3801 | // values, not types | ||
| 3783 | .simple_value => unreachable, | 3802 | .simple_value => unreachable, |
| 3784 | .extern_func => unreachable, | 3803 | .extern_func => unreachable, |
| 3785 | .int => unreachable, | 3804 | .int => unreachable, |
| 3805 | .ptr => unreachable, | ||
| 3786 | .enum_tag => unreachable, | 3806 | .enum_tag => unreachable, |
| 3787 | }, | 3807 | }, |
| 3788 | }; | 3808 | }; |
| ... | @@ -4152,10 +4172,13 @@ pub const Type = struct { | ... | @@ -4152,10 +4172,13 @@ pub const Type = struct { |
| 4152 | }, | 4172 | }, |
| 4153 | .struct_type => @panic("TODO"), | 4173 | .struct_type => @panic("TODO"), |
| 4154 | .union_type => @panic("TODO"), | 4174 | .union_type => @panic("TODO"), |
| 4175 | |||
| 4176 | // values, not types | ||
| 4155 | .simple_value => unreachable, | 4177 | .simple_value => unreachable, |
| 4156 | .extern_func => unreachable, | 4178 | .extern_func => unreachable, |
| 4157 | .int => unreachable, | 4179 | .int => unreachable, |
| 4158 | .enum_tag => unreachable, // it's a value, not a type | 4180 | .ptr => unreachable, |
| 4181 | .enum_tag => unreachable, | ||
| 4159 | }, | 4182 | }, |
| 4160 | }; | 4183 | }; |
| 4161 | } | 4184 | } |
| ... | @@ -4319,6 +4342,7 @@ pub const Type = struct { | ... | @@ -4319,6 +4342,7 @@ pub const Type = struct { |
| 4319 | .simple_value => unreachable, | 4342 | .simple_value => unreachable, |
| 4320 | .extern_func => unreachable, | 4343 | .extern_func => unreachable, |
| 4321 | .int => unreachable, | 4344 | .int => unreachable, |
| 4345 | .ptr => unreachable, | ||
| 4322 | .enum_tag => unreachable, // it's a value, not a type | 4346 | .enum_tag => unreachable, // it's a value, not a type |
| 4323 | }, | 4347 | }, |
| 4324 | }; | 4348 | }; |