aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-01-25 04:48:16 +0000
committermlugg <mlugg@mlugg.co.uk>2025-01-25 06:07:08 +0000
commitf47b8de2ad706616b648c52f5036102cb804e65d (patch)
tree20246773622e31440107d87455d5a01ac1cd8dcf /src/Sema.zig
parent5202c977d95bf65775e733264b7d37ed940a2997 (diff)
downloadzig-f47b8de2ad706616b648c52f5036102cb804e65d.tar.gz
zig-f47b8de2ad706616b648c52f5036102cb804e65d.zip
incremental: handle `@embedFile`
Uses of `@embedFile` register dependencies on the corresponding `Zcu.EmbedFile`. At the start of every update, we iterate all embedded files and update them if necessary, and invalidate the dependencies if they changed. In order to properly integrate with the lazy analysis model, failed embed files are now reported by the `AnalUnit` which actually used `@embedFile`; the filesystem error is stored in the `Zcu.EmbedFile`. An incremental test is added covering incremental updates to embedded files, and I have verified locally that dependency invalidation is working correctly.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 833b05413f..0b06eba519 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -13949,6 +13949,8 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
defer tracy.end();
const pt = sema.pt;
+ const zcu = pt.zcu;
+
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{ .simple = .operand_embedFile });
@@ -13957,18 +13959,24 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
return sema.fail(block, operand_src, "file path name cannot be empty", .{});
}
- const val = pt.embedFile(block.getFileScope(pt.zcu), name, operand_src) catch |err| switch (err) {
+ const ef_idx = pt.embedFile(block.getFileScope(zcu), name) catch |err| switch (err) {
error.ImportOutsideModulePath => {
return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});
},
- else => {
- // TODO: these errors are file system errors; make sure an update() will
- // retry this and not cache the file system error, which may be transient.
- return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ name, @errorName(err) });
+ error.CurrentWorkingDirectoryUnlinked => {
+ // TODO: this should be some kind of retryable failure, in case the cwd is put back
+ return sema.fail(block, operand_src, "unable to resolve '{s}': working directory has been unlinked", .{name});
},
+ error.OutOfMemory => |e| return e,
};
+ try sema.declareDependency(.{ .embed_file = ef_idx });
+
+ const result = ef_idx.get(zcu);
+ if (result.val == .none) {
+ return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ name, @errorName(result.err.?) });
+ }
- return Air.internedToRef(val);
+ return Air.internedToRef(result.val);
}
fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {