authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-14 17:32:51-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-14 17:32:51-07:00
logd404d8a3637bc30dffc736e5fa1a68b8af0e19cb
tree2f668bf2a185fe788fa20753ae6d8462778c4204
parent464537db62e1d4ca6bc1357135b0f6c451e48c17
parentad55fb7a209e1b9d41b8d4f1d3e48211ff20d2f9
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20593 from jacobly0/more-races

InternPool: fix more races

31 files changed, 998 insertions(+), 516 deletions(-)

src/Air/types_resolved.zig+3-3
...@@ -501,8 +501,8 @@ fn checkType(ty: Type, zcu: *Zcu) bool {...@@ -501,8 +501,8 @@ fn checkType(ty: Type, zcu: *Zcu) bool {
501 .struct_type => {501 .struct_type => {
502 const struct_obj = zcu.typeToStruct(ty).?;502 const struct_obj = zcu.typeToStruct(ty).?;
503 return switch (struct_obj.layout) {503 return switch (struct_obj.layout) {
504 .@"packed" => struct_obj.backingIntType(ip).* != .none,504 .@"packed" => struct_obj.backingIntTypeUnordered(ip) != .none,
505 .auto, .@"extern" => struct_obj.flagsPtr(ip).fully_resolved,505 .auto, .@"extern" => struct_obj.flagsUnordered(ip).fully_resolved,
506 };506 };
507 },507 },
508 .anon_struct_type => |tuple| {508 .anon_struct_type => |tuple| {
...@@ -516,6 +516,6 @@ fn checkType(ty: Type, zcu: *Zcu) bool {...@@ -516,6 +516,6 @@ fn checkType(ty: Type, zcu: *Zcu) bool {
516 },516 },
517 else => unreachable,517 else => unreachable,
518 },518 },
519 .Union => return zcu.typeToUnion(ty).?.flagsPtr(ip).status == .fully_resolved,519 .Union => return zcu.typeToUnion(ty).?.flagsUnordered(ip).status == .fully_resolved,
520 };520 };
521}521}
src/Compilation.zig+165-89
...@@ -101,7 +101,15 @@ link_error_flags: link.File.ErrorFlags = .{},...@@ -101,7 +101,15 @@ link_error_flags: link.File.ErrorFlags = .{},
101link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},101link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},
102lld_errors: std.ArrayListUnmanaged(LldError) = .{},102lld_errors: std.ArrayListUnmanaged(LldError) = .{},
103103
104work_queue: std.fifo.LinearFifo(Job, .Dynamic),104work_queues: [
105 len: {
106 var len: usize = 0;
107 for (std.enums.values(Job.Tag)) |tag| {
108 len = @max(Job.stage(tag) + 1, len);
109 }
110 break :len len;
111 }
112]std.fifo.LinearFifo(Job, .Dynamic),
105113
106codegen_work: if (InternPool.single_threaded) void else struct {114codegen_work: if (InternPool.single_threaded) void else struct {
107 mutex: std.Thread.Mutex,115 mutex: std.Thread.Mutex,
...@@ -370,6 +378,20 @@ const Job = union(enum) {...@@ -370,6 +378,20 @@ const Job = union(enum) {
370378
371 /// The value is the index into `system_libs`.379 /// The value is the index into `system_libs`.
372 windows_import_lib: usize,380 windows_import_lib: usize,
381
382 const Tag = @typeInfo(Job).Union.tag_type.?;
383 fn stage(tag: Tag) usize {
384 return switch (tag) {
385 // Prioritize functions so that codegen can get to work on them on a
386 // separate thread, while Sema goes back to its own work.
387 .resolve_type_fully, .analyze_func, .codegen_func => 0,
388 else => 1,
389 };
390 }
391 comptime {
392 // Job dependencies
393 assert(stage(.resolve_type_fully) <= stage(.codegen_func));
394 }
373};395};
374396
375const CodegenJob = union(enum) {397const CodegenJob = union(enum) {
...@@ -1452,7 +1474,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1452,7 +1474,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1452 .emit_asm = options.emit_asm,1474 .emit_asm = options.emit_asm,
1453 .emit_llvm_ir = options.emit_llvm_ir,1475 .emit_llvm_ir = options.emit_llvm_ir,
1454 .emit_llvm_bc = options.emit_llvm_bc,1476 .emit_llvm_bc = options.emit_llvm_bc,
1455 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),1477 .work_queues = .{std.fifo.LinearFifo(Job, .Dynamic).init(gpa)} ** @typeInfo(std.meta.FieldType(Compilation, .work_queues)).Array.len,
1456 .codegen_work = if (InternPool.single_threaded) {} else .{1478 .codegen_work = if (InternPool.single_threaded) {} else .{
1457 .mutex = .{},1479 .mutex = .{},
1458 .cond = .{},1480 .cond = .{},
...@@ -1760,12 +1782,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1760,12 +1782,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1760 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;1782 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
17611783
1762 if (glibc.needsCrtiCrtn(target)) {1784 if (glibc.needsCrtiCrtn(target)) {
1763 try comp.work_queue.write(&[_]Job{1785 try comp.queueJobs(&[_]Job{
1764 .{ .glibc_crt_file = .crti_o },1786 .{ .glibc_crt_file = .crti_o },
1765 .{ .glibc_crt_file = .crtn_o },1787 .{ .glibc_crt_file = .crtn_o },
1766 });1788 });
1767 }1789 }
1768 try comp.work_queue.write(&[_]Job{1790 try comp.queueJobs(&[_]Job{
1769 .{ .glibc_crt_file = .scrt1_o },1791 .{ .glibc_crt_file = .scrt1_o },
1770 .{ .glibc_crt_file = .libc_nonshared_a },1792 .{ .glibc_crt_file = .libc_nonshared_a },
1771 .{ .glibc_shared_objects = {} },1793 .{ .glibc_shared_objects = {} },
...@@ -1774,14 +1796,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1774,14 +1796,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1774 if (comp.wantBuildMuslFromSource()) {1796 if (comp.wantBuildMuslFromSource()) {
1775 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;1797 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
17761798
1777 try comp.work_queue.ensureUnusedCapacity(6);
1778 if (musl.needsCrtiCrtn(target)) {1799 if (musl.needsCrtiCrtn(target)) {
1779 comp.work_queue.writeAssumeCapacity(&[_]Job{1800 try comp.queueJobs(&[_]Job{
1780 .{ .musl_crt_file = .crti_o },1801 .{ .musl_crt_file = .crti_o },
1781 .{ .musl_crt_file = .crtn_o },1802 .{ .musl_crt_file = .crtn_o },
1782 });1803 });
1783 }1804 }
1784 comp.work_queue.writeAssumeCapacity(&[_]Job{1805 try comp.queueJobs(&[_]Job{
1785 .{ .musl_crt_file = .crt1_o },1806 .{ .musl_crt_file = .crt1_o },
1786 .{ .musl_crt_file = .scrt1_o },1807 .{ .musl_crt_file = .scrt1_o },
1787 .{ .musl_crt_file = .rcrt1_o },1808 .{ .musl_crt_file = .rcrt1_o },
...@@ -1795,15 +1816,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1795,15 +1816,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1795 if (comp.wantBuildWasiLibcFromSource()) {1816 if (comp.wantBuildWasiLibcFromSource()) {
1796 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;1817 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
17971818
1798 // worst-case we need all components
1799 try comp.work_queue.ensureUnusedCapacity(comp.wasi_emulated_libs.len + 2);
1800
1801 for (comp.wasi_emulated_libs) |crt_file| {1819 for (comp.wasi_emulated_libs) |crt_file| {
1802 comp.work_queue.writeItemAssumeCapacity(.{1820 try comp.queueJob(.{
1803 .wasi_libc_crt_file = crt_file,1821 .wasi_libc_crt_file = crt_file,
1804 });1822 });
1805 }1823 }
1806 comp.work_queue.writeAssumeCapacity(&[_]Job{1824 try comp.queueJobs(&[_]Job{
1807 .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) },1825 .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) },
1808 .{ .wasi_libc_crt_file = .libc_a },1826 .{ .wasi_libc_crt_file = .libc_a },
1809 });1827 });
...@@ -1813,9 +1831,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1813,9 +1831,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1813 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;1831 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
18141832
1815 const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o };1833 const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o };
1816 try comp.work_queue.ensureUnusedCapacity(2);1834 try comp.queueJobs(&.{
1817 comp.work_queue.writeItemAssumeCapacity(.{ .mingw_crt_file = .mingw32_lib });1835 .{ .mingw_crt_file = .mingw32_lib },
1818 comp.work_queue.writeItemAssumeCapacity(crt_job);1836 crt_job,
1837 });
18191838
1820 // When linking mingw-w64 there are some import libs we always need.1839 // When linking mingw-w64 there are some import libs we always need.
1821 for (mingw.always_link_libs) |name| {1840 for (mingw.always_link_libs) |name| {
...@@ -1829,20 +1848,19 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1829,20 +1848,19 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1829 // Generate Windows import libs.1848 // Generate Windows import libs.
1830 if (target.os.tag == .windows) {1849 if (target.os.tag == .windows) {
1831 const count = comp.system_libs.count();1850 const count = comp.system_libs.count();
1832 try comp.work_queue.ensureUnusedCapacity(count);
1833 for (0..count) |i| {1851 for (0..count) |i| {
1834 comp.work_queue.writeItemAssumeCapacity(.{ .windows_import_lib = i });1852 try comp.queueJob(.{ .windows_import_lib = i });
1835 }1853 }
1836 }1854 }
1837 if (comp.wantBuildLibUnwindFromSource()) {1855 if (comp.wantBuildLibUnwindFromSource()) {
1838 try comp.work_queue.writeItem(.{ .libunwind = {} });1856 try comp.queueJob(.{ .libunwind = {} });
1839 }1857 }
1840 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {1858 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {
1841 try comp.work_queue.writeItem(.libcxx);1859 try comp.queueJob(.libcxx);
1842 try comp.work_queue.writeItem(.libcxxabi);1860 try comp.queueJob(.libcxxabi);
1843 }1861 }
1844 if (build_options.have_llvm and comp.config.any_sanitize_thread) {1862 if (build_options.have_llvm and comp.config.any_sanitize_thread) {
1845 try comp.work_queue.writeItem(.libtsan);1863 try comp.queueJob(.libtsan);
1846 }1864 }
18471865
1848 if (target.isMinGW() and comp.config.any_non_single_threaded) {1866 if (target.isMinGW() and comp.config.any_non_single_threaded) {
...@@ -1872,7 +1890,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1872,7 +1890,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1872 if (!comp.skip_linker_dependencies and is_exe_or_dyn_lib and1890 if (!comp.skip_linker_dependencies and is_exe_or_dyn_lib and
1873 !comp.config.link_libc and capable_of_building_zig_libc)1891 !comp.config.link_libc and capable_of_building_zig_libc)
1874 {1892 {
1875 try comp.work_queue.writeItem(.{ .zig_libc = {} });1893 try comp.queueJob(.{ .zig_libc = {} });
1876 }1894 }
1877 }1895 }
18781896
...@@ -1883,7 +1901,7 @@ pub fn destroy(comp: *Compilation) void {...@@ -1883,7 +1901,7 @@ pub fn destroy(comp: *Compilation) void {
1883 if (comp.bin_file) |lf| lf.destroy();1901 if (comp.bin_file) |lf| lf.destroy();
1884 if (comp.module) |zcu| zcu.deinit();1902 if (comp.module) |zcu| zcu.deinit();
1885 comp.cache_use.deinit();1903 comp.cache_use.deinit();
1886 comp.work_queue.deinit();1904 for (comp.work_queues) |work_queue| work_queue.deinit();
1887 if (!InternPool.single_threaded) comp.codegen_work.queue.deinit();1905 if (!InternPool.single_threaded) comp.codegen_work.queue.deinit();
1888 comp.c_object_work_queue.deinit();1906 comp.c_object_work_queue.deinit();
1889 if (!build_options.only_core_functionality) {1907 if (!build_options.only_core_functionality) {
...@@ -2199,13 +2217,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2199,13 +2217,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2199 }2217 }
2200 }2218 }
22012219
2202 try comp.work_queue.writeItem(.{ .analyze_mod = std_mod });2220 try comp.queueJob(.{ .analyze_mod = std_mod });
2203 if (comp.config.is_test) {2221 if (comp.config.is_test) {
2204 try comp.work_queue.writeItem(.{ .analyze_mod = zcu.main_mod });2222 try comp.queueJob(.{ .analyze_mod = zcu.main_mod });
2205 }2223 }
22062224
2207 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {2225 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
2208 try comp.work_queue.writeItem(.{ .analyze_mod = compiler_rt_mod });2226 try comp.queueJob(.{ .analyze_mod = compiler_rt_mod });
2209 }2227 }
2210 }2228 }
22112229
...@@ -2852,11 +2870,7 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {...@@ -2852,11 +2870,7 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {
28522870
2853const Header = extern struct {2871const Header = extern struct {
2854 intern_pool: extern struct {2872 intern_pool: extern struct {
2855 //items_len: u32,2873 thread_count: u32,
2856 //extra_len: u32,
2857 //limbs_len: u32,
2858 //string_bytes_len: u32,
2859 //tracked_insts_len: u32,
2860 src_hash_deps_len: u32,2874 src_hash_deps_len: u32,
2861 decl_val_deps_len: u32,2875 decl_val_deps_len: u32,
2862 namespace_deps_len: u32,2876 namespace_deps_len: u32,
...@@ -2864,28 +2878,39 @@ const Header = extern struct {...@@ -2864,28 +2878,39 @@ const Header = extern struct {
2864 first_dependency_len: u32,2878 first_dependency_len: u32,
2865 dep_entries_len: u32,2879 dep_entries_len: u32,
2866 free_dep_entries_len: u32,2880 free_dep_entries_len: u32,
2867 //files_len: u32,
2868 },2881 },
2882
2883 const PerThread = extern struct {
2884 intern_pool: extern struct {
2885 items_len: u32,
2886 extra_len: u32,
2887 limbs_len: u32,
2888 string_bytes_len: u32,
2889 tracked_insts_len: u32,
2890 files_len: u32,
2891 },
2892 };
2869};2893};
28702894
2871/// Note that all state that is included in the cache hash namespace is *not*2895/// Note that all state that is included in the cache hash namespace is *not*
2872/// saved, such as the target and most CLI flags. A cache hit will only occur2896/// saved, such as the target and most CLI flags. A cache hit will only occur
2873/// when subsequent compiler invocations use the same set of flags.2897/// when subsequent compiler invocations use the same set of flags.
2874pub fn saveState(comp: *Compilation) !void {2898pub fn saveState(comp: *Compilation) !void {
2875 var bufs_list: [21]std.posix.iovec_const = undefined;
2876 var bufs_len: usize = 0;
2877
2878 const lf = comp.bin_file orelse return;2899 const lf = comp.bin_file orelse return;
28792900
2901 const gpa = comp.gpa;
2902
2903 var bufs = std.ArrayList(std.posix.iovec_const).init(gpa);
2904 defer bufs.deinit();
2905
2906 var pt_headers = std.ArrayList(Header.PerThread).init(gpa);
2907 defer pt_headers.deinit();
2908
2880 if (comp.module) |zcu| {2909 if (comp.module) |zcu| {
2881 const ip = &zcu.intern_pool;2910 const ip = &zcu.intern_pool;
2882 const header: Header = .{2911 const header: Header = .{
2883 .intern_pool = .{2912 .intern_pool = .{
2884 //.items_len = @intCast(ip.items.len),2913 .thread_count = @intCast(ip.locals.len),
2885 //.extra_len = @intCast(ip.extra.items.len),
2886 //.limbs_len = @intCast(ip.limbs.items.len),
2887 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
2888 //.tracked_insts_len = @intCast(ip.tracked_insts.count()),
2889 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),2914 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
2890 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),2915 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),
2891 .namespace_deps_len = @intCast(ip.namespace_deps.count()),2916 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
...@@ -2893,38 +2918,54 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2893,38 +2918,54 @@ pub fn saveState(comp: *Compilation) !void {
2893 .first_dependency_len = @intCast(ip.first_dependency.count()),2918 .first_dependency_len = @intCast(ip.first_dependency.count()),
2894 .dep_entries_len = @intCast(ip.dep_entries.items.len),2919 .dep_entries_len = @intCast(ip.dep_entries.items.len),
2895 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),2920 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),
2896 //.files_len = @intCast(ip.files.entries.len),
2897 },2921 },
2898 };2922 };
2899 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));2923
2900 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));2924 try pt_headers.ensureTotalCapacityPrecise(header.intern_pool.thread_count);
2901 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));2925 for (ip.locals) |*local| pt_headers.appendAssumeCapacity(.{
2902 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));2926 .intern_pool = .{
2903 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));2927 .items_len = @intCast(local.mutate.items.len),
2904 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);2928 .extra_len = @intCast(local.mutate.extra.len),
2905 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));2929 .limbs_len = @intCast(local.mutate.limbs.len),
29062930 .string_bytes_len = @intCast(local.mutate.strings.len),
2907 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));2931 .tracked_insts_len = @intCast(local.mutate.tracked_insts.len),
2908 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.values()));2932 .files_len = @intCast(local.mutate.files.len),
2909 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.decl_val_deps.keys()));2933 },
2910 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.decl_val_deps.values()));2934 });
2911 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.namespace_deps.keys()));2935
2912 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.namespace_deps.values()));2936 try bufs.ensureTotalCapacityPrecise(14 + 8 * pt_headers.items.len);
2913 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.namespace_name_deps.keys()));2937 addBuf(&bufs, mem.asBytes(&header));
2914 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.namespace_name_deps.values()));2938 addBuf(&bufs, mem.sliceAsBytes(pt_headers.items));
29152939
2916 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.first_dependency.keys()));2940 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.keys()));
2917 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.first_dependency.values()));2941 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.values()));
2918 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));2942 addBuf(&bufs, mem.sliceAsBytes(ip.decl_val_deps.keys()));
2919 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));2943 addBuf(&bufs, mem.sliceAsBytes(ip.decl_val_deps.values()));
29202944 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.keys()));
2921 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));2945 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.values()));
2922 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));2946 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_name_deps.keys()));
29232947 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_name_deps.values()));
2924 // TODO: compilation errors2948
2925 // TODO: namespaces2949 addBuf(&bufs, mem.sliceAsBytes(ip.first_dependency.keys()));
2926 // TODO: decls2950 addBuf(&bufs, mem.sliceAsBytes(ip.first_dependency.values()));
2927 // TODO: linker state2951 addBuf(&bufs, mem.sliceAsBytes(ip.dep_entries.items));
2952 addBuf(&bufs, mem.sliceAsBytes(ip.free_dep_entries.items));
2953
2954 for (ip.locals, pt_headers.items) |*local, pt_header| {
2955 addBuf(&bufs, mem.sliceAsBytes(local.shared.limbs.view().items(.@"0")[0..pt_header.intern_pool.limbs_len]));
2956 addBuf(&bufs, mem.sliceAsBytes(local.shared.extra.view().items(.@"0")[0..pt_header.intern_pool.extra_len]));
2957 addBuf(&bufs, mem.sliceAsBytes(local.shared.items.view().items(.data)[0..pt_header.intern_pool.items_len]));
2958 addBuf(&bufs, mem.sliceAsBytes(local.shared.items.view().items(.tag)[0..pt_header.intern_pool.items_len]));
2959 addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]);
2960 addBuf(&bufs, mem.sliceAsBytes(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len]));
2961 addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.bin_digest)[0..pt_header.intern_pool.files_len]));
2962 addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.root_decl)[0..pt_header.intern_pool.files_len]));
2963 }
2964
2965 //// TODO: compilation errors
2966 //// TODO: namespaces
2967 //// TODO: decls
2968 //// TODO: linker state
2928 }2969 }
2929 var basename_buf: [255]u8 = undefined;2970 var basename_buf: [255]u8 = undefined;
2930 const basename = std.fmt.bufPrint(&basename_buf, "{s}.zcs", .{2971 const basename = std.fmt.bufPrint(&basename_buf, "{s}.zcs", .{
...@@ -2938,20 +2979,14 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2938,20 +2979,14 @@ pub fn saveState(comp: *Compilation) !void {
2938 // the previous incremental compilation state.2979 // the previous incremental compilation state.
2939 var af = try lf.emit.directory.handle.atomicFile(basename, .{});2980 var af = try lf.emit.directory.handle.atomicFile(basename, .{});
2940 defer af.deinit();2981 defer af.deinit();
2941 try af.file.pwritevAll(bufs_list[0..bufs_len], 0);2982 try af.file.pwritevAll(bufs.items, 0);
2942 try af.finish();2983 try af.finish();
2943}2984}
29442985
2945fn addBuf(bufs_list: []std.posix.iovec_const, bufs_len: *usize, buf: []const u8) void {2986fn addBuf(list: *std.ArrayList(std.posix.iovec_const), buf: []const u8) void {
2946 // Even when len=0, the undefined pointer might cause EFAULT.2987 // Even when len=0, the undefined pointer might cause EFAULT.
2947 if (buf.len == 0) return;2988 if (buf.len == 0) return;
29482989 list.appendAssumeCapacity(.{ .base = buf.ptr, .len = buf.len });
2949 const i = bufs_len.*;
2950 bufs_len.* = i + 1;
2951 bufs_list[i] = .{
2952 .base = buf.ptr,
2953 .len = buf.len,
2954 };
2955}2990}
29562991
2957/// This function is temporally single-threaded.2992/// This function is temporally single-threaded.
...@@ -3011,7 +3046,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 {...@@ -3011,7 +3046,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
3011 }3046 }
3012 }3047 }
30133048
3014 if (zcu.intern_pool.global_error_set.mutate.list.len > zcu.error_limit) {3049 if (zcu.intern_pool.global_error_set.getNamesFromMainThread().len > zcu.error_limit) {
3015 total += 1;3050 total += 1;
3016 }3051 }
3017 }3052 }
...@@ -3095,6 +3130,39 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3095,6 +3130,39 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3095 for (zcu.failed_embed_files.values()) |error_msg| {3130 for (zcu.failed_embed_files.values()) |error_msg| {
3096 try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);3131 try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);
3097 }3132 }
3133 {
3134 const SortOrder = struct {
3135 zcu: *Zcu,
3136 err: *?Error,
3137
3138 const Error = @typeInfo(
3139 @typeInfo(@TypeOf(Zcu.SrcLoc.span)).Fn.return_type.?,
3140 ).ErrorUnion.error_set;
3141
3142 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
3143 if (ctx.err.*) |_| return lhs_index < rhs_index;
3144 const errors = ctx.zcu.failed_analysis.values();
3145 const lhs_src_loc = errors[lhs_index].src_loc.upgrade(ctx.zcu);
3146 const rhs_src_loc = errors[rhs_index].src_loc.upgrade(ctx.zcu);
3147 return if (lhs_src_loc.file_scope != rhs_src_loc.file_scope) std.mem.order(
3148 u8,
3149 lhs_src_loc.file_scope.sub_file_path,
3150 rhs_src_loc.file_scope.sub_file_path,
3151 ).compare(.lt) else (lhs_src_loc.span(ctx.zcu.gpa) catch |e| {
3152 ctx.err.* = e;
3153 return lhs_index < rhs_index;
3154 }).main < (rhs_src_loc.span(ctx.zcu.gpa) catch |e| {
3155 ctx.err.* = e;
3156 return lhs_index < rhs_index;
3157 }).main;
3158 }
3159 };
3160 var err: ?SortOrder.Error = null;
3161 // This leaves `zcu.failed_analysis` an invalid state, but we do not
3162 // need lookups anymore anyway.
3163 zcu.failed_analysis.entries.sort(SortOrder{ .zcu = zcu, .err = &err });
3164 if (err) |e| return e;
3165 }
3098 for (zcu.failed_analysis.keys(), zcu.failed_analysis.values()) |anal_unit, error_msg| {3166 for (zcu.failed_analysis.keys(), zcu.failed_analysis.values()) |anal_unit, error_msg| {
3099 const decl_index = switch (anal_unit.unwrap()) {3167 const decl_index = switch (anal_unit.unwrap()) {
3100 .decl => |d| d,3168 .decl => |d| d,
...@@ -3140,7 +3208,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3140,7 +3208,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3140 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);3208 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
3141 }3209 }
31423210
3143 const actual_error_count = zcu.intern_pool.global_error_set.mutate.list.len;3211 const actual_error_count = zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
3144 if (actual_error_count > zcu.error_limit) {3212 if (actual_error_count > zcu.error_limit) {
3145 try bundle.addRootErrorMessage(.{3213 try bundle.addRootErrorMessage(.{
3146 .msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{3214 .msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{
...@@ -3543,18 +3611,18 @@ fn performAllTheWorkInner(...@@ -3543,18 +3611,18 @@ fn performAllTheWorkInner(
3543 comp.codegen_work.cond.signal();3611 comp.codegen_work.cond.signal();
3544 };3612 };
35453613
3546 while (true) {3614 work: while (true) {
3547 if (comp.work_queue.readItem()) |work_item| {3615 for (&comp.work_queues) |*work_queue| if (work_queue.readItem()) |job| {
3548 try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, work_item, main_progress_node);3616 try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job, main_progress_node);
3549 continue;3617 continue :work;
3550 }3618 };
3551 if (comp.module) |zcu| {3619 if (comp.module) |zcu| {
3552 // If there's no work queued, check if there's anything outdated3620 // If there's no work queued, check if there's anything outdated
3553 // which we need to work on, and queue it if so.3621 // which we need to work on, and queue it if so.
3554 if (try zcu.findOutdatedToAnalyze()) |outdated| {3622 if (try zcu.findOutdatedToAnalyze()) |outdated| {
3555 switch (outdated.unwrap()) {3623 switch (outdated.unwrap()) {
3556 .decl => |decl| try comp.work_queue.writeItem(.{ .analyze_decl = decl }),3624 .decl => |decl| try comp.queueJob(.{ .analyze_decl = decl }),
3557 .func => |func| try comp.work_queue.writeItem(.{ .analyze_func = func }),3625 .func => |func| try comp.queueJob(.{ .analyze_func = func }),
3558 }3626 }
3559 continue;3627 continue;
3560 }3628 }
...@@ -3575,6 +3643,14 @@ fn performAllTheWorkInner(...@@ -3575,6 +3643,14 @@ fn performAllTheWorkInner(
35753643
3576const JobError = Allocator.Error;3644const JobError = Allocator.Error;
35773645
3646pub fn queueJob(comp: *Compilation, job: Job) !void {
3647 try comp.work_queues[Job.stage(job)].writeItem(job);
3648}
3649
3650pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
3651 for (jobs) |job| try comp.queueJob(job);
3652}
3653
3578fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {3654fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {
3579 switch (job) {3655 switch (job) {
3580 .codegen_decl => |decl_index| {3656 .codegen_decl => |decl_index| {
...@@ -6478,7 +6554,7 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -6478,7 +6554,7 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
6478 };6554 };
6479 const target = comp.root_mod.resolved_target.result;6555 const target = comp.root_mod.resolved_target.result;
6480 if (target.os.tag == .windows and target.ofmt != .c) {6556 if (target.os.tag == .windows and target.ofmt != .c) {
6481 try comp.work_queue.writeItem(.{6557 try comp.queueJob(.{
6482 .windows_import_lib = comp.system_libs.count() - 1,6558 .windows_import_lib = comp.system_libs.count() - 1,
6483 });6559 });
6484 }6560 }
src/InternPool.zig+584-153
...@@ -147,8 +147,6 @@ pub fn trackZir(...@@ -147,8 +147,6 @@ pub fn trackZir(
147 }147 }
148 defer shard.mutate.tracked_inst_map.len += 1;148 defer shard.mutate.tracked_inst_map.len += 1;
149 const local = ip.getLocal(tid);149 const local = ip.getLocal(tid);
150 local.mutate.tracked_insts.mutex.lock();
151 defer local.mutate.tracked_insts.mutex.unlock();
152 const list = local.getMutableTrackedInsts(gpa);150 const list = local.getMutableTrackedInsts(gpa);
153 try list.ensureUnusedCapacity(1);151 try list.ensureUnusedCapacity(1);
154 const map_header = map.header().*;152 const map_header = map.header().*;
...@@ -418,10 +416,10 @@ const Local = struct {...@@ -418,10 +416,10 @@ const Local = struct {
418 arena: std.heap.ArenaAllocator.State,416 arena: std.heap.ArenaAllocator.State,
419417
420 items: ListMutate,418 items: ListMutate,
421 extra: MutexListMutate,419 extra: ListMutate,
422 limbs: ListMutate,420 limbs: ListMutate,
423 strings: ListMutate,421 strings: ListMutate,
424 tracked_insts: MutexListMutate,422 tracked_insts: ListMutate,
425 files: ListMutate,423 files: ListMutate,
426 maps: ListMutate,424 maps: ListMutate,
427425
...@@ -471,20 +469,12 @@ const Local = struct {...@@ -471,20 +469,12 @@ const Local = struct {
471 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });469 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });
472470
473 const ListMutate = struct {471 const ListMutate = struct {
472 mutex: std.Thread.Mutex,
474 len: u32,473 len: u32,
475474
476 const empty: ListMutate = .{475 const empty: ListMutate = .{
477 .len = 0,
478 };
479 };
480
481 const MutexListMutate = struct {
482 mutex: std.Thread.Mutex,
483 list: ListMutate,
484
485 const empty: MutexListMutate = .{
486 .mutex = .{},476 .mutex = .{},
487 .list = ListMutate.empty,477 .len = 0,
488 };478 };
489 };479 };
490480
...@@ -694,6 +684,8 @@ const Local = struct {...@@ -694,6 +684,8 @@ const Local = struct {
694 const new_slice = new_list.view().slice();684 const new_slice = new_list.view().slice();
695 inline for (fields) |field| @memcpy(new_slice.items(field)[0..len], old_slice.items(field)[0..len]);685 inline for (fields) |field| @memcpy(new_slice.items(field)[0..len], old_slice.items(field)[0..len]);
696 }686 }
687 mutable.mutate.mutex.lock();
688 defer mutable.mutate.mutex.unlock();
697 mutable.list.release(new_list);689 mutable.list.release(new_list);
698 }690 }
699691
...@@ -760,7 +752,7 @@ const Local = struct {...@@ -760,7 +752,7 @@ const Local = struct {
760 return .{752 return .{
761 .gpa = gpa,753 .gpa = gpa,
762 .arena = &local.mutate.arena,754 .arena = &local.mutate.arena,
763 .mutate = &local.mutate.extra.list,755 .mutate = &local.mutate.extra,
764 .list = &local.shared.extra,756 .list = &local.shared.extra,
765 };757 };
766 }758 }
...@@ -802,7 +794,7 @@ const Local = struct {...@@ -802,7 +794,7 @@ const Local = struct {
802 return .{794 return .{
803 .gpa = gpa,795 .gpa = gpa,
804 .arena = &local.mutate.arena,796 .arena = &local.mutate.arena,
805 .mutate = &local.mutate.tracked_insts.list,797 .mutate = &local.mutate.tracked_insts,
806 .list = &local.shared.tracked_insts,798 .list = &local.shared.tracked_insts,
807 };799 };
808 }800 }
...@@ -1714,29 +1706,76 @@ pub const Key = union(enum) {...@@ -1714,29 +1706,76 @@ pub const Key = union(enum) {
1714 comptime_args: Index.Slice,1706 comptime_args: Index.Slice,
17151707
1716 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1708 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1717 pub fn analysis(func: *const Func, ip: *const InternPool) *FuncAnalysis {1709 fn analysisPtr(func: Func, ip: *InternPool) *FuncAnalysis {
1718 const extra = ip.getLocalShared(func.tid).extra.acquire();1710 const extra = ip.getLocalShared(func.tid).extra.acquire();
1719 return @ptrCast(&extra.view().items(.@"0")[func.analysis_extra_index]);1711 return @ptrCast(&extra.view().items(.@"0")[func.analysis_extra_index]);
1720 }1712 }
17211713
1714 pub fn analysisUnordered(func: Func, ip: *const InternPool) FuncAnalysis {
1715 return @atomicLoad(FuncAnalysis, func.analysisPtr(@constCast(ip)), .unordered);
1716 }
1717
1718 pub fn setAnalysisState(func: Func, ip: *InternPool, state: FuncAnalysis.State) void {
1719 const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex;
1720 extra_mutex.lock();
1721 defer extra_mutex.unlock();
1722
1723 const analysis_ptr = func.analysisPtr(ip);
1724 var analysis = analysis_ptr.*;
1725 analysis.state = state;
1726 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
1727 }
1728
1729 pub fn setCallsOrAwaitsErrorableFn(func: Func, ip: *InternPool, value: bool) void {
1730 const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex;
1731 extra_mutex.lock();
1732 defer extra_mutex.unlock();
1733
1734 const analysis_ptr = func.analysisPtr(ip);
1735 var analysis = analysis_ptr.*;
1736 analysis.calls_or_awaits_errorable_fn = value;
1737 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
1738 }
1739
1722 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1740 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1723 pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index {1741 fn zirBodyInstPtr(func: Func, ip: *InternPool) *TrackedInst.Index {
1724 const extra = ip.getLocalShared(func.tid).extra.acquire();1742 const extra = ip.getLocalShared(func.tid).extra.acquire();
1725 return @ptrCast(&extra.view().items(.@"0")[func.zir_body_inst_extra_index]);1743 return @ptrCast(&extra.view().items(.@"0")[func.zir_body_inst_extra_index]);
1726 }1744 }
17271745
1746 pub fn zirBodyInstUnordered(func: Func, ip: *const InternPool) TrackedInst.Index {
1747 return @atomicLoad(TrackedInst.Index, func.zirBodyInstPtr(@constCast(ip)), .unordered);
1748 }
1749
1728 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1750 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1729 pub fn branchQuota(func: *const Func, ip: *const InternPool) *u32 {1751 fn branchQuotaPtr(func: Func, ip: *InternPool) *u32 {
1730 const extra = ip.getLocalShared(func.tid).extra.acquire();1752 const extra = ip.getLocalShared(func.tid).extra.acquire();
1731 return &extra.view().items(.@"0")[func.branch_quota_extra_index];1753 return &extra.view().items(.@"0")[func.branch_quota_extra_index];
1732 }1754 }
17331755
1756 pub fn branchQuotaUnordered(func: Func, ip: *const InternPool) u32 {
1757 return @atomicLoad(u32, func.branchQuotaPtr(@constCast(ip)), .unordered);
1758 }
1759
1760 pub fn maxBranchQuota(func: Func, ip: *InternPool, new_branch_quota: u32) void {
1761 const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex;
1762 extra_mutex.lock();
1763 defer extra_mutex.unlock();
1764
1765 const branch_quota_ptr = func.branchQuotaPtr(ip);
1766 @atomicStore(u32, branch_quota_ptr, @max(branch_quota_ptr.*, new_branch_quota), .release);
1767 }
1768
1734 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1769 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1735 pub fn resolvedErrorSet(func: *const Func, ip: *const InternPool) *Index {1770 fn resolvedErrorSetPtr(func: Func, ip: *InternPool) *Index {
1736 const extra = ip.getLocalShared(func.tid).extra.acquire();1771 const extra = ip.getLocalShared(func.tid).extra.acquire();
1737 assert(func.analysis(ip).inferred_error_set);1772 assert(func.analysisUnordered(ip).inferred_error_set);
1738 return @ptrCast(&extra.view().items(.@"0")[func.resolved_error_set_extra_index]);1773 return @ptrCast(&extra.view().items(.@"0")[func.resolved_error_set_extra_index]);
1739 }1774 }
1775
1776 pub fn resolvedErrorSetUnordered(func: Func, ip: *const InternPool) Index {
1777 return @atomicLoad(Index, func.resolvedErrorSetPtr(@constCast(ip)), .unordered);
1778 }
1740 };1779 };
17411780
1742 pub const Int = struct {1781 pub const Int = struct {
...@@ -2663,47 +2702,170 @@ pub const LoadedUnionType = struct {...@@ -2663,47 +2702,170 @@ pub const LoadedUnionType = struct {
2663 /// This accessor is provided so that the tag type can be mutated, and so that2702 /// This accessor is provided so that the tag type can be mutated, and so that
2664 /// when it is mutated, the mutations are observed.2703 /// when it is mutated, the mutations are observed.
2665 /// The returned pointer expires with any addition to the `InternPool`.2704 /// The returned pointer expires with any addition to the `InternPool`.
2666 pub fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {2705 fn tagTypePtr(self: LoadedUnionType, ip: *InternPool) *Index {
2667 const extra = ip.getLocalShared(self.tid).extra.acquire();2706 const extra = ip.getLocalShared(self.tid).extra.acquire();
2668 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;2707 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;
2669 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);2708 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
2670 }2709 }
26712710
2711 pub fn tagTypeUnordered(u: LoadedUnionType, ip: *const InternPool) Index {
2712 return @atomicLoad(Index, u.tagTypePtr(@constCast(ip)), .unordered);
2713 }
2714
2715 pub fn setTagType(u: LoadedUnionType, ip: *InternPool, tag_type: Index) void {
2716 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2717 extra_mutex.lock();
2718 defer extra_mutex.unlock();
2719
2720 @atomicStore(Index, u.tagTypePtr(ip), tag_type, .release);
2721 }
2722
2672 /// The returned pointer expires with any addition to the `InternPool`.2723 /// The returned pointer expires with any addition to the `InternPool`.
2673 pub fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {2724 fn flagsPtr(self: LoadedUnionType, ip: *InternPool) *Tag.TypeUnion.Flags {
2674 const extra = ip.getLocalShared(self.tid).extra.acquire();2725 const extra = ip.getLocalShared(self.tid).extra.acquire();
2675 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;2726 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
2676 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);2727 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
2677 }2728 }
26782729
2730 pub fn flagsUnordered(u: LoadedUnionType, ip: *const InternPool) Tag.TypeUnion.Flags {
2731 return @atomicLoad(Tag.TypeUnion.Flags, u.flagsPtr(@constCast(ip)), .unordered);
2732 }
2733
2734 pub fn setStatus(u: LoadedUnionType, ip: *InternPool, status: Status) void {
2735 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2736 extra_mutex.lock();
2737 defer extra_mutex.unlock();
2738
2739 const flags_ptr = u.flagsPtr(ip);
2740 var flags = flags_ptr.*;
2741 flags.status = status;
2742 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2743 }
2744
2745 pub fn setStatusIfLayoutWip(u: LoadedUnionType, ip: *InternPool, status: Status) void {
2746 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2747 extra_mutex.lock();
2748 defer extra_mutex.unlock();
2749
2750 const flags_ptr = u.flagsPtr(ip);
2751 var flags = flags_ptr.*;
2752 if (flags.status == .layout_wip) flags.status = status;
2753 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2754 }
2755
2756 pub fn setAlignment(u: LoadedUnionType, ip: *InternPool, alignment: Alignment) void {
2757 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2758 extra_mutex.lock();
2759 defer extra_mutex.unlock();
2760
2761 const flags_ptr = u.flagsPtr(ip);
2762 var flags = flags_ptr.*;
2763 flags.alignment = alignment;
2764 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2765 }
2766
2767 pub fn assumeRuntimeBitsIfFieldTypesWip(u: LoadedUnionType, ip: *InternPool) bool {
2768 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2769 extra_mutex.lock();
2770 defer extra_mutex.unlock();
2771
2772 const flags_ptr = u.flagsPtr(ip);
2773 var flags = flags_ptr.*;
2774 defer if (flags.status == .field_types_wip) {
2775 flags.assumed_runtime_bits = true;
2776 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2777 };
2778 return flags.status == .field_types_wip;
2779 }
2780
2781 pub fn setRequiresComptimeWip(u: LoadedUnionType, ip: *InternPool) RequiresComptime {
2782 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2783 extra_mutex.lock();
2784 defer extra_mutex.unlock();
2785
2786 const flags_ptr = u.flagsPtr(ip);
2787 var flags = flags_ptr.*;
2788 defer if (flags.requires_comptime == .unknown) {
2789 flags.requires_comptime = .wip;
2790 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2791 };
2792 return flags.requires_comptime;
2793 }
2794
2795 pub fn setRequiresComptime(u: LoadedUnionType, ip: *InternPool, requires_comptime: RequiresComptime) void {
2796 assert(requires_comptime != .wip); // see setRequiresComptimeWip
2797
2798 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2799 extra_mutex.lock();
2800 defer extra_mutex.unlock();
2801
2802 const flags_ptr = u.flagsPtr(ip);
2803 var flags = flags_ptr.*;
2804 flags.requires_comptime = requires_comptime;
2805 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2806 }
2807
2808 pub fn assumePointerAlignedIfFieldTypesWip(u: LoadedUnionType, ip: *InternPool, ptr_align: Alignment) bool {
2809 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2810 extra_mutex.lock();
2811 defer extra_mutex.unlock();
2812
2813 const flags_ptr = u.flagsPtr(ip);
2814 var flags = flags_ptr.*;
2815 defer if (flags.status == .field_types_wip) {
2816 flags.alignment = ptr_align;
2817 flags.assumed_pointer_aligned = true;
2818 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2819 };
2820 return flags.status == .field_types_wip;
2821 }
2822
2679 /// The returned pointer expires with any addition to the `InternPool`.2823 /// The returned pointer expires with any addition to the `InternPool`.
2680 pub fn size(self: LoadedUnionType, ip: *const InternPool) *u32 {2824 fn sizePtr(self: LoadedUnionType, ip: *InternPool) *u32 {
2681 const extra = ip.getLocalShared(self.tid).extra.acquire();2825 const extra = ip.getLocalShared(self.tid).extra.acquire();
2682 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;2826 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;
2683 return &extra.view().items(.@"0")[self.extra_index + field_index];2827 return &extra.view().items(.@"0")[self.extra_index + field_index];
2684 }2828 }
26852829
2830 pub fn sizeUnordered(u: LoadedUnionType, ip: *const InternPool) u32 {
2831 return @atomicLoad(u32, u.sizePtr(@constCast(ip)), .unordered);
2832 }
2833
2686 /// The returned pointer expires with any addition to the `InternPool`.2834 /// The returned pointer expires with any addition to the `InternPool`.
2687 pub fn padding(self: LoadedUnionType, ip: *const InternPool) *u32 {2835 fn paddingPtr(self: LoadedUnionType, ip: *InternPool) *u32 {
2688 const extra = ip.getLocalShared(self.tid).extra.acquire();2836 const extra = ip.getLocalShared(self.tid).extra.acquire();
2689 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;2837 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;
2690 return &extra.view().items(.@"0")[self.extra_index + field_index];2838 return &extra.view().items(.@"0")[self.extra_index + field_index];
2691 }2839 }
26922840
2841 pub fn paddingUnordered(u: LoadedUnionType, ip: *const InternPool) u32 {
2842 return @atomicLoad(u32, u.paddingPtr(@constCast(ip)), .unordered);
2843 }
2844
2693 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {2845 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {
2694 return self.flagsPtr(ip).runtime_tag.hasTag();2846 return self.flagsUnordered(ip).runtime_tag.hasTag();
2695 }2847 }
26962848
2697 pub fn haveFieldTypes(self: LoadedUnionType, ip: *const InternPool) bool {2849 pub fn haveFieldTypes(self: LoadedUnionType, ip: *const InternPool) bool {
2698 return self.flagsPtr(ip).status.haveFieldTypes();2850 return self.flagsUnordered(ip).status.haveFieldTypes();
2699 }2851 }
27002852
2701 pub fn haveLayout(self: LoadedUnionType, ip: *const InternPool) bool {2853 pub fn haveLayout(self: LoadedUnionType, ip: *const InternPool) bool {
2702 return self.flagsPtr(ip).status.haveLayout();2854 return self.flagsUnordered(ip).status.haveLayout();
2703 }2855 }
27042856
2705 pub fn getLayout(self: LoadedUnionType, ip: *const InternPool) std.builtin.Type.ContainerLayout {2857 pub fn setHaveLayout(u: LoadedUnionType, ip: *InternPool, size: u32, padding: u32, alignment: Alignment) void {
2706 return self.flagsPtr(ip).layout;2858 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
2859 extra_mutex.lock();
2860 defer extra_mutex.unlock();
2861
2862 @atomicStore(u32, u.sizePtr(ip), size, .unordered);
2863 @atomicStore(u32, u.paddingPtr(ip), padding, .unordered);
2864 const flags_ptr = u.flagsPtr(ip);
2865 var flags = flags_ptr.*;
2866 flags.alignment = alignment;
2867 flags.status = .have_layout;
2868 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
2707 }2869 }
27082870
2709 pub fn fieldAlign(self: LoadedUnionType, ip: *const InternPool, field_index: usize) Alignment {2871 pub fn fieldAlign(self: LoadedUnionType, ip: *const InternPool, field_index: usize) Alignment {
...@@ -2726,7 +2888,7 @@ pub const LoadedUnionType = struct {...@@ -2726,7 +2888,7 @@ pub const LoadedUnionType = struct {
27262888
2727 pub fn setFieldAligns(self: LoadedUnionType, ip: *const InternPool, aligns: []const Alignment) void {2889 pub fn setFieldAligns(self: LoadedUnionType, ip: *const InternPool, aligns: []const Alignment) void {
2728 if (aligns.len == 0) return;2890 if (aligns.len == 0) return;
2729 assert(self.flagsPtr(ip).any_aligned_fields);2891 assert(self.flagsUnordered(ip).any_aligned_fields);
2730 @memcpy(self.field_aligns.get(ip), aligns);2892 @memcpy(self.field_aligns.get(ip), aligns);
2731 }2893 }
2732};2894};
...@@ -2877,26 +3039,26 @@ pub const LoadedStructType = struct {...@@ -2877,26 +3039,26 @@ pub const LoadedStructType = struct {
2877 };3039 };
28783040
2879 /// Look up field index based on field name.3041 /// Look up field index based on field name.
2880 pub fn nameIndex(self: LoadedStructType, ip: *const InternPool, name: NullTerminatedString) ?u32 {3042 pub fn nameIndex(s: LoadedStructType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
2881 const names_map = self.names_map.unwrap() orelse {3043 const names_map = s.names_map.unwrap() orelse {
2882 const i = name.toUnsigned(ip) orelse return null;3044 const i = name.toUnsigned(ip) orelse return null;
2883 if (i >= self.field_types.len) return null;3045 if (i >= s.field_types.len) return null;
2884 return i;3046 return i;
2885 };3047 };
2886 const map = names_map.getConst(ip);3048 const map = names_map.getConst(ip);
2887 const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) };3049 const adapter: NullTerminatedString.Adapter = .{ .strings = s.field_names.get(ip) };
2888 const field_index = map.getIndexAdapted(name, adapter) orelse return null;3050 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
2889 return @intCast(field_index);3051 return @intCast(field_index);
2890 }3052 }
28913053
2892 /// Returns the already-existing field with the same name, if any.3054 /// Returns the already-existing field with the same name, if any.
2893 pub fn addFieldName(3055 pub fn addFieldName(
2894 self: LoadedStructType,3056 s: LoadedStructType,
2895 ip: *InternPool,3057 ip: *InternPool,
2896 name: NullTerminatedString,3058 name: NullTerminatedString,
2897 ) ?u32 {3059 ) ?u32 {
2898 const extra = ip.getLocalShared(self.tid).extra.acquire();3060 const extra = ip.getLocalShared(s.tid).extra.acquire();
2899 return ip.addFieldName(extra, self.names_map.unwrap().?, self.field_names.start, name);3061 return ip.addFieldName(extra, s.names_map.unwrap().?, s.field_names.start, name);
2900 }3062 }
29013063
2902 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {3064 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {
...@@ -2924,143 +3086,313 @@ pub const LoadedStructType = struct {...@@ -2924,143 +3086,313 @@ pub const LoadedStructType = struct {
2924 s.comptime_bits.setBit(ip, i);3086 s.comptime_bits.setBit(ip, i);
2925 }3087 }
29263088
3089 /// The returned pointer expires with any addition to the `InternPool`.
3090 /// Asserts the struct is not packed.
3091 fn flagsPtr(s: LoadedStructType, ip: *InternPool) *Tag.TypeStruct.Flags {
3092 assert(s.layout != .@"packed");
3093 const extra = ip.getLocalShared(s.tid).extra.acquire();
3094 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;
3095 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + flags_field_index]);
3096 }
3097
3098 pub fn flagsUnordered(s: LoadedStructType, ip: *const InternPool) Tag.TypeStruct.Flags {
3099 return @atomicLoad(Tag.TypeStruct.Flags, s.flagsPtr(@constCast(ip)), .unordered);
3100 }
3101
3102 /// The returned pointer expires with any addition to the `InternPool`.
3103 /// Asserts that the struct is packed.
3104 fn packedFlagsPtr(s: LoadedStructType, ip: *InternPool) *Tag.TypeStructPacked.Flags {
3105 assert(s.layout == .@"packed");
3106 const extra = ip.getLocalShared(s.tid).extra.acquire();
3107 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;
3108 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + flags_field_index]);
3109 }
3110
3111 pub fn packedFlagsUnordered(s: LoadedStructType, ip: *const InternPool) Tag.TypeStructPacked.Flags {
3112 return @atomicLoad(Tag.TypeStructPacked.Flags, s.packedFlagsPtr(@constCast(ip)), .unordered);
3113 }
3114
2927 /// Reads the non-opv flag calculated during AstGen. Used to short-circuit more3115 /// Reads the non-opv flag calculated during AstGen. Used to short-circuit more
2928 /// complicated logic.3116 /// complicated logic.
2929 pub fn knownNonOpv(s: LoadedStructType, ip: *InternPool) bool {3117 pub fn knownNonOpv(s: LoadedStructType, ip: *const InternPool) bool {
2930 return switch (s.layout) {3118 return switch (s.layout) {
2931 .@"packed" => false,3119 .@"packed" => false,
2932 .auto, .@"extern" => s.flagsPtr(ip).known_non_opv,3120 .auto, .@"extern" => s.flagsUnordered(ip).known_non_opv,
2933 };3121 };
2934 }3122 }
29353123
2936 /// The returned pointer expires with any addition to the `InternPool`.3124 pub fn requiresComptime(s: LoadedStructType, ip: *const InternPool) RequiresComptime {
2937 /// Asserts the struct is not packed.3125 return s.flagsUnordered(ip).requires_comptime;
2938 pub fn flagsPtr(self: LoadedStructType, ip: *InternPool) *Tag.TypeStruct.Flags {
2939 assert(self.layout != .@"packed");
2940 const extra = ip.getLocalShared(self.tid).extra.acquire();
2941 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;
2942 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + flags_field_index]);
2943 }3126 }
29443127
2945 /// The returned pointer expires with any addition to the `InternPool`.3128 pub fn setRequiresComptimeWip(s: LoadedStructType, ip: *InternPool) RequiresComptime {
2946 /// Asserts that the struct is packed.3129 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
2947 pub fn packedFlagsPtr(self: LoadedStructType, ip: *InternPool) *Tag.TypeStructPacked.Flags {3130 extra_mutex.lock();
2948 assert(self.layout == .@"packed");3131 defer extra_mutex.unlock();
2949 const extra = ip.getLocalShared(self.tid).extra.acquire();3132
2950 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;3133 const flags_ptr = s.flagsPtr(ip);
2951 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + flags_field_index]);3134 var flags = flags_ptr.*;
3135 defer if (flags.requires_comptime == .unknown) {
3136 flags.requires_comptime = .wip;
3137 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3138 };
3139 return flags.requires_comptime;
3140 }
3141
3142 pub fn setRequiresComptime(s: LoadedStructType, ip: *InternPool, requires_comptime: RequiresComptime) void {
3143 assert(requires_comptime != .wip); // see setRequiresComptimeWip
3144
3145 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3146 extra_mutex.lock();
3147 defer extra_mutex.unlock();
3148
3149 const flags_ptr = s.flagsPtr(ip);
3150 var flags = flags_ptr.*;
3151 flags.requires_comptime = requires_comptime;
3152 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
2952 }3153 }
29533154
2954 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {3155 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {
2955 if (s.layout == .@"packed") return false;3156 if (s.layout == .@"packed") return false;
3157
3158 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3159 extra_mutex.lock();
3160 defer extra_mutex.unlock();
3161
2956 const flags_ptr = s.flagsPtr(ip);3162 const flags_ptr = s.flagsPtr(ip);
2957 if (flags_ptr.field_types_wip) {3163 var flags = flags_ptr.*;
2958 flags_ptr.assumed_runtime_bits = true;3164 defer if (flags.field_types_wip) {
2959 return true;3165 flags.assumed_runtime_bits = true;
2960 }3166 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
2961 return false;3167 };
3168 return flags.field_types_wip;
2962 }3169 }
29633170
2964 pub fn setTypesWip(s: LoadedStructType, ip: *InternPool) bool {3171 pub fn setFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {
2965 if (s.layout == .@"packed") return false;3172 if (s.layout == .@"packed") return false;
3173
3174 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3175 extra_mutex.lock();
3176 defer extra_mutex.unlock();
3177
2966 const flags_ptr = s.flagsPtr(ip);3178 const flags_ptr = s.flagsPtr(ip);
2967 if (flags_ptr.field_types_wip) return true;3179 var flags = flags_ptr.*;
2968 flags_ptr.field_types_wip = true;3180 defer {
2969 return false;3181 flags.field_types_wip = true;
3182 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3183 }
3184 return flags.field_types_wip;
2970 }3185 }
29713186
2972 pub fn clearTypesWip(s: LoadedStructType, ip: *InternPool) void {3187 pub fn clearFieldTypesWip(s: LoadedStructType, ip: *InternPool) void {
2973 if (s.layout == .@"packed") return;3188 if (s.layout == .@"packed") return;
2974 s.flagsPtr(ip).field_types_wip = false;3189
3190 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3191 extra_mutex.lock();
3192 defer extra_mutex.unlock();
3193
3194 const flags_ptr = s.flagsPtr(ip);
3195 var flags = flags_ptr.*;
3196 flags.field_types_wip = false;
3197 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
2975 }3198 }
29763199
2977 pub fn setLayoutWip(s: LoadedStructType, ip: *InternPool) bool {3200 pub fn setLayoutWip(s: LoadedStructType, ip: *InternPool) bool {
2978 if (s.layout == .@"packed") return false;3201 if (s.layout == .@"packed") return false;
3202
3203 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3204 extra_mutex.lock();
3205 defer extra_mutex.unlock();
3206
2979 const flags_ptr = s.flagsPtr(ip);3207 const flags_ptr = s.flagsPtr(ip);
2980 if (flags_ptr.layout_wip) return true;3208 var flags = flags_ptr.*;
2981 flags_ptr.layout_wip = true;3209 defer {
2982 return false;3210 flags.layout_wip = true;
3211 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3212 }
3213 return flags.layout_wip;
2983 }3214 }
29843215
2985 pub fn clearLayoutWip(s: LoadedStructType, ip: *InternPool) void {3216 pub fn clearLayoutWip(s: LoadedStructType, ip: *InternPool) void {
2986 if (s.layout == .@"packed") return;3217 if (s.layout == .@"packed") return;
2987 s.flagsPtr(ip).layout_wip = false;3218
3219 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3220 extra_mutex.lock();
3221 defer extra_mutex.unlock();
3222
3223 const flags_ptr = s.flagsPtr(ip);
3224 var flags = flags_ptr.*;
3225 flags.layout_wip = false;
3226 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
2988 }3227 }
29893228
2990 pub fn setAlignmentWip(s: LoadedStructType, ip: *InternPool) bool {3229 pub fn setAlignment(s: LoadedStructType, ip: *InternPool, alignment: Alignment) void {
2991 if (s.layout == .@"packed") return false;3230 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3231 extra_mutex.lock();
3232 defer extra_mutex.unlock();
3233
3234 const flags_ptr = s.flagsPtr(ip);
3235 var flags = flags_ptr.*;
3236 flags.alignment = alignment;
3237 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3238 }
3239
3240 pub fn assumePointerAlignedIfFieldTypesWip(s: LoadedStructType, ip: *InternPool, ptr_align: Alignment) bool {
3241 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3242 extra_mutex.lock();
3243 defer extra_mutex.unlock();
3244
3245 const flags_ptr = s.flagsPtr(ip);
3246 var flags = flags_ptr.*;
3247 defer if (flags.field_types_wip) {
3248 flags.alignment = ptr_align;
3249 flags.assumed_pointer_aligned = true;
3250 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3251 };
3252 return flags.field_types_wip;
3253 }
3254
3255 pub fn assumePointerAlignedIfWip(s: LoadedStructType, ip: *InternPool, ptr_align: Alignment) bool {
3256 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3257 extra_mutex.lock();
3258 defer extra_mutex.unlock();
3259
2992 const flags_ptr = s.flagsPtr(ip);3260 const flags_ptr = s.flagsPtr(ip);
2993 if (flags_ptr.alignment_wip) return true;3261 var flags = flags_ptr.*;
2994 flags_ptr.alignment_wip = true;3262 defer {
2995 return false;3263 if (flags.alignment_wip) {
3264 flags.alignment = ptr_align;
3265 flags.assumed_pointer_aligned = true;
3266 } else flags.alignment_wip = true;
3267 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3268 }
3269 return flags.alignment_wip;
2996 }3270 }
29973271
2998 pub fn clearAlignmentWip(s: LoadedStructType, ip: *InternPool) void {3272 pub fn clearAlignmentWip(s: LoadedStructType, ip: *InternPool) void {
2999 if (s.layout == .@"packed") return;3273 if (s.layout == .@"packed") return;
3000 s.flagsPtr(ip).alignment_wip = false;3274
3275 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3276 extra_mutex.lock();
3277 defer extra_mutex.unlock();
3278
3279 const flags_ptr = s.flagsPtr(ip);
3280 var flags = flags_ptr.*;
3281 flags.alignment_wip = false;
3282 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3001 }3283 }
30023284
3003 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {3285 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {
3004 const local = ip.getLocal(s.tid);3286 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3005 local.mutate.extra.mutex.lock();3287 extra_mutex.lock();
3006 defer local.mutate.extra.mutex.unlock();3288 defer extra_mutex.unlock();
3007 return switch (s.layout) {3289
3008 .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw(3290 switch (s.layout) {
3009 u32,3291 .@"packed" => {
3010 @as(*u32, @ptrCast(s.packedFlagsPtr(ip))),3292 const flags_ptr = s.packedFlagsPtr(ip);
3011 .Or,3293 var flags = flags_ptr.*;
3012 @bitCast(Tag.TypeStructPacked.Flags{ .field_inits_wip = true }),3294 defer {
3013 .acq_rel,3295 flags.field_inits_wip = true;
3014 ))).field_inits_wip,3296 @atomicStore(Tag.TypeStructPacked.Flags, flags_ptr, flags, .release);
3015 .auto, .@"extern" => @as(Tag.TypeStruct.Flags, @bitCast(@atomicRmw(3297 }
3016 u32,3298 return flags.field_inits_wip;
3017 @as(*u32, @ptrCast(s.flagsPtr(ip))),3299 },
3018 .Or,3300 .auto, .@"extern" => {
3019 @bitCast(Tag.TypeStruct.Flags{ .field_inits_wip = true }),3301 const flags_ptr = s.flagsPtr(ip);
3020 .acq_rel,3302 var flags = flags_ptr.*;
3021 ))).field_inits_wip,3303 defer {
3022 };3304 flags.field_inits_wip = true;
3305 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3306 }
3307 return flags.field_inits_wip;
3308 },
3309 }
3023 }3310 }
30243311
3025 pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void {3312 pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void {
3313 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3314 extra_mutex.lock();
3315 defer extra_mutex.unlock();
3316
3026 switch (s.layout) {3317 switch (s.layout) {
3027 .@"packed" => s.packedFlagsPtr(ip).field_inits_wip = false,3318 .@"packed" => {
3028 .auto, .@"extern" => s.flagsPtr(ip).field_inits_wip = false,3319 const flags_ptr = s.packedFlagsPtr(ip);
3320 var flags = flags_ptr.*;
3321 flags.field_inits_wip = false;
3322 @atomicStore(Tag.TypeStructPacked.Flags, flags_ptr, flags, .release);
3323 },
3324 .auto, .@"extern" => {
3325 const flags_ptr = s.flagsPtr(ip);
3326 var flags = flags_ptr.*;
3327 flags.field_inits_wip = false;
3328 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3329 },
3029 }3330 }
3030 }3331 }
30313332
3032 pub fn setFullyResolved(s: LoadedStructType, ip: *InternPool) bool {3333 pub fn setFullyResolved(s: LoadedStructType, ip: *InternPool) bool {
3033 if (s.layout == .@"packed") return true;3334 if (s.layout == .@"packed") return true;
3335
3336 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3337 extra_mutex.lock();
3338 defer extra_mutex.unlock();
3339
3034 const flags_ptr = s.flagsPtr(ip);3340 const flags_ptr = s.flagsPtr(ip);
3035 if (flags_ptr.fully_resolved) return true;3341 var flags = flags_ptr.*;
3036 flags_ptr.fully_resolved = true;3342 defer {
3037 return false;3343 flags.fully_resolved = true;
3344 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3345 }
3346 return flags.fully_resolved;
3038 }3347 }
30393348
3040 pub fn clearFullyResolved(s: LoadedStructType, ip: *InternPool) void {3349 pub fn clearFullyResolved(s: LoadedStructType, ip: *InternPool) void {
3041 s.flagsPtr(ip).fully_resolved = false;3350 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3351 extra_mutex.lock();
3352 defer extra_mutex.unlock();
3353
3354 const flags_ptr = s.flagsPtr(ip);
3355 var flags = flags_ptr.*;
3356 flags.fully_resolved = false;
3357 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3042 }3358 }
30433359
3044 /// The returned pointer expires with any addition to the `InternPool`.3360 /// The returned pointer expires with any addition to the `InternPool`.
3045 /// Asserts the struct is not packed.3361 /// Asserts the struct is not packed.
3046 pub fn size(self: LoadedStructType, ip: *InternPool) *u32 {3362 fn sizePtr(s: LoadedStructType, ip: *InternPool) *u32 {
3047 assert(self.layout != .@"packed");3363 assert(s.layout != .@"packed");
3048 const extra = ip.getLocalShared(self.tid).extra.acquire();3364 const extra = ip.getLocalShared(s.tid).extra.acquire();
3049 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;3365 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;
3050 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + size_field_index]);3366 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + size_field_index]);
3367 }
3368
3369 pub fn sizeUnordered(s: LoadedStructType, ip: *const InternPool) u32 {
3370 return @atomicLoad(u32, s.sizePtr(@constCast(ip)), .unordered);
3051 }3371 }
30523372
3053 /// The backing integer type of the packed struct. Whether zig chooses3373 /// The backing integer type of the packed struct. Whether zig chooses
3054 /// this type or the user specifies it, it is stored here. This will be3374 /// this type or the user specifies it, it is stored here. This will be
3055 /// set to `none` until the layout is resolved.3375 /// set to `none` until the layout is resolved.
3056 /// Asserts the struct is packed.3376 /// Asserts the struct is packed.
3057 pub fn backingIntType(s: LoadedStructType, ip: *InternPool) *Index {3377 fn backingIntTypePtr(s: LoadedStructType, ip: *InternPool) *Index {
3058 assert(s.layout == .@"packed");3378 assert(s.layout == .@"packed");
3059 const extra = ip.getLocalShared(s.tid).extra.acquire();3379 const extra = ip.getLocalShared(s.tid).extra.acquire();
3060 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;3380 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;
3061 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + field_index]);3381 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + field_index]);
3062 }3382 }
30633383
3384 pub fn backingIntTypeUnordered(s: LoadedStructType, ip: *const InternPool) Index {
3385 return @atomicLoad(Index, s.backingIntTypePtr(@constCast(ip)), .unordered);
3386 }
3387
3388 pub fn setBackingIntType(s: LoadedStructType, ip: *InternPool, backing_int_ty: Index) void {
3389 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3390 extra_mutex.lock();
3391 defer extra_mutex.unlock();
3392
3393 @atomicStore(Index, s.backingIntTypePtr(ip), backing_int_ty, .release);
3394 }
3395
3064 /// Asserts the struct is not packed.3396 /// Asserts the struct is not packed.
3065 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {3397 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {
3066 assert(s.layout != .@"packed");3398 assert(s.layout != .@"packed");
...@@ -3073,29 +3405,56 @@ pub const LoadedStructType = struct {...@@ -3073,29 +3405,56 @@ pub const LoadedStructType = struct {
3073 return types.len == 0 or types[0] != .none;3405 return types.len == 0 or types[0] != .none;
3074 }3406 }
30753407
3076 pub fn haveFieldInits(s: LoadedStructType, ip: *InternPool) bool {3408 pub fn haveFieldInits(s: LoadedStructType, ip: *const InternPool) bool {
3077 return switch (s.layout) {3409 return switch (s.layout) {
3078 .@"packed" => s.packedFlagsPtr(ip).inits_resolved,3410 .@"packed" => s.packedFlagsUnordered(ip).inits_resolved,
3079 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved,3411 .auto, .@"extern" => s.flagsUnordered(ip).inits_resolved,
3080 };3412 };
3081 }3413 }
30823414
3083 pub fn setHaveFieldInits(s: LoadedStructType, ip: *InternPool) void {3415 pub fn setHaveFieldInits(s: LoadedStructType, ip: *InternPool) void {
3416 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3417 extra_mutex.lock();
3418 defer extra_mutex.unlock();
3419
3084 switch (s.layout) {3420 switch (s.layout) {
3085 .@"packed" => s.packedFlagsPtr(ip).inits_resolved = true,3421 .@"packed" => {
3086 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved = true,3422 const flags_ptr = s.packedFlagsPtr(ip);
3423 var flags = flags_ptr.*;
3424 flags.inits_resolved = true;
3425 @atomicStore(Tag.TypeStructPacked.Flags, flags_ptr, flags, .release);
3426 },
3427 .auto, .@"extern" => {
3428 const flags_ptr = s.flagsPtr(ip);
3429 var flags = flags_ptr.*;
3430 flags.inits_resolved = true;
3431 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3432 },
3087 }3433 }
3088 }3434 }
30893435
3090 pub fn haveLayout(s: LoadedStructType, ip: *InternPool) bool {3436 pub fn haveLayout(s: LoadedStructType, ip: *InternPool) bool {
3091 return switch (s.layout) {3437 return switch (s.layout) {
3092 .@"packed" => s.backingIntType(ip).* != .none,3438 .@"packed" => s.backingIntTypeUnordered(ip) != .none,
3093 .auto, .@"extern" => s.flagsPtr(ip).layout_resolved,3439 .auto, .@"extern" => s.flagsUnordered(ip).layout_resolved,
3094 };3440 };
3095 }3441 }
30963442
3443 pub fn setLayoutResolved(s: LoadedStructType, ip: *InternPool, size: u32, alignment: Alignment) void {
3444 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3445 extra_mutex.lock();
3446 defer extra_mutex.unlock();
3447
3448 @atomicStore(u32, s.sizePtr(ip), size, .unordered);
3449 const flags_ptr = s.flagsPtr(ip);
3450 var flags = flags_ptr.*;
3451 flags.alignment = alignment;
3452 flags.layout_resolved = true;
3453 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3454 }
3455
3097 pub fn isTuple(s: LoadedStructType, ip: *InternPool) bool {3456 pub fn isTuple(s: LoadedStructType, ip: *InternPool) bool {
3098 return s.layout != .@"packed" and s.flagsPtr(ip).is_tuple;3457 return s.layout != .@"packed" and s.flagsUnordered(ip).is_tuple;
3099 }3458 }
31003459
3101 pub fn hasReorderedFields(s: LoadedStructType) bool {3460 pub fn hasReorderedFields(s: LoadedStructType) bool {
...@@ -3209,7 +3568,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3209,7 +3568,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3209 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]);3568 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]);
3210 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);3569 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
3211 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];3570 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
3212 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic));3571 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
3213 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);3572 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);
3214 const captures_len = if (flags.any_captures) c: {3573 const captures_len = if (flags.any_captures) c: {
3215 const len = extra_list.view().items(.@"0")[extra_index];3574 const len = extra_list.view().items(.@"0")[extra_index];
...@@ -3317,7 +3676,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3317,7 +3676,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3317 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];3676 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
3318 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);3677 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
3319 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);3678 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);
3320 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic));3679 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));
3321 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);3680 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
3322 const has_inits = item.tag == .type_struct_packed_inits;3681 const has_inits = item.tag == .type_struct_packed_inits;
3323 const captures_len = if (flags.any_captures) c: {3682 const captures_len = if (flags.any_captures) c: {
...@@ -5442,10 +5801,10 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5442,10 +5801,10 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5442 .arena = .{},5801 .arena = .{},
54435802
5444 .items = Local.ListMutate.empty,5803 .items = Local.ListMutate.empty,
5445 .extra = Local.MutexListMutate.empty,5804 .extra = Local.ListMutate.empty,
5446 .limbs = Local.ListMutate.empty,5805 .limbs = Local.ListMutate.empty,
5447 .strings = Local.ListMutate.empty,5806 .strings = Local.ListMutate.empty,
5448 .tracked_insts = Local.MutexListMutate.empty,5807 .tracked_insts = Local.ListMutate.empty,
5449 .files = Local.ListMutate.empty,5808 .files = Local.ListMutate.empty,
5450 .maps = Local.ListMutate.empty,5809 .maps = Local.ListMutate.empty,
54515810
...@@ -5635,7 +5994,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5635,7 +5994,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5635 const extra_list = unwrapped_index.getExtra(ip);5994 const extra_list = unwrapped_index.getExtra(ip);
5636 const extra_items = extra_list.view().items(.@"0");5995 const extra_items = extra_list.view().items(.@"0");
5637 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);5996 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
5638 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic));5997 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
5639 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);5998 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);
5640 if (flags.is_reified) {5999 if (flags.is_reified) {
5641 assert(!flags.any_captures);6000 assert(!flags.any_captures);
...@@ -5658,7 +6017,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5658,7 +6017,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5658 const extra_list = unwrapped_index.getExtra(ip);6017 const extra_list = unwrapped_index.getExtra(ip);
5659 const extra_items = extra_list.view().items(.@"0");6018 const extra_items = extra_list.view().items(.@"0");
5660 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);6019 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
5661 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic));6020 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));
5662 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);6021 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
5663 if (flags.is_reified) {6022 if (flags.is_reified) {
5664 assert(!flags.any_captures);6023 assert(!flags.any_captures);
...@@ -6155,7 +6514,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke...@@ -6155,7 +6514,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
6155fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {6514fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
6156 const extra_items = extra.view().items(.@"0");6515 const extra_items = extra.view().items(.@"0");
6157 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;6516 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;
6158 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .monotonic));6517 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .unordered));
6159 const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]);6518 const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]);
6160 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);6519 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);
6161 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);6520 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
...@@ -8702,7 +9061,7 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {...@@ -8702,7 +9061,7 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8702 // Restore the original item at this index.9061 // Restore the original item at this index.
8703 assert(static_keys[@intFromEnum(index)] == .simple_type);9062 assert(static_keys[@intFromEnum(index)] == .simple_type);
8704 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();9063 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8705 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .simple_type, .monotonic);9064 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .simple_type, .unordered);
8706 return;9065 return;
8707 }9066 }
87089067
...@@ -8719,7 +9078,7 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {...@@ -8719,7 +9078,7 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8719 // Thus, we will rewrite the tag to `removed`, leaking the item until9078 // Thus, we will rewrite the tag to `removed`, leaking the item until
8720 // next GC but causing `KeyAdapter` to ignore it.9079 // next GC but causing `KeyAdapter` to ignore it.
8721 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();9080 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8722 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .removed, .monotonic);9081 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .removed, .unordered);
8723}9082}
87249083
8725fn addInt(9084fn addInt(
...@@ -9415,9 +9774,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {...@@ -9415,9 +9774,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
9415/// The is only legal because the initializer is not part of the hash.9774/// The is only legal because the initializer is not part of the hash.
9416pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {9775pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
9417 const unwrapped_index = index.unwrap(ip);9776 const unwrapped_index = index.unwrap(ip);
9777
9418 const local = ip.getLocal(unwrapped_index.tid);9778 const local = ip.getLocal(unwrapped_index.tid);
9419 local.mutate.extra.mutex.lock();9779 local.mutate.extra.mutex.lock();
9420 defer local.mutate.extra.mutex.unlock();9780 defer local.mutate.extra.mutex.unlock();
9781
9421 const extra_items = local.shared.extra.view().items(.@"0");9782 const extra_items = local.shared.extra.view().items(.@"0");
9422 const item = unwrapped_index.getItem(ip);9783 const item = unwrapped_index.getItem(ip);
9423 assert(item.tag == .variable);9784 assert(item.tag == .variable);
...@@ -9436,7 +9797,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9436,7 +9797,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9436 var decls_len: usize = 0;9797 var decls_len: usize = 0;
9437 for (ip.locals) |*local| {9798 for (ip.locals) |*local| {
9438 items_len += local.mutate.items.len;9799 items_len += local.mutate.items.len;
9439 extra_len += local.mutate.extra.list.len;9800 extra_len += local.mutate.extra.len;
9440 limbs_len += local.mutate.limbs.len;9801 limbs_len += local.mutate.limbs.len;
9441 decls_len += local.mutate.decls.buckets_list.len;9802 decls_len += local.mutate.decls.buckets_list.len;
9442 }9803 }
...@@ -10730,29 +11091,29 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -10730,29 +11091,29 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
10730 };11091 };
10731}11092}
1073211093
10733pub fn isFuncBody(ip: *const InternPool, index: Index) bool {11094pub fn isFuncBody(ip: *const InternPool, func: Index) bool {
10734 return switch (index.unwrap(ip).getTag(ip)) {11095 return switch (func.unwrap(ip).getTag(ip)) {
10735 .func_decl, .func_instance, .func_coerced => true,11096 .func_decl, .func_instance, .func_coerced => true,
10736 else => false,11097 else => false,
10737 };11098 };
10738}11099}
1073911100
10740pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {11101fn funcAnalysisPtr(ip: *InternPool, func: Index) *FuncAnalysis {
10741 const unwrapped_index = index.unwrap(ip);11102 const unwrapped_func = func.unwrap(ip);
10742 const extra = unwrapped_index.getExtra(ip);11103 const extra = unwrapped_func.getExtra(ip);
10743 const item = unwrapped_index.getItem(ip);11104 const item = unwrapped_func.getItem(ip);
10744 const extra_index = switch (item.tag) {11105 const extra_index = switch (item.tag) {
10745 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,11106 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
10746 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,11107 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10747 .func_coerced => {11108 .func_coerced => {
10748 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;11109 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;
10749 const func_index: Index = @enumFromInt(extra.view().items(.@"0")[extra_index]);11110 const coerced_func_index: Index = @enumFromInt(extra.view().items(.@"0")[extra_index]);
10750 const unwrapped_func = func_index.unwrap(ip);11111 const unwrapped_coerced_func = coerced_func_index.unwrap(ip);
10751 const func_item = unwrapped_func.getItem(ip);11112 const coerced_func_item = unwrapped_coerced_func.getItem(ip);
10752 return @ptrCast(&unwrapped_func.getExtra(ip).view().items(.@"0")[11113 return @ptrCast(&unwrapped_coerced_func.getExtra(ip).view().items(.@"0")[
10753 switch (func_item.tag) {11114 switch (coerced_func_item.tag) {
10754 .func_decl => func_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,11115 .func_decl => coerced_func_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
10755 .func_instance => func_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,11116 .func_instance => coerced_func_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10756 else => unreachable,11117 else => unreachable,
10757 }11118 }
10758 ]);11119 ]);
...@@ -10762,14 +11123,65 @@ pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {...@@ -10762,14 +11123,65 @@ pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {
10762 return @ptrCast(&extra.view().items(.@"0")[extra_index]);11123 return @ptrCast(&extra.view().items(.@"0")[extra_index]);
10763}11124}
1076411125
10765pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {11126pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
10766 return funcAnalysis(ip, i).inferred_error_set;11127 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
10767}11128}
1076811129
10769pub fn funcZirBodyInst(ip: *const InternPool, index: Index) TrackedInst.Index {11130pub fn funcSetAnalysisState(ip: *InternPool, func: Index, state: FuncAnalysis.State) void {
10770 const unwrapped_index = index.unwrap(ip);11131 const unwrapped_func = func.unwrap(ip);
10771 const item = unwrapped_index.getItem(ip);11132 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
10772 const item_extra = unwrapped_index.getExtra(ip);11133 extra_mutex.lock();
11134 defer extra_mutex.unlock();
11135
11136 const analysis_ptr = ip.funcAnalysisPtr(func);
11137 var analysis = analysis_ptr.*;
11138 analysis.state = state;
11139 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11140}
11141
11142pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
11143 const unwrapped_func = func.unwrap(ip);
11144 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11145 extra_mutex.lock();
11146 defer extra_mutex.unlock();
11147
11148 const analysis_ptr = ip.funcAnalysisPtr(func);
11149 var analysis = analysis_ptr.*;
11150 analysis.stack_alignment = switch (analysis.stack_alignment) {
11151 .none => new_stack_alignment,
11152 else => |old_stack_alignment| old_stack_alignment.maxStrict(new_stack_alignment),
11153 };
11154 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11155}
11156
11157pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void {
11158 const unwrapped_func = func.unwrap(ip);
11159 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11160 extra_mutex.lock();
11161 defer extra_mutex.unlock();
11162
11163 const analysis_ptr = ip.funcAnalysisPtr(func);
11164 var analysis = analysis_ptr.*;
11165 analysis.calls_or_awaits_errorable_fn = true;
11166 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11167}
11168
11169pub fn funcSetCold(ip: *InternPool, func: Index, is_cold: bool) void {
11170 const unwrapped_func = func.unwrap(ip);
11171 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11172 extra_mutex.lock();
11173 defer extra_mutex.unlock();
11174
11175 const analysis_ptr = ip.funcAnalysisPtr(func);
11176 var analysis = analysis_ptr.*;
11177 analysis.is_cold = is_cold;
11178 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11179}
11180
11181pub fn funcZirBodyInst(ip: *const InternPool, func: Index) TrackedInst.Index {
11182 const unwrapped_func = func.unwrap(ip);
11183 const item = unwrapped_func.getItem(ip);
11184 const item_extra = unwrapped_func.getExtra(ip);
10773 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;11185 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
10774 switch (item.tag) {11186 switch (item.tag) {
10775 .func_decl => return @enumFromInt(item_extra.view().items(.@"0")[item.data + zir_body_inst_field_index]),11187 .func_decl => return @enumFromInt(item_extra.view().items(.@"0")[item.data + zir_body_inst_field_index]),
...@@ -10806,17 +11218,17 @@ pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {...@@ -10806,17 +11218,17 @@ pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {
10806/// Returns a mutable pointer to the resolved error set type of an inferred11218/// Returns a mutable pointer to the resolved error set type of an inferred
10807/// error set function. The returned pointer is invalidated when anything is11219/// error set function. The returned pointer is invalidated when anything is
10808/// added to `ip`.11220/// added to `ip`.
10809pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {11221fn iesResolvedPtr(ip: *InternPool, ies_index: Index) *Index {
10810 const ies_item = ies_index.getItem(ip);11222 const ies_item = ies_index.getItem(ip);
10811 assert(ies_item.tag == .type_inferred_error_set);11223 assert(ies_item.tag == .type_inferred_error_set);
10812 return funcIesResolved(ip, ies_item.data);11224 return ip.funcIesResolvedPtr(ies_item.data);
10813}11225}
1081411226
10815/// Returns a mutable pointer to the resolved error set type of an inferred11227/// Returns a mutable pointer to the resolved error set type of an inferred
10816/// error set function. The returned pointer is invalidated when anything is11228/// error set function. The returned pointer is invalidated when anything is
10817/// added to `ip`.11229/// added to `ip`.
10818pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {11230fn funcIesResolvedPtr(ip: *InternPool, func_index: Index) *Index {
10819 assert(funcHasInferredErrorSet(ip, func_index));11231 assert(ip.funcAnalysisUnordered(func_index).inferred_error_set);
10820 const unwrapped_func = func_index.unwrap(ip);11232 const unwrapped_func = func_index.unwrap(ip);
10821 const func_extra = unwrapped_func.getExtra(ip);11233 const func_extra = unwrapped_func.getExtra(ip);
10822 const func_item = unwrapped_func.getItem(ip);11234 const func_item = unwrapped_func.getItem(ip);
...@@ -10842,6 +11254,19 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {...@@ -10842,6 +11254,19 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
10842 return @ptrCast(&func_extra.view().items(.@"0")[extra_index]);11254 return @ptrCast(&func_extra.view().items(.@"0")[extra_index]);
10843}11255}
1084411256
11257pub fn funcIesResolvedUnordered(ip: *const InternPool, index: Index) Index {
11258 return @atomicLoad(Index, @constCast(ip).funcIesResolvedPtr(index), .unordered);
11259}
11260
11261pub fn funcSetIesResolved(ip: *InternPool, index: Index, ies: Index) void {
11262 const unwrapped_func = index.unwrap(ip);
11263 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11264 extra_mutex.lock();
11265 defer extra_mutex.unlock();
11266
11267 @atomicStore(Index, ip.funcIesResolvedPtr(index), ies, .release);
11268}
11269
10845pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {11270pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
10846 const unwrapped_index = index.unwrap(ip);11271 const unwrapped_index = index.unwrap(ip);
10847 const item = unwrapped_index.getItem(ip);11272 const item = unwrapped_index.getItem(ip);
...@@ -10950,7 +11375,10 @@ const GlobalErrorSet = struct {...@@ -10950,7 +11375,10 @@ const GlobalErrorSet = struct {
10950 names: Names,11375 names: Names,
10951 map: Shard.Map(GlobalErrorSet.Index),11376 map: Shard.Map(GlobalErrorSet.Index),
10952 } align(std.atomic.cache_line),11377 } align(std.atomic.cache_line),
10953 mutate: Local.MutexListMutate align(std.atomic.cache_line),11378 mutate: struct {
11379 names: Local.ListMutate,
11380 map: struct { mutex: std.Thread.Mutex },
11381 } align(std.atomic.cache_line),
1095411382
10955 const Names = Local.List(struct { NullTerminatedString });11383 const Names = Local.List(struct { NullTerminatedString });
1095611384
...@@ -10959,7 +11387,10 @@ const GlobalErrorSet = struct {...@@ -10959,7 +11387,10 @@ const GlobalErrorSet = struct {
10959 .names = Names.empty,11387 .names = Names.empty,
10960 .map = Shard.Map(GlobalErrorSet.Index).empty,11388 .map = Shard.Map(GlobalErrorSet.Index).empty,
10961 },11389 },
10962 .mutate = Local.MutexListMutate.empty,11390 .mutate = .{
11391 .names = Local.ListMutate.empty,
11392 .map = .{ .mutex = .{} },
11393 },
10963 };11394 };
1096411395
10965 const Index = enum(Zcu.ErrorInt) {11396 const Index = enum(Zcu.ErrorInt) {
...@@ -10969,7 +11400,7 @@ const GlobalErrorSet = struct {...@@ -10969,7 +11400,7 @@ const GlobalErrorSet = struct {
1096911400
10970 /// Not thread-safe, may only be called from the main thread.11401 /// Not thread-safe, may only be called from the main thread.
10971 pub fn getNamesFromMainThread(ges: *const GlobalErrorSet) []const NullTerminatedString {11402 pub fn getNamesFromMainThread(ges: *const GlobalErrorSet) []const NullTerminatedString {
10972 const len = ges.mutate.list.len;11403 const len = ges.mutate.names.len;
10973 return if (len > 0) ges.shared.names.view().items(.@"0")[0..len] else &.{};11404 return if (len > 0) ges.shared.names.view().items(.@"0")[0..len] else &.{};
10974 }11405 }
1097511406
...@@ -10994,8 +11425,8 @@ const GlobalErrorSet = struct {...@@ -10994,8 +11425,8 @@ const GlobalErrorSet = struct {
10994 if (entry.hash != hash) continue;11425 if (entry.hash != hash) continue;
10995 if (names.view().items(.@"0")[@intFromEnum(index) - 1] == name) return index;11426 if (names.view().items(.@"0")[@intFromEnum(index) - 1] == name) return index;
10996 }11427 }
10997 ges.mutate.mutex.lock();11428 ges.mutate.map.mutex.lock();
10998 defer ges.mutate.mutex.unlock();11429 defer ges.mutate.map.mutex.unlock();
10999 if (map.entries != ges.shared.map.entries) {11430 if (map.entries != ges.shared.map.entries) {
11000 map = ges.shared.map;11431 map = ges.shared.map;
11001 map_mask = map.header().mask();11432 map_mask = map.header().mask();
...@@ -11012,12 +11443,12 @@ const GlobalErrorSet = struct {...@@ -11012,12 +11443,12 @@ const GlobalErrorSet = struct {
11012 const mutable_names: Names.Mutable = .{11443 const mutable_names: Names.Mutable = .{
11013 .gpa = gpa,11444 .gpa = gpa,
11014 .arena = arena_state,11445 .arena = arena_state,
11015 .mutate = &ges.mutate.list,11446 .mutate = &ges.mutate.names,
11016 .list = &ges.shared.names,11447 .list = &ges.shared.names,
11017 };11448 };
11018 try mutable_names.ensureUnusedCapacity(1);11449 try mutable_names.ensureUnusedCapacity(1);
11019 const map_header = map.header().*;11450 const map_header = map.header().*;
11020 if (ges.mutate.list.len < map_header.capacity * 3 / 5) {11451 if (ges.mutate.names.len < map_header.capacity * 3 / 5) {
11021 mutable_names.appendAssumeCapacity(.{name});11452 mutable_names.appendAssumeCapacity(.{name});
11022 const index: GlobalErrorSet.Index = @enumFromInt(mutable_names.mutate.len);11453 const index: GlobalErrorSet.Index = @enumFromInt(mutable_names.mutate.len);
11023 const entry = &map.entries[map_index];11454 const entry = &map.entries[map_index];
src/Sema.zig+98-123
...@@ -2530,13 +2530,13 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error...@@ -2530,13 +2530,13 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
2530 }2530 }
25312531
2532 if (sema.owner_func_index != .none) {2532 if (sema.owner_func_index != .none) {
2533 ip.funcAnalysis(sema.owner_func_index).state = .sema_failure;2533 ip.funcSetAnalysisState(sema.owner_func_index, .sema_failure);
2534 } else {2534 } else {
2535 sema.owner_decl.analysis = .sema_failure;2535 sema.owner_decl.analysis = .sema_failure;
2536 }2536 }
25372537
2538 if (sema.func_index != .none) {2538 if (sema.func_index != .none) {
2539 ip.funcAnalysis(sema.func_index).state = .sema_failure;2539 ip.funcSetAnalysisState(sema.func_index, .sema_failure);
2540 }2540 }
25412541
2542 return error.AnalysisFail;2542 return error.AnalysisFail;
...@@ -2848,7 +2848,7 @@ fn zirStructDecl(...@@ -2848,7 +2848,7 @@ fn zirStructDecl(
2848 }2848 }
28492849
2850 try pt.finalizeAnonDecl(new_decl_index);2850 try pt.finalizeAnonDecl(new_decl_index);
2851 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });2851 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
2852 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));2852 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
2853 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));2853 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
2854}2854}
...@@ -3353,7 +3353,7 @@ fn zirUnionDecl(...@@ -3353,7 +3353,7 @@ fn zirUnionDecl(
3353 }3353 }
33543354
3355 try pt.finalizeAnonDecl(new_decl_index);3355 try pt.finalizeAnonDecl(new_decl_index);
3356 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });3356 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
3357 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));3357 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
3358 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3358 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3359}3359}
...@@ -6550,14 +6550,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -6550,14 +6550,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
6550 }6550 }
6551 sema.prev_stack_alignment_src = src;6551 sema.prev_stack_alignment_src = src;
65526552
6553 const ip = &mod.intern_pool;6553 mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
6554 const a = ip.funcAnalysis(sema.func_index);
6555 if (a.stack_alignment != .none) {
6556 a.stack_alignment = @enumFromInt(@max(
6557 @intFromEnum(alignment),
6558 @intFromEnum(a.stack_alignment),
6559 ));
6560 }
6561}6554}
65626555
6563fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6556fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
...@@ -6570,7 +6563,7 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -6570,7 +6563,7 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
6570 .needed_comptime_reason = "operand to @setCold must be comptime-known",6563 .needed_comptime_reason = "operand to @setCold must be comptime-known",
6571 });6564 });
6572 if (sema.func_index == .none) return; // does nothing outside a function6565 if (sema.func_index == .none) return; // does nothing outside a function
6573 ip.funcAnalysis(sema.func_index).is_cold = is_cold;6566 ip.funcSetCold(sema.func_index, is_cold);
6574}6567}
65756568
6576fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6569fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
...@@ -7085,7 +7078,7 @@ fn zirCall(...@@ -7085,7 +7078,7 @@ fn zirCall(
7085 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);7078 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
70867079
7087 if (sema.owner_func_index == .none or7080 if (sema.owner_func_index == .none or
7088 !mod.intern_pool.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn)7081 !mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn)
7089 {7082 {
7090 // No errorable fn actually called; we have no error return trace7083 // No errorable fn actually called; we have no error return trace
7091 input_is_error = false;7084 input_is_error = false;
...@@ -7793,7 +7786,7 @@ fn analyzeCall(...@@ -7793,7 +7786,7 @@ fn analyzeCall(
7793 _ = ics.callee();7786 _ = ics.callee();
77947787
7795 if (!inlining.has_comptime_args) {7788 if (!inlining.has_comptime_args) {
7796 if (module_fn.analysis(ip).state == .sema_failure)7789 if (module_fn.analysisUnordered(ip).state == .sema_failure)
7797 return error.AnalysisFail;7790 return error.AnalysisFail;
77987791
7799 var block_it = block;7792 var block_it = block;
...@@ -7816,7 +7809,7 @@ fn analyzeCall(...@@ -7816,7 +7809,7 @@ fn analyzeCall(
7816 try sema.resolveInst(fn_info.ret_ty_ref);7809 try sema.resolveInst(fn_info.ret_ty_ref);
7817 const ret_ty_src: LazySrcLoc = .{ .base_node_inst = module_fn.zir_body_inst, .offset = .{ .node_offset_fn_type_ret_ty = 0 } };7810 const ret_ty_src: LazySrcLoc = .{ .base_node_inst = module_fn.zir_body_inst, .offset = .{ .node_offset_fn_type_ret_ty = 0 } };
7818 sema.fn_ret_ty = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);7811 sema.fn_ret_ty = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);
7819 if (module_fn.analysis(ip).inferred_error_set) {7812 if (module_fn.analysisUnordered(ip).inferred_error_set) {
7820 // Create a fresh inferred error set type for inline/comptime calls.7813 // Create a fresh inferred error set type for inline/comptime calls.
7821 const ies = try sema.arena.create(InferredErrorSet);7814 const ies = try sema.arena.create(InferredErrorSet);
7822 ies.* = .{ .func = .none };7815 ies.* = .{ .func = .none };
...@@ -7942,7 +7935,7 @@ fn analyzeCall(...@@ -7942,7 +7935,7 @@ fn analyzeCall(
7942 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);7935 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
79437936
7944 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {7937 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7945 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;7938 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
7946 }7939 }
79477940
7948 if (try sema.resolveValue(func)) |func_val| {7941 if (try sema.resolveValue(func)) |func_val| {
...@@ -8386,7 +8379,7 @@ fn instantiateGenericCall(...@@ -8386,7 +8379,7 @@ fn instantiateGenericCall(
8386 const callee_index = (child_sema.resolveConstDefinedValue(&child_block, LazySrcLoc.unneeded, new_func_inst, undefined) catch unreachable).toIntern();8379 const callee_index = (child_sema.resolveConstDefinedValue(&child_block, LazySrcLoc.unneeded, new_func_inst, undefined) catch unreachable).toIntern();
83878380
8388 const callee = zcu.funcInfo(callee_index);8381 const callee = zcu.funcInfo(callee_index);
8389 callee.branchQuota(ip).* = @max(callee.branchQuota(ip).*, sema.branch_quota);8382 callee.maxBranchQuota(ip, sema.branch_quota);
83908383
8391 // Make a runtime call to the new function, making sure to omit the comptime args.8384 // Make a runtime call to the new function, making sure to omit the comptime args.
8392 const func_ty = Type.fromInterned(callee.ty);8385 const func_ty = Type.fromInterned(callee.ty);
...@@ -8408,7 +8401,7 @@ fn instantiateGenericCall(...@@ -8408,7 +8401,7 @@ fn instantiateGenericCall(
8408 if (sema.owner_func_index != .none and8401 if (sema.owner_func_index != .none and
8409 Type.fromInterned(func_ty_info.return_type).isError(zcu))8402 Type.fromInterned(func_ty_info.return_type).isError(zcu))
8410 {8403 {
8411 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;8404 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
8412 }8405 }
84138406
8414 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));8407 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));
...@@ -8769,9 +8762,9 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8769,9 +8762,9 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8769 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));8762 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
8770 if (int > len: {8763 if (int > len: {
8771 const mutate = &ip.global_error_set.mutate;8764 const mutate = &ip.global_error_set.mutate;
8772 mutate.mutex.lock();8765 mutate.map.mutex.lock();
8773 defer mutate.mutex.unlock();8766 defer mutate.map.mutex.unlock();
8774 break :len mutate.list.len;8767 break :len mutate.names.len;
8775 } or int == 0)8768 } or int == 0)
8776 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8769 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8777 return Air.internedToRef((try pt.intern(.{ .err = .{8770 return Air.internedToRef((try pt.intern(.{ .err = .{
...@@ -18395,7 +18388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18395,7 +18388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18395 try ty.resolveLayout(pt); // Getting alignment requires type layout18388 try ty.resolveLayout(pt); // Getting alignment requires type layout
18396 const union_obj = mod.typeToUnion(ty).?;18389 const union_obj = mod.typeToUnion(ty).?;
18397 const tag_type = union_obj.loadTagType(ip);18390 const tag_type = union_obj.loadTagType(ip);
18398 const layout = union_obj.getLayout(ip);18391 const layout = union_obj.flagsUnordered(ip).layout;
1839918392
18400 const union_field_vals = try gpa.alloc(InternPool.Index, tag_type.names.len);18393 const union_field_vals = try gpa.alloc(InternPool.Index, tag_type.names.len);
18401 defer gpa.free(union_field_vals);18394 defer gpa.free(union_field_vals);
...@@ -18713,8 +18706,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18713,8 +18706,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18713 const backing_integer_val = try pt.intern(.{ .opt = .{18706 const backing_integer_val = try pt.intern(.{ .opt = .{
18714 .ty = (try pt.optionalType(.type_type)).toIntern(),18707 .ty = (try pt.optionalType(.type_type)).toIntern(),
18715 .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {18708 .val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {
18716 assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod));18709 assert(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)).isInt(mod));
18717 break :val packed_struct.backingIntType(ip).*;18710 break :val packed_struct.backingIntTypeUnordered(ip);
18718 } else .none,18711 } else .none,
18719 } });18712 } });
1872018713
...@@ -19795,7 +19788,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19795,7 +19788,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19795 return;19788 return;
19796 }19789 }
1979719790
19798 if (!mod.intern_pool.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return;19791 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
19799 if (!start_block.ownerModule().error_tracing) return;19792 if (!start_block.ownerModule().error_tracing) return;
1980019793
19801 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere19794 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
...@@ -21053,7 +21046,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21053,7 +21046,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21053 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());21046 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2105421047
21055 if (sema.owner_func_index != .none and21048 if (sema.owner_func_index != .none and
21056 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and21049 ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and
21057 block.ownerModule().error_tracing)21050 block.ownerModule().error_tracing)
21058 {21051 {
21059 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21052 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
...@@ -22201,11 +22194,11 @@ fn reifyUnion(...@@ -22201,11 +22194,11 @@ fn reifyUnion(
22201 if (any_aligns) {22194 if (any_aligns) {
22202 loaded_union.setFieldAligns(ip, field_aligns);22195 loaded_union.setFieldAligns(ip, field_aligns);
22203 }22196 }
22204 loaded_union.tagTypePtr(ip).* = enum_tag_ty;22197 loaded_union.setTagType(ip, enum_tag_ty);
22205 loaded_union.flagsPtr(ip).status = .have_field_types;22198 loaded_union.setStatus(ip, .have_field_types);
2220622199
22207 try pt.finalizeAnonDecl(new_decl_index);22200 try pt.finalizeAnonDecl(new_decl_index);
22208 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });22201 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22209 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22202 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
22210 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22203 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22211}22204}
...@@ -22464,15 +22457,15 @@ fn reifyStruct(...@@ -22464,15 +22457,15 @@ fn reifyStruct(
22464 if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {22457 if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {
22465 const backing_int_ty = backing_int_val.toType();22458 const backing_int_ty = backing_int_val.toType();
22466 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);22459 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
22467 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();22460 struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
22468 } else {22461 } else {
22469 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));22462 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
22470 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();22463 struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
22471 }22464 }
22472 }22465 }
2247322466
22474 try pt.finalizeAnonDecl(new_decl_index);22467 try pt.finalizeAnonDecl(new_decl_index);
22475 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });22468 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22476 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22469 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
22477 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22470 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22478}22471}
...@@ -28347,7 +28340,7 @@ fn unionFieldPtr(...@@ -28347,7 +28340,7 @@ fn unionFieldPtr(
28347 .is_const = union_ptr_info.flags.is_const,28340 .is_const = union_ptr_info.flags.is_const,
28348 .is_volatile = union_ptr_info.flags.is_volatile,28341 .is_volatile = union_ptr_info.flags.is_volatile,
28349 .address_space = union_ptr_info.flags.address_space,28342 .address_space = union_ptr_info.flags.address_space,
28350 .alignment = if (union_obj.getLayout(ip) == .auto) blk: {28343 .alignment = if (union_obj.flagsUnordered(ip).layout == .auto) blk: {
28351 const union_align = if (union_ptr_info.flags.alignment != .none)28344 const union_align = if (union_ptr_info.flags.alignment != .none)
28352 union_ptr_info.flags.alignment28345 union_ptr_info.flags.alignment
28353 else28346 else
...@@ -28375,7 +28368,7 @@ fn unionFieldPtr(...@@ -28375,7 +28368,7 @@ fn unionFieldPtr(
28375 }28368 }
2837628369
28377 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {28370 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {
28378 switch (union_obj.getLayout(ip)) {28371 switch (union_obj.flagsUnordered(ip).layout) {
28379 .auto => if (initializing) {28372 .auto => if (initializing) {
28380 // Store to the union to initialize the tag.28373 // Store to the union to initialize the tag.
28381 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28374 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
...@@ -28413,7 +28406,7 @@ fn unionFieldPtr(...@@ -28413,7 +28406,7 @@ fn unionFieldPtr(
28413 }28406 }
2841428407
28415 try sema.requireRuntimeBlock(block, src, null);28408 try sema.requireRuntimeBlock(block, src, null);
28416 if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and28409 if (!initializing and union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
28417 union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1)28410 union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1)
28418 {28411 {
28419 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28412 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
...@@ -28456,7 +28449,7 @@ fn unionFieldVal(...@@ -28456,7 +28449,7 @@ fn unionFieldVal(
28456 const un = ip.indexToKey(union_val.toIntern()).un;28449 const un = ip.indexToKey(union_val.toIntern()).un;
28457 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28450 const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
28458 const tag_matches = un.tag == field_tag.toIntern();28451 const tag_matches = un.tag == field_tag.toIntern();
28459 switch (union_obj.getLayout(ip)) {28452 switch (union_obj.flagsUnordered(ip).layout) {
28460 .auto => {28453 .auto => {
28461 if (tag_matches) {28454 if (tag_matches) {
28462 return Air.internedToRef(un.val);28455 return Air.internedToRef(un.val);
...@@ -28490,7 +28483,7 @@ fn unionFieldVal(...@@ -28490,7 +28483,7 @@ fn unionFieldVal(
28490 }28483 }
2849128484
28492 try sema.requireRuntimeBlock(block, src, null);28485 try sema.requireRuntimeBlock(block, src, null);
28493 if (union_obj.getLayout(ip) == .auto and block.wantSafety() and28486 if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
28494 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)28487 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
28495 {28488 {
28496 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);28489 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
...@@ -32037,7 +32030,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile...@@ -32037,7 +32030,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
3203732030
32038 pt.ensureDeclAnalyzed(decl_index) catch |err| {32031 pt.ensureDeclAnalyzed(decl_index) catch |err| {
32039 if (sema.owner_func_index != .none) {32032 if (sema.owner_func_index != .none) {
32040 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;32033 ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
32041 } else {32034 } else {
32042 sema.owner_decl.analysis = .dependency_failure;32035 sema.owner_decl.analysis = .dependency_failure;
32043 }32036 }
...@@ -32051,7 +32044,7 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void...@@ -32051,7 +32044,7 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
32051 const ip = &mod.intern_pool;32044 const ip = &mod.intern_pool;
32052 pt.ensureFuncBodyAnalyzed(func) catch |err| {32045 pt.ensureFuncBodyAnalyzed(func) catch |err| {
32053 if (sema.owner_func_index != .none) {32046 if (sema.owner_func_index != .none) {
32054 ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;32047 ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
32055 } else {32048 } else {
32056 sema.owner_decl.analysis = .dependency_failure;32049 sema.owner_decl.analysis = .dependency_failure;
32057 }32050 }
...@@ -32397,7 +32390,7 @@ fn analyzeIsNonErrComptimeOnly(...@@ -32397,7 +32390,7 @@ fn analyzeIsNonErrComptimeOnly(
32397 // If the error set is empty, we must return a comptime true or false.32390 // If the error set is empty, we must return a comptime true or false.
32398 // However we want to avoid unnecessarily resolving an inferred error set32391 // However we want to avoid unnecessarily resolving an inferred error set
32399 // in case it is already non-empty.32392 // in case it is already non-empty.
32400 switch (ip.funcIesResolved(func_index).*) {32393 switch (ip.funcIesResolvedUnordered(func_index)) {
32401 .anyerror_type => break :blk,32394 .anyerror_type => break :blk,
32402 .none => {},32395 .none => {},
32403 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,32396 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
...@@ -33466,7 +33459,7 @@ fn wrapErrorUnionSet(...@@ -33466,7 +33459,7 @@ fn wrapErrorUnionSet(
33466 .inferred_error_set_type => |func_index| ok: {33459 .inferred_error_set_type => |func_index| ok: {
33467 // We carefully do this in an order that avoids unnecessarily33460 // We carefully do this in an order that avoids unnecessarily
33468 // resolving the destination error set type.33461 // resolving the destination error set type.
33469 switch (ip.funcIesResolved(func_index).*) {33462 switch (ip.funcIesResolvedUnordered(func_index)) {
33470 .anyerror_type => break :ok,33463 .anyerror_type => break :ok,
33471 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {33464 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
33472 break :ok;33465 break :ok;
...@@ -35071,33 +35064,25 @@ pub fn resolveStructAlignment(...@@ -35071,33 +35064,25 @@ pub fn resolveStructAlignment(
3507135064
35072 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);35065 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
3507335066
35074 assert(struct_type.flagsPtr(ip).alignment == .none);
35075 assert(struct_type.layout != .@"packed");35067 assert(struct_type.layout != .@"packed");
35068 assert(struct_type.flagsUnordered(ip).alignment == .none);
3507635069
35077 if (struct_type.flagsPtr(ip).field_types_wip) {35070 const ptr_align = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
35078 // We'll guess "pointer-aligned", if the struct has an35071
35079 // underaligned pointer field then some allocations35072 // We'll guess "pointer-aligned", if the struct has an
35080 // might require explicit alignment.35073 // underaligned pointer field then some allocations
35081 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;35074 // might require explicit alignment.
35082 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));35075 if (struct_type.assumePointerAlignedIfFieldTypesWip(ip, ptr_align)) return;
35083 struct_type.flagsPtr(ip).alignment = result;
35084 return;
35085 }
3508635076
35087 try sema.resolveTypeFieldsStruct(ty, struct_type);35077 try sema.resolveTypeFieldsStruct(ty, struct_type);
3508835078
35089 if (struct_type.setAlignmentWip(ip)) {35079 // We'll guess "pointer-aligned", if the struct has an
35090 // We'll guess "pointer-aligned", if the struct has an35080 // underaligned pointer field then some allocations
35091 // underaligned pointer field then some allocations35081 // might require explicit alignment.
35092 // might require explicit alignment.35082 if (struct_type.assumePointerAlignedIfWip(ip, ptr_align)) return;
35093 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
35094 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
35095 struct_type.flagsPtr(ip).alignment = result;
35096 return;
35097 }
35098 defer struct_type.clearAlignmentWip(ip);35083 defer struct_type.clearAlignmentWip(ip);
3509935084
35100 var result: Alignment = .@"1";35085 var alignment: Alignment = .@"1";
3510135086
35102 for (0..struct_type.field_types.len) |i| {35087 for (0..struct_type.field_types.len) |i| {
35103 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35088 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
...@@ -35109,10 +35094,10 @@ pub fn resolveStructAlignment(...@@ -35109,10 +35094,10 @@ pub fn resolveStructAlignment(
35109 struct_type.layout,35094 struct_type.layout,
35110 .sema,35095 .sema,
35111 );35096 );
35112 result = result.maxStrict(field_align);35097 alignment = alignment.maxStrict(field_align);
35113 }35098 }
3511435099
35115 struct_type.flagsPtr(ip).alignment = result;35100 struct_type.setAlignment(ip, alignment);
35116}35101}
3511735102
35118pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {35103pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
...@@ -35177,7 +35162,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35177,7 +35162,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35177 big_align = big_align.maxStrict(field_align.*);35162 big_align = big_align.maxStrict(field_align.*);
35178 }35163 }
3517935164
35180 if (struct_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {35165 if (struct_type.flagsUnordered(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
35181 const msg = try sema.errMsg(35166 const msg = try sema.errMsg(
35182 ty.srcLoc(zcu),35167 ty.srcLoc(zcu),
35183 "struct layout depends on it having runtime bits",35168 "struct layout depends on it having runtime bits",
...@@ -35186,7 +35171,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35186,7 +35171,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35186 return sema.failWithOwnedErrorMsg(null, msg);35171 return sema.failWithOwnedErrorMsg(null, msg);
35187 }35172 }
3518835173
35189 if (struct_type.flagsPtr(ip).assumed_pointer_aligned and35174 if (struct_type.flagsUnordered(ip).assumed_pointer_aligned and
35190 big_align.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))35175 big_align.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))
35191 {35176 {
35192 const msg = try sema.errMsg(35177 const msg = try sema.errMsg(
...@@ -35254,10 +35239,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35254,10 +35239,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35254 offsets[i] = @intCast(aligns[i].forward(offset));35239 offsets[i] = @intCast(aligns[i].forward(offset));
35255 offset = offsets[i] + sizes[i];35240 offset = offsets[i] + sizes[i];
35256 }35241 }
35257 struct_type.size(ip).* = @intCast(big_align.forward(offset));35242 struct_type.setLayoutResolved(ip, @intCast(big_align.forward(offset)), big_align);
35258 const flags = struct_type.flagsPtr(ip);
35259 flags.alignment = big_align;
35260 flags.layout_resolved = true;
35261 _ = try sema.typeRequiresComptime(ty);35243 _ = try sema.typeRequiresComptime(ty);
35262}35244}
3526335245
...@@ -35350,13 +35332,13 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp...@@ -35350,13 +35332,13 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35350 };35332 };
3535135333
35352 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);35334 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
35353 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();35335 struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
35354 } else {35336 } else {
35355 if (fields_bit_sum > std.math.maxInt(u16)) {35337 if (fields_bit_sum > std.math.maxInt(u16)) {
35356 return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});35338 return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
35357 }35339 }
35358 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));35340 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
35359 struct_type.backingIntType(ip).* = backing_int_ty.toIntern();35341 struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
35360 }35342 }
3536135343
35362 try sema.flushExports();35344 try sema.flushExports();
...@@ -35430,15 +35412,12 @@ pub fn resolveUnionAlignment(...@@ -35430,15 +35412,12 @@ pub fn resolveUnionAlignment(
3543035412
35431 assert(!union_type.haveLayout(ip));35413 assert(!union_type.haveLayout(ip));
3543235414
35433 if (union_type.flagsPtr(ip).status == .field_types_wip) {35415 const ptr_align = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
35434 // We'll guess "pointer-aligned", if the union has an35416
35435 // underaligned pointer field then some allocations35417 // We'll guess "pointer-aligned", if the union has an
35436 // might require explicit alignment.35418 // underaligned pointer field then some allocations
35437 union_type.flagsPtr(ip).assumed_pointer_aligned = true;35419 // might require explicit alignment.
35438 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));35420 if (union_type.assumePointerAlignedIfFieldTypesWip(ip, ptr_align)) return;
35439 union_type.flagsPtr(ip).alignment = result;
35440 return;
35441 }
3544235421
35443 try sema.resolveTypeFieldsUnion(ty, union_type);35422 try sema.resolveTypeFieldsUnion(ty, union_type);
3544435423
...@@ -35456,7 +35435,7 @@ pub fn resolveUnionAlignment(...@@ -35456,7 +35435,7 @@ pub fn resolveUnionAlignment(
35456 max_align = max_align.max(field_align);35435 max_align = max_align.max(field_align);
35457 }35436 }
3545835437
35459 union_type.flagsPtr(ip).alignment = max_align;35438 union_type.setAlignment(ip, max_align);
35460}35439}
3546135440
35462/// This logic must be kept in sync with `Module.getUnionLayout`.35441/// This logic must be kept in sync with `Module.getUnionLayout`.
...@@ -35471,7 +35450,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35471,7 +35450,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3547135450
35472 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35451 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
3547335452
35474 switch (union_type.flagsPtr(ip).status) {35453 const old_flags = union_type.flagsUnordered(ip);
35454 switch (old_flags.status) {
35475 .none, .have_field_types => {},35455 .none, .have_field_types => {},
35476 .field_types_wip, .layout_wip => {35456 .field_types_wip, .layout_wip => {
35477 const msg = try sema.errMsg(35457 const msg = try sema.errMsg(
...@@ -35484,12 +35464,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35484,12 +35464,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35484 .have_layout, .fully_resolved_wip, .fully_resolved => return,35464 .have_layout, .fully_resolved_wip, .fully_resolved => return,
35485 }35465 }
3548635466
35487 const prev_status = union_type.flagsPtr(ip).status;35467 errdefer union_type.setStatusIfLayoutWip(ip, old_flags.status);
35488 errdefer if (union_type.flagsPtr(ip).status == .layout_wip) {
35489 union_type.flagsPtr(ip).status = prev_status;
35490 };
3549135468
35492 union_type.flagsPtr(ip).status = .layout_wip;35469 union_type.setStatus(ip, .layout_wip);
3549335470
35494 var max_size: u64 = 0;35471 var max_size: u64 = 0;
35495 var max_align: Alignment = .@"1";35472 var max_align: Alignment = .@"1";
...@@ -35516,8 +35493,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35516,8 +35493,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35516 max_align = max_align.max(field_align);35493 max_align = max_align.max(field_align);
35517 }35494 }
3551835495
35519 const flags = union_type.flagsPtr(ip);35496 const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and
35520 const has_runtime_tag = flags.runtime_tag.hasTag() and try sema.typeHasRuntimeBits(Type.fromInterned(union_type.enum_tag_ty));35497 try sema.typeHasRuntimeBits(Type.fromInterned(union_type.enum_tag_ty));
35521 const size, const alignment, const padding = if (has_runtime_tag) layout: {35498 const size, const alignment, const padding = if (has_runtime_tag) layout: {
35522 const enum_tag_type = Type.fromInterned(union_type.enum_tag_ty);35499 const enum_tag_type = Type.fromInterned(union_type.enum_tag_ty);
35523 const tag_align = try sema.typeAbiAlignment(enum_tag_type);35500 const tag_align = try sema.typeAbiAlignment(enum_tag_type);
...@@ -35551,12 +35528,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35551,12 +35528,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35551 break :layout .{ size, max_align.max(tag_align), padding };35528 break :layout .{ size, max_align.max(tag_align), padding };
35552 } else .{ max_align.forward(max_size), max_align, 0 };35529 } else .{ max_align.forward(max_size), max_align, 0 };
3555335530
35554 union_type.size(ip).* = @intCast(size);35531 union_type.setHaveLayout(ip, @intCast(size), padding, alignment);
35555 union_type.padding(ip).* = padding;
35556 flags.alignment = alignment;
35557 flags.status = .have_layout;
3555835532
35559 if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {35533 if (union_type.flagsUnordered(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
35560 const msg = try sema.errMsg(35534 const msg = try sema.errMsg(
35561 ty.srcLoc(pt.zcu),35535 ty.srcLoc(pt.zcu),
35562 "union layout depends on it having runtime bits",35536 "union layout depends on it having runtime bits",
...@@ -35565,7 +35539,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35565,7 +35539,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35565 return sema.failWithOwnedErrorMsg(null, msg);35539 return sema.failWithOwnedErrorMsg(null, msg);
35566 }35540 }
3556735541
35568 if (union_type.flagsPtr(ip).assumed_pointer_aligned and35542 if (union_type.flagsUnordered(ip).assumed_pointer_aligned and
35569 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8))))35543 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8))))
35570 {35544 {
35571 const msg = try sema.errMsg(35545 const msg = try sema.errMsg(
...@@ -35612,7 +35586,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35612,7 +35586,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
3561235586
35613 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);35587 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);
3561435588
35615 switch (union_obj.flagsPtr(ip).status) {35589 switch (union_obj.flagsUnordered(ip).status) {
35616 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},35590 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
35617 .fully_resolved_wip, .fully_resolved => return,35591 .fully_resolved_wip, .fully_resolved => return,
35618 }35592 }
...@@ -35621,15 +35595,15 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35621,15 +35595,15 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35621 // After we have resolve union layout we have to go over the fields again to35595 // After we have resolve union layout we have to go over the fields again to
35622 // make sure pointer fields get their child types resolved as well.35596 // make sure pointer fields get their child types resolved as well.
35623 // See also similar code for structs.35597 // See also similar code for structs.
35624 const prev_status = union_obj.flagsPtr(ip).status;35598 const prev_status = union_obj.flagsUnordered(ip).status;
35625 errdefer union_obj.flagsPtr(ip).status = prev_status;35599 errdefer union_obj.setStatus(ip, prev_status);
3562635600
35627 union_obj.flagsPtr(ip).status = .fully_resolved_wip;35601 union_obj.setStatus(ip, .fully_resolved_wip);
35628 for (0..union_obj.field_types.len) |field_index| {35602 for (0..union_obj.field_types.len) |field_index| {
35629 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);35603 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
35630 try field_ty.resolveFully(pt);35604 try field_ty.resolveFully(pt);
35631 }35605 }
35632 union_obj.flagsPtr(ip).status = .fully_resolved;35606 union_obj.setStatus(ip, .fully_resolved);
35633 }35607 }
3563435608
35635 // And let's not forget comptime-only status.35609 // And let's not forget comptime-only status.
...@@ -35662,7 +35636,7 @@ pub fn resolveTypeFieldsStruct(...@@ -35662,7 +35636,7 @@ pub fn resolveTypeFieldsStruct(
3566235636
35663 if (struct_type.haveFieldTypes(ip)) return;35637 if (struct_type.haveFieldTypes(ip)) return;
3566435638
35665 if (struct_type.setTypesWip(ip)) {35639 if (struct_type.setFieldTypesWip(ip)) {
35666 const msg = try sema.errMsg(35640 const msg = try sema.errMsg(
35667 Type.fromInterned(ty).srcLoc(zcu),35641 Type.fromInterned(ty).srcLoc(zcu),
35668 "struct '{}' depends on itself",35642 "struct '{}' depends on itself",
...@@ -35670,7 +35644,7 @@ pub fn resolveTypeFieldsStruct(...@@ -35670,7 +35644,7 @@ pub fn resolveTypeFieldsStruct(
35670 );35644 );
35671 return sema.failWithOwnedErrorMsg(null, msg);35645 return sema.failWithOwnedErrorMsg(null, msg);
35672 }35646 }
35673 defer struct_type.clearTypesWip(ip);35647 defer struct_type.clearFieldTypesWip(ip);
3567435648
35675 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {35649 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
35676 error.AnalysisFail => {35650 error.AnalysisFail => {
...@@ -35739,7 +35713,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35739,7 +35713,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35739 },35713 },
35740 else => {},35714 else => {},
35741 }35715 }
35742 switch (union_type.flagsPtr(ip).status) {35716 switch (union_type.flagsUnordered(ip).status) {
35743 .none => {},35717 .none => {},
35744 .field_types_wip => {35718 .field_types_wip => {
35745 const msg = try sema.errMsg(35719 const msg = try sema.errMsg(
...@@ -35757,8 +35731,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35757,8 +35731,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35757 => return,35731 => return,
35758 }35732 }
3575935733
35760 union_type.flagsPtr(ip).status = .field_types_wip;35734 union_type.setStatus(ip, .field_types_wip);
35761 errdefer union_type.flagsPtr(ip).status = .none;35735 errdefer union_type.setStatus(ip, .none);
35762 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {35736 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {
35763 error.AnalysisFail => {35737 error.AnalysisFail => {
35764 if (owner_decl.analysis == .complete) {35738 if (owner_decl.analysis == .complete) {
...@@ -35769,7 +35743,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35769,7 +35743,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35769 error.OutOfMemory => return error.OutOfMemory,35743 error.OutOfMemory => return error.OutOfMemory,
35770 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,35744 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35771 };35745 };
35772 union_type.flagsPtr(ip).status = .have_field_types;35746 union_type.setStatus(ip, .have_field_types);
35773}35747}
3577435748
35775/// Returns a normal error set corresponding to the fully populated inferred35749/// Returns a normal error set corresponding to the fully populated inferred
...@@ -35790,10 +35764,10 @@ fn resolveInferredErrorSet(...@@ -35790,10 +35764,10 @@ fn resolveInferredErrorSet(
3579035764
35791 // TODO: during an incremental update this might not be `.none`, but the35765 // TODO: during an incremental update this might not be `.none`, but the
35792 // function might be out-of-date!35766 // function might be out-of-date!
35793 const resolved_ty = func.resolvedErrorSet(ip).*;35767 const resolved_ty = func.resolvedErrorSetUnordered(ip);
35794 if (resolved_ty != .none) return resolved_ty;35768 if (resolved_ty != .none) return resolved_ty;
3579535769
35796 if (func.analysis(ip).state == .in_progress)35770 if (func.analysisUnordered(ip).state == .in_progress)
35797 return sema.fail(block, src, "unable to resolve inferred error set", .{});35771 return sema.fail(block, src, "unable to resolve inferred error set", .{});
3579835772
35799 // In order to ensure that all dependencies are properly added to the set,35773 // In order to ensure that all dependencies are properly added to the set,
...@@ -35830,7 +35804,7 @@ fn resolveInferredErrorSet(...@@ -35830,7 +35804,7 @@ fn resolveInferredErrorSet(
3583035804
35831 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`35805 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`
35832 // which calls `resolveInferredErrorSetPtr`.35806 // which calls `resolveInferredErrorSetPtr`.
35833 const final_resolved_ty = func.resolvedErrorSet(ip).*;35807 const final_resolved_ty = func.resolvedErrorSetUnordered(ip);
35834 assert(final_resolved_ty != .none);35808 assert(final_resolved_ty != .none);
35835 return final_resolved_ty;35809 return final_resolved_ty;
35836}35810}
...@@ -35996,8 +35970,7 @@ fn semaStructFields(...@@ -35996,8 +35970,7 @@ fn semaStructFields(
35996 return;35970 return;
35997 },35971 },
35998 .auto, .@"extern" => {35972 .auto, .@"extern" => {
35999 struct_type.size(ip).* = 0;35973 struct_type.setLayoutResolved(ip, 0, .none);
36000 struct_type.flagsPtr(ip).layout_resolved = true;
36001 return;35974 return;
36002 },35975 },
36003 };35976 };
...@@ -36191,7 +36164,7 @@ fn semaStructFields(...@@ -36191,7 +36164,7 @@ fn semaStructFields(
36191 extra_index += zir_field.init_body_len;36164 extra_index += zir_field.init_body_len;
36192 }36165 }
3619336166
36194 struct_type.clearTypesWip(ip);36167 struct_type.clearFieldTypesWip(ip);
36195 if (!any_inits) struct_type.setHaveFieldInits(ip);36168 if (!any_inits) struct_type.setHaveFieldInits(ip);
3619636169
36197 try sema.flushExports();36170 try sema.flushExports();
...@@ -36467,7 +36440,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36467,7 +36440,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36467 }36440 }
36468 } else {36441 } else {
36469 // The provided type is the enum tag type.36442 // The provided type is the enum tag type.
36470 union_type.tagTypePtr(ip).* = provided_ty.toIntern();36443 union_type.setTagType(ip, provided_ty.toIntern());
36471 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {36444 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {
36472 .enum_type => ip.loadEnumType(provided_ty.toIntern()),36445 .enum_type => ip.loadEnumType(provided_ty.toIntern()),
36473 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}),36446 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}),
...@@ -36605,10 +36578,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36605,10 +36578,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36605 }36578 }
3660636579
36607 if (explicit_tags_seen.len > 0) {36580 if (explicit_tags_seen.len > 0) {
36608 const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);36581 const tag_ty = union_type.tagTypeUnordered(ip);
36582 const tag_info = ip.loadEnumType(tag_ty);
36609 const enum_index = tag_info.nameIndex(ip, field_name) orelse {36583 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
36610 return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{36584 return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{
36611 field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(pt),36585 field_name.fmt(ip), Type.fromInterned(tag_ty).fmt(pt),
36612 });36586 });
36613 };36587 };
3661436588
...@@ -36645,7 +36619,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36645,7 +36619,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36645 };36619 };
36646 return sema.failWithOwnedErrorMsg(&block_scope, msg);36620 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36647 }36621 }
36648 const layout = union_type.getLayout(ip);36622 const layout = union_type.flagsUnordered(ip).layout;
36649 if (layout == .@"extern" and36623 if (layout == .@"extern" and
36650 !try sema.validateExternType(field_ty, .union_field))36624 !try sema.validateExternType(field_ty, .union_field))
36651 {36625 {
...@@ -36688,7 +36662,8 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36688,7 +36662,8 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36688 union_type.setFieldAligns(ip, field_aligns.items);36662 union_type.setFieldAligns(ip, field_aligns.items);
3668936663
36690 if (explicit_tags_seen.len > 0) {36664 if (explicit_tags_seen.len > 0) {
36691 const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);36665 const tag_ty = union_type.tagTypeUnordered(ip);
36666 const tag_info = ip.loadEnumType(tag_ty);
36692 if (tag_info.names.len > fields_len) {36667 if (tag_info.names.len > fields_len) {
36693 const msg = msg: {36668 const msg = msg: {
36694 const msg = try sema.errMsg(src, "enum field(s) missing in union", .{});36669 const msg = try sema.errMsg(src, "enum field(s) missing in union", .{});
...@@ -36696,21 +36671,21 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36696,21 +36671,21 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3669636671
36697 for (tag_info.names.get(ip), 0..) |field_name, field_index| {36672 for (tag_info.names.get(ip), 0..) |field_name, field_index| {
36698 if (explicit_tags_seen[field_index]) continue;36673 if (explicit_tags_seen[field_index]) continue;
36699 try sema.addFieldErrNote(Type.fromInterned(union_type.tagTypePtr(ip).*), field_index, msg, "field '{}' missing, declared here", .{36674 try sema.addFieldErrNote(Type.fromInterned(tag_ty), field_index, msg, "field '{}' missing, declared here", .{
36700 field_name.fmt(ip),36675 field_name.fmt(ip),
36701 });36676 });
36702 }36677 }
36703 try sema.addDeclaredHereNote(msg, Type.fromInterned(union_type.tagTypePtr(ip).*));36678 try sema.addDeclaredHereNote(msg, Type.fromInterned(tag_ty));
36704 break :msg msg;36679 break :msg msg;
36705 };36680 };
36706 return sema.failWithOwnedErrorMsg(&block_scope, msg);36681 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36707 }36682 }
36708 } else if (enum_field_vals.count() > 0) {36683 } else if (enum_field_vals.count() > 0) {
36709 const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl));36684 const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl));
36710 union_type.tagTypePtr(ip).* = enum_ty;36685 union_type.setTagType(ip, enum_ty);
36711 } else {36686 } else {
36712 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl));36687 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl));
36713 union_type.tagTypePtr(ip).* = enum_ty;36688 union_type.setTagType(ip, enum_ty);
36714 }36689 }
3671536690
36716 try sema.flushExports();36691 try sema.flushExports();
...@@ -37086,7 +37061,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37086,7 +37061,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37086 try ty.resolveLayout(pt);37061 try ty.resolveLayout(pt);
3708737062
37088 const union_obj = ip.loadUnionType(ty.toIntern());37063 const union_obj = ip.loadUnionType(ty.toIntern());
37089 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse37064 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse
37090 return null;37065 return null;
37091 if (union_obj.field_types.len == 0) {37066 if (union_obj.field_types.len == 0) {
37092 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });37067 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
src/Type.zig+48-47
...@@ -605,17 +605,15 @@ pub fn hasRuntimeBitsAdvanced(...@@ -605,17 +605,15 @@ pub fn hasRuntimeBitsAdvanced(
605605
606 .union_type => {606 .union_type => {
607 const union_type = ip.loadUnionType(ty.toIntern());607 const union_type = ip.loadUnionType(ty.toIntern());
608 switch (union_type.flagsPtr(ip).runtime_tag) {608 const union_flags = union_type.flagsUnordered(ip);
609 switch (union_flags.runtime_tag) {
609 .none => {610 .none => {
610 if (union_type.flagsPtr(ip).status == .field_types_wip) {611 // In this case, we guess that hasRuntimeBits() for this type is true,
611 // In this case, we guess that hasRuntimeBits() for this type is true,612 // and then later if our guess was incorrect, we emit a compile error.
612 // and then later if our guess was incorrect, we emit a compile error.613 if (union_type.assumeRuntimeBitsIfFieldTypesWip(ip)) return true;
613 union_type.flagsPtr(ip).assumed_runtime_bits = true;
614 return true;
615 }
616 },614 },
617 .safety, .tagged => {615 .safety, .tagged => {
618 const tag_ty = union_type.tagTypePtr(ip).*;616 const tag_ty = union_type.tagTypeUnordered(ip);
619 // tag_ty will be `none` if this union's tag type is not resolved yet,617 // tag_ty will be `none` if this union's tag type is not resolved yet,
620 // in which case we want control flow to continue down below.618 // in which case we want control flow to continue down below.
621 if (tag_ty != .none and619 if (tag_ty != .none and
...@@ -627,8 +625,8 @@ pub fn hasRuntimeBitsAdvanced(...@@ -627,8 +625,8 @@ pub fn hasRuntimeBitsAdvanced(
627 }625 }
628 switch (strat) {626 switch (strat) {
629 .sema => try ty.resolveFields(pt),627 .sema => try ty.resolveFields(pt),
630 .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()),628 .eager => assert(union_flags.status.haveFieldTypes()),
631 .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes())629 .lazy => if (!union_flags.status.haveFieldTypes())
632 return error.NeedLazy,630 return error.NeedLazy,
633 }631 }
634 for (0..union_type.field_types.len) |field_index| {632 for (0..union_type.field_types.len) |field_index| {
...@@ -745,8 +743,8 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {...@@ -745,8 +743,8 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
745 },743 },
746 .union_type => {744 .union_type => {
747 const union_type = ip.loadUnionType(ty.toIntern());745 const union_type = ip.loadUnionType(ty.toIntern());
748 return switch (union_type.flagsPtr(ip).runtime_tag) {746 return switch (union_type.flagsUnordered(ip).runtime_tag) {
749 .none, .safety => union_type.flagsPtr(ip).layout != .auto,747 .none, .safety => union_type.flagsUnordered(ip).layout != .auto,
750 .tagged => false,748 .tagged => false,
751 };749 };
752 },750 },
...@@ -1045,7 +1043,7 @@ pub fn abiAlignmentAdvanced(...@@ -1045,7 +1043,7 @@ pub fn abiAlignmentAdvanced(
1045 if (struct_type.layout == .@"packed") {1043 if (struct_type.layout == .@"packed") {
1046 switch (strat) {1044 switch (strat) {
1047 .sema => try ty.resolveLayout(pt),1045 .sema => try ty.resolveLayout(pt),
1048 .lazy => if (struct_type.backingIntType(ip).* == .none) return .{1046 .lazy => if (struct_type.backingIntTypeUnordered(ip) == .none) return .{
1049 .val = Value.fromInterned(try pt.intern(.{ .int = .{1047 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1050 .ty = .comptime_int_type,1048 .ty = .comptime_int_type,
1051 .storage = .{ .lazy_align = ty.toIntern() },1049 .storage = .{ .lazy_align = ty.toIntern() },
...@@ -1053,10 +1051,10 @@ pub fn abiAlignmentAdvanced(...@@ -1053,10 +1051,10 @@ pub fn abiAlignmentAdvanced(
1053 },1051 },
1054 .eager => {},1052 .eager => {},
1055 }1053 }
1056 return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(pt) };1054 return .{ .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiAlignment(pt) };
1057 }1055 }
10581056
1059 if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) {1057 if (struct_type.flagsUnordered(ip).alignment == .none) switch (strat) {
1060 .eager => unreachable, // struct alignment not resolved1058 .eager => unreachable, // struct alignment not resolved
1061 .sema => try ty.resolveStructAlignment(pt),1059 .sema => try ty.resolveStructAlignment(pt),
1062 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{1060 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
...@@ -1065,7 +1063,7 @@ pub fn abiAlignmentAdvanced(...@@ -1065,7 +1063,7 @@ pub fn abiAlignmentAdvanced(
1065 } })) },1063 } })) },
1066 };1064 };
10671065
1068 return .{ .scalar = struct_type.flagsPtr(ip).alignment };1066 return .{ .scalar = struct_type.flagsUnordered(ip).alignment };
1069 },1067 },
1070 .anon_struct_type => |tuple| {1068 .anon_struct_type => |tuple| {
1071 var big_align: Alignment = .@"1";1069 var big_align: Alignment = .@"1";
...@@ -1088,7 +1086,7 @@ pub fn abiAlignmentAdvanced(...@@ -1088,7 +1086,7 @@ pub fn abiAlignmentAdvanced(
1088 .union_type => {1086 .union_type => {
1089 const union_type = ip.loadUnionType(ty.toIntern());1087 const union_type = ip.loadUnionType(ty.toIntern());
10901088
1091 if (union_type.flagsPtr(ip).alignment == .none) switch (strat) {1089 if (union_type.flagsUnordered(ip).alignment == .none) switch (strat) {
1092 .eager => unreachable, // union layout not resolved1090 .eager => unreachable, // union layout not resolved
1093 .sema => try ty.resolveUnionAlignment(pt),1091 .sema => try ty.resolveUnionAlignment(pt),
1094 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{1092 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
...@@ -1097,7 +1095,7 @@ pub fn abiAlignmentAdvanced(...@@ -1097,7 +1095,7 @@ pub fn abiAlignmentAdvanced(
1097 } })) },1095 } })) },
1098 };1096 };
10991097
1100 return .{ .scalar = union_type.flagsPtr(ip).alignment };1098 return .{ .scalar = union_type.flagsUnordered(ip).alignment };
1101 },1099 },
1102 .opaque_type => return .{ .scalar = .@"1" },1100 .opaque_type => return .{ .scalar = .@"1" },
1103 .enum_type => return .{1101 .enum_type => return .{
...@@ -1420,7 +1418,7 @@ pub fn abiSizeAdvanced(...@@ -1420,7 +1418,7 @@ pub fn abiSizeAdvanced(
1420 .sema => try ty.resolveLayout(pt),1418 .sema => try ty.resolveLayout(pt),
1421 .lazy => switch (struct_type.layout) {1419 .lazy => switch (struct_type.layout) {
1422 .@"packed" => {1420 .@"packed" => {
1423 if (struct_type.backingIntType(ip).* == .none) return .{1421 if (struct_type.backingIntTypeUnordered(ip) == .none) return .{
1424 .val = Value.fromInterned(try pt.intern(.{ .int = .{1422 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1425 .ty = .comptime_int_type,1423 .ty = .comptime_int_type,
1426 .storage = .{ .lazy_size = ty.toIntern() },1424 .storage = .{ .lazy_size = ty.toIntern() },
...@@ -1440,11 +1438,11 @@ pub fn abiSizeAdvanced(...@@ -1440,11 +1438,11 @@ pub fn abiSizeAdvanced(
1440 }1438 }
1441 switch (struct_type.layout) {1439 switch (struct_type.layout) {
1442 .@"packed" => return .{1440 .@"packed" => return .{
1443 .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(pt),1441 .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiSize(pt),
1444 },1442 },
1445 .auto, .@"extern" => {1443 .auto, .@"extern" => {
1446 assert(struct_type.haveLayout(ip));1444 assert(struct_type.haveLayout(ip));
1447 return .{ .scalar = struct_type.size(ip).* };1445 return .{ .scalar = struct_type.sizeUnordered(ip) };
1448 },1446 },
1449 }1447 }
1450 },1448 },
...@@ -1464,7 +1462,7 @@ pub fn abiSizeAdvanced(...@@ -1464,7 +1462,7 @@ pub fn abiSizeAdvanced(
1464 const union_type = ip.loadUnionType(ty.toIntern());1462 const union_type = ip.loadUnionType(ty.toIntern());
1465 switch (strat) {1463 switch (strat) {
1466 .sema => try ty.resolveLayout(pt),1464 .sema => try ty.resolveLayout(pt),
1467 .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{1465 .lazy => if (!union_type.flagsUnordered(ip).status.haveLayout()) return .{
1468 .val = Value.fromInterned(try pt.intern(.{ .int = .{1466 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1469 .ty = .comptime_int_type,1467 .ty = .comptime_int_type,
1470 .storage = .{ .lazy_size = ty.toIntern() },1468 .storage = .{ .lazy_size = ty.toIntern() },
...@@ -1474,7 +1472,7 @@ pub fn abiSizeAdvanced(...@@ -1474,7 +1472,7 @@ pub fn abiSizeAdvanced(
1474 }1472 }
14751473
1476 assert(union_type.haveLayout(ip));1474 assert(union_type.haveLayout(ip));
1477 return .{ .scalar = union_type.size(ip).* };1475 return .{ .scalar = union_type.sizeUnordered(ip) };
1478 },1476 },
1479 .opaque_type => unreachable, // no size available1477 .opaque_type => unreachable, // no size available
1480 .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(pt) },1478 .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(pt) },
...@@ -1788,7 +1786,7 @@ pub fn bitSizeAdvanced(...@@ -1788,7 +1786,7 @@ pub fn bitSizeAdvanced(
1788 if (is_packed) try ty.resolveLayout(pt);1786 if (is_packed) try ty.resolveLayout(pt);
1789 }1787 }
1790 if (is_packed) {1788 if (is_packed) {
1791 return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(pt, strat);1789 return try Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).bitSizeAdvanced(pt, strat);
1792 }1790 }
1793 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;1791 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1794 },1792 },
...@@ -1808,7 +1806,7 @@ pub fn bitSizeAdvanced(...@@ -1808,7 +1806,7 @@ pub fn bitSizeAdvanced(
1808 if (!is_packed) {1806 if (!is_packed) {
1809 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;1807 return (try ty.abiSizeAdvanced(pt, strat_lazy)).scalar * 8;
1810 }1808 }
1811 assert(union_type.flagsPtr(ip).status.haveFieldTypes());1809 assert(union_type.flagsUnordered(ip).status.haveFieldTypes());
18121810
1813 var size: u64 = 0;1811 var size: u64 = 0;
1814 for (0..union_type.field_types.len) |field_index| {1812 for (0..union_type.field_types.len) |field_index| {
...@@ -2056,9 +2054,10 @@ pub fn unionTagType(ty: Type, mod: *Module) ?Type {...@@ -2056,9 +2054,10 @@ pub fn unionTagType(ty: Type, mod: *Module) ?Type {
2056 else => return null,2054 else => return null,
2057 }2055 }
2058 const union_type = ip.loadUnionType(ty.toIntern());2056 const union_type = ip.loadUnionType(ty.toIntern());
2059 switch (union_type.flagsPtr(ip).runtime_tag) {2057 const union_flags = union_type.flagsUnordered(ip);
2058 switch (union_flags.runtime_tag) {
2060 .tagged => {2059 .tagged => {
2061 assert(union_type.flagsPtr(ip).status.haveFieldTypes());2060 assert(union_flags.status.haveFieldTypes());
2062 return Type.fromInterned(union_type.enum_tag_ty);2061 return Type.fromInterned(union_type.enum_tag_ty);
2063 },2062 },
2064 else => return null,2063 else => return null,
...@@ -2135,7 +2134,7 @@ pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout...@@ -2135,7 +2134,7 @@ pub fn containerLayout(ty: Type, mod: *Module) std.builtin.Type.ContainerLayout
2135 return switch (ip.indexToKey(ty.toIntern())) {2134 return switch (ip.indexToKey(ty.toIntern())) {
2136 .struct_type => ip.loadStructType(ty.toIntern()).layout,2135 .struct_type => ip.loadStructType(ty.toIntern()).layout,
2137 .anon_struct_type => .auto,2136 .anon_struct_type => .auto,
2138 .union_type => ip.loadUnionType(ty.toIntern()).flagsPtr(ip).layout,2137 .union_type => ip.loadUnionType(ty.toIntern()).flagsUnordered(ip).layout,
2139 else => unreachable,2138 else => unreachable,
2140 };2139 };
2141}2140}
...@@ -2157,7 +2156,7 @@ pub fn errorSetIsEmpty(ty: Type, mod: *Module) bool {...@@ -2157,7 +2156,7 @@ pub fn errorSetIsEmpty(ty: Type, mod: *Module) bool {
2157 .anyerror_type, .adhoc_inferred_error_set_type => false,2156 .anyerror_type, .adhoc_inferred_error_set_type => false,
2158 else => switch (ip.indexToKey(ty.toIntern())) {2157 else => switch (ip.indexToKey(ty.toIntern())) {
2159 .error_set_type => |error_set_type| error_set_type.names.len == 0,2158 .error_set_type => |error_set_type| error_set_type.names.len == 0,
2160 .inferred_error_set_type => |i| switch (ip.funcIesResolved(i).*) {2159 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
2161 .none, .anyerror_type => false,2160 .none, .anyerror_type => false,
2162 else => |t| ip.indexToKey(t).error_set_type.names.len == 0,2161 else => |t| ip.indexToKey(t).error_set_type.names.len == 0,
2163 },2162 },
...@@ -2175,7 +2174,7 @@ pub fn isAnyError(ty: Type, mod: *Module) bool {...@@ -2175,7 +2174,7 @@ pub fn isAnyError(ty: Type, mod: *Module) bool {
2175 .anyerror_type => true,2174 .anyerror_type => true,
2176 .adhoc_inferred_error_set_type => false,2175 .adhoc_inferred_error_set_type => false,
2177 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {2176 else => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
2178 .inferred_error_set_type => |i| ip.funcIesResolved(i).* == .anyerror_type,2177 .inferred_error_set_type => |i| ip.funcIesResolvedUnordered(i) == .anyerror_type,
2179 else => false,2178 else => false,
2180 },2179 },
2181 };2180 };
...@@ -2200,7 +2199,7 @@ pub fn errorSetHasFieldIp(...@@ -2200,7 +2199,7 @@ pub fn errorSetHasFieldIp(
2200 .anyerror_type => true,2199 .anyerror_type => true,
2201 else => switch (ip.indexToKey(ty)) {2200 else => switch (ip.indexToKey(ty)) {
2202 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,2201 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,
2203 .inferred_error_set_type => |i| switch (ip.funcIesResolved(i).*) {2202 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
2204 .anyerror_type => true,2203 .anyerror_type => true,
2205 .none => false,2204 .none => false,
2206 else => |t| ip.indexToKey(t).error_set_type.nameIndex(ip, name) != null,2205 else => |t| ip.indexToKey(t).error_set_type.nameIndex(ip, name) != null,
...@@ -2336,7 +2335,7 @@ pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType {...@@ -2336,7 +2335,7 @@ pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType {
2336 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) },2335 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) },
2337 else => switch (ip.indexToKey(ty.toIntern())) {2336 else => switch (ip.indexToKey(ty.toIntern())) {
2338 .int_type => |int_type| return int_type,2337 .int_type => |int_type| return int_type,
2339 .struct_type => ty = Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntType(ip).*),2338 .struct_type => ty = Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntTypeUnordered(ip)),
2340 .enum_type => ty = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty),2339 .enum_type => ty = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty),
2341 .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child),2340 .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child),
23422341
...@@ -2826,17 +2825,18 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se...@@ -2826,17 +2825,18 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se
2826 return false;2825 return false;
28272826
2828 // A struct with no fields is not comptime-only.2827 // A struct with no fields is not comptime-only.
2829 return switch (struct_type.flagsPtr(ip).requires_comptime) {2828 return switch (struct_type.setRequiresComptimeWip(ip)) {
2830 .no, .wip => false,2829 .no, .wip => false,
2831 .yes => true,2830 .yes => true,
2832 .unknown => {2831 .unknown => {
2833 assert(strat == .sema);2832 assert(strat == .sema);
28342833
2835 if (struct_type.flagsPtr(ip).field_types_wip)2834 if (struct_type.flagsUnordered(ip).field_types_wip) {
2835 struct_type.setRequiresComptime(ip, .unknown);
2836 return false;2836 return false;
2837 }
28372838
2838 struct_type.flagsPtr(ip).requires_comptime = .wip;2839 errdefer struct_type.setRequiresComptime(ip, .unknown);
2839 errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown;
28402840
2841 try ty.resolveFields(pt);2841 try ty.resolveFields(pt);
28422842
...@@ -2849,12 +2849,12 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se...@@ -2849,12 +2849,12 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se
2849 // be considered resolved. Comptime-only types2849 // be considered resolved. Comptime-only types
2850 // still maintain a layout of their2850 // still maintain a layout of their
2851 // runtime-known fields.2851 // runtime-known fields.
2852 struct_type.flagsPtr(ip).requires_comptime = .yes;2852 struct_type.setRequiresComptime(ip, .yes);
2853 return true;2853 return true;
2854 }2854 }
2855 }2855 }
28562856
2857 struct_type.flagsPtr(ip).requires_comptime = .no;2857 struct_type.setRequiresComptime(ip, .no);
2858 return false;2858 return false;
2859 },2859 },
2860 };2860 };
...@@ -2870,29 +2870,30 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se...@@ -2870,29 +2870,30 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, strat: ResolveStrat) Se
28702870
2871 .union_type => {2871 .union_type => {
2872 const union_type = ip.loadUnionType(ty.toIntern());2872 const union_type = ip.loadUnionType(ty.toIntern());
2873 switch (union_type.flagsPtr(ip).requires_comptime) {2873 switch (union_type.setRequiresComptimeWip(ip)) {
2874 .no, .wip => return false,2874 .no, .wip => return false,
2875 .yes => return true,2875 .yes => return true,
2876 .unknown => {2876 .unknown => {
2877 assert(strat == .sema);2877 assert(strat == .sema);
28782878
2879 if (union_type.flagsPtr(ip).status == .field_types_wip)2879 if (union_type.flagsUnordered(ip).status == .field_types_wip) {
2880 union_type.setRequiresComptime(ip, .unknown);
2880 return false;2881 return false;
2882 }
28812883
2882 union_type.flagsPtr(ip).requires_comptime = .wip;2884 errdefer union_type.setRequiresComptime(ip, .unknown);
2883 errdefer union_type.flagsPtr(ip).requires_comptime = .unknown;
28842885
2885 try ty.resolveFields(pt);2886 try ty.resolveFields(pt);
28862887
2887 for (0..union_type.field_types.len) |field_idx| {2888 for (0..union_type.field_types.len) |field_idx| {
2888 const field_ty = union_type.field_types.get(ip)[field_idx];2889 const field_ty = union_type.field_types.get(ip)[field_idx];
2889 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) {2890 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(pt, strat)) {
2890 union_type.flagsPtr(ip).requires_comptime = .yes;2891 union_type.setRequiresComptime(ip, .yes);
2891 return true;2892 return true;
2892 }2893 }
2893 }2894 }
28942895
2895 union_type.flagsPtr(ip).requires_comptime = .no;2896 union_type.setRequiresComptime(ip, .no);
2896 return false;2897 return false;
2897 },2898 },
2898 }2899 }
...@@ -3117,7 +3118,7 @@ pub fn errorSetNames(ty: Type, mod: *Module) InternPool.NullTerminatedString.Sli...@@ -3117,7 +3118,7 @@ pub fn errorSetNames(ty: Type, mod: *Module) InternPool.NullTerminatedString.Sli
3117 const ip = &mod.intern_pool;3118 const ip = &mod.intern_pool;
3118 return switch (ip.indexToKey(ty.toIntern())) {3119 return switch (ip.indexToKey(ty.toIntern())) {
3119 .error_set_type => |x| x.names,3120 .error_set_type => |x| x.names,
3120 .inferred_error_set_type => |i| switch (ip.funcIesResolved(i).*) {3121 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
3121 .none => unreachable, // unresolved inferred error set3122 .none => unreachable, // unresolved inferred error set
3122 .anyerror_type => unreachable,3123 .anyerror_type => unreachable,
3123 else => |t| ip.indexToKey(t).error_set_type.names,3124 else => |t| ip.indexToKey(t).error_set_type.names,
...@@ -3374,7 +3375,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {...@@ -3374,7 +3375,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {
3374 const struct_type = ip.loadStructType(ty.toIntern());3375 const struct_type = ip.loadStructType(ty.toIntern());
3375 if (struct_type.layout == .@"packed") return false;3376 if (struct_type.layout == .@"packed") return false;
3376 if (struct_type.decl == .none) return false;3377 if (struct_type.decl == .none) return false;
3377 return struct_type.flagsPtr(ip).is_tuple;3378 return struct_type.flagsUnordered(ip).is_tuple;
3378 },3379 },
3379 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,3380 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,
3380 else => false,3381 else => false,
...@@ -3396,7 +3397,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {...@@ -3396,7 +3397,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {
3396 const struct_type = ip.loadStructType(ty.toIntern());3397 const struct_type = ip.loadStructType(ty.toIntern());
3397 if (struct_type.layout == .@"packed") return false;3398 if (struct_type.layout == .@"packed") return false;
3398 if (struct_type.decl == .none) return false;3399 if (struct_type.decl == .none) return false;
3399 return struct_type.flagsPtr(ip).is_tuple;3400 return struct_type.flagsUnordered(ip).is_tuple;
3400 },3401 },
3401 .anon_struct_type => true,3402 .anon_struct_type => true,
3402 else => false,3403 else => false,
src/Value.zig+1-1
...@@ -558,7 +558,7 @@ pub fn writeToPackedMemory(...@@ -558,7 +558,7 @@ pub fn writeToPackedMemory(
558 },558 },
559 .Union => {559 .Union => {
560 const union_obj = mod.typeToUnion(ty).?;560 const union_obj = mod.typeToUnion(ty).?;
561 switch (union_obj.getLayout(ip)) {561 switch (union_obj.flagsUnordered(ip).layout) {
562 .auto, .@"extern" => unreachable, // Handled in non-packed writeToMemory562 .auto, .@"extern" => unreachable, // Handled in non-packed writeToMemory
563 .@"packed" => {563 .@"packed" => {
564 if (val.unionTag(mod)) |union_tag| {564 if (val.unionTag(mod)) |union_tag| {
src/Zcu.zig+4-4
...@@ -2968,7 +2968,7 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)...@@ -2968,7 +2968,7 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
2968 const is_outdated = mod.outdated.contains(func_as_depender) or2968 const is_outdated = mod.outdated.contains(func_as_depender) or
2969 mod.potentially_outdated.contains(func_as_depender);2969 mod.potentially_outdated.contains(func_as_depender);
29702970
2971 switch (func.analysis(ip).state) {2971 switch (func.analysisUnordered(ip).state) {
2972 .none => {},2972 .none => {},
2973 .queued => return,2973 .queued => return,
2974 // As above, we don't need to forward errors here.2974 // As above, we don't need to forward errors here.
...@@ -2983,13 +2983,13 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)...@@ -2983,13 +2983,13 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
29832983
2984 // Decl itself is safely analyzed, and body analysis is not yet queued2984 // Decl itself is safely analyzed, and body analysis is not yet queued
29852985
2986 try mod.comp.work_queue.writeItem(.{ .analyze_func = func_index });2986 try mod.comp.queueJob(.{ .analyze_func = func_index });
2987 if (mod.emit_h != null) {2987 if (mod.emit_h != null) {
2988 // TODO: we ideally only want to do this if the function's type changed2988 // TODO: we ideally only want to do this if the function's type changed
2989 // since the last update2989 // since the last update
2990 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });2990 try mod.comp.queueJob(.{ .emit_h_decl = decl_index });
2991 }2991 }
2992 func.analysis(ip).state = .queued;2992 func.setAnalysisState(ip, .queued);
2993}2993}
29942994
2995pub const SemaDeclResult = packed struct {2995pub const SemaDeclResult = packed struct {
src/Zcu/PerThread.zig+34-36
...@@ -641,8 +641,8 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -641,8 +641,8 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
641641
642 // We'll want to remember what the IES used to be before the update for642 // We'll want to remember what the IES used to be before the update for
643 // dependency invalidation purposes.643 // dependency invalidation purposes.
644 const old_resolved_ies = if (func.analysis(ip).inferred_error_set)644 const old_resolved_ies = if (func.analysisUnordered(ip).inferred_error_set)
645 func.resolvedErrorSet(ip).*645 func.resolvedErrorSetUnordered(ip)
646 else646 else
647 .none;647 .none;
648648
...@@ -671,7 +671,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -671,7 +671,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
671 zcu.deleteUnitReferences(func_as_depender);671 zcu.deleteUnitReferences(func_as_depender);
672 }672 }
673673
674 switch (func.analysis(ip).state) {674 switch (func.analysisUnordered(ip).state) {
675 .success => if (!was_outdated) return,675 .success => if (!was_outdated) return,
676 .sema_failure,676 .sema_failure,
677 .dependency_failure,677 .dependency_failure,
...@@ -693,11 +693,11 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -693,11 +693,11 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
693693
694 var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {694 var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
695 error.AnalysisFail => {695 error.AnalysisFail => {
696 if (func.analysis(ip).state == .in_progress) {696 if (func.analysisUnordered(ip).state == .in_progress) {
697 // If this decl caused the compile error, the analysis field would697 // If this decl caused the compile error, the analysis field would
698 // be changed to indicate it was this Decl's fault. Because this698 // be changed to indicate it was this Decl's fault. Because this
699 // did not happen, we infer here that it was a dependency failure.699 // did not happen, we infer here that it was a dependency failure.
700 func.analysis(ip).state = .dependency_failure;700 func.setAnalysisState(ip, .dependency_failure);
701 }701 }
702 return error.AnalysisFail;702 return error.AnalysisFail;
703 },703 },
...@@ -707,8 +707,8 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -707,8 +707,8 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
707707
708 const invalidate_ies_deps = i: {708 const invalidate_ies_deps = i: {
709 if (!was_outdated) break :i false;709 if (!was_outdated) break :i false;
710 if (!func.analysis(ip).inferred_error_set) break :i true;710 if (!func.analysisUnordered(ip).inferred_error_set) break :i true;
711 const new_resolved_ies = func.resolvedErrorSet(ip).*;711 const new_resolved_ies = func.resolvedErrorSetUnordered(ip);
712 break :i new_resolved_ies != old_resolved_ies;712 break :i new_resolved_ies != old_resolved_ies;
713 };713 };
714 if (invalidate_ies_deps) {714 if (invalidate_ies_deps) {
...@@ -729,7 +729,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -729,7 +729,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
729 return;729 return;
730 }730 }
731731
732 try comp.work_queue.writeItem(.{ .codegen_func = .{732 try comp.queueJob(.{ .codegen_func = .{
733 .func = func_index,733 .func = func_index,
734 .air = air,734 .air = air,
735 } });735 } });
...@@ -783,7 +783,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -783,7 +783,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
783 .{@errorName(err)},783 .{@errorName(err)},
784 ),784 ),
785 );785 );
786 func.analysis(ip).state = .codegen_failure;786 func.setAnalysisState(ip, .codegen_failure);
787 return;787 return;
788 },788 },
789 };789 };
...@@ -797,12 +797,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -797,12 +797,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
797 // Correcting this failure will involve changing a type this function797 // Correcting this failure will involve changing a type this function
798 // depends on, hence triggering re-analysis of this function, so this798 // depends on, hence triggering re-analysis of this function, so this
799 // interacts correctly with incremental compilation.799 // interacts correctly with incremental compilation.
800 func.analysis(ip).state = .codegen_failure;800 func.setAnalysisState(ip, .codegen_failure);
801 } else if (comp.bin_file) |lf| {801 } else if (comp.bin_file) |lf| {
802 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {802 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
803 error.OutOfMemory => return error.OutOfMemory,803 error.OutOfMemory => return error.OutOfMemory,
804 error.AnalysisFail => {804 error.AnalysisFail => {
805 func.analysis(ip).state = .codegen_failure;805 func.setAnalysisState(ip, .codegen_failure);
806 },806 },
807 else => {807 else => {
808 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);808 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
...@@ -812,7 +812,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -812,7 +812,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
812 "unable to codegen: {s}",812 "unable to codegen: {s}",
813 .{@errorName(err)},813 .{@errorName(err)},
814 ));814 ));
815 func.analysis(ip).state = .codegen_failure;815 func.setAnalysisState(ip, .codegen_failure);
816 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));816 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
817 },817 },
818 };818 };
...@@ -903,7 +903,7 @@ fn getFileRootStruct(...@@ -903,7 +903,7 @@ fn getFileRootStruct(
903 decl.analysis = .complete;903 decl.analysis = .complete;
904904
905 try pt.scanNamespace(namespace_index, decls, decl);905 try pt.scanNamespace(namespace_index, decls, decl);
906 try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });906 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
907 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());907 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
908}908}
909909
...@@ -1080,7 +1080,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1080,7 +1080,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1080 const old_linksection = decl.@"linksection";1080 const old_linksection = decl.@"linksection";
1081 const old_addrspace = decl.@"addrspace";1081 const old_addrspace = decl.@"addrspace";
1082 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|1082 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|
1083 prev_func.analysis(ip).state == .inline_only1083 prev_func.analysisUnordered(ip).state == .inline_only
1084 else1084 else
1085 false;1085 false;
10861086
...@@ -1311,10 +1311,10 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1311,10 +1311,10 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1311 // codegen backend wants full access to the Decl Type.1311 // codegen backend wants full access to the Decl Type.
1312 try decl_ty.resolveFully(pt);1312 try decl_ty.resolveFully(pt);
13131313
1314 try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });1314 try zcu.comp.queueJob(.{ .codegen_decl = decl_index });
13151315
1316 if (result.invalidate_decl_ref and zcu.emit_h != null) {1316 if (result.invalidate_decl_ref and zcu.emit_h != null) {
1317 try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index });1317 try zcu.comp.queueJob(.{ .emit_h_decl = decl_index });
1318 }1318 }
1319 }1319 }
13201320
...@@ -1740,8 +1740,6 @@ pub fn scanNamespace(...@@ -1740,8 +1740,6 @@ pub fn scanNamespace(
1740 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};1740 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
1741 defer seen_decls.deinit(gpa);1741 defer seen_decls.deinit(gpa);
17421742
1743 try zcu.comp.work_queue.ensureUnusedCapacity(decls.len);
1744
1745 namespace.decls.clearRetainingCapacity();1743 namespace.decls.clearRetainingCapacity();
1746 try namespace.decls.ensureTotalCapacity(gpa, decls.len);1744 try namespace.decls.ensureTotalCapacity(gpa, decls.len);
17471745
...@@ -1967,7 +1965,7 @@ const ScanDeclIter = struct {...@@ -1967,7 +1965,7 @@ const ScanDeclIter = struct {
1967 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{1965 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{
1968 namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,1966 namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
1969 });1967 });
1970 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = decl_index });1968 try comp.queueJob(.{ .analyze_decl = decl_index });
1971 }1969 }
1972 }1970 }
19731971
...@@ -1976,7 +1974,7 @@ const ScanDeclIter = struct {...@@ -1976,7 +1974,7 @@ const ScanDeclIter = struct {
1976 // updated line numbers. Look into this!1974 // updated line numbers. Look into this!
1977 // TODO Look into detecting when this would be unnecessary by storing enough state1975 // TODO Look into detecting when this would be unnecessary by storing enough state
1978 // in `Decl` to notice that the line number did not change.1976 // in `Decl` to notice that the line number did not change.
1979 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });1977 try comp.queueJob(.{ .update_line_number = decl_index });
1980 }1978 }
1981 }1979 }
1982};1980};
...@@ -1991,7 +1989,7 @@ pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {...@@ -1991,7 +1989,7 @@ pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1991/// Finalize the creation of an anon decl.1989/// Finalize the creation of an anon decl.
1992pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {1990pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1993 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {1991 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1994 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });1992 try pt.zcu.comp.queueJob(.{ .codegen_decl = decl_index });
1995 }1993 }
1996}1994}
19971995
...@@ -2037,7 +2035,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2037,7 +2035,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2037 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),2035 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
2038 .fn_ret_ty_ies = null,2036 .fn_ret_ty_ies = null,
2039 .owner_func_index = func_index,2037 .owner_func_index = func_index,
2040 .branch_quota = @max(func.branchQuota(ip).*, Sema.default_branch_quota),2038 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),
2041 .comptime_err_ret_trace = &comptime_err_ret_trace,2039 .comptime_err_ret_trace = &comptime_err_ret_trace,
2042 };2040 };
2043 defer sema.deinit();2041 defer sema.deinit();
...@@ -2047,14 +2045,14 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2047,14 +2045,14 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2047 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });2045 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
2048 try sema.declareDependency(.{ .decl_val = decl_index });2046 try sema.declareDependency(.{ .decl_val = decl_index });
20492047
2050 if (func.analysis(ip).inferred_error_set) {2048 if (func.analysisUnordered(ip).inferred_error_set) {
2051 const ies = try arena.create(Sema.InferredErrorSet);2049 const ies = try arena.create(Sema.InferredErrorSet);
2052 ies.* = .{ .func = func_index };2050 ies.* = .{ .func = func_index };
2053 sema.fn_ret_ty_ies = ies;2051 sema.fn_ret_ty_ies = ies;
2054 }2052 }
20552053
2056 // reset in case calls to errorable functions are removed.2054 // reset in case calls to errorable functions are removed.
2057 func.analysis(ip).calls_or_awaits_errorable_fn = false;2055 func.setCallsOrAwaitsErrorableFn(ip, false);
20582056
2059 // First few indexes of extra are reserved and set at the end.2057 // First few indexes of extra are reserved and set at the end.
2060 const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len;2058 const reserved_count = @typeInfo(Air.ExtraIndex).Enum.fields.len;
...@@ -2080,7 +2078,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2080,7 +2078,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2080 };2078 };
2081 defer inner_block.instructions.deinit(gpa);2079 defer inner_block.instructions.deinit(gpa);
20822080
2083 const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip));2081 const fn_info = sema.code.getFnInfo(func.zirBodyInstUnordered(ip).resolve(ip));
20842082
2085 // Here we are performing "runtime semantic analysis" for a function body, which means2083 // Here we are performing "runtime semantic analysis" for a function body, which means
2086 // we must map the parameter ZIR instructions to `arg` AIR instructions.2084 // we must map the parameter ZIR instructions to `arg` AIR instructions.
...@@ -2149,7 +2147,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2149,7 +2147,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2149 });2147 });
2150 }2148 }
21512149
2152 func.analysis(ip).state = .in_progress;2150 func.setAnalysisState(ip, .in_progress);
21532151
2154 const last_arg_index = inner_block.instructions.items.len;2152 const last_arg_index = inner_block.instructions.items.len;
21552153
...@@ -2176,7 +2174,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2176,7 +2174,7 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2176 }2174 }
21772175
2178 // If we don't get an error return trace from a caller, create our own.2176 // If we don't get an error return trace from a caller, create our own.
2179 if (func.analysis(ip).calls_or_awaits_errorable_fn and2177 if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and
2180 mod.comp.config.any_error_tracing and2178 mod.comp.config.any_error_tracing and
2181 !sema.fn_ret_ty.isError(mod))2179 !sema.fn_ret_ty.isError(mod))
2182 {2180 {
...@@ -2218,10 +2216,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2218,10 +2216,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2218 else => |e| return e,2216 else => |e| return e,
2219 };2217 };
2220 assert(ies.resolved != .none);2218 assert(ies.resolved != .none);
2221 ip.funcIesResolved(func_index).* = ies.resolved;2219 ip.funcSetIesResolved(func_index, ies.resolved);
2222 }2220 }
22232221
2224 func.analysis(ip).state = .success;2222 func.setAnalysisState(ip, .success);
22252223
2226 // Finally we must resolve the return type and parameter types so that backends2224 // Finally we must resolve the return type and parameter types so that backends
2227 // have full access to type information.2225 // have full access to type information.
...@@ -2415,6 +2413,7 @@ fn processExportsInner(...@@ -2415,6 +2413,7 @@ fn processExportsInner(
2415) error{OutOfMemory}!void {2413) error{OutOfMemory}!void {
2416 const zcu = pt.zcu;2414 const zcu = pt.zcu;
2417 const gpa = zcu.gpa;2415 const gpa = zcu.gpa;
2416 const ip = &zcu.intern_pool;
24182417
2419 for (export_indices) |export_idx| {2418 for (export_indices) |export_idx| {
2420 const new_export = &zcu.all_exports.items[export_idx];2419 const new_export = &zcu.all_exports.items[export_idx];
...@@ -2423,7 +2422,7 @@ fn processExportsInner(...@@ -2423,7 +2422,7 @@ fn processExportsInner(
2423 new_export.status = .failed_retryable;2422 new_export.status = .failed_retryable;
2424 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);2423 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
2425 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{2424 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{
2426 new_export.opts.name.fmt(&zcu.intern_pool),2425 new_export.opts.name.fmt(ip),
2427 });2426 });
2428 errdefer msg.destroy(gpa);2427 errdefer msg.destroy(gpa);
2429 const other_export = zcu.all_exports.items[gop.value_ptr.*];2428 const other_export = zcu.all_exports.items[gop.value_ptr.*];
...@@ -2443,8 +2442,7 @@ fn processExportsInner(...@@ -2443,8 +2442,7 @@ fn processExportsInner(
2443 if (!decl.owns_tv) break :failed false;2442 if (!decl.owns_tv) break :failed false;
2444 if (decl.typeOf(zcu).zigTypeTag(zcu) != .Fn) break :failed false;2443 if (decl.typeOf(zcu).zigTypeTag(zcu) != .Fn) break :failed false;
2445 // Check if owned function failed2444 // Check if owned function failed
2446 const a = zcu.funcInfo(decl.val.toIntern()).analysis(&zcu.intern_pool);2445 break :failed zcu.funcInfo(decl.val.toIntern()).analysisUnordered(ip).state != .success;
2447 break :failed a.state != .success;
2448 }) {2446 }) {
2449 // This `Decl` is failed, so was never sent to codegen.2447 // This `Decl` is failed, so was never sent to codegen.
2450 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?2448 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?
...@@ -3072,7 +3070,7 @@ pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionTyp...@@ -3072,7 +3070,7 @@ pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionTyp
3072 most_aligned_field_size = field_size;3070 most_aligned_field_size = field_size;
3073 }3071 }
3074 }3072 }
3075 const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag();3073 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();
3076 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) {3074 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) {
3077 return .{3075 return .{
3078 .abi_size = payload_align.forward(payload_size),3076 .abi_size = payload_align.forward(payload_size),
...@@ -3091,7 +3089,7 @@ pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionTyp...@@ -3091,7 +3089,7 @@ pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionTyp
3091 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt);3089 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt);
3092 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1");3090 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1");
3093 return .{3091 return .{
3094 .abi_size = loaded_union.size(ip).*,3092 .abi_size = loaded_union.sizeUnordered(ip),
3095 .abi_align = tag_align.max(payload_align),3093 .abi_align = tag_align.max(payload_align),
3096 .most_aligned_field = most_aligned_field,3094 .most_aligned_field = most_aligned_field,
3097 .most_aligned_field_size = most_aligned_field_size,3095 .most_aligned_field_size = most_aligned_field_size,
...@@ -3100,7 +3098,7 @@ pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionTyp...@@ -3100,7 +3098,7 @@ pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionTyp
3100 .payload_align = payload_align,3098 .payload_align = payload_align,
3101 .tag_align = tag_align,3099 .tag_align = tag_align,
3102 .tag_size = tag_size,3100 .tag_size = tag_size,
3103 .padding = loaded_union.padding(ip).*,3101 .padding = loaded_union.paddingUnordered(ip),
3104 };3102 };
3105}3103}
31063104
...@@ -3142,7 +3140,7 @@ pub fn unionFieldNormalAlignmentAdvanced(...@@ -3142,7 +3140,7 @@ pub fn unionFieldNormalAlignmentAdvanced(
3142 strat: Type.ResolveStrat,3140 strat: Type.ResolveStrat,
3143) Zcu.SemaError!InternPool.Alignment {3141) Zcu.SemaError!InternPool.Alignment {
3144 const ip = &pt.zcu.intern_pool;3142 const ip = &pt.zcu.intern_pool;
3145 assert(loaded_union.flagsPtr(ip).layout != .@"packed");3143 assert(loaded_union.flagsUnordered(ip).layout != .@"packed");
3146 const field_align = loaded_union.fieldAlign(ip, field_index);3144 const field_align = loaded_union.fieldAlign(ip, field_index);
3147 if (field_align != .none) return field_align;3145 if (field_align != .none) return field_align;
3148 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);3146 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
src/arch/arm/abi.zig+1-1
...@@ -56,7 +56,7 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class {...@@ -56,7 +56,7 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread, ctx: Context) Class {
56 .Union => {56 .Union => {
57 const bit_size = ty.bitSize(pt);57 const bit_size = ty.bitSize(pt);
58 const union_obj = pt.zcu.typeToUnion(ty).?;58 const union_obj = pt.zcu.typeToUnion(ty).?;
59 if (union_obj.getLayout(ip) == .@"packed") {59 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
60 if (bit_size > 64) return .memory;60 if (bit_size > 64) return .memory;
61 return .byval;61 return .byval;
62 }62 }
src/arch/riscv64/CodeGen.zig+1-1
...@@ -768,7 +768,7 @@ pub fn generate(...@@ -768,7 +768,7 @@ pub fn generate(
768 @intFromEnum(FrameIndex.stack_frame),768 @intFromEnum(FrameIndex.stack_frame),
769 FrameAlloc.init(.{769 FrameAlloc.init(.{
770 .size = 0,770 .size = 0,
771 .alignment = func.analysis(ip).stack_alignment.max(.@"1"),771 .alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"),
772 }),772 }),
773 );773 );
774 function.frame_allocs.set(774 function.frame_allocs.set(
src/arch/wasm/CodeGen.zig+7-7
...@@ -1011,7 +1011,7 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {...@@ -1011,7 +1011,7 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
1011 },1011 },
1012 .Struct => {1012 .Struct => {
1013 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {1013 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {
1014 return typeToValtype(Type.fromInterned(packed_struct.backingIntType(ip).*), pt);1014 return typeToValtype(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt);
1015 } else {1015 } else {
1016 return wasm.Valtype.i32;1016 return wasm.Valtype.i32;
1017 }1017 }
...@@ -1746,7 +1746,7 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {...@@ -1746,7 +1746,7 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
1746 => return ty.hasRuntimeBitsIgnoreComptime(pt),1746 => return ty.hasRuntimeBitsIgnoreComptime(pt),
1747 .Union => {1747 .Union => {
1748 if (mod.typeToUnion(ty)) |union_obj| {1748 if (mod.typeToUnion(ty)) |union_obj| {
1749 if (union_obj.getLayout(ip) == .@"packed") {1749 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
1750 return ty.abiSize(pt) > 8;1750 return ty.abiSize(pt) > 8;
1751 }1751 }
1752 }1752 }
...@@ -1754,7 +1754,7 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {...@@ -1754,7 +1754,7 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
1754 },1754 },
1755 .Struct => {1755 .Struct => {
1756 if (mod.typeToPackedStruct(ty)) |packed_struct| {1756 if (mod.typeToPackedStruct(ty)) |packed_struct| {
1757 return isByRef(Type.fromInterned(packed_struct.backingIntType(ip).*), pt);1757 return isByRef(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt);
1758 }1758 }
1759 return ty.hasRuntimeBitsIgnoreComptime(pt);1759 return ty.hasRuntimeBitsIgnoreComptime(pt);
1760 },1760 },
...@@ -3377,7 +3377,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3377,7 +3377,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3377 assert(struct_type.layout == .@"packed");3377 assert(struct_type.layout == .@"packed");
3378 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer3378 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3379 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;3379 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3380 const backing_int_ty = Type.fromInterned(struct_type.backingIntType(ip).*);3380 const backing_int_ty = Type.fromInterned(struct_type.backingIntTypeUnordered(ip));
3381 const int_val = try pt.intValue(3381 const int_val = try pt.intValue(
3382 backing_int_ty,3382 backing_int_ty,
3383 mem.readInt(u64, &buf, .little),3383 mem.readInt(u64, &buf, .little),
...@@ -3443,7 +3443,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3443,7 +3443,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3443 },3443 },
3444 .Struct => {3444 .Struct => {
3445 const packed_struct = mod.typeToPackedStruct(ty).?;3445 const packed_struct = mod.typeToPackedStruct(ty).?;
3446 return func.emitUndefined(Type.fromInterned(packed_struct.backingIntType(ip).*));3446 return func.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));
3447 },3447 },
3448 else => return func.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(mod)}),3448 else => return func.fail("Wasm TODO: emitUndefined for type: {}\n", .{ty.zigTypeTag(mod)}),
3449 }3449 }
...@@ -3974,7 +3974,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3974,7 +3974,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3974 .Struct => result: {3974 .Struct => result: {
3975 const packed_struct = mod.typeToPackedStruct(struct_ty).?;3975 const packed_struct = mod.typeToPackedStruct(struct_ty).?;
3976 const offset = pt.structPackedFieldBitOffset(packed_struct, field_index);3976 const offset = pt.structPackedFieldBitOffset(packed_struct, field_index);
3977 const backing_ty = Type.fromInterned(packed_struct.backingIntType(ip).*);3977 const backing_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
3978 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {3978 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {
3979 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});3979 return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
3980 };3980 };
...@@ -5377,7 +5377,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5377,7 +5377,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5377 }5377 }
5378 const packed_struct = mod.typeToPackedStruct(result_ty).?;5378 const packed_struct = mod.typeToPackedStruct(result_ty).?;
5379 const field_types = packed_struct.field_types;5379 const field_types = packed_struct.field_types;
5380 const backing_type = Type.fromInterned(packed_struct.backingIntType(ip).*);5380 const backing_type = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
53815381
5382 // ensure the result is zero'd5382 // ensure the result is zero'd
5383 const result = try func.allocLocal(backing_type);5383 const result = try func.allocLocal(backing_type);
src/arch/wasm/abi.zig+3-3
...@@ -71,7 +71,7 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class {...@@ -71,7 +71,7 @@ pub fn classifyType(ty: Type, pt: Zcu.PerThread) [2]Class {
71 },71 },
72 .Union => {72 .Union => {
73 const union_obj = pt.zcu.typeToUnion(ty).?;73 const union_obj = pt.zcu.typeToUnion(ty).?;
74 if (union_obj.getLayout(ip) == .@"packed") {74 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
75 if (ty.bitSize(pt) <= 64) return direct;75 if (ty.bitSize(pt) <= 64) return direct;
76 return .{ .direct, .direct };76 return .{ .direct, .direct };
77 }77 }
...@@ -107,7 +107,7 @@ pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type {...@@ -107,7 +107,7 @@ pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type {
107 switch (ty.zigTypeTag(mod)) {107 switch (ty.zigTypeTag(mod)) {
108 .Struct => {108 .Struct => {
109 if (mod.typeToPackedStruct(ty)) |packed_struct| {109 if (mod.typeToPackedStruct(ty)) |packed_struct| {
110 return scalarType(Type.fromInterned(packed_struct.backingIntType(ip).*), pt);110 return scalarType(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt);
111 } else {111 } else {
112 assert(ty.structFieldCount(mod) == 1);112 assert(ty.structFieldCount(mod) == 1);
113 return scalarType(ty.structFieldType(0, mod), pt);113 return scalarType(ty.structFieldType(0, mod), pt);
...@@ -115,7 +115,7 @@ pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type {...@@ -115,7 +115,7 @@ pub fn scalarType(ty: Type, pt: Zcu.PerThread) Type {
115 },115 },
116 .Union => {116 .Union => {
117 const union_obj = mod.typeToUnion(ty).?;117 const union_obj = mod.typeToUnion(ty).?;
118 if (union_obj.getLayout(ip) != .@"packed") {118 if (union_obj.flagsUnordered(ip).layout != .@"packed") {
119 const layout = pt.getUnionLayout(union_obj);119 const layout = pt.getUnionLayout(union_obj);
120 if (layout.payload_size == 0 and layout.tag_size != 0) {120 if (layout.payload_size == 0 and layout.tag_size != 0) {
121 return scalarType(ty.unionTagTypeSafety(mod).?, pt);121 return scalarType(ty.unionTagTypeSafety(mod).?, pt);
src/arch/x86_64/CodeGen.zig+1-1
...@@ -856,7 +856,7 @@ pub fn generate(...@@ -856,7 +856,7 @@ pub fn generate(
856 @intFromEnum(FrameIndex.stack_frame),856 @intFromEnum(FrameIndex.stack_frame),
857 FrameAlloc.init(.{857 FrameAlloc.init(.{
858 .size = 0,858 .size = 0,
859 .alignment = func.analysis(ip).stack_alignment.max(.@"1"),859 .alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"),
860 }),860 }),
861 );861 );
862 function.frame_allocs.set(862 function.frame_allocs.set(
src/arch/x86_64/abi.zig+5-5
...@@ -349,7 +349,7 @@ fn classifySystemVStruct(...@@ -349,7 +349,7 @@ fn classifySystemVStruct(
349 .@"packed" => {},349 .@"packed" => {},
350 }350 }
351 } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| {351 } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| {
352 switch (field_loaded_union.getLayout(ip)) {352 switch (field_loaded_union.flagsUnordered(ip).layout) {
353 .auto, .@"extern" => {353 .auto, .@"extern" => {
354 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, pt, target);354 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, pt, target);
355 continue;355 continue;
...@@ -362,11 +362,11 @@ fn classifySystemVStruct(...@@ -362,11 +362,11 @@ fn classifySystemVStruct(
362 result_class.* = result_class.combineSystemV(field_class);362 result_class.* = result_class.combineSystemV(field_class);
363 byte_offset += field_ty.abiSize(pt);363 byte_offset += field_ty.abiSize(pt);
364 }364 }
365 const final_byte_offset = starting_byte_offset + loaded_struct.size(ip).*;365 const final_byte_offset = starting_byte_offset + loaded_struct.sizeUnordered(ip);
366 std.debug.assert(final_byte_offset == std.mem.alignForward(366 std.debug.assert(final_byte_offset == std.mem.alignForward(
367 u64,367 u64,
368 byte_offset,368 byte_offset,
369 loaded_struct.flagsPtr(ip).alignment.toByteUnits().?,369 loaded_struct.flagsUnordered(ip).alignment.toByteUnits().?,
370 ));370 ));
371 return final_byte_offset;371 return final_byte_offset;
372}372}
...@@ -390,7 +390,7 @@ fn classifySystemVUnion(...@@ -390,7 +390,7 @@ fn classifySystemVUnion(
390 .@"packed" => {},390 .@"packed" => {},
391 }391 }
392 } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| {392 } else if (pt.zcu.typeToUnion(field_ty)) |field_loaded_union| {
393 switch (field_loaded_union.getLayout(ip)) {393 switch (field_loaded_union.flagsUnordered(ip).layout) {
394 .auto, .@"extern" => {394 .auto, .@"extern" => {
395 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, pt, target);395 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, pt, target);
396 continue;396 continue;
...@@ -402,7 +402,7 @@ fn classifySystemVUnion(...@@ -402,7 +402,7 @@ fn classifySystemVUnion(
402 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|402 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
403 result_class.* = result_class.combineSystemV(field_class);403 result_class.* = result_class.combineSystemV(field_class);
404 }404 }
405 return starting_byte_offset + loaded_union.size(ip).*;405 return starting_byte_offset + loaded_union.sizeUnordered(ip);
406}406}
407407
408pub const SysV = struct {408pub const SysV = struct {
src/codegen.zig+2-2
...@@ -548,8 +548,8 @@ pub fn generateSymbol(...@@ -548,8 +548,8 @@ pub fn generateSymbol(
548 }548 }
549 }549 }
550550
551 const size = struct_type.size(ip).*;551 const size = struct_type.sizeUnordered(ip);
552 const alignment = struct_type.flagsPtr(ip).alignment.toByteUnits().?;552 const alignment = struct_type.flagsUnordered(ip).alignment.toByteUnits().?;
553553
554 const padding = math.cast(554 const padding = math.cast(
555 usize,555 usize,
src/codegen/c.zig+7-7
...@@ -1366,7 +1366,7 @@ pub const DeclGen = struct {...@@ -1366,7 +1366,7 @@ pub const DeclGen = struct {
1366 const loaded_union = ip.loadUnionType(ty.toIntern());1366 const loaded_union = ip.loadUnionType(ty.toIntern());
1367 if (un.tag == .none) {1367 if (un.tag == .none) {
1368 const backing_ty = try ty.unionBackingType(pt);1368 const backing_ty = try ty.unionBackingType(pt);
1369 switch (loaded_union.getLayout(ip)) {1369 switch (loaded_union.flagsUnordered(ip).layout) {
1370 .@"packed" => {1370 .@"packed" => {
1371 if (!location.isInitializer()) {1371 if (!location.isInitializer()) {
1372 try writer.writeByte('(');1372 try writer.writeByte('(');
...@@ -1401,7 +1401,7 @@ pub const DeclGen = struct {...@@ -1401,7 +1401,7 @@ pub const DeclGen = struct {
1401 const field_index = zcu.unionTagFieldIndex(loaded_union, Value.fromInterned(un.tag)).?;1401 const field_index = zcu.unionTagFieldIndex(loaded_union, Value.fromInterned(un.tag)).?;
1402 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);1402 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
1403 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];1403 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];
1404 if (loaded_union.getLayout(ip) == .@"packed") {1404 if (loaded_union.flagsUnordered(ip).layout == .@"packed") {
1405 if (field_ty.hasRuntimeBits(pt)) {1405 if (field_ty.hasRuntimeBits(pt)) {
1406 if (field_ty.isPtrAtRuntime(zcu)) {1406 if (field_ty.isPtrAtRuntime(zcu)) {
1407 try writer.writeByte('(');1407 try writer.writeByte('(');
...@@ -1629,7 +1629,7 @@ pub const DeclGen = struct {...@@ -1629,7 +1629,7 @@ pub const DeclGen = struct {
1629 },1629 },
1630 .union_type => {1630 .union_type => {
1631 const loaded_union = ip.loadUnionType(ty.toIntern());1631 const loaded_union = ip.loadUnionType(ty.toIntern());
1632 switch (loaded_union.getLayout(ip)) {1632 switch (loaded_union.flagsUnordered(ip).layout) {
1633 .auto, .@"extern" => {1633 .auto, .@"extern" => {
1634 if (!location.isInitializer()) {1634 if (!location.isInitializer()) {
1635 try writer.writeByte('(');1635 try writer.writeByte('(');
...@@ -1792,7 +1792,7 @@ pub const DeclGen = struct {...@@ -1792,7 +1792,7 @@ pub const DeclGen = struct {
1792 else => unreachable,1792 else => unreachable,
1793 }1793 }
1794 }1794 }
1795 if (fn_val.getFunction(zcu)) |func| if (func.analysis(ip).is_cold)1795 if (fn_val.getFunction(zcu)) |func| if (func.analysisUnordered(ip).is_cold)
1796 try w.writeAll("zig_cold ");1796 try w.writeAll("zig_cold ");
1797 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");1797 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
17981798
...@@ -5527,7 +5527,7 @@ fn fieldLocation(...@@ -5527,7 +5527,7 @@ fn fieldLocation(
5527 .{ .field = field_index } },5527 .{ .field = field_index } },
5528 .union_type => {5528 .union_type => {
5529 const loaded_union = ip.loadUnionType(container_ty.toIntern());5529 const loaded_union = ip.loadUnionType(container_ty.toIntern());
5530 switch (loaded_union.getLayout(ip)) {5530 switch (loaded_union.flagsUnordered(ip).layout) {
5531 .auto, .@"extern" => {5531 .auto, .@"extern" => {
5532 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);5532 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
5533 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt))5533 if (!field_ty.hasRuntimeBitsIgnoreComptime(pt))
...@@ -5763,7 +5763,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5763,7 +5763,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5763 .{ .field = extra.field_index },5763 .{ .field = extra.field_index },
5764 .union_type => field_name: {5764 .union_type => field_name: {
5765 const loaded_union = ip.loadUnionType(struct_ty.toIntern());5765 const loaded_union = ip.loadUnionType(struct_ty.toIntern());
5766 switch (loaded_union.getLayout(ip)) {5766 switch (loaded_union.flagsUnordered(ip).layout) {
5767 .auto, .@"extern" => {5767 .auto, .@"extern" => {
5768 const name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index];5768 const name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index];
5769 break :field_name if (loaded_union.hasTag(ip))5769 break :field_name if (loaded_union.hasTag(ip))
...@@ -7267,7 +7267,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7267,7 +7267,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
72677267
7268 const writer = f.object.writer();7268 const writer = f.object.writer();
7269 const local = try f.allocLocal(inst, union_ty);7269 const local = try f.allocLocal(inst, union_ty);
7270 if (loaded_union.getLayout(ip) == .@"packed") return f.moveCValue(inst, union_ty, payload);7270 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
72717271
7272 const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {7272 const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {
7273 const layout = union_ty.unionGetLayout(pt);7273 const layout = union_ty.unionGetLayout(pt);
src/codegen/c/Type.zig+2-2
...@@ -1744,7 +1744,7 @@ pub const Pool = struct {...@@ -1744,7 +1744,7 @@ pub const Pool = struct {
1744 .@"packed" => return pool.fromType(1744 .@"packed" => return pool.fromType(
1745 allocator,1745 allocator,
1746 scratch,1746 scratch,
1747 Type.fromInterned(loaded_struct.backingIntType(ip).*),1747 Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)),
1748 pt,1748 pt,
1749 mod,1749 mod,
1750 kind,1750 kind,
...@@ -1817,7 +1817,7 @@ pub const Pool = struct {...@@ -1817,7 +1817,7 @@ pub const Pool = struct {
1817 },1817 },
1818 .union_type => {1818 .union_type => {
1819 const loaded_union = ip.loadUnionType(ip_index);1819 const loaded_union = ip.loadUnionType(ip_index);
1820 switch (loaded_union.getLayout(ip)) {1820 switch (loaded_union.flagsUnordered(ip).layout) {
1821 .auto, .@"extern" => {1821 .auto, .@"extern" => {
1822 const has_tag = loaded_union.hasTag(ip);1822 const has_tag = loaded_union.hasTag(ip);
1823 const fwd_decl = try pool.getFwdDecl(allocator, .{1823 const fwd_decl = try pool.getFwdDecl(allocator, .{
src/codegen/llvm.zig+17-16
...@@ -1086,7 +1086,7 @@ pub const Object = struct {...@@ -1086,7 +1086,7 @@ pub const Object = struct {
1086 // If there is no such function in the module, it means the source code does not need it.1086 // If there is no such function in the module, it means the source code does not need it.
1087 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;1087 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;
1088 const llvm_fn = o.builder.getGlobal(name) orelse return;1088 const llvm_fn = o.builder.getGlobal(name) orelse return;
1089 const errors_len = o.pt.zcu.intern_pool.global_error_set.mutate.list.len;1089 const errors_len = o.pt.zcu.intern_pool.global_error_set.getNamesFromMainThread().len;
10901090
1091 var wip = try Builder.WipFunction.init(&o.builder, .{1091 var wip = try Builder.WipFunction.init(&o.builder, .{
1092 .function = llvm_fn.ptrConst(&o.builder).kind.function,1092 .function = llvm_fn.ptrConst(&o.builder).kind.function,
...@@ -1385,13 +1385,14 @@ pub const Object = struct {...@@ -1385,13 +1385,14 @@ pub const Object = struct {
1385 var attributes = try function_index.ptrConst(&o.builder).attributes.toWip(&o.builder);1385 var attributes = try function_index.ptrConst(&o.builder).attributes.toWip(&o.builder);
1386 defer attributes.deinit(&o.builder);1386 defer attributes.deinit(&o.builder);
13871387
1388 if (func.analysis(ip).is_noinline) {1388 const func_analysis = func.analysisUnordered(ip);
1389 if (func_analysis.is_noinline) {
1389 try attributes.addFnAttr(.@"noinline", &o.builder);1390 try attributes.addFnAttr(.@"noinline", &o.builder);
1390 } else {1391 } else {
1391 _ = try attributes.removeFnAttr(.@"noinline");1392 _ = try attributes.removeFnAttr(.@"noinline");
1392 }1393 }
13931394
1394 const stack_alignment = func.analysis(ip).stack_alignment;1395 const stack_alignment = func.analysisUnordered(ip).stack_alignment;
1395 if (stack_alignment != .none) {1396 if (stack_alignment != .none) {
1396 try attributes.addFnAttr(.{ .alignstack = stack_alignment.toLlvm() }, &o.builder);1397 try attributes.addFnAttr(.{ .alignstack = stack_alignment.toLlvm() }, &o.builder);
1397 try attributes.addFnAttr(.@"noinline", &o.builder);1398 try attributes.addFnAttr(.@"noinline", &o.builder);
...@@ -1399,7 +1400,7 @@ pub const Object = struct {...@@ -1399,7 +1400,7 @@ pub const Object = struct {
1399 _ = try attributes.removeFnAttr(.alignstack);1400 _ = try attributes.removeFnAttr(.alignstack);
1400 }1401 }
14011402
1402 if (func.analysis(ip).is_cold) {1403 if (func_analysis.is_cold) {
1403 try attributes.addFnAttr(.cold, &o.builder);1404 try attributes.addFnAttr(.cold, &o.builder);
1404 } else {1405 } else {
1405 _ = try attributes.removeFnAttr(.cold);1406 _ = try attributes.removeFnAttr(.cold);
...@@ -1624,7 +1625,7 @@ pub const Object = struct {...@@ -1624,7 +1625,7 @@ pub const Object = struct {
1624 llvm_arg_i += 1;1625 llvm_arg_i += 1;
16251626
1626 const alignment = param_ty.abiAlignment(pt).toLlvm();1627 const alignment = param_ty.abiAlignment(pt).toLlvm();
1627 const arg_ptr = try buildAllocaInner(&wip, param_llvm_ty, alignment, target);1628 const arg_ptr = try buildAllocaInner(&wip, param.typeOfWip(&wip), alignment, target);
1628 _ = try wip.store(.normal, param, arg_ptr, alignment);1629 _ = try wip.store(.normal, param, arg_ptr, alignment);
16291630
1630 args.appendAssumeCapacity(if (isByRef(param_ty, pt))1631 args.appendAssumeCapacity(if (isByRef(param_ty, pt))
...@@ -2403,7 +2404,7 @@ pub const Object = struct {...@@ -2403,7 +2404,7 @@ pub const Object = struct {
2403 defer gpa.free(name);2404 defer gpa.free(name);
24042405
2405 if (zcu.typeToPackedStruct(ty)) |struct_type| {2406 if (zcu.typeToPackedStruct(ty)) |struct_type| {
2406 const backing_int_ty = struct_type.backingIntType(ip).*;2407 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
2407 if (backing_int_ty != .none) {2408 if (backing_int_ty != .none) {
2408 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);2409 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2409 const builder_name = try o.builder.metadataString(name);2410 const builder_name = try o.builder.metadataString(name);
...@@ -2615,7 +2616,7 @@ pub const Object = struct {...@@ -2615,7 +2616,7 @@ pub const Object = struct {
2615 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;2616 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue;
26162617
2617 const field_size = Type.fromInterned(field_ty).abiSize(pt);2618 const field_size = Type.fromInterned(field_ty).abiSize(pt);
2618 const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) {2619 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2619 .@"packed" => .none,2620 .@"packed" => .none,
2620 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),2621 .auto, .@"extern" => pt.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2621 };2622 };
...@@ -3303,7 +3304,7 @@ pub const Object = struct {...@@ -3303,7 +3304,7 @@ pub const Object = struct {
3303 const struct_type = ip.loadStructType(t.toIntern());3304 const struct_type = ip.loadStructType(t.toIntern());
33043305
3305 if (struct_type.layout == .@"packed") {3306 if (struct_type.layout == .@"packed") {
3306 const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*));3307 const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntTypeUnordered(ip)));
3307 try o.type_map.put(o.gpa, t.toIntern(), int_ty);3308 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3308 return int_ty;3309 return int_ty;
3309 }3310 }
...@@ -3346,7 +3347,7 @@ pub const Object = struct {...@@ -3346,7 +3347,7 @@ pub const Object = struct {
3346 // This is a zero-bit field. If there are runtime bits after this field,3347 // This is a zero-bit field. If there are runtime bits after this field,
3347 // map to the next LLVM field (which we know exists): otherwise, don't3348 // map to the next LLVM field (which we know exists): otherwise, don't
3348 // map the field, indicating it's at the end of the struct.3349 // map the field, indicating it's at the end of the struct.
3349 if (offset != struct_type.size(ip).*) {3350 if (offset != struct_type.sizeUnordered(ip)) {
3350 try o.struct_field_map.put(o.gpa, .{3351 try o.struct_field_map.put(o.gpa, .{
3351 .struct_ty = t.toIntern(),3352 .struct_ty = t.toIntern(),
3352 .field_index = field_index,3353 .field_index = field_index,
...@@ -3450,7 +3451,7 @@ pub const Object = struct {...@@ -3450,7 +3451,7 @@ pub const Object = struct {
3450 const union_obj = ip.loadUnionType(t.toIntern());3451 const union_obj = ip.loadUnionType(t.toIntern());
3451 const layout = pt.getUnionLayout(union_obj);3452 const layout = pt.getUnionLayout(union_obj);
34523453
3453 if (union_obj.flagsPtr(ip).layout == .@"packed") {3454 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
3454 const int_ty = try o.builder.intType(@intCast(t.bitSize(pt)));3455 const int_ty = try o.builder.intType(@intCast(t.bitSize(pt)));
3455 try o.type_map.put(o.gpa, t.toIntern(), int_ty);3456 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3456 return int_ty;3457 return int_ty;
...@@ -3697,7 +3698,7 @@ pub const Object = struct {...@@ -3697,7 +3698,7 @@ pub const Object = struct {
3697 if (layout.payload_size == 0) return o.lowerValue(un.tag);3698 if (layout.payload_size == 0) return o.lowerValue(un.tag);
36983699
3699 const union_obj = mod.typeToUnion(ty).?;3700 const union_obj = mod.typeToUnion(ty).?;
3700 const container_layout = union_obj.getLayout(ip);3701 const container_layout = union_obj.flagsUnordered(ip).layout;
37013702
3702 assert(container_layout == .@"packed");3703 assert(container_layout == .@"packed");
37033704
...@@ -4205,7 +4206,7 @@ pub const Object = struct {...@@ -4205,7 +4206,7 @@ pub const Object = struct {
4205 if (layout.payload_size == 0) return o.lowerValue(un.tag);4206 if (layout.payload_size == 0) return o.lowerValue(un.tag);
42064207
4207 const union_obj = mod.typeToUnion(ty).?;4208 const union_obj = mod.typeToUnion(ty).?;
4208 const container_layout = union_obj.getLayout(ip);4209 const container_layout = union_obj.flagsUnordered(ip).layout;
42094210
4210 var need_unnamed = false;4211 var need_unnamed = false;
4211 const payload = if (un.tag != .none) p: {4212 const payload = if (un.tag != .none) p: {
...@@ -10045,7 +10046,7 @@ pub const FuncGen = struct {...@@ -10045,7 +10046,7 @@ pub const FuncGen = struct {
10045 },10046 },
10046 .Struct => {10047 .Struct => {
10047 if (mod.typeToPackedStruct(result_ty)) |struct_type| {10048 if (mod.typeToPackedStruct(result_ty)) |struct_type| {
10048 const backing_int_ty = struct_type.backingIntType(ip).*;10049 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
10049 assert(backing_int_ty != .none);10050 assert(backing_int_ty != .none);
10050 const big_bits = Type.fromInterned(backing_int_ty).bitSize(pt);10051 const big_bits = Type.fromInterned(backing_int_ty).bitSize(pt);
10051 const int_ty = try o.builder.intType(@intCast(big_bits));10052 const int_ty = try o.builder.intType(@intCast(big_bits));
...@@ -10155,7 +10156,7 @@ pub const FuncGen = struct {...@@ -10155,7 +10156,7 @@ pub const FuncGen = struct {
10155 const layout = union_ty.unionGetLayout(pt);10156 const layout = union_ty.unionGetLayout(pt);
10156 const union_obj = mod.typeToUnion(union_ty).?;10157 const union_obj = mod.typeToUnion(union_ty).?;
1015710158
10158 if (union_obj.getLayout(ip) == .@"packed") {10159 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
10159 const big_bits = union_ty.bitSize(pt);10160 const big_bits = union_ty.bitSize(pt);
10160 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));10161 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));
10161 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);10162 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
...@@ -11281,7 +11282,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E...@@ -11281,7 +11282,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E
11281 .struct_type => {11282 .struct_type => {
11282 const struct_type = ip.loadStructType(return_type.toIntern());11283 const struct_type = ip.loadStructType(return_type.toIntern());
11283 assert(struct_type.haveLayout(ip));11284 assert(struct_type.haveLayout(ip));
11284 const size: u64 = struct_type.size(ip).*;11285 const size: u64 = struct_type.sizeUnordered(ip);
11285 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);11286 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
11286 if (size % 8 > 0) {11287 if (size % 8 > 0) {
11287 types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8));11288 types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8));
...@@ -11587,7 +11588,7 @@ const ParamTypeIterator = struct {...@@ -11587,7 +11588,7 @@ const ParamTypeIterator = struct {
11587 .struct_type => {11588 .struct_type => {
11588 const struct_type = ip.loadStructType(ty.toIntern());11589 const struct_type = ip.loadStructType(ty.toIntern());
11589 assert(struct_type.haveLayout(ip));11590 assert(struct_type.haveLayout(ip));
11590 const size: u64 = struct_type.size(ip).*;11591 const size: u64 = struct_type.sizeUnordered(ip);
11591 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);11592 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
11592 if (size % 8 > 0) {11593 if (size % 8 > 0) {
11593 types_buffer[types_index - 1] =11594 types_buffer[types_index - 1] =
src/codegen/spirv.zig+3-3
...@@ -1463,7 +1463,7 @@ const DeclGen = struct {...@@ -1463,7 +1463,7 @@ const DeclGen = struct {
1463 const ip = &mod.intern_pool;1463 const ip = &mod.intern_pool;
1464 const union_obj = mod.typeToUnion(ty).?;1464 const union_obj = mod.typeToUnion(ty).?;
14651465
1466 if (union_obj.getLayout(ip) == .@"packed") {1466 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
1467 return self.todo("packed union types", .{});1467 return self.todo("packed union types", .{});
1468 }1468 }
14691469
...@@ -1735,7 +1735,7 @@ const DeclGen = struct {...@@ -1735,7 +1735,7 @@ const DeclGen = struct {
1735 };1735 };
17361736
1737 if (struct_type.layout == .@"packed") {1737 if (struct_type.layout == .@"packed") {
1738 return try self.resolveType(Type.fromInterned(struct_type.backingIntType(ip).*), .direct);1738 return try self.resolveType(Type.fromInterned(struct_type.backingIntTypeUnordered(ip)), .direct);
1739 }1739 }
17401740
1741 var member_types = std.ArrayList(IdRef).init(self.gpa);1741 var member_types = std.ArrayList(IdRef).init(self.gpa);
...@@ -5081,7 +5081,7 @@ const DeclGen = struct {...@@ -5081,7 +5081,7 @@ const DeclGen = struct {
5081 const union_ty = mod.typeToUnion(ty).?;5081 const union_ty = mod.typeToUnion(ty).?;
5082 const tag_ty = Type.fromInterned(union_ty.enum_tag_ty);5082 const tag_ty = Type.fromInterned(union_ty.enum_tag_ty);
50835083
5084 if (union_ty.getLayout(ip) == .@"packed") {5084 if (union_ty.flagsUnordered(ip).layout == .@"packed") {
5085 unreachable; // TODO5085 unreachable; // TODO
5086 }5086 }
50875087
src/link/Coff.zig+1-1
...@@ -1156,7 +1156,7 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -1156,7 +1156,7 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,
1156 const code = switch (res) {1156 const code = switch (res) {
1157 .ok => code_buffer.items,1157 .ok => code_buffer.items,
1158 .fail => |em| {1158 .fail => |em| {
1159 func.analysis(&mod.intern_pool).state = .codegen_failure;1159 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
1160 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);1160 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1161 return;1161 return;
1162 },1162 },
src/link/Elf/ZigObject.zig+1-1
...@@ -1093,7 +1093,7 @@ pub fn updateFunc(...@@ -1093,7 +1093,7 @@ pub fn updateFunc(
1093 const code = switch (res) {1093 const code = switch (res) {
1094 .ok => code_buffer.items,1094 .ok => code_buffer.items,
1095 .fail => |em| {1095 .fail => |em| {
1096 func.analysis(&mod.intern_pool).state = .codegen_failure;1096 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
1097 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);1097 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1098 return;1098 return;
1099 },1099 },
src/link/MachO/ZigObject.zig+1-1
...@@ -699,7 +699,7 @@ pub fn updateFunc(...@@ -699,7 +699,7 @@ pub fn updateFunc(
699 const code = switch (res) {699 const code = switch (res) {
700 .ok => code_buffer.items,700 .ok => code_buffer.items,
701 .fail => |em| {701 .fail => |em| {
702 func.analysis(&mod.intern_pool).state = .codegen_failure;702 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
703 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);703 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
704 return;704 return;
705 },705 },
src/link/Plan9.zig+1-1
...@@ -449,7 +449,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -449,7 +449,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
449 const code = switch (res) {449 const code = switch (res) {
450 .ok => try code_buffer.toOwnedSlice(),450 .ok => try code_buffer.toOwnedSlice(),
451 .fail => |em| {451 .fail => |em| {
452 func.analysis(&mod.intern_pool).state = .codegen_failure;452 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
453 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);453 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
454 return;454 return;
455 },455 },
src/link/Wasm/ZigObject.zig+1-1
...@@ -1051,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -1051,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {
1051 const gpa = wasm_file.base.comp.gpa;1051 const gpa = wasm_file.base.comp.gpa;
1052 const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return;1052 const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return;
10531053
1054 const errors_len = 1 + wasm_file.base.comp.module.?.intern_pool.global_error_set.mutate.list.len;1054 const errors_len = 1 + wasm_file.base.comp.module.?.intern_pool.global_error_set.getNamesFromMainThread().len;
1055 // overwrite existing atom if it already exists (maybe the error set has increased)1055 // overwrite existing atom if it already exists (maybe the error set has increased)
1056 // if not, allcoate a new atom.1056 // if not, allcoate a new atom.
1057 const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {1057 const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/cases/compile_errors/bogus_method_call_on_slice.zig+1-1
...@@ -16,6 +16,6 @@ pub export fn entry2() void {...@@ -16,6 +16,6 @@ pub export fn entry2() void {
16// backend=stage216// backend=stage2
17// target=native17// target=native
18//18//
19// :3:6: error: no field or member function named 'copy' in '[]const u8'
19// :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})'20// :9:8: error: no field or member function named 'bar' in '@TypeOf(.{})'
20// :12:18: error: no field or member function named 'bar' in 'struct{comptime foo: comptime_int = 1}'21// :12:18: error: no field or member function named 'bar' in 'struct{comptime foo: comptime_int = 1}'
21// :3:6: error: no field or member function named 'copy' in '[]const u8'
test/cases/compile_errors/compile_log.zig+2-2
...@@ -17,14 +17,14 @@ export fn baz() void {...@@ -17,14 +17,14 @@ export fn baz() void {
17// target=native17// target=native
18//18//
19// :6:5: error: found compile log statement19// :6:5: error: found compile log statement
20// :12:5: note: also here
21// :6:5: note: also here20// :6:5: note: also here
21// :12:5: note: also here
22//22//
23// Compile Log Output:23// Compile Log Output:
24// @as(*const [5:0]u8, "begin")24// @as(*const [5:0]u8, "begin")
25// @as(*const [1:0]u8, "a"), @as(i32, 12), @as(*const [1:0]u8, "b"), @as([]const u8, "hi"[0..2])25// @as(*const [1:0]u8, "a"), @as(i32, 12), @as(*const [1:0]u8, "b"), @as([]const u8, "hi"[0..2])
26// @as(*const [3:0]u8, "end")26// @as(*const [3:0]u8, "end")
27// @as(comptime_int, 4)
28// @as(*const [5:0]u8, "begin")27// @as(*const [5:0]u8, "begin")
29// @as(*const [1:0]u8, "a"), @as(i32, [runtime value]), @as(*const [1:0]u8, "b"), @as([]const u8, [runtime value])28// @as(*const [1:0]u8, "a"), @as(i32, [runtime value]), @as(*const [1:0]u8, "b"), @as([]const u8, [runtime value])
30// @as(*const [3:0]u8, "end")29// @as(*const [3:0]u8, "end")
30// @as(comptime_int, 4)
test/cases/compile_errors/extern_function_with_comptime_parameter.zig+1-1
...@@ -18,6 +18,6 @@ comptime {...@@ -18,6 +18,6 @@ comptime {
18// backend=stage218// backend=stage2
19// target=native19// target=native
20//20//
21// :1:15: error: comptime parameters not allowed in function with calling convention 'C'
21// :5:30: error: comptime parameters not allowed in function with calling convention 'C'22// :5:30: error: comptime parameters not allowed in function with calling convention 'C'
22// :6:30: error: generic parameters not allowed in function with calling convention 'C'23// :6:30: error: generic parameters not allowed in function with calling convention 'C'
23// :1:15: error: comptime parameters not allowed in function with calling convention 'C'
test/cases/compile_errors/invalid_store_to_comptime_field.zig+1-1
...@@ -82,6 +82,6 @@ pub export fn entry8() void {...@@ -82,6 +82,6 @@ pub export fn entry8() void {
82// :36:29: note: default value set here82// :36:29: note: default value set here
83// :46:12: error: value stored in comptime field does not match the default value of the field83// :46:12: error: value stored in comptime field does not match the default value of the field
84// :55:25: error: value stored in comptime field does not match the default value of the field84// :55:25: error: value stored in comptime field does not match the default value of the field
85// :68:36: error: value stored in comptime field does not match the default value of the field
86// :61:30: error: value stored in comptime field does not match the default value of the field85// :61:30: error: value stored in comptime field does not match the default value of the field
87// :59:29: note: default value set here86// :59:29: note: default value set here
87// :68:36: error: value stored in comptime field does not match the default value of the field
test/cases/compile_errors/invalid_variadic_function.zig+1-1
...@@ -18,6 +18,6 @@ comptime {...@@ -18,6 +18,6 @@ comptime {
18//18//
19// :1:1: error: variadic function does not support '.Unspecified' calling convention19// :1:1: error: variadic function does not support '.Unspecified' calling convention
20// :1:1: note: supported calling conventions: '.C'20// :1:1: note: supported calling conventions: '.C'
21// :2:1: error: generic function cannot be variadic
22// :1:1: error: variadic function does not support '.Inline' calling convention21// :1:1: error: variadic function does not support '.Inline' calling convention
23// :1:1: note: supported calling conventions: '.C'22// :1:1: note: supported calling conventions: '.C'
23// :2:1: error: generic function cannot be variadic
test/cases/error_in_nested_declaration.zig+1-1
...@@ -26,6 +26,6 @@ pub export fn entry2() void {...@@ -26,6 +26,6 @@ pub export fn entry2() void {
26// backend=llvm26// backend=llvm
27// target=native27// target=native
28//28//
29// :17:12: error: C pointers cannot point to opaque types
30// :6:20: error: cannot @bitCast to '[]i32'29// :6:20: error: cannot @bitCast to '[]i32'
31// :6:20: note: use @ptrCast to cast from '[]u32'30// :6:20: note: use @ptrCast to cast from '[]u32'
31// :17:12: error: C pointers cannot point to opaque types