authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-08-08 15:07:03+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-08-08 22:37:27+01:00
log1440519239516f0b16a5cc7094aa3997f4b508f5
treee82d2826665e5d1116c73d57b41432aa63d46813
parent3d25a9c1e07cfcb72250760b2c1a1d9d4f6174ed

compiler: improve error reporting

The functions `Compilation.create` and `Compilation.update` previously returned inferred error sets, which had built up a lot of crap over time. This meant that certain error conditions -- particularly certain filesystem errors -- were not being reported properly (at best the CLI would just print the error name). This was also a problem in sub-compilations, where at times only the error name -- which might just be something like `LinkFailed` -- would be visible. This commit makes the error handling here more disciplined by introducing concrete error sets to these functions (and a few more as a consequence). These error sets are small: errors in `update` are almost all reported via compile errors, and errors in `create` are reported through a new `Compilation.CreateDiagnostic` type, a tagged union of possible error cases. This allows for better error reporting. Sub-compilations also report errors more correctly in several cases, leading to more informative errors in the case of compiler bugs. Also fixes some race conditions in library building by replacing calls to `setMiscFailure` with calls to `lockAndSetMiscFailure`. Compilation of libraries such as libc happens on the thread pool, so the logic must synchronize its access to shared `Compilation` state.

16 files changed, 647 insertions(+), 345 deletions(-)

