diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2025-01-25 04:48:16 +0000 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2025-01-25 06:07:08 +0000 |
| commit | f47b8de2ad706616b648c52f5036102cb804e65d (patch) | |
| tree | 20246773622e31440107d87455d5a01ac1cd8dcf /src/Sema.zig | |
| parent | 5202c977d95bf65775e733264b7d37ed940a2997 (diff) | |
| download | zig-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.zig | 20 |
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 { |
