aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
diff options
context:
space:
mode:
authorMatthew Lugg <mlugg@mlugg.co.uk>2025-11-18 12:03:06 +0000
committerMatthew Lugg <mlugg@mlugg.co.uk>2025-11-19 09:44:22 +0000
commit806470b492f15c4e3350ce4a48e607f2c8e94ff8 (patch)
tree3bbc7184dc62cc4f1e583c9e907620517f44e4c7 /src/Compilation.zig
parent4ea472808437c932f6240c0df5e4d5912d282052 (diff)
downloadzig-806470b492f15c4e3350ce4a48e607f2c8e94ff8.tar.gz
zig-806470b492f15c4e3350ce4a48e607f2c8e94ff8.zip
compiler: fix crash if file contents change during update
When reporting a compile error, we would load the new file, but assume we could apply old AST/token indices (etc) to it, potentially causing crashes. Instead, if the file stat has changed since it was loaded, just emit an error that the file was modified mid-update.
Diffstat (limited to 'src/Compilation.zig')
-rw-r--r--src/Compilation.zig19
1 files changed, 10 insertions, 9 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index d6167b2e66..2d92e27f38 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -3935,17 +3935,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
for (zcu.failed_imports.items) |failed| {
assert(zcu.alive_files.contains(failed.file_index)); // otherwise it wouldn't have been added
const file = zcu.fileByIndex(failed.file_index);
- const source = file.getSource(zcu) catch |err| {
- try unableToLoadZcuFile(zcu, &bundle, file, err);
- continue;
- };
const tree = file.getTree(zcu) catch |err| {
try unableToLoadZcuFile(zcu, &bundle, file, err);
continue;
};
const start = tree.tokenStart(failed.import_token);
const end = start + tree.tokenSlice(failed.import_token).len;
- const loc = std.zig.findLineColumn(source.bytes, start);
+ const loc = std.zig.findLineColumn(tree.source, start);
try bundle.addRootErrorMessage(.{
.msg = switch (failed.kind) {
.file_outside_module_root => try bundle.addString("import of file outside module path"),
@@ -4338,7 +4334,7 @@ pub fn addModuleErrorMsg(
const err_span = err_src_loc.span(zcu) catch |err| {
return unableToLoadZcuFile(zcu, eb, err_src_loc.file_scope, err);
};
- const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main);
+ const err_loc = std.zig.findLineColumn(err_source, err_span.main);
var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty;
defer ref_traces.deinit(gpa);
@@ -4434,7 +4430,7 @@ pub fn addModuleErrorMsg(
const span = note_src_loc.span(zcu) catch |err| {
return unableToLoadZcuFile(zcu, eb, note_src_loc.file_scope, err);
};
- const loc = std.zig.findLineColumn(source.bytes, span.main);
+ const loc = std.zig.findLineColumn(source, span.main);
const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?));
last_note_loc = loc;
@@ -4489,7 +4485,7 @@ fn addReferenceTraceFrame(
try unableToLoadZcuFile(zcu, eb, src.file_scope, err);
return error.AlreadyReported;
};
- const loc = std.zig.findLineColumn(source.bytes, span.main);
+ const loc = std.zig.findLineColumn(source, span.main);
try ref_traces.append(gpa, .{
.decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }),
.src_loc = try eb.addSourceLocation(.{
@@ -4545,8 +4541,13 @@ pub fn unableToLoadZcuFile(
file: *Zcu.File,
err: Zcu.File.GetSourceError,
) Allocator.Error!void {
+ const msg = switch (err) {
+ error.OutOfMemory => |e| return e,
+ error.FileChanged => try eb.addString("file contents changed during update"),
+ else => |e| try eb.printString("unable to load: {t}", .{e}),
+ };
try eb.addRootErrorMessage(.{
- .msg = try eb.printString("unable to load: {t}", .{err}),
+ .msg = msg,
.src_loc = try file.errorBundleWholeFileSrc(zcu, eb),
});
}