lib/std/zig/LibCDirs.zig+2-2
...@@ -19,7 +19,7 @@ pub fn detect(...@@ -19,7 +19,7 @@ pub fn detect(
19 is_native_abi: bool,19 is_native_abi: bool,
20 link_libc: bool,20 link_libc: bool,
21 libc_installation: ?*const LibCInstallation,21 libc_installation: ?*const LibCInstallation,
22) !LibCDirs {22) LibCInstallation.FindError!LibCDirs {
23 if (!link_libc) {23 if (!link_libc) {
24 return .{24 return .{
25 .libc_include_dir_list = &[0][]u8{},25 .libc_include_dir_list = &[0][]u8{},
...@@ -114,7 +114,7 @@ fn detectFromInstallation(arena: Allocator, target: *const std.Target, lci: *con...@@ -114,7 +114,7 @@ fn detectFromInstallation(arena: Allocator, target: *const std.Target, lci: *con
114 }114 }
115 }115 }
116 if (target.os.tag == .haiku) {116 if (target.os.tag == .haiku) {
117 const include_dir_path = lci.include_dir orelse return error.LibCInstallationNotAvailable;117 const include_dir_path = lci.include_dir.?;
118 const os_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_path, "os" });118 const os_dir = try std.fs.path.join(arena, &[_][]const u8{ include_dir_path, "os" });
119 list.appendAssumeCapacity(os_dir);119 list.appendAssumeCapacity(os_dir);
120 // Errors.h120 // Errors.h
src/Compilation.zig+410-180
...@@ -1391,6 +1391,7 @@ pub const Win32Resource = struct {...@@ -1391,6 +1391,7 @@ pub const Win32Resource = struct {
1391};1391};
13921392
1393pub const MiscTask = enum {1393pub const MiscTask = enum {
1394 open_output,
1394 write_builtin_zig,1395 write_builtin_zig,
1395 rename_results,1396 rename_results,
1396 check_whole_cache,1397 check_whole_cache,
...@@ -1874,7 +1875,49 @@ fn addModuleTableToCacheHash(...@@ -1874,7 +1875,49 @@ fn addModuleTableToCacheHash(
18741875
1875const RtStrat = enum { none, lib, obj, zcu, dyn_lib };1876const RtStrat = enum { none, lib, obj, zcu, dyn_lib };
18761877
1877pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compilation {1878pub const CreateDiagnostic = union(enum) {
1879 export_table_import_table_conflict,
1880 emit_h_without_zcu,
1881 illegal_zig_import,
1882 cross_libc_unavailable,
1883 find_native_libc: std.zig.LibCInstallation.FindError,
1884 libc_installation_missing_crt_dir,
1885 create_cache_path: CreateCachePath,
1886 open_output_bin: link.File.OpenError,
1887 pub const CreateCachePath = struct {
1888 which: enum { local, global },
1889 sub: []const u8,
1890 err: (fs.Dir.MakeError || fs.Dir.OpenError || fs.Dir.StatFileError),
1891 };
1892 pub fn format(diag: CreateDiagnostic, w: *std.Io.Writer) std.Io.Writer.Error!void {
1893 switch (diag) {
1894 .export_table_import_table_conflict => try w.writeAll("'--import-table' and '--export-table' cannot be used together"),
1895 .emit_h_without_zcu => try w.writeAll("cannot emit C header with no Zig source files"),
1896 .illegal_zig_import => try w.writeAll("this compiler implementation does not support importing the root source file of a provided module"),
1897 .cross_libc_unavailable => try w.writeAll("unable to provide libc for this target"),
1898 .find_native_libc => |err| try w.print("failed to find libc installation: {t}", .{err}),
1899 .libc_installation_missing_crt_dir => try w.writeAll("libc installation is missing crt directory"),
1900 .create_cache_path => |cache| try w.print("failed to create path '{s}' in {t} cache directory: {t}", .{
1901 cache.sub,
1902 cache.which,
1903 cache.err,
1904 }),
1905 .open_output_bin => |err| try w.print("failed to open output binary: {t}", .{err}),
1906 }
1907 }
1908
1909 fn fail(out: *CreateDiagnostic, result: CreateDiagnostic) error{CreateFail} {
1910 out.* = result;
1911 return error.CreateFail;
1912 }
1913};
1914pub fn create(gpa: Allocator, arena: Allocator, diag: *CreateDiagnostic, options: CreateOptions) error{
1915 OutOfMemory,
1916 Unexpected,
1917 CurrentWorkingDirectoryUnlinked,
1918 /// An error has been stored to `diag`.
1919 CreateFail,
1920}!*Compilation {
1878 const output_mode = options.config.output_mode;1921 const output_mode = options.config.output_mode;
1879 const is_dyn_lib = switch (output_mode) {1922 const is_dyn_lib = switch (output_mode) {
1880 .Obj, .Exe => false,1923 .Obj, .Exe => false,
...@@ -1887,7 +1930,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1887,7 +1930,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1887 };1930 };
18881931
1889 if (options.linker_export_table and options.linker_import_table) {1932 if (options.linker_export_table and options.linker_import_table) {
1890 return error.ExportTableAndImportTableConflict;1933 return diag.fail(.export_table_import_table_conflict);
1891 }1934 }
18921935
1893 const have_zcu = options.config.have_zcu;1936 const have_zcu = options.config.have_zcu;
...@@ -1920,14 +1963,18 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1920,14 +1963,18 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
19201963
1921 const link_libc = options.config.link_libc;1964 const link_libc = options.config.link_libc;
19221965
1923 const libc_dirs = try std.zig.LibCDirs.detect(1966 const libc_dirs = std.zig.LibCDirs.detect(
1924 arena,1967 arena,
1925 options.dirs.zig_lib.path.?,1968 options.dirs.zig_lib.path.?,
1926 target,1969 target,
1927 options.root_mod.resolved_target.is_native_abi,1970 options.root_mod.resolved_target.is_native_abi,
1928 link_libc,1971 link_libc,
1929 options.libc_installation,1972 options.libc_installation,
1930 );1973 ) catch |err| switch (err) {
1974 error.OutOfMemory => |e| return e,
1975 // Every other error is specifically related to finding the native installation
1976 else => |e| return diag.fail(.{ .find_native_libc = e }),
1977 };
19311978
1932 const sysroot = options.sysroot orelse libc_dirs.sysroot;1979 const sysroot = options.sysroot orelse libc_dirs.sysroot;
19331980
...@@ -1949,7 +1996,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1949,7 +1996,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1949 if (compiler_rt_strat == .zcu) {1996 if (compiler_rt_strat == .zcu) {
1950 // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");`1997 // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");`
1951 // injected into the object.1998 // injected into the object.
1952 const compiler_rt_mod = try Package.Module.create(arena, .{1999 const compiler_rt_mod = Package.Module.create(arena, .{
1953 .paths = .{2000 .paths = .{
1954 .root = .zig_lib_root,2001 .root = .zig_lib_root,
1955 .root_src_path = "compiler_rt.zig",2002 .root_src_path = "compiler_rt.zig",
...@@ -1963,7 +2010,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1963,7 +2010,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1963 },2010 },
1964 .global = options.config,2011 .global = options.config,
1965 .parent = options.root_mod,2012 .parent = options.root_mod,
1966 });2013 }) catch |err| switch (err) {
2014 error.OutOfMemory => |e| return e,
2015 // None of these are possible because the configuration matches the root module
2016 // which already passed these checks.
2017 error.ValgrindUnsupportedOnTarget => unreachable,
2018 error.TargetRequiresSingleThreaded => unreachable,
2019 error.BackendRequiresSingleThreaded => unreachable,
2020 error.TargetRequiresPic => unreachable,
2021 error.PieRequiresPic => unreachable,
2022 error.DynamicLinkingRequiresPic => unreachable,
2023 error.TargetHasNoRedZone => unreachable,
2024 // These are not possible because are explicitly *not* requesting these things.
2025 error.StackCheckUnsupportedByTarget => unreachable,
2026 error.StackProtectorUnsupportedByTarget => unreachable,
2027 error.StackProtectorUnavailableWithoutLibC => unreachable,
2028 };
1967 try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod);2029 try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod);
1968 }2030 }
19692031
...@@ -1981,7 +2043,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1981,7 +2043,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1981 };2043 };
19822044
1983 if (ubsan_rt_strat == .zcu) {2045 if (ubsan_rt_strat == .zcu) {
1984 const ubsan_rt_mod = try Package.Module.create(arena, .{2046 const ubsan_rt_mod = Package.Module.create(arena, .{
1985 .paths = .{2047 .paths = .{
1986 .root = .zig_lib_root,2048 .root = .zig_lib_root,
1987 .root_src_path = "ubsan_rt.zig",2049 .root_src_path = "ubsan_rt.zig",
...@@ -1991,7 +2053,21 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1991,7 +2053,21 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1991 .inherited = .{},2053 .inherited = .{},
1992 .global = options.config,2054 .global = options.config,
1993 .parent = options.root_mod,2055 .parent = options.root_mod,
1994 });2056 }) catch |err| switch (err) {
2057 error.OutOfMemory => |e| return e,
2058 // None of these are possible because the configuration matches the root module
2059 // which already passed these checks.
2060 error.ValgrindUnsupportedOnTarget => unreachable,
2061 error.TargetRequiresSingleThreaded => unreachable,
2062 error.BackendRequiresSingleThreaded => unreachable,
2063 error.TargetRequiresPic => unreachable,
2064 error.PieRequiresPic => unreachable,
2065 error.DynamicLinkingRequiresPic => unreachable,
2066 error.TargetHasNoRedZone => unreachable,
2067 error.StackCheckUnsupportedByTarget => unreachable,
2068 error.StackProtectorUnsupportedByTarget => unreachable,
2069 error.StackProtectorUnavailableWithoutLibC => unreachable,
2070 };
1995 try options.root_mod.deps.putNoClobber(arena, "ubsan_rt", ubsan_rt_mod);2071 try options.root_mod.deps.putNoClobber(arena, "ubsan_rt", ubsan_rt_mod);
1996 }2072 }
19972073
...@@ -2019,7 +2095,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2019,7 +2095,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2019 const cache = try arena.create(Cache);2095 const cache = try arena.create(Cache);
2020 cache.* = .{2096 cache.* = .{
2021 .gpa = gpa,2097 .gpa = gpa,
2022 .manifest_dir = try options.dirs.local_cache.handle.makeOpenPath("h", .{}),2098 .manifest_dir = options.dirs.local_cache.handle.makeOpenPath("h", .{}) catch |err| {
2099 return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = "h", .err = err } });
2100 },
2023 };2101 };
2024 // These correspond to std.zig.Server.Message.PathPrefix.2102 // These correspond to std.zig.Server.Message.PathPrefix.
2025 cache.addPrefix(.{ .path = null, .handle = fs.cwd() });2103 cache.addPrefix(.{ .path = null, .handle = fs.cwd() });
...@@ -2067,20 +2145,24 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2067,20 +2145,24 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2067 // to redundantly happen for each AstGen operation.2145 // to redundantly happen for each AstGen operation.
2068 const zir_sub_dir = "z";2146 const zir_sub_dir = "z";
20692147
2070 var local_zir_dir = try options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{});2148 var local_zir_dir = options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| {
2149 return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = zir_sub_dir, .err = err } });
2150 };
2071 errdefer local_zir_dir.close();2151 errdefer local_zir_dir.close();
2072 const local_zir_cache: Cache.Directory = .{2152 const local_zir_cache: Cache.Directory = .{
2073 .handle = local_zir_dir,2153 .handle = local_zir_dir,
2074 .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}),2154 .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}),
2075 };2155 };
2076 var global_zir_dir = try options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{});2156 var global_zir_dir = options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}) catch |err| {
2157 return diag.fail(.{ .create_cache_path = .{ .which = .global, .sub = zir_sub_dir, .err = err } });
2158 };
2077 errdefer global_zir_dir.close();2159 errdefer global_zir_dir.close();
2078 const global_zir_cache: Cache.Directory = .{2160 const global_zir_cache: Cache.Directory = .{
2079 .handle = global_zir_dir,2161 .handle = global_zir_dir,
2080 .path = try options.dirs.global_cache.join(arena, &.{zir_sub_dir}),2162 .path = try options.dirs.global_cache.join(arena, &.{zir_sub_dir}),
2081 };2163 };
20822164
2083 const std_mod = options.std_mod orelse try Package.Module.create(arena, .{2165 const std_mod = options.std_mod orelse Package.Module.create(arena, .{
2084 .paths = .{2166 .paths = .{
2085 .root = try .fromRoot(arena, options.dirs, .zig_lib, "std"),2167 .root = try .fromRoot(arena, options.dirs, .zig_lib, "std"),
2086 .root_src_path = "std.zig",2168 .root_src_path = "std.zig",
...@@ -2090,7 +2172,21 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2090,7 +2172,21 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2090 .inherited = .{},2172 .inherited = .{},
2091 .global = options.config,2173 .global = options.config,
2092 .parent = options.root_mod,2174 .parent = options.root_mod,
2093 });2175 }) catch |err| return switch (err) {
2176 error.OutOfMemory => |e| return e,
2177 // None of these are possible because the configuration matches the root module
2178 // which already passed these checks.
2179 error.ValgrindUnsupportedOnTarget => unreachable,
2180 error.TargetRequiresSingleThreaded => unreachable,
2181 error.BackendRequiresSingleThreaded => unreachable,
2182 error.TargetRequiresPic => unreachable,
2183 error.PieRequiresPic => unreachable,
2184 error.DynamicLinkingRequiresPic => unreachable,
2185 error.TargetHasNoRedZone => unreachable,
2186 error.StackCheckUnsupportedByTarget => unreachable,
2187 error.StackProtectorUnsupportedByTarget => unreachable,
2188 error.StackProtectorUnavailableWithoutLibC => unreachable,
2189 };
20942190
2095 const zcu = try arena.create(Zcu);2191 const zcu = try arena.create(Zcu);
2096 zcu.* = .{2192 zcu.* = .{
...@@ -2109,7 +2205,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2109,7 +2205,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2109 try zcu.init(options.thread_pool.getIdCount());2205 try zcu.init(options.thread_pool.getIdCount());
2110 break :blk zcu;2206 break :blk zcu;
2111 } else blk: {2207 } else blk: {
2112 if (options.emit_h != .no) return error.NoZigModuleForCHeader;2208 if (options.emit_h != .no) return diag.fail(.emit_h_without_zcu);
2113 break :blk null;2209 break :blk null;
2114 };2210 };
2115 errdefer if (opt_zcu) |zcu| zcu.deinit();2211 errdefer if (opt_zcu) |zcu| zcu.deinit();
...@@ -2204,7 +2300,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2204,7 +2300,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2204 // Populate `zcu.module_roots`.2300 // Populate `zcu.module_roots`.
2205 const pt: Zcu.PerThread = .activate(zcu, .main);2301 const pt: Zcu.PerThread = .activate(zcu, .main);
2206 defer pt.deactivate();2302 defer pt.deactivate();
2207 try pt.populateModuleRootTable();2303 pt.populateModuleRootTable() catch |err| switch (err) {
2304 error.OutOfMemory => |e| return e,
2305 error.IllegalZigImport => return diag.fail(.illegal_zig_import),
2306 };
2208 }2307 }
22092308
2210 const lf_open_opts: link.File.OpenOptions = .{2309 const lf_open_opts: link.File.OpenOptions = .{
...@@ -2279,10 +2378,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2279,10 +2378,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2279 none.* = .{ .tmp_artifact_directory = null };2378 none.* = .{ .tmp_artifact_directory = null };
2280 comp.cache_use = .{ .none = none };2379 comp.cache_use = .{ .none = none };
2281 if (comp.emit_bin) |path| {2380 if (comp.emit_bin) |path| {
2282 comp.bin_file = try link.File.open(arena, comp, .{2381 comp.bin_file = link.File.open(arena, comp, .{
2283 .root_dir = .cwd(),2382 .root_dir = .cwd(),
2284 .sub_path = path,2383 .sub_path = path,
2285 }, lf_open_opts);2384 }, lf_open_opts) catch |err| {
2385 return diag.fail(.{ .open_output_bin = err });
2386 };
2286 }2387 }
2287 },2388 },
2288 .incremental => {2389 .incremental => {
...@@ -2320,7 +2421,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2320,7 +2421,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2320 const digest = hash.final();2421 const digest = hash.final();
23212422
2322 const artifact_sub_dir = "o" ++ fs.path.sep_str ++ digest;2423 const artifact_sub_dir = "o" ++ fs.path.sep_str ++ digest;
2323 var artifact_dir = try options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{});2424 var artifact_dir = options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}) catch |err| {
2425 return diag.fail(.{ .create_cache_path = .{ .which = .local, .sub = artifact_sub_dir, .err = err } });
2426 };
2324 errdefer artifact_dir.close();2427 errdefer artifact_dir.close();
2325 const artifact_directory: Cache.Directory = .{2428 const artifact_directory: Cache.Directory = .{
2326 .handle = artifact_dir,2429 .handle = artifact_dir,
...@@ -2338,7 +2441,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2338,7 +2441,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2338 .root_dir = artifact_directory,2441 .root_dir = artifact_directory,
2339 .sub_path = cache_rel_path,2442 .sub_path = cache_rel_path,
2340 };2443 };
2341 comp.bin_file = try link.File.open(arena, comp, emit, lf_open_opts);2444 comp.bin_file = link.File.open(arena, comp, emit, lf_open_opts) catch |err| {
2445 return diag.fail(.{ .open_output_bin = err });
2446 };
2342 }2447 }
2343 },2448 },
2344 .whole => {2449 .whole => {
...@@ -2433,7 +2538,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2433,7 +2538,10 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2433 .link_mode = comp.config.link_mode,2538 .link_mode = comp.config.link_mode,
2434 .pie = comp.config.pie,2539 .pie = comp.config.pie,
2435 });2540 });
2436 const paths = try lci.resolveCrtPaths(arena, basenames, target);2541 const paths = lci.resolveCrtPaths(arena, basenames, target) catch |err| switch (err) {
2542 error.OutOfMemory => |e| return e,
2543 error.LibCInstallationMissingCrtDir => return diag.fail(.libc_installation_missing_crt_dir),
2544 };
24372545
2438 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;2546 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;
2439 try comp.link_task_queue.queued_prelink.ensureUnusedCapacity(gpa, fields.len + 1);2547 try comp.link_task_queue.queued_prelink.ensureUnusedCapacity(gpa, fields.len + 1);
...@@ -2445,7 +2553,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2445,7 +2553,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2445 // Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.2553 // Loads the libraries provided by `target_util.libcFullLinkFlags(target)`.
2446 comp.link_task_queue.queued_prelink.appendAssumeCapacity(.load_host_libc);2554 comp.link_task_queue.queued_prelink.appendAssumeCapacity(.load_host_libc);
2447 } else if (target.isMuslLibC()) {2555 } else if (target.isMuslLibC()) {
2448 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2556 if (!std.zig.target.canBuildLibC(target)) return diag.fail(.cross_libc_unavailable);
24492557
2450 if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| {2558 if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| {
2451 comp.queued_jobs.musl_crt_file[@intFromEnum(f)] = true;2559 comp.queued_jobs.musl_crt_file[@intFromEnum(f)] = true;
...@@ -2455,7 +2563,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2455,7 +2563,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2455 .dynamic => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_so)] = true,2563 .dynamic => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_so)] = true,
2456 }2564 }
2457 } else if (target.isGnuLibC()) {2565 } else if (target.isGnuLibC()) {
2458 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2566 if (!std.zig.target.canBuildLibC(target)) return diag.fail(.cross_libc_unavailable);
24592567
2460 if (glibc.needsCrt0(comp.config.output_mode)) |f| {2568 if (glibc.needsCrt0(comp.config.output_mode)) |f| {
2461 comp.queued_jobs.glibc_crt_file[@intFromEnum(f)] = true;2569 comp.queued_jobs.glibc_crt_file[@intFromEnum(f)] = true;
...@@ -2464,7 +2572,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2464,7 +2572,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24642572
2465 comp.queued_jobs.glibc_crt_file[@intFromEnum(glibc.CrtFile.libc_nonshared_a)] = true;2573 comp.queued_jobs.glibc_crt_file[@intFromEnum(glibc.CrtFile.libc_nonshared_a)] = true;
2466 } else if (target.isFreeBSDLibC()) {2574 } else if (target.isFreeBSDLibC()) {
2467 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2575 if (!std.zig.target.canBuildLibC(target)) return diag.fail(.cross_libc_unavailable);
24682576
2469 if (freebsd.needsCrt0(comp.config.output_mode)) |f| {2577 if (freebsd.needsCrt0(comp.config.output_mode)) |f| {
2470 comp.queued_jobs.freebsd_crt_file[@intFromEnum(f)] = true;2578 comp.queued_jobs.freebsd_crt_file[@intFromEnum(f)] = true;
...@@ -2472,7 +2580,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2472,7 +2580,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24722580
2473 comp.queued_jobs.freebsd_shared_objects = true;2581 comp.queued_jobs.freebsd_shared_objects = true;
2474 } else if (target.isNetBSDLibC()) {2582 } else if (target.isNetBSDLibC()) {
2475 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2583 if (!std.zig.target.canBuildLibC(target)) return diag.fail(.cross_libc_unavailable);
24762584
2477 if (netbsd.needsCrt0(comp.config.output_mode)) |f| {2585 if (netbsd.needsCrt0(comp.config.output_mode)) |f| {
2478 comp.queued_jobs.netbsd_crt_file[@intFromEnum(f)] = true;2586 comp.queued_jobs.netbsd_crt_file[@intFromEnum(f)] = true;
...@@ -2480,12 +2588,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2480,12 +2588,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24802588
2481 comp.queued_jobs.netbsd_shared_objects = true;2589 comp.queued_jobs.netbsd_shared_objects = true;
2482 } else if (target.isWasiLibC()) {2590 } else if (target.isWasiLibC()) {
2483 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2591 if (!std.zig.target.canBuildLibC(target)) return diag.fail(.cross_libc_unavailable);
24842592
2485 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.execModelCrtFile(comp.config.wasi_exec_model))] = true;2593 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.execModelCrtFile(comp.config.wasi_exec_model))] = true;
2486 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.CrtFile.libc_a)] = true;2594 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(wasi_libc.CrtFile.libc_a)] = true;
2487 } else if (target.isMinGW()) {2595 } else if (target.isMinGW()) {
2488 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;2596 if (!std.zig.target.canBuildLibC(target)) return diag.fail(.cross_libc_unavailable);
24892597
2490 const main_crt_file: mingw.CrtFile = if (is_dyn_lib) .dllcrt2_o else .crt2_o;2598 const main_crt_file: mingw.CrtFile = if (is_dyn_lib) .dllcrt2_o else .crt2_o;
2491 comp.queued_jobs.mingw_crt_file[@intFromEnum(main_crt_file)] = true;2599 comp.queued_jobs.mingw_crt_file[@intFromEnum(main_crt_file)] = true;
...@@ -2495,7 +2603,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -2495,7 +2603,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
2495 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);2603 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
2496 for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {});2604 for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {});
2497 } else {2605 } else {
2498 return error.LibCUnavailable;2606 return diag.fail(.cross_libc_unavailable);
2499 }2607 }
25002608
2501 if ((target.isMuslLibC() and comp.config.link_mode == .static) or2609 if ((target.isMuslLibC() and comp.config.link_mode == .static) or
...@@ -2737,8 +2845,14 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void {...@@ -2737,8 +2845,14 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void {
2737 }2845 }
2738}2846}
27392847
2848pub const UpdateError = error{
2849 OutOfMemory,
2850 Unexpected,
2851 CurrentWorkingDirectoryUnlinked,
2852};
2853
2740/// Detect changes to source files, perform semantic analysis, and update the output files.2854/// Detect changes to source files, perform semantic analysis, and update the output files.
2741pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {2855pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateError!void {
2742 const tracy_trace = trace(@src());2856 const tracy_trace = trace(@src());
2743 defer tracy_trace.end();2857 defer tracy_trace.end();
27442858
...@@ -2769,10 +2883,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2769,10 +2883,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2769 tmp_dir_rand_int = std.crypto.random.int(u64);2883 tmp_dir_rand_int = std.crypto.random.int(u64);
2770 const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);2884 const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);
2771 const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path});2885 const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path});
2772 break :d .{2886 const handle = comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}) catch |err| {
2773 .path = path,2887 return comp.setMiscFailure(.open_output, "failed to create output directory '{s}': {t}", .{ path, err });
2774 .handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}),
2775 };2888 };
2889 break :d .{ .path = path, .handle = handle };
2776 };2890 };
2777 },2891 },
2778 .incremental => {},2892 .incremental => {},
...@@ -2849,17 +2963,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2849,17 +2963,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2849 tmp_dir_rand_int = std.crypto.random.int(u64);2963 tmp_dir_rand_int = std.crypto.random.int(u64);
2850 const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);2964 const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int);
2851 const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path});2965 const path = try comp.dirs.local_cache.join(arena, &.{tmp_dir_sub_path});
2852 break :d .{2966 const handle = comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}) catch |err| {
2853 .path = path,2967 return comp.setMiscFailure(.open_output, "failed to create output directory '{s}': {t}", .{ path, err });
2854 .handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}),
2855 };2968 };
2969 break :d .{ .path = path, .handle = handle };
2856 };2970 };
2857 if (comp.emit_bin) |sub_path| {2971 if (comp.emit_bin) |sub_path| {
2858 const emit: Cache.Path = .{2972 const emit: Cache.Path = .{
2859 .root_dir = whole.tmp_artifact_directory.?,2973 .root_dir = whole.tmp_artifact_directory.?,
2860 .sub_path = sub_path,2974 .sub_path = sub_path,
2861 };2975 };
2862 comp.bin_file = try link.File.createEmpty(arena, comp, emit, whole.lf_open_opts);2976 comp.bin_file = link.File.createEmpty(arena, comp, emit, whole.lf_open_opts) catch |err| {
2977 return comp.setMiscFailure(.open_output, "failed to open output file '{f}': {t}", .{ emit, err });
2978 };
2863 }2979 }
2864 },2980 },
2865 }2981 }
...@@ -3036,11 +3152,11 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -3036,11 +3152,11 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
3036 renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| {3152 renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| {
3037 return comp.setMiscFailure(3153 return comp.setMiscFailure(
3038 .rename_results,3154 .rename_results,
3039 "failed to rename compilation results ('{f}{s}') into local cache ('{f}{s}'): {s}",3155 "failed to rename compilation results ('{f}{s}') into local cache ('{f}{s}'): {t}",
3040 .{3156 .{
3041 comp.dirs.local_cache, tmp_dir_sub_path,3157 comp.dirs.local_cache, tmp_dir_sub_path,
3042 comp.dirs.local_cache, o_sub_path,3158 comp.dirs.local_cache, o_sub_path,
3043 @errorName(err),3159 err,
3044 },3160 },
3045 );3161 );
3046 };3162 };
...@@ -3054,15 +3170,21 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -3054,15 +3170,21 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
3054 .root_dir = comp.dirs.local_cache,3170 .root_dir = comp.dirs.local_cache,
3055 .sub_path = try fs.path.join(arena, &.{ o_sub_path, comp.emit_bin.? }),3171 .sub_path = try fs.path.join(arena, &.{ o_sub_path, comp.emit_bin.? }),
3056 };3172 };
30573173 const result: link.File.OpenError!void = switch (need_writable_dance) {
3058 switch (need_writable_dance) {
3059 .no => {},3174 .no => {},
3060 .lf_only => try lf.makeWritable(),3175 .lf_only => lf.makeWritable(),
3061 .lf_and_debug => {3176 .lf_and_debug => res: {
3062 try lf.makeWritable();3177 lf.makeWritable() catch |err| break :res err;
3063 try lf.reopenDebugInfo();3178 lf.reopenDebugInfo() catch |err| break :res err;
3064 },3179 },
3065 }3180 };
3181 result catch |err| {
3182 return comp.setMiscFailure(
3183 .rename_results,
3184 "failed to re-open renamed compilation results ('{f}{s}'): {t}",
3185 .{ comp.dirs.local_cache, o_sub_path, err },
3186 );
3187 };
3066 }3188 }
30673189
3068 try flush(comp, arena, .main);3190 try flush(comp, arena, .main);
...@@ -3155,7 +3277,7 @@ fn flush(...@@ -3155,7 +3277,7 @@ fn flush(
3155 comp: *Compilation,3277 comp: *Compilation,
3156 arena: Allocator,3278 arena: Allocator,
3157 tid: Zcu.PerThread.Id,3279 tid: Zcu.PerThread.Id,
3158) !void {3280) Allocator.Error!void {
3159 if (comp.zcu) |zcu| {3281 if (comp.zcu) |zcu| {
3160 if (zcu.llvm_object) |llvm_object| {3282 if (zcu.llvm_object) |llvm_object| {
3161 const pt: Zcu.PerThread = .activate(zcu, tid);3283 const pt: Zcu.PerThread = .activate(zcu, tid);
...@@ -3173,7 +3295,7 @@ fn flush(...@@ -3173,7 +3295,7 @@ fn flush(
3173 comp.time_report.?.stats.real_ns_llvm_emit = ns;3295 comp.time_report.?.stats.real_ns_llvm_emit = ns;
3174 };3296 };
31753297
3176 try llvm_object.emit(pt, .{3298 llvm_object.emit(pt, .{
3177 .pre_ir_path = comp.verbose_llvm_ir,3299 .pre_ir_path = comp.verbose_llvm_ir,
3178 .pre_bc_path = comp.verbose_llvm_bc,3300 .pre_bc_path = comp.verbose_llvm_bc,
31793301
...@@ -3204,7 +3326,10 @@ fn flush(...@@ -3204,7 +3326,10 @@ fn flush(
3204 .sanitize_thread = comp.config.any_sanitize_thread,3326 .sanitize_thread = comp.config.any_sanitize_thread,
3205 .fuzz = comp.config.any_fuzz,3327 .fuzz = comp.config.any_fuzz,
3206 .lto = comp.config.lto,3328 .lto = comp.config.lto,
3207 });3329 }) catch |err| switch (err) {
3330 error.LinkFailure => {}, // Already reported.
3331 error.OutOfMemory => return error.OutOfMemory,
3332 };
3208 }3333 }
3209 }3334 }
3210 if (comp.bin_file) |lf| {3335 if (comp.bin_file) |lf| {
...@@ -3746,7 +3871,7 @@ fn addBuf(list: *std.ArrayList([]const u8), buf: []const u8) void {...@@ -3746,7 +3871,7 @@ fn addBuf(list: *std.ArrayList([]const u8), buf: []const u8) void {
3746}3871}
37473872
3748/// This function is temporally single-threaded.3873/// This function is temporally single-threaded.
3749pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {3874pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
3750 const gpa = comp.gpa;3875 const gpa = comp.gpa;
37513876
3752 var bundle: ErrorBundle.Wip = undefined;3877 var bundle: ErrorBundle.Wip = undefined;
...@@ -3796,8 +3921,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3796,8 +3921,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3796 for (zcu.failed_imports.items) |failed| {3921 for (zcu.failed_imports.items) |failed| {
3797 assert(zcu.alive_files.contains(failed.file_index)); // otherwise it wouldn't have been added3922 assert(zcu.alive_files.contains(failed.file_index)); // otherwise it wouldn't have been added
3798 const file = zcu.fileByIndex(failed.file_index);3923 const file = zcu.fileByIndex(failed.file_index);
3799 const source = try file.getSource(zcu);3924 const source = file.getSource(zcu) catch |err| {
3800 const tree = try file.getTree(zcu);3925 try unableToLoadZcuFile(zcu, &bundle, file, err);
3926 continue;
3927 };
3928 const tree = file.getTree(zcu) catch |err| {
3929 try unableToLoadZcuFile(zcu, &bundle, file, err);
3930 continue;
3931 };
3801 const start = tree.tokenStart(failed.import_token);3932 const start = tree.tokenStart(failed.import_token);
3802 const end = start + tree.tokenSlice(failed.import_token).len;3933 const end = start + tree.tokenSlice(failed.import_token).len;
3803 const loc = std.zig.findLineColumn(source.bytes, start);3934 const loc = std.zig.findLineColumn(source.bytes, start);
...@@ -3853,7 +3984,11 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3853,7 +3984,11 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3853 } else {3984 } else {
3854 assert(!is_retryable);3985 assert(!is_retryable);
3855 // AstGen/ZoirGen succeeded with errors. Note that this may include AST errors.3986 // AstGen/ZoirGen succeeded with errors. Note that this may include AST errors.
3856 _ = try file.getTree(zcu); // Tree must be loaded.3987 // Tree must be loaded.
3988 _ = file.getTree(zcu) catch |err| {
3989 try unableToLoadZcuFile(zcu, &bundle, file, err);
3990 continue;
3991 };
3857 const path = try std.fmt.allocPrint(gpa, "{f}", .{file.path.fmt(comp)});3992 const path = try std.fmt.allocPrint(gpa, "{f}", .{file.path.fmt(comp)});
3858 defer gpa.free(path);3993 defer gpa.free(path);
3859 if (file.zir != null) {3994 if (file.zir != null) {
...@@ -3871,16 +4006,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3871,16 +4006,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3871 const SortOrder = struct {4006 const SortOrder = struct {
3872 zcu: *Zcu,4007 zcu: *Zcu,
3873 errors: []const *Zcu.ErrorMsg,4008 errors: []const *Zcu.ErrorMsg,
3874 err: *?Error,4009 read_err: *?ReadError,
38754010 const ReadError = struct {
3876 const Error = @typeInfo(4011 file: *Zcu.File,
3877 @typeInfo(@TypeOf(Zcu.LazySrcLoc.lessThan)).@"fn".return_type.?,4012 err: Zcu.File.GetSourceError,
3878 ).error_union.error_set;4013 };
3879
3880 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {4014 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
3881 if (ctx.err.* != null) return lhs_index < rhs_index;4015 if (ctx.read_err.* != null) return lhs_index < rhs_index;
3882 return ctx.errors[lhs_index].src_loc.lessThan(ctx.errors[rhs_index].src_loc, ctx.zcu) catch |e| {4016 var bad_file: *Zcu.File = undefined;
3883 ctx.err.* = e;4017 return ctx.errors[lhs_index].src_loc.lessThan(ctx.errors[rhs_index].src_loc, ctx.zcu, &bad_file) catch |err| {
4018 ctx.read_err.* = .{
4019 .file = bad_file,
4020 .err = err,
4021 };
3884 return lhs_index < rhs_index;4022 return lhs_index < rhs_index;
3885 };4023 };
3886 }4024 }
...@@ -3892,13 +4030,16 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3892,13 +4030,16 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3892 var entries = try zcu.failed_analysis.entries.clone(gpa);4030 var entries = try zcu.failed_analysis.entries.clone(gpa);
3893 errdefer entries.deinit(gpa);4031 errdefer entries.deinit(gpa);
38944032
3895 var err: ?SortOrder.Error = null;4033 var read_err: ?SortOrder.ReadError = null;
3896 entries.sort(SortOrder{4034 entries.sort(SortOrder{
3897 .zcu = zcu,4035 .zcu = zcu,
3898 .errors = entries.items(.value),4036 .errors = entries.items(.value),
3899 .err = &err,4037 .read_err = &read_err,
3900 });4038 });
3901 if (err) |e| return e;4039 if (read_err) |e| {
4040 try unableToLoadZcuFile(zcu, &bundle, e.file, e.err);
4041 break :zcu_errors;
4042 }
3902 break :s entries.slice();4043 break :s entries.slice();
3903 };4044 };
3904 defer sorted_failed_analysis.deinit(gpa);4045 defer sorted_failed_analysis.deinit(gpa);
...@@ -4018,23 +4159,33 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -4018,23 +4159,33 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
40184159
4019 // Okay, there *are* referenced compile logs. Sort them into a consistent order.4160 // Okay, there *are* referenced compile logs. Sort them into a consistent order.
40204161
4021 const SortContext = struct {4162 {
4022 err: *?Error,4163 const SortContext = struct {
4023 zcu: *Zcu,4164 zcu: *Zcu,
4024 const Error = @typeInfo(4165 read_err: *?ReadError,
4025 @typeInfo(@TypeOf(Zcu.LazySrcLoc.lessThan)).@"fn".return_type.?,4166 const ReadError = struct {
4026 ).error_union.error_set;4167 file: *Zcu.File,
4027 fn lessThan(ctx: @This(), lhs: Zcu.ErrorMsg, rhs: Zcu.ErrorMsg) bool {4168 err: Zcu.File.GetSourceError,
4028 if (ctx.err.* != null) return false;
4029 return lhs.src_loc.lessThan(rhs.src_loc, ctx.zcu) catch |e| {
4030 ctx.err.* = e;
4031 return false;
4032 };4169 };
4170 fn lessThan(ctx: @This(), lhs: Zcu.ErrorMsg, rhs: Zcu.ErrorMsg) bool {
4171 if (ctx.read_err.* != null) return false;
4172 var bad_file: *Zcu.File = undefined;
4173 return lhs.src_loc.lessThan(rhs.src_loc, ctx.zcu, &bad_file) catch |err| {
4174 ctx.read_err.* = .{
4175 .file = bad_file,
4176 .err = err,
4177 };
4178 return false;
4179 };
4180 }
4181 };
4182 var read_err: ?SortContext.ReadError = null;
4183 std.mem.sort(Zcu.ErrorMsg, messages.items, @as(SortContext, .{ .read_err = &read_err, .zcu = zcu }), SortContext.lessThan);
4184 if (read_err) |e| {
4185 try unableToLoadZcuFile(zcu, &bundle, e.file, e.err);
4186 break :compile_log_text "";
4033 }4187 }
4034 };4188 }
4035 var sort_err: ?SortContext.Error = null;
4036 std.mem.sort(Zcu.ErrorMsg, messages.items, @as(SortContext, .{ .err = &sort_err, .zcu = zcu }), SortContext.lessThan);
4037 if (sort_err) |e| return e;
40384189
4039 var log_text: std.ArrayListUnmanaged(u8) = .empty;4190 var log_text: std.ArrayListUnmanaged(u8) = .empty;
4040 defer log_text.deinit(gpa);4191 defer log_text.deinit(gpa);
...@@ -4068,18 +4219,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -4068,18 +4219,19 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
4068 // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error.4219 // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error.
4069 // However, we haven't reported any such error.4220 // However, we haven't reported any such error.
4070 // This is a compiler bug.4221 // This is a compiler bug.
4071 var stderr_w = std.debug.lockStderrWriter(&.{});4222 print_ctx: {
4072 defer std.debug.unlockStderrWriter();4223 var stderr_w = std.debug.lockStderrWriter(&.{});
4073 try stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n");4224 defer std.debug.unlockStderrWriter();
4074 try stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)});4225 stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx;
4075 while (ref) |r| {4226 stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx;
4076 try stderr_w.print("referenced by: {f}{s}\n", .{4227 while (ref) |r| {
4077 zcu.fmtAnalUnit(r.referencer),4228 stderr_w.print("referenced by: {f}{s}\n", .{
4078 if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "",4229 zcu.fmtAnalUnit(r.referencer),
4079 });4230 if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "",
4080 ref = refs.get(r.referencer).?;4231 }) catch break :print_ctx;
4232 ref = refs.get(r.referencer).?;
4233 }
4081 }4234 }
4082
4083 @panic("referenced transitive analysis errors, but none actually emitted");4235 @panic("referenced transitive analysis errors, but none actually emitted");
4084 }4236 }
4085 };4237 };
...@@ -4166,19 +4318,16 @@ pub fn addModuleErrorMsg(...@@ -4166,19 +4318,16 @@ pub fn addModuleErrorMsg(
4166 /// If `-freference-trace` is not specified, we only want to show the one reference trace.4318 /// If `-freference-trace` is not specified, we only want to show the one reference trace.
4167 /// So, this is whether we have already emitted an error with a reference trace.4319 /// So, this is whether we have already emitted an error with a reference trace.
4168 already_added_error: bool,4320 already_added_error: bool,
4169) !void {4321) Allocator.Error!void {
4170 const gpa = eb.gpa;4322 const gpa = eb.gpa;
4171 const ip = &zcu.intern_pool;4323 const ip = &zcu.intern_pool;
4172 const err_src_loc = module_err_msg.src_loc.upgrade(zcu);4324 const err_src_loc = module_err_msg.src_loc.upgrade(zcu);
4173 const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| {4325 const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| {
4174 try eb.addRootErrorMessage(.{4326 return unableToLoadZcuFile(zcu, eb, err_src_loc.file_scope, err);
4175 .msg = try eb.printString("unable to load '{f}': {s}", .{4327 };
4176 err_src_loc.file_scope.path.fmt(zcu.comp), @errorName(err),4328 const err_span = err_src_loc.span(zcu) catch |err| {
4177 }),4329 return unableToLoadZcuFile(zcu, eb, err_src_loc.file_scope, err);
4178 });
4179 return;
4180 };4330 };
4181 const err_span = try err_src_loc.span(zcu);
4182 const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main);4331 const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main);
41834332
4184 var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;4333 var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;
...@@ -4208,7 +4357,13 @@ pub fn addModuleErrorMsg(...@@ -4208,7 +4357,13 @@ pub fn addModuleErrorMsg(
4208 const f = inline_frame.ptr(zcu).*;4357 const f = inline_frame.ptr(zcu).*;
4209 const func_nav = ip.indexToKey(f.callee).func.owner_nav;4358 const func_nav = ip.indexToKey(f.callee).func.owner_nav;
4210 const func_name = ip.getNav(func_nav).name.toSlice(ip);4359 const func_name = ip.getNav(func_nav).name.toSlice(ip);
4211 try addReferenceTraceFrame(zcu, eb, &ref_traces, func_name, last_call_src, true);4360 addReferenceTraceFrame(zcu, eb, &ref_traces, func_name, last_call_src, true) catch |err| switch (err) {
4361 error.OutOfMemory => |e| return e,
4362 error.AlreadyReported => {
4363 // An incomplete reference trace isn't the end of the world; just cut it off.
4364 break :rt;
4365 },
4366 };
4212 last_call_src = f.call_src;4367 last_call_src = f.call_src;
4213 opt_inline_frame = f.parent;4368 opt_inline_frame = f.parent;
4214 }4369 }
...@@ -4220,7 +4375,13 @@ pub fn addModuleErrorMsg(...@@ -4220,7 +4375,13 @@ pub fn addModuleErrorMsg(
4220 .memoized_state => null,4375 .memoized_state => null,
4221 };4376 };
4222 if (root_name) |n| {4377 if (root_name) |n| {
4223 try addReferenceTraceFrame(zcu, eb, &ref_traces, n, last_call_src, false);4378 addReferenceTraceFrame(zcu, eb, &ref_traces, n, last_call_src, false) catch |err| switch (err) {
4379 error.OutOfMemory => |e| return e,
4380 error.AlreadyReported => {
4381 // An incomplete reference trace isn't the end of the world; just cut it off.
4382 break :rt;
4383 },
4384 };
4224 }4385 }
4225 }4386 }
4226 referenced_by = ref.referencer;4387 referenced_by = ref.referencer;
...@@ -4257,8 +4418,12 @@ pub fn addModuleErrorMsg(...@@ -4257,8 +4418,12 @@ pub fn addModuleErrorMsg(
4257 var last_note_loc: ?std.zig.Loc = null;4418 var last_note_loc: ?std.zig.Loc = null;
4258 for (module_err_msg.notes) |module_note| {4419 for (module_err_msg.notes) |module_note| {
4259 const note_src_loc = module_note.src_loc.upgrade(zcu);4420 const note_src_loc = module_note.src_loc.upgrade(zcu);
4260 const source = try note_src_loc.file_scope.getSource(zcu);4421 const source = note_src_loc.file_scope.getSource(zcu) catch |err| {
4261 const span = try note_src_loc.span(zcu);4422 return unableToLoadZcuFile(zcu, eb, note_src_loc.file_scope, err);
4423 };
4424 const span = note_src_loc.span(zcu) catch |err| {
4425 return unableToLoadZcuFile(zcu, eb, note_src_loc.file_scope, err);
4426 };
4262 const loc = std.zig.findLineColumn(source.bytes, span.main);4427 const loc = std.zig.findLineColumn(source.bytes, span.main);
42634428
4264 const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?));4429 const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?));
...@@ -4303,11 +4468,17 @@ fn addReferenceTraceFrame(...@@ -4303,11 +4468,17 @@ fn addReferenceTraceFrame(
4303 name: []const u8,4468 name: []const u8,
4304 lazy_src: Zcu.LazySrcLoc,4469 lazy_src: Zcu.LazySrcLoc,
4305 inlined: bool,4470 inlined: bool,
4306) !void {4471) error{ OutOfMemory, AlreadyReported }!void {
4307 const gpa = zcu.gpa;4472 const gpa = zcu.gpa;
4308 const src = lazy_src.upgrade(zcu);4473 const src = lazy_src.upgrade(zcu);
4309 const source = try src.file_scope.getSource(zcu);4474 const source = src.file_scope.getSource(zcu) catch |err| {
4310 const span = try src.span(zcu);4475 try unableToLoadZcuFile(zcu, eb, src.file_scope, err);
4476 return error.AlreadyReported;
4477 };
4478 const span = src.span(zcu) catch |err| {
4479 try unableToLoadZcuFile(zcu, eb, src.file_scope, err);
4480 return error.AlreadyReported;
4481 };
4311 const loc = std.zig.findLineColumn(source.bytes, span.main);4482 const loc = std.zig.findLineColumn(source.bytes, span.main);
4312 try ref_traces.append(gpa, .{4483 try ref_traces.append(gpa, .{
4313 .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }),4484 .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }),
...@@ -4323,19 +4494,26 @@ fn addReferenceTraceFrame(...@@ -4323,19 +4494,26 @@ fn addReferenceTraceFrame(
4323 });4494 });
4324}4495}
43254496
4326pub fn addWholeFileError(4497fn addWholeFileError(
4327 zcu: *Zcu,4498 zcu: *Zcu,
4328 eb: *ErrorBundle.Wip,4499 eb: *ErrorBundle.Wip,
4329 file_index: Zcu.File.Index,4500 file_index: Zcu.File.Index,
4330 msg: []const u8,4501 msg: []const u8,
4331) !void {4502) Allocator.Error!void {
4332 // note: "file imported here" on the import reference token4503 // note: "file imported here" on the import reference token
4333 const imported_note: ?ErrorBundle.MessageIndex = switch (zcu.alive_files.get(file_index).?) {4504 const imported_note: ?ErrorBundle.MessageIndex = switch (zcu.alive_files.get(file_index).?) {
4334 .analysis_root => null,4505 .analysis_root => null,
4335 .import => |import| try eb.addErrorMessage(.{4506 .import => |import| note: {
4336 .msg = try eb.addString("file imported here"),4507 const file = zcu.fileByIndex(import.importer);
4337 .src_loc = try zcu.fileByIndex(import.importer).errorBundleTokenSrc(import.tok, zcu, eb),4508 // `errorBundleTokenSrc` expects the tree to be loaded
4338 }),4509 _ = file.getTree(zcu) catch |err| {
4510 return unableToLoadZcuFile(zcu, eb, file, err);
4511 };
4512 break :note try eb.addErrorMessage(.{
4513 .msg = try eb.addString("file imported here"),
4514 .src_loc = try file.errorBundleTokenSrc(import.tok, zcu, eb),
4515 });
4516 },
4339 };4517 };
43404518
4341 try eb.addRootErrorMessage(.{4519 try eb.addRootErrorMessage(.{
...@@ -4349,6 +4527,20 @@ pub fn addWholeFileError(...@@ -4349,6 +4527,20 @@ pub fn addWholeFileError(
4349 }4527 }
4350}4528}
43514529
4530/// Adds an error to `eb` that the contents of `file` could not be loaded due to `err`. This is
4531/// useful if `Zcu.File.getSource`/`Zcu.File.getTree` fails while lowering compile errors.
4532pub fn unableToLoadZcuFile(
4533 zcu: *const Zcu,
4534 eb: *ErrorBundle.Wip,
4535 file: *Zcu.File,
4536 err: Zcu.File.GetSourceError,
4537) Allocator.Error!void {
4538 try eb.addRootErrorMessage(.{
4539 .msg = try eb.printString("unable to load: {t}", .{err}),
4540 .src_loc = try file.errorBundleWholeFileSrc(zcu, eb),
4541 });
4542}
4543
4352fn performAllTheWork(4544fn performAllTheWork(
4353 comp: *Compilation,4545 comp: *Compilation,
4354 main_progress_node: std.Progress.Node,4546 main_progress_node: std.Progress.Node,
...@@ -5002,18 +5194,15 @@ pub fn separateCodegenThreadOk(comp: *const Compilation) bool {...@@ -5002,18 +5194,15 @@ pub fn separateCodegenThreadOk(comp: *const Compilation) bool {
5002}5194}
50035195
5004fn workerDocsCopy(comp: *Compilation) void {5196fn workerDocsCopy(comp: *Compilation) void {
5005 docsCopyFallible(comp) catch |err| {5197 docsCopyFallible(comp) catch |err| return comp.lockAndSetMiscFailure(
5006 return comp.lockAndSetMiscFailure(5198 .docs_copy,
5007 .docs_copy,5199 "unable to copy autodocs artifacts: {s}",
5008 "unable to copy autodocs artifacts: {s}",5200 .{@errorName(err)},
5009 .{@errorName(err)},5201 );
5010 );
5011 };
5012}5202}
50135203
5014fn docsCopyFallible(comp: *Compilation) anyerror!void {5204fn docsCopyFallible(comp: *Compilation) anyerror!void {
5015 const zcu = comp.zcu orelse5205 const zcu = comp.zcu orelse return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{});
5016 return comp.lockAndSetMiscFailure(.docs_copy, "no Zig code to document", .{});
50175206
5018 const docs_path = comp.resolveEmitPath(comp.emit_docs.?);5207 const docs_path = comp.resolveEmitPath(comp.emit_docs.?);
5019 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {5208 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {
...@@ -5127,12 +5316,12 @@ fn workerDocsWasm(comp: *Compilation, parent_prog_node: std.Progress.Node) void...@@ -5127,12 +5316,12 @@ fn workerDocsWasm(comp: *Compilation, parent_prog_node: std.Progress.Node) void
5127 defer prog_node.end();5316 defer prog_node.end();
51285317
5129 workerDocsWasmFallible(comp, prog_node) catch |err| switch (err) {5318 workerDocsWasmFallible(comp, prog_node) catch |err| switch (err) {
5130 error.SubCompilationFailed => return, // error reported already5319 error.AlreadyReported => return,
5131 else => comp.lockAndSetMiscFailure(.docs_wasm, "unable to build autodocs: {t}", .{err}),5320 else => comp.lockAndSetMiscFailure(.docs_wasm, "unable to build autodocs: {t}", .{err}),
5132 };5321 };
5133}5322}
51345323
5135fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {5324fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubUpdateError!void {
5136 const gpa = comp.gpa;5325 const gpa = comp.gpa;
51375326
5138 var arena_allocator = std.heap.ArenaAllocator.init(gpa);5327 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
...@@ -5162,7 +5351,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5162,7 +5351,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
5162 .is_explicit_dynamic_linker = false,5351 .is_explicit_dynamic_linker = false,
5163 };5352 };
51645353
5165 const config = try Config.resolve(.{5354 const config = Config.resolve(.{
5166 .output_mode = output_mode,5355 .output_mode = output_mode,
5167 .resolved_target = resolved_target,5356 .resolved_target = resolved_target,
5168 .is_test = false,5357 .is_test = false,
...@@ -5171,14 +5360,17 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5171,14 +5360,17 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
5171 .root_optimize_mode = optimize_mode,5360 .root_optimize_mode = optimize_mode,
5172 .link_libc = false,5361 .link_libc = false,
5173 .rdynamic = true,5362 .rdynamic = true,
5174 });5363 }) catch |err| {
5364 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: failed to resolve compilation config: {t}", .{err});
5365 return error.AlreadyReported;
5366 };
51755367
5176 const src_basename = "main.zig";5368 const src_basename = "main.zig";
5177 const root_name = fs.path.stem(src_basename);5369 const root_name = fs.path.stem(src_basename);
51785370
5179 const dirs = comp.dirs.withoutLocalCache();5371 const dirs = comp.dirs.withoutLocalCache();
51805372
5181 const root_mod = try Package.Module.create(arena, .{5373 const root_mod = Package.Module.create(arena, .{
5182 .paths = .{5374 .paths = .{
5183 .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"),5375 .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"),
5184 .root_src_path = src_basename,5376 .root_src_path = src_basename,
...@@ -5191,8 +5383,11 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5191,8 +5383,11 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
5191 .global = config,5383 .global = config,
5192 .cc_argv = &.{},5384 .cc_argv = &.{},
5193 .parent = null,5385 .parent = null,
5194 });5386 }) catch |err| {
5195 const walk_mod = try Package.Module.create(arena, .{5387 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: failed to create root module: {t}", .{err});
5388 return error.AlreadyReported;
5389 };
5390 const walk_mod = Package.Module.create(arena, .{
5196 .paths = .{5391 .paths = .{
5197 .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"),5392 .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"),
5198 .root_src_path = "Walk.zig",5393 .root_src_path = "Walk.zig",
...@@ -5205,10 +5400,14 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5205,10 +5400,14 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
5205 .global = config,5400 .global = config,
5206 .cc_argv = &.{},5401 .cc_argv = &.{},
5207 .parent = root_mod,5402 .parent = root_mod,
5208 });5403 }) catch |err| {
5404 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: failed to create 'Walk' module: {t}", .{err});
5405 return error.AlreadyReported;
5406 };
5209 try root_mod.deps.put(arena, "Walk", walk_mod);5407 try root_mod.deps.put(arena, "Walk", walk_mod);
52105408
5211 const sub_compilation = try Compilation.create(gpa, arena, .{5409 var sub_create_diag: CreateDiagnostic = undefined;
5410 const sub_compilation = Compilation.create(gpa, arena, &sub_create_diag, .{
5212 .dirs = dirs,5411 .dirs = dirs,
5213 .self_exe_path = comp.self_exe_path,5412 .self_exe_path = comp.self_exe_path,
5214 .config = config,5413 .config = config,
...@@ -5228,7 +5427,13 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5228,7 +5427,13 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
5228 .verbose_llvm_bc = comp.verbose_llvm_bc,5427 .verbose_llvm_bc = comp.verbose_llvm_bc,
5229 .verbose_cimport = comp.verbose_cimport,5428 .verbose_cimport = comp.verbose_cimport,
5230 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,5429 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
5231 });5430 }) catch |err| switch (err) {
5431 error.CreateFail => {
5432 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: {f}", .{sub_create_diag});
5433 return error.AlreadyReported;
5434 },
5435 else => |e| return e,
5436 };
5232 defer sub_compilation.destroy();5437 defer sub_compilation.destroy();
52335438
5234 try comp.updateSubCompilation(sub_compilation, .docs_wasm, prog_node);5439 try comp.updateSubCompilation(sub_compilation, .docs_wasm, prog_node);
...@@ -5241,11 +5446,12 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5241,11 +5446,12 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
52415446
5242 const docs_path = comp.resolveEmitPath(comp.emit_docs.?);5447 const docs_path = comp.resolveEmitPath(comp.emit_docs.?);
5243 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {5448 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {
5244 return comp.lockAndSetMiscFailure(5449 comp.lockAndSetMiscFailure(
5245 .docs_copy,5450 .docs_copy,
5246 "unable to create output directory '{f}': {s}",5451 "unable to create output directory '{f}': {t}",
5247 .{ docs_path, @errorName(err) },5452 .{ docs_path, err },
5248 );5453 );
5454 return error.AlreadyReported;
5249 };5455 };
5250 defer out_dir.close();5456 defer out_dir.close();
52515457
...@@ -5255,9 +5461,10 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -5255,9 +5461,10 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
5255 "main.wasm",5461 "main.wasm",
5256 .{},5462 .{},
5257 ) catch |err| {5463 ) catch |err| {
5258 return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{f}' to '{f}': {s}", .{5464 comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{f}' to '{f}': {t}", .{
5259 crt_file.full_object_path, docs_path, @errorName(err),5465 crt_file.full_object_path, docs_path, err,
5260 });5466 });
5467 return error.AlreadyReported;
5261 };5468 };
5262}5469}
52635470
...@@ -5324,15 +5531,11 @@ fn workerUpdateFile(...@@ -5324,15 +5531,11 @@ fn workerUpdateFile(
5324}5531}
53255532
5326fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void {5533fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void {
5327 Builtin.updateFileOnDisk(file, comp) catch |err| {5534 Builtin.updateFileOnDisk(file, comp) catch |err| comp.lockAndSetMiscFailure(
5328 comp.mutex.lock();5535 .write_builtin_zig,
5329 defer comp.mutex.unlock();5536 "unable to write '{f}': {s}",
5330 comp.setMiscFailure(5537 .{ file.path.fmt(comp), @errorName(err) },
5331 .write_builtin_zig,5538 );
5332 "unable to write '{f}': {s}",
5333 .{ file.path.fmt(comp), @errorName(err) },
5334 );
5335 };
5336}5539}
53375540
5338fn workerUpdateEmbedFile(tid: usize, comp: *Compilation, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) void {5541fn workerUpdateEmbedFile(tid: usize, comp: *Compilation, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) void {
...@@ -5632,7 +5835,7 @@ fn buildRt(...@@ -5632,7 +5835,7 @@ fn buildRt(
5632 options,5835 options,
5633 out,5836 out,
5634 ) catch |err| switch (err) {5837 ) catch |err| switch (err) {
5635 error.SubCompilationFailed => return, // error reported already5838 error.AlreadyReported => return,
5636 else => comp.lockAndSetMiscFailure(misc_task, "unable to build {s}: {s}", .{5839 else => comp.lockAndSetMiscFailure(misc_task, "unable to build {s}: {s}", .{
5637 @tagName(misc_task), @errorName(err),5840 @tagName(misc_task), @errorName(err),
5638 }),5841 }),
...@@ -5644,7 +5847,7 @@ fn buildMuslCrtFile(comp: *Compilation, crt_file: musl.CrtFile, prog_node: std.P...@@ -5644,7 +5847,7 @@ fn buildMuslCrtFile(comp: *Compilation, crt_file: musl.CrtFile, prog_node: std.P
5644 if (musl.buildCrtFile(comp, crt_file, prog_node)) |_| {5847 if (musl.buildCrtFile(comp, crt_file, prog_node)) |_| {
5645 comp.queued_jobs.musl_crt_file[@intFromEnum(crt_file)] = false;5848 comp.queued_jobs.musl_crt_file[@intFromEnum(crt_file)] = false;
5646 } else |err| switch (err) {5849 } else |err| switch (err) {
5647 error.SubCompilationFailed => return, // error reported already5850 error.AlreadyReported => return,
5648 else => comp.lockAndSetMiscFailure(.musl_crt_file, "unable to build musl {s}: {s}", .{5851 else => comp.lockAndSetMiscFailure(.musl_crt_file, "unable to build musl {s}: {s}", .{
5649 @tagName(crt_file), @errorName(err),5852 @tagName(crt_file), @errorName(err),
5650 }),5853 }),
...@@ -5656,7 +5859,7 @@ fn buildGlibcCrtFile(comp: *Compilation, crt_file: glibc.CrtFile, prog_node: std...@@ -5656,7 +5859,7 @@ fn buildGlibcCrtFile(comp: *Compilation, crt_file: glibc.CrtFile, prog_node: std
5656 if (glibc.buildCrtFile(comp, crt_file, prog_node)) |_| {5859 if (glibc.buildCrtFile(comp, crt_file, prog_node)) |_| {
5657 comp.queued_jobs.glibc_crt_file[@intFromEnum(crt_file)] = false;5860 comp.queued_jobs.glibc_crt_file[@intFromEnum(crt_file)] = false;
5658 } else |err| switch (err) {5861 } else |err| switch (err) {
5659 error.SubCompilationFailed => return, // error reported already5862 error.AlreadyReported => return,
5660 else => comp.lockAndSetMiscFailure(.glibc_crt_file, "unable to build glibc {s}: {s}", .{5863 else => comp.lockAndSetMiscFailure(.glibc_crt_file, "unable to build glibc {s}: {s}", .{
5661 @tagName(crt_file), @errorName(err),5864 @tagName(crt_file), @errorName(err),
5662 }),5865 }),
...@@ -5669,7 +5872,7 @@ fn buildGlibcSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) voi...@@ -5669,7 +5872,7 @@ fn buildGlibcSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) voi
5669 // The job should no longer be queued up since it succeeded.5872 // The job should no longer be queued up since it succeeded.
5670 comp.queued_jobs.glibc_shared_objects = false;5873 comp.queued_jobs.glibc_shared_objects = false;
5671 } else |err| switch (err) {5874 } else |err| switch (err) {
5672 error.SubCompilationFailed => return, // error reported already5875 error.AlreadyReported => return,
5673 else => comp.lockAndSetMiscFailure(.glibc_shared_objects, "unable to build glibc shared objects: {s}", .{5876 else => comp.lockAndSetMiscFailure(.glibc_shared_objects, "unable to build glibc shared objects: {s}", .{
5674 @errorName(err),5877 @errorName(err),
5675 }),5878 }),
...@@ -5681,7 +5884,7 @@ fn buildFreeBSDCrtFile(comp: *Compilation, crt_file: freebsd.CrtFile, prog_node:...@@ -5681,7 +5884,7 @@ fn buildFreeBSDCrtFile(comp: *Compilation, crt_file: freebsd.CrtFile, prog_node:
5681 if (freebsd.buildCrtFile(comp, crt_file, prog_node)) |_| {5884 if (freebsd.buildCrtFile(comp, crt_file, prog_node)) |_| {
5682 comp.queued_jobs.freebsd_crt_file[@intFromEnum(crt_file)] = false;5885 comp.queued_jobs.freebsd_crt_file[@intFromEnum(crt_file)] = false;
5683 } else |err| switch (err) {5886 } else |err| switch (err) {
5684 error.SubCompilationFailed => return, // error reported already5887 error.AlreadyReported => return,
5685 else => comp.lockAndSetMiscFailure(.freebsd_crt_file, "unable to build FreeBSD {s}: {s}", .{5888 else => comp.lockAndSetMiscFailure(.freebsd_crt_file, "unable to build FreeBSD {s}: {s}", .{
5686 @tagName(crt_file), @errorName(err),5889 @tagName(crt_file), @errorName(err),
5687 }),5890 }),
...@@ -5694,7 +5897,7 @@ fn buildFreeBSDSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) v...@@ -5694,7 +5897,7 @@ fn buildFreeBSDSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) v
5694 // The job should no longer be queued up since it succeeded.5897 // The job should no longer be queued up since it succeeded.
5695 comp.queued_jobs.freebsd_shared_objects = false;5898 comp.queued_jobs.freebsd_shared_objects = false;
5696 } else |err| switch (err) {5899 } else |err| switch (err) {
5697 error.SubCompilationFailed => return, // error reported already5900 error.AlreadyReported => return,
5698 else => comp.lockAndSetMiscFailure(.freebsd_shared_objects, "unable to build FreeBSD libc shared objects: {s}", .{5901 else => comp.lockAndSetMiscFailure(.freebsd_shared_objects, "unable to build FreeBSD libc shared objects: {s}", .{
5699 @errorName(err),5902 @errorName(err),
5700 }),5903 }),
...@@ -5706,7 +5909,7 @@ fn buildNetBSDCrtFile(comp: *Compilation, crt_file: netbsd.CrtFile, prog_node: s...@@ -5706,7 +5909,7 @@ fn buildNetBSDCrtFile(comp: *Compilation, crt_file: netbsd.CrtFile, prog_node: s
5706 if (netbsd.buildCrtFile(comp, crt_file, prog_node)) |_| {5909 if (netbsd.buildCrtFile(comp, crt_file, prog_node)) |_| {
5707 comp.queued_jobs.netbsd_crt_file[@intFromEnum(crt_file)] = false;5910 comp.queued_jobs.netbsd_crt_file[@intFromEnum(crt_file)] = false;
5708 } else |err| switch (err) {5911 } else |err| switch (err) {
5709 error.SubCompilationFailed => return, // error reported already5912 error.AlreadyReported => return,
5710 else => comp.lockAndSetMiscFailure(.netbsd_crt_file, "unable to build NetBSD {s}: {s}", .{5913 else => comp.lockAndSetMiscFailure(.netbsd_crt_file, "unable to build NetBSD {s}: {s}", .{
5711 @tagName(crt_file), @errorName(err),5914 @tagName(crt_file), @errorName(err),
5712 }),5915 }),
...@@ -5719,7 +5922,7 @@ fn buildNetBSDSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) vo...@@ -5719,7 +5922,7 @@ fn buildNetBSDSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) vo
5719 // The job should no longer be queued up since it succeeded.5922 // The job should no longer be queued up since it succeeded.
5720 comp.queued_jobs.netbsd_shared_objects = false;5923 comp.queued_jobs.netbsd_shared_objects = false;
5721 } else |err| switch (err) {5924 } else |err| switch (err) {
5722 error.SubCompilationFailed => return, // error reported already5925 error.AlreadyReported => return,
5723 else => comp.lockAndSetMiscFailure(.netbsd_shared_objects, "unable to build NetBSD libc shared objects: {s}", .{5926 else => comp.lockAndSetMiscFailure(.netbsd_shared_objects, "unable to build NetBSD libc shared objects: {s}", .{
5724 @errorName(err),5927 @errorName(err),
5725 }),5928 }),
...@@ -5731,7 +5934,7 @@ fn buildMingwCrtFile(comp: *Compilation, crt_file: mingw.CrtFile, prog_node: std...@@ -5731,7 +5934,7 @@ fn buildMingwCrtFile(comp: *Compilation, crt_file: mingw.CrtFile, prog_node: std
5731 if (mingw.buildCrtFile(comp, crt_file, prog_node)) |_| {5934 if (mingw.buildCrtFile(comp, crt_file, prog_node)) |_| {
5732 comp.queued_jobs.mingw_crt_file[@intFromEnum(crt_file)] = false;5935 comp.queued_jobs.mingw_crt_file[@intFromEnum(crt_file)] = false;
5733 } else |err| switch (err) {5936 } else |err| switch (err) {
5734 error.SubCompilationFailed => return, // error reported already5937 error.AlreadyReported => return,
5735 else => comp.lockAndSetMiscFailure(.mingw_crt_file, "unable to build mingw-w64 {s}: {s}", .{5938 else => comp.lockAndSetMiscFailure(.mingw_crt_file, "unable to build mingw-w64 {s}: {s}", .{
5736 @tagName(crt_file), @errorName(err),5939 @tagName(crt_file), @errorName(err),
5737 }),5940 }),
...@@ -5743,7 +5946,7 @@ fn buildWasiLibcCrtFile(comp: *Compilation, crt_file: wasi_libc.CrtFile, prog_no...@@ -5743,7 +5946,7 @@ fn buildWasiLibcCrtFile(comp: *Compilation, crt_file: wasi_libc.CrtFile, prog_no
5743 if (wasi_libc.buildCrtFile(comp, crt_file, prog_node)) |_| {5946 if (wasi_libc.buildCrtFile(comp, crt_file, prog_node)) |_| {
5744 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(crt_file)] = false;5947 comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(crt_file)] = false;
5745 } else |err| switch (err) {5948 } else |err| switch (err) {
5746 error.SubCompilationFailed => return, // error reported already5949 error.AlreadyReported => return,
5747 else => comp.lockAndSetMiscFailure(.wasi_libc_crt_file, "unable to build WASI libc {s}: {s}", .{5950 else => comp.lockAndSetMiscFailure(.wasi_libc_crt_file, "unable to build WASI libc {s}: {s}", .{
5748 @tagName(crt_file), @errorName(err),5951 @tagName(crt_file), @errorName(err),
5749 }),5952 }),
...@@ -5755,7 +5958,7 @@ fn buildLibUnwind(comp: *Compilation, prog_node: std.Progress.Node) void {...@@ -5755,7 +5958,7 @@ fn buildLibUnwind(comp: *Compilation, prog_node: std.Progress.Node) void {
5755 if (libunwind.buildStaticLib(comp, prog_node)) |_| {5958 if (libunwind.buildStaticLib(comp, prog_node)) |_| {
5756 comp.queued_jobs.libunwind = false;5959 comp.queued_jobs.libunwind = false;
5757 } else |err| switch (err) {5960 } else |err| switch (err) {
5758 error.SubCompilationFailed => return, // error reported already5961 error.AlreadyReported => return,
5759 else => comp.lockAndSetMiscFailure(.libunwind, "unable to build libunwind: {s}", .{@errorName(err)}),5962 else => comp.lockAndSetMiscFailure(.libunwind, "unable to build libunwind: {s}", .{@errorName(err)}),
5760 }5963 }
5761}5964}
...@@ -5765,7 +5968,7 @@ fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) void {...@@ -5765,7 +5968,7 @@ fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) void {
5765 if (libcxx.buildLibCxx(comp, prog_node)) |_| {5968 if (libcxx.buildLibCxx(comp, prog_node)) |_| {
5766 comp.queued_jobs.libcxx = false;5969 comp.queued_jobs.libcxx = false;
5767 } else |err| switch (err) {5970 } else |err| switch (err) {
5768 error.SubCompilationFailed => return, // error reported already5971 error.AlreadyReported => return,
5769 else => comp.lockAndSetMiscFailure(.libcxx, "unable to build libcxx: {s}", .{@errorName(err)}),5972 else => comp.lockAndSetMiscFailure(.libcxx, "unable to build libcxx: {s}", .{@errorName(err)}),
5770 }5973 }
5771}5974}
...@@ -5775,7 +5978,7 @@ fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) void {...@@ -5775,7 +5978,7 @@ fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) void {
5775 if (libcxx.buildLibCxxAbi(comp, prog_node)) |_| {5978 if (libcxx.buildLibCxxAbi(comp, prog_node)) |_| {
5776 comp.queued_jobs.libcxxabi = false;5979 comp.queued_jobs.libcxxabi = false;
5777 } else |err| switch (err) {5980 } else |err| switch (err) {
5778 error.SubCompilationFailed => return, // error reported already5981 error.AlreadyReported => return,
5779 else => comp.lockAndSetMiscFailure(.libcxxabi, "unable to build libcxxabi: {s}", .{@errorName(err)}),5982 else => comp.lockAndSetMiscFailure(.libcxxabi, "unable to build libcxxabi: {s}", .{@errorName(err)}),
5780 }5983 }
5781}5984}
...@@ -5785,7 +5988,7 @@ fn buildLibTsan(comp: *Compilation, prog_node: std.Progress.Node) void {...@@ -5785,7 +5988,7 @@ fn buildLibTsan(comp: *Compilation, prog_node: std.Progress.Node) void {
5785 if (libtsan.buildTsan(comp, prog_node)) |_| {5988 if (libtsan.buildTsan(comp, prog_node)) |_| {
5786 comp.queued_jobs.libtsan = false;5989 comp.queued_jobs.libtsan = false;
5787 } else |err| switch (err) {5990 } else |err| switch (err) {
5788 error.SubCompilationFailed => return, // error reported already5991 error.AlreadyReported => return,
5789 else => comp.lockAndSetMiscFailure(.libtsan, "unable to build TSAN library: {s}", .{@errorName(err)}),5992 else => comp.lockAndSetMiscFailure(.libtsan, "unable to build TSAN library: {s}", .{@errorName(err)}),
5790 }5993 }
5791}5994}
...@@ -5802,7 +6005,7 @@ fn buildLibZigC(comp: *Compilation, prog_node: std.Progress.Node) void {...@@ -5802,7 +6005,7 @@ fn buildLibZigC(comp: *Compilation, prog_node: std.Progress.Node) void {
5802 .{},6005 .{},
5803 &comp.zigc_static_lib,6006 &comp.zigc_static_lib,
5804 ) catch |err| switch (err) {6007 ) catch |err| switch (err) {
5805 error.SubCompilationFailed => return, // error reported already6008 error.AlreadyReported => return,
5806 else => comp.lockAndSetMiscFailure(.libzigc, "unable to build libzigc: {s}", .{@errorName(err)}),6009 else => comp.lockAndSetMiscFailure(.libzigc, "unable to build libzigc: {s}", .{@errorName(err)}),
5807 };6010 };
5808}6011}
...@@ -7439,12 +7642,13 @@ pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {...@@ -7439,12 +7642,13 @@ pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {
7439 return target_util.zigBackend(target, comp.config.use_llvm);7642 return target_util.zigBackend(target, comp.config.use_llvm);
7440}7643}
74417644
7645pub const SubUpdateError = UpdateError || error{AlreadyReported};
7442pub fn updateSubCompilation(7646pub fn updateSubCompilation(
7443 parent_comp: *Compilation,7647 parent_comp: *Compilation,
7444 sub_comp: *Compilation,7648 sub_comp: *Compilation,
7445 misc_task: MiscTask,7649 misc_task: MiscTask,
7446 prog_node: std.Progress.Node,7650 prog_node: std.Progress.Node,
7447) !void {7651) SubUpdateError!void {
7448 {7652 {
7449 const sub_node = prog_node.start(@tagName(misc_task), 0);7653 const sub_node = prog_node.start(@tagName(misc_task), 0);
7450 defer sub_node.end();7654 defer sub_node.end();
...@@ -7454,20 +7658,20 @@ pub fn updateSubCompilation(...@@ -7454,20 +7658,20 @@ pub fn updateSubCompilation(
74547658
7455 // Look for compilation errors in this sub compilation7659 // Look for compilation errors in this sub compilation
7456 const gpa = parent_comp.gpa;7660 const gpa = parent_comp.gpa;
7457 var keep_errors = false;7661
7458 var errors = try sub_comp.getAllErrorsAlloc();7662 var errors = try sub_comp.getAllErrorsAlloc();
7459 defer if (!keep_errors) errors.deinit(gpa);7663 defer errors.deinit(gpa);
74607664
7461 if (errors.errorMessageCount() > 0) {7665 if (errors.errorMessageCount() > 0) {
7666 parent_comp.mutex.lock();
7667 defer parent_comp.mutex.unlock();
7462 try parent_comp.misc_failures.ensureUnusedCapacity(gpa, 1);7668 try parent_comp.misc_failures.ensureUnusedCapacity(gpa, 1);
7463 parent_comp.misc_failures.putAssumeCapacityNoClobber(misc_task, .{7669 parent_comp.misc_failures.putAssumeCapacityNoClobber(misc_task, .{
7464 .msg = try std.fmt.allocPrint(gpa, "sub-compilation of {s} failed", .{7670 .msg = try std.fmt.allocPrint(gpa, "sub-compilation of {t} failed", .{misc_task}),
7465 @tagName(misc_task),
7466 }),
7467 .children = errors,7671 .children = errors,
7468 });7672 });
7469 keep_errors = true;7673 errors = .empty; // ownership moved to the failures map
7470 return error.SubCompilationFailed;7674 return error.AlreadyReported;
7471 }7675 }
7472}7676}
74737677
...@@ -7481,7 +7685,7 @@ fn buildOutputFromZig(...@@ -7481,7 +7685,7 @@ fn buildOutputFromZig(
7481 prog_node: std.Progress.Node,7685 prog_node: std.Progress.Node,
7482 options: RtOptions,7686 options: RtOptions,
7483 out: *?CrtFile,7687 out: *?CrtFile,
7484) !void {7688) SubUpdateError!void {
7485 const tracy_trace = trace(@src());7689 const tracy_trace = trace(@src());
7486 defer tracy_trace.end();7690 defer tracy_trace.end();
74877691
...@@ -7495,7 +7699,7 @@ fn buildOutputFromZig(...@@ -7495,7 +7699,7 @@ fn buildOutputFromZig(
7495 const strip = comp.compilerRtStrip();7699 const strip = comp.compilerRtStrip();
7496 const optimize_mode = comp.compilerRtOptMode();7700 const optimize_mode = comp.compilerRtOptMode();
74977701
7498 const config = try Config.resolve(.{7702 const config = Config.resolve(.{
7499 .output_mode = output_mode,7703 .output_mode = output_mode,
7500 .link_mode = link_mode,7704 .link_mode = link_mode,
7501 .resolved_target = comp.root_mod.resolved_target,7705 .resolved_target = comp.root_mod.resolved_target,
...@@ -7509,9 +7713,12 @@ fn buildOutputFromZig(...@@ -7509,9 +7713,12 @@ fn buildOutputFromZig(
7509 .any_error_tracing = false,7713 .any_error_tracing = false,
7510 .root_error_tracing = false,7714 .root_error_tracing = false,
7511 .lto = if (options.allow_lto) comp.config.lto else .none,7715 .lto = if (options.allow_lto) comp.config.lto else .none,
7512 });7716 }) catch |err| {
7717 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: failed to resolve compilation config: {t}", .{ misc_task_tag, err });
7718 return error.AlreadyReported;
7719 };
75137720
7514 const root_mod = try Package.Module.create(arena, .{7721 const root_mod = Package.Module.create(arena, .{
7515 .paths = .{7722 .paths = .{
7516 .root = .zig_lib_root,7723 .root = .zig_lib_root,
7517 .root_src_path = src_basename,7724 .root_src_path = src_basename,
...@@ -7536,7 +7743,10 @@ fn buildOutputFromZig(...@@ -7536,7 +7743,10 @@ fn buildOutputFromZig(
7536 .global = config,7743 .global = config,
7537 .cc_argv = &.{},7744 .cc_argv = &.{},
7538 .parent = null,7745 .parent = null,
7539 });7746 }) catch |err| {
7747 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: failed to create module: {t}", .{ misc_task_tag, err });
7748 return error.AlreadyReported;
7749 };
75407750
7541 const parent_whole_cache: ?ParentWholeCache = switch (comp.cache_use) {7751 const parent_whole_cache: ?ParentWholeCache = switch (comp.cache_use) {
7542 .whole => |whole| .{7752 .whole => |whole| .{
...@@ -7552,7 +7762,8 @@ fn buildOutputFromZig(...@@ -7552,7 +7762,8 @@ fn buildOutputFromZig(
7552 .incremental, .none => null,7762 .incremental, .none => null,
7553 };7763 };
75547764
7555 const sub_compilation = try Compilation.create(gpa, arena, .{7765 var sub_create_diag: CreateDiagnostic = undefined;
7766 const sub_compilation = Compilation.create(gpa, arena, &sub_create_diag, .{
7556 .dirs = comp.dirs.withoutLocalCache(),7767 .dirs = comp.dirs.withoutLocalCache(),
7557 .cache_mode = .whole,7768 .cache_mode = .whole,
7558 .parent_whole_cache = parent_whole_cache,7769 .parent_whole_cache = parent_whole_cache,
...@@ -7576,7 +7787,13 @@ fn buildOutputFromZig(...@@ -7576,7 +7787,13 @@ fn buildOutputFromZig(
7576 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,7787 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
7577 .clang_passthrough_mode = comp.clang_passthrough_mode,7788 .clang_passthrough_mode = comp.clang_passthrough_mode,
7578 .skip_linker_dependencies = true,7789 .skip_linker_dependencies = true,
7579 });7790 }) catch |err| switch (err) {
7791 error.CreateFail => {
7792 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: {f}", .{ misc_task_tag, sub_create_diag });
7793 return error.AlreadyReported;
7794 },
7795 else => |e| return e,
7796 };
7580 defer sub_compilation.destroy();7797 defer sub_compilation.destroy();
75817798
7582 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);7799 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
...@@ -7609,7 +7826,7 @@ pub fn build_crt_file(...@@ -7609,7 +7826,7 @@ pub fn build_crt_file(
7609 /// created within this function.7826 /// created within this function.
7610 c_source_files: []CSourceFile,7827 c_source_files: []CSourceFile,
7611 options: CrtFileOptions,7828 options: CrtFileOptions,
7612) !void {7829) SubUpdateError!void {
7613 const tracy_trace = trace(@src());7830 const tracy_trace = trace(@src());
7614 defer tracy_trace.end();7831 defer tracy_trace.end();
76157832
...@@ -7624,7 +7841,7 @@ pub fn build_crt_file(...@@ -7624,7 +7841,7 @@ pub fn build_crt_file(
7624 .output_mode = output_mode,7841 .output_mode = output_mode,
7625 });7842 });
76267843
7627 const config = try Config.resolve(.{7844 const config = Config.resolve(.{
7628 .output_mode = output_mode,7845 .output_mode = output_mode,
7629 .resolved_target = comp.root_mod.resolved_target,7846 .resolved_target = comp.root_mod.resolved_target,
7630 .is_test = false,7847 .is_test = false,
...@@ -7638,8 +7855,11 @@ pub fn build_crt_file(...@@ -7638,8 +7855,11 @@ pub fn build_crt_file(
7638 .Lib => if (options.allow_lto) comp.config.lto else .none,7855 .Lib => if (options.allow_lto) comp.config.lto else .none,
7639 .Obj, .Exe => .none,7856 .Obj, .Exe => .none,
7640 },7857 },
7641 });7858 }) catch |err| {
7642 const root_mod = try Package.Module.create(arena, .{7859 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: failed to resolve compilation config: {t}", .{ misc_task_tag, err });
7860 return error.AlreadyReported;
7861 };
7862 const root_mod = Package.Module.create(arena, .{
7643 .paths = .{7863 .paths = .{
7644 .root = .zig_lib_root,7864 .root = .zig_lib_root,
7645 .root_src_path = "",7865 .root_src_path = "",
...@@ -7669,13 +7889,17 @@ pub fn build_crt_file(...@@ -7669,13 +7889,17 @@ pub fn build_crt_file(
7669 .global = config,7889 .global = config,
7670 .cc_argv = &.{},7890 .cc_argv = &.{},
7671 .parent = null,7891 .parent = null,
7672 });7892 }) catch |err| {
7893 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: failed to create module: {t}", .{ misc_task_tag, err });
7894 return error.AlreadyReported;
7895 };
76737896
7674 for (c_source_files) |*item| {7897 for (c_source_files) |*item| {
7675 item.owner = root_mod;7898 item.owner = root_mod;
7676 }7899 }
76777900
7678 const sub_compilation = try Compilation.create(gpa, arena, .{7901 var sub_create_diag: CreateDiagnostic = undefined;
7902 const sub_compilation = Compilation.create(gpa, arena, &sub_create_diag, .{
7679 .dirs = comp.dirs.withoutLocalCache(),7903 .dirs = comp.dirs.withoutLocalCache(),
7680 .self_exe_path = comp.self_exe_path,7904 .self_exe_path = comp.self_exe_path,
7681 .cache_mode = .whole,7905 .cache_mode = .whole,
...@@ -7699,7 +7923,13 @@ pub fn build_crt_file(...@@ -7699,7 +7923,13 @@ pub fn build_crt_file(
7699 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,7923 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
7700 .clang_passthrough_mode = comp.clang_passthrough_mode,7924 .clang_passthrough_mode = comp.clang_passthrough_mode,
7701 .skip_linker_dependencies = true,7925 .skip_linker_dependencies = true,
7702 });7926 }) catch |err| switch (err) {
7927 error.CreateFail => {
7928 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: {f}", .{ misc_task_tag, sub_create_diag });
7929 return error.AlreadyReported;
7930 },
7931 else => |e| return e,
7932 };
7703 defer sub_compilation.destroy();7933 defer sub_compilation.destroy();
77047934
7705 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);7935 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
src/Package/Module.zig+14
...@@ -92,6 +92,20 @@ pub const ResolvedTarget = struct {...@@ -92,6 +92,20 @@ pub const ResolvedTarget = struct {
92 llvm_cpu_features: ?[*:0]const u8 = null,92 llvm_cpu_features: ?[*:0]const u8 = null,
93};93};
9494
95pub const CreateError = error{
96 OutOfMemory,
97 ValgrindUnsupportedOnTarget,
98 TargetRequiresSingleThreaded,
99 BackendRequiresSingleThreaded,
100 TargetRequiresPic,
101 PieRequiresPic,
102 DynamicLinkingRequiresPic,
103 TargetHasNoRedZone,
104 StackCheckUnsupportedByTarget,
105 StackProtectorUnsupportedByTarget,
106 StackProtectorUnavailableWithoutLibC,
107};
108
95/// At least one of `parent` and `resolved_target` must be non-null.109/// At least one of `parent` and `resolved_target` must be non-null.
96pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {110pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
97 if (options.inherited.sanitize_thread == true) assert(options.global.any_sanitize_thread);111 if (options.inherited.sanitize_thread == true) assert(options.global.any_sanitize_thread);
src/Sema.zig+1-2
...@@ -5726,6 +5726,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5726,6 +5726,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5726 .global = comp.config,5726 .global = comp.config,
5727 .parent = parent_mod,5727 .parent = parent_mod,
5728 }) catch |err| switch (err) {5728 }) catch |err| switch (err) {
5729 error.OutOfMemory => |e| return e,
5729 // None of these are possible because we are creating a package with5730 // None of these are possible because we are creating a package with
5730 // the exact same configuration as the parent package, which already5731 // the exact same configuration as the parent package, which already
5731 // passed these checks.5732 // passed these checks.
...@@ -5739,8 +5740,6 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5739,8 +5740,6 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5739 error.StackCheckUnsupportedByTarget => unreachable,5740 error.StackCheckUnsupportedByTarget => unreachable,
5740 error.StackProtectorUnsupportedByTarget => unreachable,5741 error.StackProtectorUnsupportedByTarget => unreachable,
5741 error.StackProtectorUnavailableWithoutLibC => unreachable,5742 error.StackProtectorUnavailableWithoutLibC => unreachable,
5742
5743 else => |e| return e,
5744 };5743 };
5745 const c_import_file_path: Compilation.Path = try c_import_mod.root.join(gpa, comp.dirs, "cimport.zig");5744 const c_import_file_path: Compilation.Path = try c_import_mod.root.join(gpa, comp.dirs, "cimport.zig");
5746 errdefer c_import_file_path.deinit(gpa);5745 errdefer c_import_file_path.deinit(gpa);
src/Zcu.zig+30-15
...@@ -1038,7 +1038,9 @@ pub const File = struct {...@@ -1038,7 +1038,9 @@ pub const File = struct {
1038 stat: Cache.File.Stat,1038 stat: Cache.File.Stat,
1039 };1039 };
10401040
1041 pub fn getSource(file: *File, zcu: *const Zcu) !Source {1041 pub const GetSourceError = error{ OutOfMemory, FileTooBig } || std.fs.File.OpenError || std.fs.File.ReadError;
1042
1043 pub fn getSource(file: *File, zcu: *const Zcu) GetSourceError!Source {
1042 const gpa = zcu.gpa;1044 const gpa = zcu.gpa;
10431045
1044 if (file.source) |source| return .{1046 if (file.source) |source| return .{
...@@ -1062,7 +1064,7 @@ pub const File = struct {...@@ -1062,7 +1064,7 @@ pub const File = struct {
10621064
1063 var file_reader = f.reader(&.{});1065 var file_reader = f.reader(&.{});
1064 file_reader.size = stat.size;1066 file_reader.size = stat.size;
1065 try file_reader.interface.readSliceAll(source);1067 file_reader.interface.readSliceAll(source) catch return file_reader.err.?;
10661068
1067 // Here we do not modify stat fields because this function is the one1069 // Here we do not modify stat fields because this function is the one
1068 // used for error reporting. We need to keep the stat fields stale so that1070 // used for error reporting. We need to keep the stat fields stale so that
...@@ -1081,7 +1083,7 @@ pub const File = struct {...@@ -1081,7 +1083,7 @@ pub const File = struct {
1081 };1083 };
1082 }1084 }
10831085
1084 pub fn getTree(file: *File, zcu: *const Zcu) !*const Ast {1086 pub fn getTree(file: *File, zcu: *const Zcu) GetSourceError!*const Ast {
1085 if (file.tree) |*tree| return tree;1087 if (file.tree) |*tree| return tree;
10861088
1087 const source = try file.getSource(zcu);1089 const source = try file.getSource(zcu);
...@@ -1127,7 +1129,7 @@ pub const File = struct {...@@ -1127,7 +1129,7 @@ pub const File = struct {
1127 file: *File,1129 file: *File,
1128 zcu: *const Zcu,1130 zcu: *const Zcu,
1129 eb: *std.zig.ErrorBundle.Wip,1131 eb: *std.zig.ErrorBundle.Wip,
1130 ) !std.zig.ErrorBundle.SourceLocationIndex {1132 ) Allocator.Error!std.zig.ErrorBundle.SourceLocationIndex {
1131 return eb.addSourceLocation(.{1133 return eb.addSourceLocation(.{
1132 .src_path = try eb.printString("{f}", .{file.path.fmt(zcu.comp)}),1134 .src_path = try eb.printString("{f}", .{file.path.fmt(zcu.comp)}),
1133 .span_start = 0,1135 .span_start = 0,
...@@ -1138,17 +1140,17 @@ pub const File = struct {...@@ -1138,17 +1140,17 @@ pub const File = struct {
1138 .source_line = 0,1140 .source_line = 0,
1139 });1141 });
1140 }1142 }
1143 /// Asserts that the tree has already been loaded with `getTree`.
1141 pub fn errorBundleTokenSrc(1144 pub fn errorBundleTokenSrc(
1142 file: *File,1145 file: *File,
1143 tok: Ast.TokenIndex,1146 tok: Ast.TokenIndex,
1144 zcu: *const Zcu,1147 zcu: *const Zcu,
1145 eb: *std.zig.ErrorBundle.Wip,1148 eb: *std.zig.ErrorBundle.Wip,
1146 ) !std.zig.ErrorBundle.SourceLocationIndex {1149 ) Allocator.Error!std.zig.ErrorBundle.SourceLocationIndex {
1147 const source = try file.getSource(zcu);1150 const tree = &file.tree.?;
1148 const tree = try file.getTree(zcu);
1149 const start = tree.tokenStart(tok);1151 const start = tree.tokenStart(tok);
1150 const end = start + tree.tokenSlice(tok).len;1152 const end = start + tree.tokenSlice(tok).len;
1151 const loc = std.zig.findLineColumn(source.bytes, start);1153 const loc = std.zig.findLineColumn(file.source.?, start);
1152 return eb.addSourceLocation(.{1154 return eb.addSourceLocation(.{
1153 .src_path = try eb.printString("{f}", .{file.path.fmt(zcu.comp)}),1155 .src_path = try eb.printString("{f}", .{file.path.fmt(zcu.comp)}),
1154 .span_start = start,1156 .span_start = start,
...@@ -2665,8 +2667,9 @@ pub const LazySrcLoc = struct {...@@ -2665,8 +2667,9 @@ pub const LazySrcLoc = struct {
2665 }2667 }
26662668
2667 /// Used to sort error messages, so that they're printed in a consistent order.2669 /// Used to sort error messages, so that they're printed in a consistent order.
2668 /// If an error is returned, that error makes sorting impossible.2670 /// If an error is returned, a file could not be read in order to resolve a source location.
2669 pub fn lessThan(lhs_lazy: LazySrcLoc, rhs_lazy: LazySrcLoc, zcu: *Zcu) !bool {2671 /// In that case, `bad_file_out` is populated, and sorting is impossible.
2672 pub fn lessThan(lhs_lazy: LazySrcLoc, rhs_lazy: LazySrcLoc, zcu: *Zcu, bad_file_out: **Zcu.File) File.GetSourceError!bool {
2670 const lhs_src = lhs_lazy.upgradeOrLost(zcu) orelse {2673 const lhs_src = lhs_lazy.upgradeOrLost(zcu) orelse {
2671 // LHS source location lost, so should never be referenced. Just sort it to the end.2674 // LHS source location lost, so should never be referenced. Just sort it to the end.
2672 return false;2675 return false;
...@@ -2684,8 +2687,14 @@ pub const LazySrcLoc = struct {...@@ -2684,8 +2687,14 @@ pub const LazySrcLoc = struct {
2684 return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt);2687 return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt);
2685 }2688 }
26862689
2687 const lhs_span = try lhs_src.span(zcu);2690 const lhs_span = lhs_src.span(zcu) catch |err| {
2688 const rhs_span = try rhs_src.span(zcu);2691 bad_file_out.* = lhs_src.file_scope;
2692 return err;
2693 };
2694 const rhs_span = rhs_src.span(zcu) catch |err| {
2695 bad_file_out.* = rhs_src.file_scope;
2696 return err;
2697 };
2689 return lhs_span.main < rhs_span.main;2698 return lhs_span.main < rhs_span.main;
2690 }2699 }
2691};2700};
...@@ -4584,7 +4593,7 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg)...@@ -4584,7 +4593,7 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg)
4584pub fn addFileInMultipleModulesError(4593pub fn addFileInMultipleModulesError(
4585 zcu: *Zcu,4594 zcu: *Zcu,
4586 eb: *std.zig.ErrorBundle.Wip,4595 eb: *std.zig.ErrorBundle.Wip,
4587) !void {4596) Allocator.Error!void {
4588 const gpa = zcu.gpa;4597 const gpa = zcu.gpa;
45894598
4590 const info = zcu.multi_module_err.?;4599 const info = zcu.multi_module_err.?;
...@@ -4631,7 +4640,7 @@ fn explainWhyFileIsInModule(...@@ -4631,7 +4640,7 @@ fn explainWhyFileIsInModule(
4631 file: File.Index,4640 file: File.Index,
4632 in_module: *Package.Module,4641 in_module: *Package.Module,
4633 ref: File.Reference,4642 ref: File.Reference,
4634) !void {4643) Allocator.Error!void {
4635 const gpa = zcu.gpa;4644 const gpa = zcu.gpa;
46364645
4637 // error: file is the root of module 'foo'4646 // error: file is the root of module 'foo'
...@@ -4666,7 +4675,13 @@ fn explainWhyFileIsInModule(...@@ -4666,7 +4675,13 @@ fn explainWhyFileIsInModule(
4666 const thing: []const u8 = if (is_first) "file" else "which";4675 const thing: []const u8 = if (is_first) "file" else "which";
4667 is_first = false;4676 is_first = false;
46684677
4669 const import_src = try zcu.fileByIndex(import.importer).errorBundleTokenSrc(import.tok, zcu, eb);4678 const importer_file = zcu.fileByIndex(import.importer);
4679 // `errorBundleTokenSrc` expects the tree to be loaded
4680 _ = importer_file.getTree(zcu) catch |err| {
4681 try Compilation.unableToLoadZcuFile(zcu, eb, importer_file, err);
4682 return; // stop the explanation early
4683 };
4684 const import_src = try importer_file.errorBundleTokenSrc(import.tok, zcu, eb);
46704685
4671 const importer_ref = zcu.alive_files.get(import.importer).?;4686 const importer_ref = zcu.alive_files.get(import.importer).?;
4672 const importer_root: ?*Package.Module = switch (importer_ref) {4687 const importer_root: ?*Package.Module = switch (importer_ref) {
src/libs/freebsd.zig+14-5
...@@ -57,7 +57,7 @@ fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const...@@ -57,7 +57,7 @@ fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const
57}57}
5858
59/// TODO replace anyerror with explicit error set, recording user-friendly errors with59/// TODO replace anyerror with explicit error set, recording user-friendly errors with
60/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.60/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
61pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {61pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {
62 if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;62 if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
6363
...@@ -414,7 +414,7 @@ fn wordDirective(target: *const std.Target) []const u8 {...@@ -414,7 +414,7 @@ fn wordDirective(target: *const std.Target) []const u8 {
414}414}
415415
416/// TODO replace anyerror with explicit error set, recording user-friendly errors with416/// TODO replace anyerror with explicit error set, recording user-friendly errors with
417/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.417/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
418pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {418pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {
419 // See also glibc.zig which this code is based on.419 // See also glibc.zig which this code is based on.
420420
...@@ -1065,7 +1065,10 @@ fn buildSharedLib(...@@ -1065,7 +1065,10 @@ fn buildSharedLib(
1065 },1065 },
1066 };1066 };
10671067
1068 const sub_compilation = try Compilation.create(comp.gpa, arena, .{1068 const misc_task: Compilation.MiscTask = .@"freebsd libc shared object";
1069
1070 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
1071 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
1069 .dirs = comp.dirs.withoutLocalCache(),1072 .dirs = comp.dirs.withoutLocalCache(),
1070 .thread_pool = comp.thread_pool,1073 .thread_pool = comp.thread_pool,
1071 .self_exe_path = comp.self_exe_path,1074 .self_exe_path = comp.self_exe_path,
...@@ -1090,8 +1093,14 @@ fn buildSharedLib(...@@ -1090,8 +1093,14 @@ fn buildSharedLib(
1090 .soname = soname,1093 .soname = soname,
1091 .c_source_files = &c_source_files,1094 .c_source_files = &c_source_files,
1092 .skip_linker_dependencies = true,1095 .skip_linker_dependencies = true,
1093 });1096 }) catch |err| switch (err) {
1097 error.CreateFail => {
1098 comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
1099 return error.AlreadyReported;
1100 },
1101 else => |e| return e,
1102 };
1094 defer sub_compilation.destroy();1103 defer sub_compilation.destroy();
10951104
1096 try comp.updateSubCompilation(sub_compilation, .@"freebsd libc shared object", prog_node);1105 try comp.updateSubCompilation(sub_compilation, misc_task, prog_node);
1097}1106}
src/libs/glibc.zig+14-5
...@@ -162,7 +162,7 @@ pub const CrtFile = enum {...@@ -162,7 +162,7 @@ pub const CrtFile = enum {
162};162};
163163
164/// TODO replace anyerror with explicit error set, recording user-friendly errors with164/// TODO replace anyerror with explicit error set, recording user-friendly errors with
165/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.165/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
166pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {166pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {
167 if (!build_options.have_llvm) {167 if (!build_options.have_llvm) {
168 return error.ZigCompilerNotBuiltWithLLVMExtensions;168 return error.ZigCompilerNotBuiltWithLLVMExtensions;
...@@ -656,7 +656,7 @@ fn wordDirective(target: *const std.Target) []const u8 {...@@ -656,7 +656,7 @@ fn wordDirective(target: *const std.Target) []const u8 {
656}656}
657657
658/// TODO replace anyerror with explicit error set, recording user-friendly errors with658/// TODO replace anyerror with explicit error set, recording user-friendly errors with
659/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.659/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
660pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {660pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {
661 const tracy = trace(@src());661 const tracy = trace(@src());
662 defer tracy.end();662 defer tracy.end();
...@@ -1223,7 +1223,10 @@ fn buildSharedLib(...@@ -1223,7 +1223,10 @@ fn buildSharedLib(
1223 },1223 },
1224 };1224 };
12251225
1226 const sub_compilation = try Compilation.create(comp.gpa, arena, .{1226 const misc_task: Compilation.MiscTask = .@"glibc shared object";
1227
1228 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
1229 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
1227 .dirs = comp.dirs.withoutLocalCache(),1230 .dirs = comp.dirs.withoutLocalCache(),
1228 .thread_pool = comp.thread_pool,1231 .thread_pool = comp.thread_pool,
1229 .self_exe_path = comp.self_exe_path,1232 .self_exe_path = comp.self_exe_path,
...@@ -1248,10 +1251,16 @@ fn buildSharedLib(...@@ -1248,10 +1251,16 @@ fn buildSharedLib(
1248 .soname = soname,1251 .soname = soname,
1249 .c_source_files = &c_source_files,1252 .c_source_files = &c_source_files,
1250 .skip_linker_dependencies = true,1253 .skip_linker_dependencies = true,
1251 });1254 }) catch |err| switch (err) {
1255 error.CreateFail => {
1256 comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
1257 return error.AlreadyReported;
1258 },
1259 else => |e| return e,
1260 };
1252 defer sub_compilation.destroy();1261 defer sub_compilation.destroy();
12531262
1254 try comp.updateSubCompilation(sub_compilation, .@"glibc shared object", prog_node);1263 try comp.updateSubCompilation(sub_compilation, misc_task, prog_node);
1255}1264}
12561265
1257pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile {1266pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile {
src/libs/libcxx.zig+35-35
...@@ -102,7 +102,7 @@ const libcxx_thread_files = [_][]const u8{...@@ -102,7 +102,7 @@ const libcxx_thread_files = [_][]const u8{
102102
103pub const BuildError = error{103pub const BuildError = error{
104 OutOfMemory,104 OutOfMemory,
105 SubCompilationFailed,105 AlreadyReported,
106 ZigCompilerNotBuiltWithLLVMExtensions,106 ZigCompilerNotBuiltWithLLVMExtensions,
107};107};
108108
...@@ -144,12 +144,12 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -144,12 +144,12 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
144 .lto = comp.config.lto,144 .lto = comp.config.lto,
145 .any_sanitize_thread = comp.config.any_sanitize_thread,145 .any_sanitize_thread = comp.config.any_sanitize_thread,
146 }) catch |err| {146 }) catch |err| {
147 comp.setMiscFailure(147 comp.lockAndSetMiscFailure(
148 .libcxx,148 .libcxx,
149 "unable to build libc++: resolving configuration failed: {s}",149 "unable to build libc++: resolving configuration failed: {s}",
150 .{@errorName(err)},150 .{@errorName(err)},
151 );151 );
152 return error.SubCompilationFailed;152 return error.AlreadyReported;
153 };153 };
154154
155 const root_mod = Module.create(arena, .{155 const root_mod = Module.create(arena, .{
...@@ -177,12 +177,12 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -177,12 +177,12 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
177 .cc_argv = &.{},177 .cc_argv = &.{},
178 .parent = null,178 .parent = null,
179 }) catch |err| {179 }) catch |err| {
180 comp.setMiscFailure(180 comp.lockAndSetMiscFailure(
181 .libcxx,181 .libcxx,
182 "unable to build libc++: creating module failed: {s}",182 "unable to build libc++: creating module failed: {s}",
183 .{@errorName(err)},183 .{@errorName(err)},
184 );184 );
185 return error.SubCompilationFailed;185 return error.AlreadyReported;
186 };186 };
187187
188 const libcxx_files = if (comp.config.any_non_single_threaded)188 const libcxx_files = if (comp.config.any_non_single_threaded)
...@@ -255,7 +255,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -255,7 +255,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
255 });255 });
256 }256 }
257257
258 const sub_compilation = Compilation.create(comp.gpa, arena, .{258 const misc_task: Compilation.MiscTask = .libcxx;
259
260 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
261 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
259 .dirs = comp.dirs.withoutLocalCache(),262 .dirs = comp.dirs.withoutLocalCache(),
260 .self_exe_path = comp.self_exe_path,263 .self_exe_path = comp.self_exe_path,
261 .cache_mode = .whole,264 .cache_mode = .whole,
...@@ -276,24 +279,19 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -276,24 +279,19 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
276 .clang_passthrough_mode = comp.clang_passthrough_mode,279 .clang_passthrough_mode = comp.clang_passthrough_mode,
277 .skip_linker_dependencies = true,280 .skip_linker_dependencies = true,
278 }) catch |err| {281 }) catch |err| {
279 comp.setMiscFailure(282 switch (err) {
280 .libcxx,283 else => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: create compilation failed: {t}", .{err}),
281 "unable to build libc++: create compilation failed: {s}",284 error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: create compilation failed: {f}", .{sub_create_diag}),
282 .{@errorName(err)},285 }
283 );286 return error.AlreadyReported;
284 return error.SubCompilationFailed;
285 };287 };
286 defer sub_compilation.destroy();288 defer sub_compilation.destroy();
287289
288 comp.updateSubCompilation(sub_compilation, .libcxx, prog_node) catch |err| switch (err) {290 comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) {
289 error.SubCompilationFailed => return error.SubCompilationFailed,291 error.AlreadyReported => return error.AlreadyReported,
290 else => |e| {292 else => |e| {
291 comp.setMiscFailure(293 comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: compilation failed: {t}", .{e});
292 .libcxx,294 return error.AlreadyReported;
293 "unable to build libc++: compilation failed: {s}",
294 .{@errorName(e)},
295 );
296 return error.SubCompilationFailed;
297 },295 },
298 };296 };
299297
...@@ -345,12 +343,12 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -345,12 +343,12 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
345 .lto = comp.config.lto,343 .lto = comp.config.lto,
346 .any_sanitize_thread = comp.config.any_sanitize_thread,344 .any_sanitize_thread = comp.config.any_sanitize_thread,
347 }) catch |err| {345 }) catch |err| {
348 comp.setMiscFailure(346 comp.lockAndSetMiscFailure(
349 .libcxxabi,347 .libcxxabi,
350 "unable to build libc++abi: resolving configuration failed: {s}",348 "unable to build libc++abi: resolving configuration failed: {s}",
351 .{@errorName(err)},349 .{@errorName(err)},
352 );350 );
353 return error.SubCompilationFailed;351 return error.AlreadyReported;
354 };352 };
355353
356 const root_mod = Module.create(arena, .{354 const root_mod = Module.create(arena, .{
...@@ -379,12 +377,12 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -379,12 +377,12 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
379 .cc_argv = &.{},377 .cc_argv = &.{},
380 .parent = null,378 .parent = null,
381 }) catch |err| {379 }) catch |err| {
382 comp.setMiscFailure(380 comp.lockAndSetMiscFailure(
383 .libcxxabi,381 .libcxxabi,
384 "unable to build libc++abi: creating module failed: {s}",382 "unable to build libc++abi: creating module failed: {s}",
385 .{@errorName(err)},383 .{@errorName(err)},
386 );384 );
387 return error.SubCompilationFailed;385 return error.AlreadyReported;
388 };386 };
389387
390 var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len);388 var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len);
...@@ -446,7 +444,10 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -446,7 +444,10 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
446 });444 });
447 }445 }
448446
449 const sub_compilation = Compilation.create(comp.gpa, arena, .{447 const misc_task: Compilation.MiscTask = .libcxxabi;
448
449 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
450 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
450 .dirs = comp.dirs.withoutLocalCache(),451 .dirs = comp.dirs.withoutLocalCache(),
451 .self_exe_path = comp.self_exe_path,452 .self_exe_path = comp.self_exe_path,
452 .cache_mode = .whole,453 .cache_mode = .whole,
...@@ -467,24 +468,23 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -467,24 +468,23 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
467 .clang_passthrough_mode = comp.clang_passthrough_mode,468 .clang_passthrough_mode = comp.clang_passthrough_mode,
468 .skip_linker_dependencies = true,469 .skip_linker_dependencies = true,
469 }) catch |err| {470 }) catch |err| {
470 comp.setMiscFailure(471 switch (err) {
471 .libcxxabi,472 else => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++abi: create compilation failed: {t}", .{err}),
472 "unable to build libc++abi: create compilation failed: {s}",473 error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++abi: create compilation failed: {f}", .{sub_create_diag}),
473 .{@errorName(err)},474 }
474 );475 return error.AlreadyReported;
475 return error.SubCompilationFailed;
476 };476 };
477 defer sub_compilation.destroy();477 defer sub_compilation.destroy();
478478
479 comp.updateSubCompilation(sub_compilation, .libcxxabi, prog_node) catch |err| switch (err) {479 comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) {
480 error.SubCompilationFailed => return error.SubCompilationFailed,480 error.AlreadyReported => return error.AlreadyReported,
481 else => |e| {481 else => |e| {
482 comp.setMiscFailure(482 comp.lockAndSetMiscFailure(
483 .libcxxabi,483 .libcxxabi,
484 "unable to build libc++abi: compilation failed: {s}",484 "unable to build libc++abi: compilation failed: {s}",
485 .{@errorName(e)},485 .{@errorName(e)},
486 );486 );
487 return error.SubCompilationFailed;487 return error.AlreadyReported;
488 },488 },
489 };489 };
490490
src/libs/libtsan.zig+19-20
...@@ -8,7 +8,7 @@ const Module = @import("../Package/Module.zig");...@@ -8,7 +8,7 @@ const Module = @import("../Package/Module.zig");
88
9pub const BuildError = error{9pub const BuildError = error{
10 OutOfMemory,10 OutOfMemory,
11 SubCompilationFailed,11 AlreadyReported,
12 ZigCompilerNotBuiltWithLLVMExtensions,12 ZigCompilerNotBuiltWithLLVMExtensions,
13 TSANUnsupportedCPUArchitecture,13 TSANUnsupportedCPUArchitecture,
14};14};
...@@ -66,12 +66,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -66,12 +66,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
66 // LLVM disables LTO for its libtsan.66 // LLVM disables LTO for its libtsan.
67 .lto = .none,67 .lto = .none,
68 }) catch |err| {68 }) catch |err| {
69 comp.setMiscFailure(69 comp.lockAndSetMiscFailure(
70 .libtsan,70 .libtsan,
71 "unable to build thread sanitizer runtime: resolving configuration failed: {s}",71 "unable to build thread sanitizer runtime: resolving configuration failed: {s}",
72 .{@errorName(err)},72 .{@errorName(err)},
73 );73 );
74 return error.SubCompilationFailed;74 return error.AlreadyReported;
75 };75 };
7676
77 const common_flags = [_][]const u8{77 const common_flags = [_][]const u8{
...@@ -105,12 +105,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -105,12 +105,12 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
105 .cc_argv = &common_flags,105 .cc_argv = &common_flags,
106 .parent = null,106 .parent = null,
107 }) catch |err| {107 }) catch |err| {
108 comp.setMiscFailure(108 comp.lockAndSetMiscFailure(
109 .libtsan,109 .libtsan,
110 "unable to build thread sanitizer runtime: creating module failed: {s}",110 "unable to build thread sanitizer runtime: creating module failed: {s}",
111 .{@errorName(err)},111 .{@errorName(err)},
112 );112 );
113 return error.SubCompilationFailed;113 return error.AlreadyReported;
114 };114 };
115115
116 var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena);116 var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena);
...@@ -273,7 +273,11 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -273,7 +273,11 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
273 null;273 null;
274 // Workaround for https://github.com/llvm/llvm-project/issues/97627274 // Workaround for https://github.com/llvm/llvm-project/issues/97627
275 const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null;275 const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null;
276 const sub_compilation = Compilation.create(comp.gpa, arena, .{276
277 const misc_task: Compilation.MiscTask = .libtsan;
278
279 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
280 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
277 .dirs = comp.dirs.withoutLocalCache(),281 .dirs = comp.dirs.withoutLocalCache(),
278 .thread_pool = comp.thread_pool,282 .thread_pool = comp.thread_pool,
279 .self_exe_path = comp.self_exe_path,283 .self_exe_path = comp.self_exe_path,
...@@ -297,24 +301,19 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo...@@ -297,24 +301,19 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
297 .install_name = install_name,301 .install_name = install_name,
298 .headerpad_size = headerpad_size,302 .headerpad_size = headerpad_size,
299 }) catch |err| {303 }) catch |err| {
300 comp.setMiscFailure(304 switch (err) {
301 .libtsan,305 else => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {t}", .{ misc_task, err }),
302 "unable to build thread sanitizer runtime: create compilation failed: {s}",306 error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {f}", .{ misc_task, sub_create_diag }),
303 .{@errorName(err)},307 }
304 );308 return error.AlreadyReported;
305 return error.SubCompilationFailed;
306 };309 };
307 defer sub_compilation.destroy();310 defer sub_compilation.destroy();
308311
309 comp.updateSubCompilation(sub_compilation, .libtsan, prog_node) catch |err| switch (err) {312 comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) {
310 error.SubCompilationFailed => return error.SubCompilationFailed,313 error.AlreadyReported => return error.AlreadyReported,
311 else => |e| {314 else => |e| {
312 comp.setMiscFailure(315 comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: compilation failed: {s}", .{ misc_task, @errorName(e) });
313 .libtsan,316 return error.AlreadyReported;
314 "unable to build thread sanitizer runtime: compilation failed: {s}",
315 .{@errorName(e)},
316 );
317 return error.SubCompilationFailed;
318 },317 },
319 };318 };
320319
src/libs/libunwind.zig+19-20
...@@ -10,7 +10,7 @@ const trace = @import("../tracy.zig").trace;...@@ -10,7 +10,7 @@ const trace = @import("../tracy.zig").trace;
1010
11pub const BuildError = error{11pub const BuildError = error{
12 OutOfMemory,12 OutOfMemory,
13 SubCompilationFailed,13 AlreadyReported,
14 ZigCompilerNotBuiltWithLLVMExtensions,14 ZigCompilerNotBuiltWithLLVMExtensions,
15};15};
1616
...@@ -42,12 +42,12 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -42,12 +42,12 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
42 .any_unwind_tables = unwind_tables != .none,42 .any_unwind_tables = unwind_tables != .none,
43 .lto = comp.config.lto,43 .lto = comp.config.lto,
44 }) catch |err| {44 }) catch |err| {
45 comp.setMiscFailure(45 comp.lockAndSetMiscFailure(
46 .libunwind,46 .libunwind,
47 "unable to build libunwind: resolving configuration failed: {s}",47 "unable to build libunwind: resolving configuration failed: {s}",
48 .{@errorName(err)},48 .{@errorName(err)},
49 );49 );
50 return error.SubCompilationFailed;50 return error.AlreadyReported;
51 };51 };
52 const root_mod = Module.create(arena, .{52 const root_mod = Module.create(arena, .{
53 .paths = .{53 .paths = .{
...@@ -76,12 +76,12 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -76,12 +76,12 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
76 .cc_argv = &.{},76 .cc_argv = &.{},
77 .parent = null,77 .parent = null,
78 }) catch |err| {78 }) catch |err| {
79 comp.setMiscFailure(79 comp.lockAndSetMiscFailure(
80 .libunwind,80 .libunwind,
81 "unable to build libunwind: creating module failed: {s}",81 "unable to build libunwind: creating module failed: {s}",
82 .{@errorName(err)},82 .{@errorName(err)},
83 );83 );
84 return error.SubCompilationFailed;84 return error.AlreadyReported;
85 };85 };
8686
87 const root_name = "unwind";87 const root_name = "unwind";
...@@ -139,7 +139,11 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -139,7 +139,11 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
139 .owner = root_mod,139 .owner = root_mod,
140 };140 };
141 }141 }
142 const sub_compilation = Compilation.create(comp.gpa, arena, .{142
143 const misc_task: Compilation.MiscTask = .libunwind;
144
145 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
146 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
143 .dirs = comp.dirs.withoutLocalCache(),147 .dirs = comp.dirs.withoutLocalCache(),
144 .self_exe_path = comp.self_exe_path,148 .self_exe_path = comp.self_exe_path,
145 .config = config,149 .config = config,
...@@ -162,24 +166,19 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -162,24 +166,19 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
162 .clang_passthrough_mode = comp.clang_passthrough_mode,166 .clang_passthrough_mode = comp.clang_passthrough_mode,
163 .skip_linker_dependencies = true,167 .skip_linker_dependencies = true,
164 }) catch |err| {168 }) catch |err| {
165 comp.setMiscFailure(169 switch (err) {
166 .libunwind,170 else => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {t}", .{ misc_task, err }),
167 "unable to build libunwind: create compilation failed: {s}",171 error.CreateFail => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {f}", .{ misc_task, sub_create_diag }),
168 .{@errorName(err)},172 }
169 );173 return error.AlreadyReported;
170 return error.SubCompilationFailed;
171 };174 };
172 defer sub_compilation.destroy();175 defer sub_compilation.destroy();
173176
174 comp.updateSubCompilation(sub_compilation, .libunwind, prog_node) catch |err| switch (err) {177 comp.updateSubCompilation(sub_compilation, misc_task, prog_node) catch |err| switch (err) {
175 error.SubCompilationFailed => return error.SubCompilationFailed,178 error.AlreadyReported => return error.AlreadyReported,
176 else => |e| {179 else => |e| {
177 comp.setMiscFailure(180 comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: compilation failed: {s}", .{ misc_task, @errorName(e) });
178 .libunwind,181 return error.AlreadyReported;
179 "unable to build libunwind: compilation failed: {s}",
180 .{@errorName(e)},
181 );
182 return error.SubCompilationFailed;
183 },182 },
184 };183 };
185184
src/libs/mingw.zig+1-1
...@@ -18,7 +18,7 @@ pub const CrtFile = enum {...@@ -18,7 +18,7 @@ pub const CrtFile = enum {
18};18};
1919
20/// TODO replace anyerror with explicit error set, recording user-friendly errors with20/// TODO replace anyerror with explicit error set, recording user-friendly errors with
21/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.21/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
22pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {22pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {
23 if (!build_options.have_llvm) {23 if (!build_options.have_llvm) {
24 return error.ZigCompilerNotBuiltWithLLVMExtensions;24 return error.ZigCompilerNotBuiltWithLLVMExtensions;
src/libs/musl.zig+13-4
...@@ -17,7 +17,7 @@ pub const CrtFile = enum {...@@ -17,7 +17,7 @@ pub const CrtFile = enum {
17};17};
1818
19/// TODO replace anyerror with explicit error set, recording user-friendly errors with19/// TODO replace anyerror with explicit error set, recording user-friendly errors with
20/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.20/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
21pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {21pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {
22 if (!build_options.have_llvm) {22 if (!build_options.have_llvm) {
23 return error.ZigCompilerNotBuiltWithLLVMExtensions;23 return error.ZigCompilerNotBuiltWithLLVMExtensions;
...@@ -243,7 +243,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro...@@ -243,7 +243,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
243 .parent = null,243 .parent = null,
244 });244 });
245245
246 const sub_compilation = try Compilation.create(comp.gpa, arena, .{246 const misc_task: Compilation.MiscTask = .@"musl libc.so";
247
248 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
249 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
247 .dirs = comp.dirs.withoutLocalCache(),250 .dirs = comp.dirs.withoutLocalCache(),
248 .self_exe_path = comp.self_exe_path,251 .self_exe_path = comp.self_exe_path,
249 .cache_mode = .whole,252 .cache_mode = .whole,
...@@ -268,10 +271,16 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro...@@ -268,10 +271,16 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
268 },271 },
269 .skip_linker_dependencies = true,272 .skip_linker_dependencies = true,
270 .soname = "libc.so",273 .soname = "libc.so",
271 });274 }) catch |err| switch (err) {
275 error.CreateFail => {
276 comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
277 return error.AlreadyReported;
278 },
279 else => |e| return e,
280 };
272 defer sub_compilation.destroy();281 defer sub_compilation.destroy();
273282
274 try comp.updateSubCompilation(sub_compilation, .@"musl libc.so", prog_node);283 try comp.updateSubCompilation(sub_compilation, misc_task, prog_node);
275284
276 const basename = try comp.gpa.dupe(u8, "libc.so");285 const basename = try comp.gpa.dupe(u8, "libc.so");
277 errdefer comp.gpa.free(basename);286 errdefer comp.gpa.free(basename);
src/libs/netbsd.zig+14-5
...@@ -49,7 +49,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const...@@ -49,7 +49,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const
49}49}
5050
51/// TODO replace anyerror with explicit error set, recording user-friendly errors with51/// TODO replace anyerror with explicit error set, recording user-friendly errors with
52/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.52/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
53pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {53pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {
54 if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;54 if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions;
5555
...@@ -360,7 +360,7 @@ fn wordDirective(target: *const std.Target) []const u8 {...@@ -360,7 +360,7 @@ fn wordDirective(target: *const std.Target) []const u8 {
360}360}
361361
362/// TODO replace anyerror with explicit error set, recording user-friendly errors with362/// TODO replace anyerror with explicit error set, recording user-friendly errors with
363/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.363/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
364pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {364pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anyerror!void {
365 // See also glibc.zig which this code is based on.365 // See also glibc.zig which this code is based on.
366366
...@@ -729,7 +729,10 @@ fn buildSharedLib(...@@ -729,7 +729,10 @@ fn buildSharedLib(
729 },729 },
730 };730 };
731731
732 const sub_compilation = try Compilation.create(comp.gpa, arena, .{732 const misc_task: Compilation.MiscTask = .@"netbsd libc shared object";
733
734 var sub_create_diag: Compilation.CreateDiagnostic = undefined;
735 const sub_compilation = Compilation.create(comp.gpa, arena, &sub_create_diag, .{
733 .dirs = comp.dirs.withoutLocalCache(),736 .dirs = comp.dirs.withoutLocalCache(),
734 .thread_pool = comp.thread_pool,737 .thread_pool = comp.thread_pool,
735 .self_exe_path = comp.self_exe_path,738 .self_exe_path = comp.self_exe_path,
...@@ -753,8 +756,14 @@ fn buildSharedLib(...@@ -753,8 +756,14 @@ fn buildSharedLib(
753 .soname = soname,756 .soname = soname,
754 .c_source_files = &c_source_files,757 .c_source_files = &c_source_files,
755 .skip_linker_dependencies = true,758 .skip_linker_dependencies = true,
756 });759 }) catch |err| switch (err) {
760 error.CreateFail => {
761 comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
762 return error.AlreadyReported;
763 },
764 else => |e| return e,
765 };
757 defer sub_compilation.destroy();766 defer sub_compilation.destroy();
758767
759 try comp.updateSubCompilation(sub_compilation, .@"netbsd libc shared object", prog_node);768 try comp.updateSubCompilation(sub_compilation, misc_task, prog_node);
760}769}
src/libs/wasi_libc.zig+1-1
...@@ -28,7 +28,7 @@ pub fn execModelCrtFileFullName(wasi_exec_model: std.builtin.WasiExecModel) []co...@@ -28,7 +28,7 @@ pub fn execModelCrtFileFullName(wasi_exec_model: std.builtin.WasiExecModel) []co
28}28}
2929
30/// TODO replace anyerror with explicit error set, recording user-friendly errors with30/// TODO replace anyerror with explicit error set, recording user-friendly errors with
31/// setMiscFailure and returning error.SubCompilationFailed. see libcxx.zig for example.31/// lockAndSetMiscFailure and returning error.AlreadyReported. see libcxx.zig for example.
32pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {32pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progress.Node) anyerror!void {
33 if (!build_options.have_llvm) {33 if (!build_options.have_llvm) {
34 return error.ZigCompilerNotBuiltWithLLVMExtensions;34 return error.ZigCompilerNotBuiltWithLLVMExtensions;
src/link.zig+2
...@@ -509,6 +509,8 @@ pub const File = struct {...@@ -509,6 +509,8 @@ pub const File = struct {
509 };509 };
510 };510 };
511511
512 pub const OpenError = @typeInfo(@typeInfo(@TypeOf(open)).@"fn".return_type.?).error_union.error_set;
513
512 /// Attempts incremental linking, if the file already exists. If514 /// Attempts incremental linking, if the file already exists. If
513 /// incremental linking fails, falls back to truncating the file and515 /// incremental linking fails, falls back to truncating the file and
514 /// rewriting it. A malicious file is detected as incremental link failure516 /// rewriting it. A malicious file is detected as incremental link failure
src/main.zig+58-50
...@@ -3395,7 +3395,8 @@ fn buildOutputType(...@@ -3395,7 +3395,8 @@ fn buildOutputType(
3395 var file_system_inputs: std.ArrayListUnmanaged(u8) = .empty;3395 var file_system_inputs: std.ArrayListUnmanaged(u8) = .empty;
3396 defer file_system_inputs.deinit(gpa);3396 defer file_system_inputs.deinit(gpa);
33973397
3398 const comp = Compilation.create(gpa, arena, .{3398 var create_diag: Compilation.CreateDiagnostic = undefined;
3399 const comp = Compilation.create(gpa, arena, &create_diag, .{
3399 .dirs = dirs,3400 .dirs = dirs,
3400 .thread_pool = &thread_pool,3401 .thread_pool = &thread_pool,
3401 .self_exe_path = switch (native_os) {3402 .self_exe_path = switch (native_os) {
...@@ -3521,47 +3522,45 @@ fn buildOutputType(...@@ -3521,47 +3522,45 @@ fn buildOutputType(
3521 .file_system_inputs = &file_system_inputs,3522 .file_system_inputs = &file_system_inputs,
3522 .debug_compiler_runtime_libs = debug_compiler_runtime_libs,3523 .debug_compiler_runtime_libs = debug_compiler_runtime_libs,
3523 }) catch |err| switch (err) {3524 }) catch |err| switch (err) {
3524 error.LibCUnavailable => {3525 error.CreateFail => switch (create_diag) {
3525 const triple_name = try target.zigTriple(arena);3526 .cross_libc_unavailable => {
3526 std.log.err("unable to find or provide libc for target '{s}'", .{triple_name});3527 // We can emit a more informative error for this.
35273528 const triple_name = try target.zigTriple(arena);
3528 for (std.zig.target.available_libcs) |t| {3529 std.log.err("unable to provide libc for target '{s}'", .{triple_name});
3529 if (t.arch == target.cpu.arch and t.os == target.os.tag) {3530
3530 // If there's a `glibc_min`, there's also an `os_ver`.3531 for (std.zig.target.available_libcs) |t| {
3531 if (t.glibc_min) |glibc_min| {3532 if (t.arch == target.cpu.arch and t.os == target.os.tag) {
3532 std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}.{d}.{d}", .{3533 // If there's a `glibc_min`, there's also an `os_ver`.
3533 @tagName(t.arch),3534 if (t.glibc_min) |glibc_min| {
3534 @tagName(t.os),3535 std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}.{d}.{d}", .{
3535 t.os_ver.?,3536 @tagName(t.arch),
3536 @tagName(t.abi),3537 @tagName(t.os),
3537 glibc_min.major,3538 t.os_ver.?,
3538 glibc_min.minor,3539 @tagName(t.abi),
3539 });3540 glibc_min.major,
3540 } else if (t.os_ver) |os_ver| {3541 glibc_min.minor,
3541 std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}", .{3542 });
3542 @tagName(t.arch),3543 } else if (t.os_ver) |os_ver| {
3543 @tagName(t.os),3544 std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}", .{
3544 os_ver,3545 @tagName(t.arch),
3545 @tagName(t.abi),3546 @tagName(t.os),
3546 });3547 os_ver,
3547 } else {3548 @tagName(t.abi),
3548 std.log.info("zig can provide libc for related target {s}-{s}-{s}", .{3549 });
3549 @tagName(t.arch),3550 } else {
3550 @tagName(t.os),3551 std.log.info("zig can provide libc for related target {s}-{s}-{s}", .{
3551 @tagName(t.abi),3552 @tagName(t.arch),
3552 });3553 @tagName(t.os),
3554 @tagName(t.abi),
3555 });
3556 }
3553 }3557 }
3554 }3558 }
3555 }3559 process.exit(1);
3556 process.exit(1);3560 },
3557 },3561 else => fatal("{f}", .{create_diag}),
3558 error.ExportTableAndImportTableConflict => {
3559 fatal("--import-table and --export-table may not be used together", .{});
3560 },
3561 error.IllegalZigImport => {
3562 fatal("this compiler implementation does not support importing the root source file of a provided module", .{});
3563 },3562 },
3564 else => fatal("unable to create compilation: {s}", .{@errorName(err)}),3563 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
3565 };3564 };
3566 var comp_destroyed = false;3565 var comp_destroyed = false;
3567 defer if (!comp_destroyed) comp.destroy();3566 defer if (!comp_destroyed) comp.destroy();
...@@ -3627,7 +3626,7 @@ fn buildOutputType(...@@ -3627,7 +3626,7 @@ fn buildOutputType(
3627 }3626 }
36283627
3629 updateModule(comp, color, root_prog_node) catch |err| switch (err) {3628 updateModule(comp, color, root_prog_node) catch |err| switch (err) {
3630 error.SemanticAnalyzeFail => {3629 error.CompileErrorsReported => {
3631 assert(listen == .none);3630 assert(listen == .none);
3632 saveState(comp, incremental);3631 saveState(comp, incremental);
3633 process.exit(1);3632 process.exit(1);
...@@ -4521,7 +4520,12 @@ fn runOrTestHotSwap(...@@ -4521,7 +4520,12 @@ fn runOrTestHotSwap(
4521 }4520 }
4522}4521}
45234522
4524fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node) !void {4523const UpdateModuleError = Compilation.UpdateError || error{
4524 /// The update caused compile errors. The error bundle has already been
4525 /// reported to the user by being rendered to stderr.
4526 CompileErrorsReported,
4527};
4528fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node) UpdateModuleError!void {
4525 try comp.update(prog_node);4529 try comp.update(prog_node);
45264530
4527 var errors = try comp.getAllErrorsAlloc();4531 var errors = try comp.getAllErrorsAlloc();
...@@ -4529,7 +4533,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)...@@ -4529,7 +4533,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
45294533
4530 if (errors.errorMessageCount() > 0) {4534 if (errors.errorMessageCount() > 0) {
4531 errors.renderToStdErr(color.renderOptions());4535 errors.renderToStdErr(color.renderOptions());
4532 return error.SemanticAnalyzeFail;4536 return error.CompileErrorsReported;
4533 }4537 }
4534}4538}
45354539
...@@ -5373,7 +5377,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5373,7 +5377,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
53735377
5374 try root_mod.deps.put(arena, "@build", build_mod);5378 try root_mod.deps.put(arena, "@build", build_mod);
53755379
5376 const comp = Compilation.create(gpa, arena, .{5380 var create_diag: Compilation.CreateDiagnostic = undefined;
5381 const comp = Compilation.create(gpa, arena, &create_diag, .{
5377 .libc_installation = libc_installation,5382 .libc_installation = libc_installation,
5378 .dirs = dirs,5383 .dirs = dirs,
5379 .root_name = "build",5384 .root_name = "build",
...@@ -5395,13 +5400,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5395,13 +5400,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5395 .cache_mode = .whole,5400 .cache_mode = .whole,
5396 .reference_trace = reference_trace,5401 .reference_trace = reference_trace,
5397 .debug_compile_errors = debug_compile_errors,5402 .debug_compile_errors = debug_compile_errors,
5398 }) catch |err| {5403 }) catch |err| switch (err) {
5399 fatal("unable to create compilation: {s}", .{@errorName(err)});5404 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
5405 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
5400 };5406 };
5401 defer comp.destroy();5407 defer comp.destroy();
54025408
5403 updateModule(comp, color, root_prog_node) catch |err| switch (err) {5409 updateModule(comp, color, root_prog_node) catch |err| switch (err) {
5404 error.SemanticAnalyzeFail => process.exit(2),5410 error.CompileErrorsReported => process.exit(2),
5405 else => |e| return e,5411 else => |e| return e,
5406 };5412 };
54075413
...@@ -5614,7 +5620,8 @@ fn jitCmd(...@@ -5614,7 +5620,8 @@ fn jitCmd(
5614 try root_mod.deps.put(arena, "aro", aro_mod);5620 try root_mod.deps.put(arena, "aro", aro_mod);
5615 }5621 }
56165622
5617 const comp = Compilation.create(gpa, arena, .{5623 var create_diag: Compilation.CreateDiagnostic = undefined;
5624 const comp = Compilation.create(gpa, arena, &create_diag, .{
5618 .dirs = dirs,5625 .dirs = dirs,
5619 .root_name = options.cmd_name,5626 .root_name = options.cmd_name,
5620 .config = config,5627 .config = config,
...@@ -5624,8 +5631,9 @@ fn jitCmd(...@@ -5624,8 +5631,9 @@ fn jitCmd(
5624 .self_exe_path = self_exe_path,5631 .self_exe_path = self_exe_path,
5625 .thread_pool = &thread_pool,5632 .thread_pool = &thread_pool,
5626 .cache_mode = .whole,5633 .cache_mode = .whole,
5627 }) catch |err| {5634 }) catch |err| switch (err) {
5628 fatal("unable to create compilation: {s}", .{@errorName(err)});5635 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
5636 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
5629 };5637 };
5630 defer comp.destroy();5638 defer comp.destroy();
56315639
...@@ -5646,7 +5654,7 @@ fn jitCmd(...@@ -5646,7 +5654,7 @@ fn jitCmd(
5646 }5654 }
5647 } else {5655 } else {
5648 updateModule(comp, color, root_prog_node) catch |err| switch (err) {5656 updateModule(comp, color, root_prog_node) catch |err| switch (err) {
5649 error.SemanticAnalyzeFail => process.exit(2),5657 error.CompileErrorsReported => process.exit(2),
5650 else => |e| return e,5658 else => |e| return e,
5651 };5659 };
5652 }5660 }