Commit 4000685557

Andrew Kelley <andrew@ziglang.org>
2024-10-10 23:19:32
Compilation: don't write cache manifest on failure
When errors occurred during flush(), incremental cache mode was still writing a successful cache manifest, making subsequent compilations fail because they would get a cache hit only to find invalid data.
1 parent 01aab9f
Changed files (1)
src/Compilation.zig
@@ -2302,7 +2302,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
         try pt.processExports();
     }
 
-    if (try comp.totalErrorCount() != 0) {
+    if (anyErrors(comp)) {
         // Skip flushing and keep source files loaded for error reporting.
         comp.link_error_flags = .{};
         return;
@@ -2392,6 +2392,10 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
                 .sub_path = o_sub_path,
             }, .main, main_progress_node);
 
+            // Calling `flush` may have produced errors, in which case the
+            // cache manifest must not be written.
+            if (anyErrors(comp)) return;
+
             // Failure here only means an unnecessary cache miss.
             man.writeManifest() catch |err| {
                 log.warn("failed to write cache manifest: {s}", .{@errorName(err)});
@@ -3291,6 +3295,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
     return bundle.toOwnedBundle(compile_log_text);
 }
 
+fn anyErrors(comp: *Compilation) bool {
+    return (totalErrorCount(comp) catch return true) != 0;
+}
+
 fn totalErrorCount(comp: *Compilation) !u32 {
     var errors = try comp.getAllErrorsAlloc();
     defer errors.deinit(comp.gpa);