| author | |
| committer | |
| log | 37a9a4e0f16c1df8de3a4add3a9566b24f024a95 |
| tree | 0fc8f1fc15193e8e3c3ccd5e97408cef7372f394 |
| parent | d32829e053af2a0f382d4d692ede85c176c9f803 |
| signature |
This commit makes some big changes to how we track state for Zig source
files. In particular, it changes:
* How `File` tracks its path on-disk
* How AstGen discovers files
* How file-level errors are tracked
* How `builtin.zig` files and modules are created
The original motivation here was to address incremental compilation bugs
with the handling of files, such as #22696. To fix this, a few changes
are necessary.
Just like declarations may become unreferenced on an incremental update,
meaning we suppress analysis errors associated with them, it is also
possible for all imports of a file to be removed on an incremental
update, in which case file-level errors for that file should be
suppressed. As such, after AstGen, the compiler must traverse files
(starting from analysis roots) and discover the set of "live files" for
this update.
Additionally, the compiler's previous handling of retryable file errors
was not very good; the source location the error was reported as was
based only on the first discovered import of that file. This source
location also disappeared on future incremental updates. So, as a part
of the file traversal above, we also need to figure out the source
locations of imports which errors should be reported against.
Another observation I made is that the "file exists in multiple modules"
error was not implemented in a particularly good way (I get to say that
because I wrote it!). It was subject to races, where the order in which
different imports of a file were discovered affects both how errors are
printed, and which module the file is arbitrarily assigned, with the
latter in turn affecting which other files are considered for import.
The thing I realised here is that while the AstGen worker pool is
running, we cannot know for sure which module(s) a file is in; we could
always discover an import later which changes the answer.
So, here's how the AstGen workers have changed. We initially ensure that
`zcu.import_table` contains the root files for all modules in this Zcu,
even if we don't know any imports for them yet. Then, the AstGen
workers do not need to be aware of modules. Instead, they simply ignore
module imports, and only spin off more workers when they see a by-path
import.
During AstGen, we can't use module-root-relative paths, since we don't
know which modules files are in; but we don't want to unnecessarily use
absolute files either, because those are non-portable and can make
`error.NameTooLong` more likely. As such, I have introduced a new
abstraction, `Compilation.Path`. This type is a way of representing a
filesystem path which has a *canonical form*. The path is represented
relative to one of a few special directories: the lib directory, the
global cache directory, or the local cache directory. As a fallback, we
use absolute (or cwd-relative on WASI) paths. This is kind of similar to
`std.Build.Cache.Path` with a pre-defined list of possible
`std.Build.Cache.Directory`, but has stricter canonicalization rules
based on path resolution to make sure deduplicating files works
properly. A `Compilation.Path` can be trivially converted to a
`std.Build.Cache.Path` from a `Compilation`, but is smaller, has a
canonical form, and has a digest which will be consistent across
different compiler processes with the same lib and cache directories
(important when we serialize incremental compilation state in the
future). `Zcu.File` and `Zcu.EmbedFile` both contain a
`Compilation.Path`, which is used to access the file on-disk;
module-relative sub paths are used quite rarely (`EmbedFile` doesn't
even have one now for simplicity).
After the AstGen workers all complete, we know that any file which might
be imported is definitely in `import_table` and up-to-date. So, we
perform a single-threaded graph traversal; similar to what
`resolveReferences` plays for `AnalUnit`s, but for files instead. We
figure out which files are alive, and which module each file is in. If a
file turns out to be in multiple modules, we set a field on `Zcu` to
indicate this error. If a file is in a different module to a prior
update, we set a flag instructing `updateZirRefs` to invalidate all
dependencies on the file. This traversal also discovers "import errors";
these are errors associated with a specific `@import`. With Zig's
current design, there is only one possible error here: "import outside
of module root". This must be identified during this traversal instead
of during AstGen, because it depends on which module the file is in. I
tried also representing "module not found" errors in this same way, but
it turns out to be much more useful to report those in Sema, because of
use cases like optional dependencies where a module import is behind a
comptime-known build option.
For simplicity, `failed_files` now just maps to `?[]u8`, since the
source location is always the whole file. In fact, this allows removing
`LazySrcLoc.Offset.entire_file` completely, slightly simplifying some
error reporting logic. File-level errors are now directly built in the
`std.zig.ErrorBundle.Wip`. If the payload is not `null`, it is the
message for a retryable error (i.e. an error loading the source file),
and will be reported with a "file imported here" note pointing to the
import site discovered during the single-threaded file traversal.
The last piece of fallout here is how `Builtin` works. Rather than
constructing "builtin" modules when creating `Package.Module`s, they are
now constructed on-the-fly by `Zcu`. The map `Zcu.builtin_modules` maps
from digests to `*Package.Module`s. These digests are abstract hashes of
the `Builtin` value; i.e. all of the options which are placed into
"builtin.zig". During the file traversal, we populate `builtin_modules`
as needed, so that when we see this imports in Sema, we just grab the
relevant entry from this map. This eliminates a bunch of awkward state
tracking during construction of the module graph. It's also now clearer
exactly what options the builtin module has, since previously it
inherited some options arbitrarily from the first-created module with
that "builtin" module!
The user-visible effects of this commit are:
* retryable file errors are now consistently reported against the whole
file, with a note pointing to a live import of that file
* some theoretical bugs where imports are wrongly considered distinct
(when the import path moves out of the cwd and then back in) are fixed
* some consistency issues with how file-level errors are reported are
fixed; these errors will now always be printed in the same order
regardless of how the AstGen pass assigns file indices
* incremental updates do not print retryable file errors differently
between updates or depending on file structure/contents
* incremental updates support files changing modules
* incremental updates support files becoming unreferenced
Resolves: #2269649 files changed, 2746 insertions(+), 2377 deletions(-)
src/Builtin.zig+64-27| ... | @@ -19,6 +19,26 @@ code_model: std.builtin.CodeModel, | ... | @@ -19,6 +19,26 @@ code_model: std.builtin.CodeModel, |
| 19 | omit_frame_pointer: bool, | 19 | omit_frame_pointer: bool, |
| 20 | wasi_exec_model: std.builtin.WasiExecModel, | 20 | wasi_exec_model: std.builtin.WasiExecModel, |
| 21 | 21 | ||
| 22 | /// Compute an abstract hash representing this `Builtin`. This is *not* a hash | ||
| 23 | /// of the resulting file contents. | ||
| 24 | pub fn hash(opts: @This()) [std.Build.Cache.bin_digest_len]u8 { | ||
| 25 | var h: Cache.Hasher = Cache.hasher_init; | ||
| 26 | inline for (@typeInfo(@This()).@"struct".fields) |f| { | ||
| 27 | if (comptime std.mem.eql(u8, f.name, "target")) { | ||
| 28 | // This needs special handling. | ||
| 29 | std.hash.autoHash(&h, opts.target.cpu); | ||
| 30 | std.hash.autoHash(&h, opts.target.os.tag); | ||
| 31 | std.hash.autoHash(&h, opts.target.os.versionRange()); | ||
| 32 | std.hash.autoHash(&h, opts.target.abi); | ||
| 33 | std.hash.autoHash(&h, opts.target.ofmt); | ||
| 34 | std.hash.autoHash(&h, opts.target.dynamic_linker); | ||
| 35 | } else { | ||
| 36 | std.hash.autoHash(&h, @field(opts, f.name)); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | return h.finalResult(); | ||
| 40 | } | ||
| 41 | |||
| 22 | pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 { | 42 | pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 { |
| 23 | var buffer = std.ArrayList(u8).init(allocator); | 43 | var buffer = std.ArrayList(u8).init(allocator); |
| 24 | try append(opts, &buffer); | 44 | try append(opts, &buffer); |
| ... | @@ -263,50 +283,66 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { | ... | @@ -263,50 +283,66 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 263 | } | 283 | } |
| 264 | } | 284 | } |
| 265 | 285 | ||
| 266 | pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void { | 286 | /// This essentially takes the place of `Zcu.PerThread.updateFile`, but for 'builtin' modules. |
| 267 | if (mod.root.statFile(mod.root_src_path)) |stat| { | 287 | /// Instead of reading the file from disk, its contents are generated in-memory. |
| 288 | pub fn populateFile(opts: @This(), gpa: Allocator, file: *File) Allocator.Error!void { | ||
| 289 | assert(file.is_builtin); | ||
| 290 | assert(file.status == .never_loaded); | ||
| 291 | assert(file.source == null); | ||
| 292 | assert(file.tree == null); | ||
| 293 | assert(file.zir == null); | ||
| 294 | |||
| 295 | file.source = try opts.generate(gpa); | ||
| 296 | |||
| 297 | log.debug("parsing and generating 'builtin.zig'", .{}); | ||
| 298 | |||
| 299 | file.tree = try std.zig.Ast.parse(gpa, file.source.?, .zig); | ||
| 300 | assert(file.tree.?.errors.len == 0); // builtin.zig must parse | ||
| 301 | |||
| 302 | file.zir = try AstGen.generate(gpa, file.tree.?); | ||
| 303 | assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors | ||
| 304 | file.status = .success; | ||
| 305 | } | ||
| 306 | |||
| 307 | /// After `populateFile` succeeds, call this function to write the generated file out to disk | ||
| 308 | /// if necessary. This is useful for external tooling such as debuggers. | ||
| 309 | /// Assumes that `file.mod` is correctly set to the builtin module. | ||
| 310 | pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { | ||
| 311 | assert(file.is_builtin); | ||
| 312 | assert(file.status == .success); | ||
| 313 | assert(file.source != null); | ||
| 314 | |||
| 315 | const root_dir, const sub_path = file.path.openInfo(comp.dirs); | ||
| 316 | |||
| 317 | if (root_dir.statFile(sub_path)) |stat| { | ||
| 268 | if (stat.size != file.source.?.len) { | 318 | if (stat.size != file.source.?.len) { |
| 269 | std.log.warn( | 319 | std.log.warn( |
| 270 | "the cached file '{}{s}' had the wrong size. Expected {d}, found {d}. " ++ | 320 | "the cached file '{}' had the wrong size. Expected {d}, found {d}. " ++ |
| 271 | "Overwriting with correct file contents now", | 321 | "Overwriting with correct file contents now", |
| 272 | .{ mod.root, mod.root_src_path, file.source.?.len, stat.size }, | 322 | .{ file.path.fmt(comp), file.source.?.len, stat.size }, |
| 273 | ); | 323 | ); |
| 274 | |||
| 275 | try writeFile(file, mod); | ||
| 276 | } else { | 324 | } else { |
| 277 | file.stat = .{ | 325 | file.stat = .{ |
| 278 | .size = stat.size, | 326 | .size = stat.size, |
| 279 | .inode = stat.inode, | 327 | .inode = stat.inode, |
| 280 | .mtime = stat.mtime, | 328 | .mtime = stat.mtime, |
| 281 | }; | 329 | }; |
| 330 | return; | ||
| 282 | } | 331 | } |
| 283 | } else |err| switch (err) { | 332 | } else |err| switch (err) { |
| 284 | error.BadPathName => unreachable, // it's always "builtin.zig" | 333 | error.FileNotFound => {}, |
| 285 | error.NameTooLong => unreachable, // it's always "builtin.zig" | ||
| 286 | error.PipeBusy => unreachable, // it's not a pipe | ||
| 287 | error.NoDevice => unreachable, // it's not a pipe | ||
| 288 | error.WouldBlock => unreachable, // not asking for non-blocking I/O | ||
| 289 | 334 | ||
| 290 | error.FileNotFound => try writeFile(file, mod), | 335 | error.WouldBlock => unreachable, // not asking for non-blocking I/O |
| 336 | error.BadPathName => unreachable, // it's always "o/digest/builtin.zig" | ||
| 337 | error.NameTooLong => unreachable, // it's always "o/digest/builtin.zig" | ||
| 291 | 338 | ||
| 339 | // We don't expect the file to be a pipe, but can't mark `error.PipeBusy` as `unreachable`, | ||
| 340 | // because the user could always replace the file on disk. | ||
| 292 | else => |e| return e, | 341 | else => |e| return e, |
| 293 | } | 342 | } |
| 294 | 343 | ||
| 295 | log.debug("parsing and generating '{s}'", .{mod.root_src_path}); | 344 | // `make_path` matters because the dir hasn't actually been created yet. |
| 296 | 345 | var af = try root_dir.atomicFile(sub_path, .{ .make_path = true }); | |
| 297 | file.tree = try std.zig.Ast.parse(comp.gpa, file.source.?, .zig); | ||
| 298 | assert(file.tree.?.errors.len == 0); // builtin.zig must parse | ||
| 299 | |||
| 300 | file.zir = try AstGen.generate(comp.gpa, file.tree.?); | ||
| 301 | assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors | ||
| 302 | file.status = .success; | ||
| 303 | // Note that whilst we set `zir` here, we populated `path_digest` | ||
| 304 | // all the way back in `Package.Module.create`. | ||
| 305 | } | ||
| 306 | |||
| 307 | fn writeFile(file: *File, mod: *Module) !void { | ||
| 308 | var buf: [std.fs.max_path_bytes]u8 = undefined; | ||
| 309 | var af = try mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf); | ||
| 310 | defer af.deinit(); | 346 | defer af.deinit(); |
| 311 | try af.file.writeAll(file.source.?); | 347 | try af.file.writeAll(file.source.?); |
| 312 | af.finish() catch |err| switch (err) { | 348 | af.finish() catch |err| switch (err) { |
| ... | @@ -331,6 +367,7 @@ fn writeFile(file: *File, mod: *Module) !void { | ... | @@ -331,6 +367,7 @@ fn writeFile(file: *File, mod: *Module) !void { |
| 331 | const builtin = @import("builtin"); | 367 | const builtin = @import("builtin"); |
| 332 | const std = @import("std"); | 368 | const std = @import("std"); |
| 333 | const Allocator = std.mem.Allocator; | 369 | const Allocator = std.mem.Allocator; |
| 370 | const Cache = std.Build.Cache; | ||
| 334 | const build_options = @import("build_options"); | 371 | const build_options = @import("build_options"); |
| 335 | const Module = @import("Package/Module.zig"); | 372 | const Module = @import("Package/Module.zig"); |
| 336 | const assert = std.debug.assert; | 373 | const assert = std.debug.assert; |
src/Compilation.zig+830-577| ... | @@ -2,6 +2,7 @@ const Compilation = @This(); | ... | @@ -2,6 +2,7 @@ const Compilation = @This(); |
| 2 | 2 | ||
| 3 | const std = @import("std"); | 3 | const std = @import("std"); |
| 4 | const builtin = @import("builtin"); | 4 | const builtin = @import("builtin"); |
| 5 | const fs = std.fs; | ||
| 5 | const mem = std.mem; | 6 | const mem = std.mem; |
| 6 | const Allocator = std.mem.Allocator; | 7 | const Allocator = std.mem.Allocator; |
| 7 | const assert = std.debug.assert; | 8 | const assert = std.debug.assert; |
| ... | @@ -10,12 +11,13 @@ const Target = std.Target; | ... | @@ -10,12 +11,13 @@ const Target = std.Target; |
| 10 | const ThreadPool = std.Thread.Pool; | 11 | const ThreadPool = std.Thread.Pool; |
| 11 | const WaitGroup = std.Thread.WaitGroup; | 12 | const WaitGroup = std.Thread.WaitGroup; |
| 12 | const ErrorBundle = std.zig.ErrorBundle; | 13 | const ErrorBundle = std.zig.ErrorBundle; |
| 13 | const Path = Cache.Path; | 14 | const fatal = std.process.fatal; |
| 14 | 15 | ||
| 15 | const Value = @import("Value.zig"); | 16 | const Value = @import("Value.zig"); |
| 16 | const Type = @import("Type.zig"); | 17 | const Type = @import("Type.zig"); |
| 17 | const target_util = @import("target.zig"); | 18 | const target_util = @import("target.zig"); |
| 18 | const Package = @import("Package.zig"); | 19 | const Package = @import("Package.zig"); |
| 20 | const introspect = @import("introspect.zig"); | ||
| 19 | const link = @import("link.zig"); | 21 | const link = @import("link.zig"); |
| 20 | const tracy = @import("tracy.zig"); | 22 | const tracy = @import("tracy.zig"); |
| 21 | const trace = tracy.trace; | 23 | const trace = tracy.trace; |
| ... | @@ -28,7 +30,6 @@ const mingw = @import("libs/mingw.zig"); | ... | @@ -28,7 +30,6 @@ const mingw = @import("libs/mingw.zig"); |
| 28 | const libunwind = @import("libs/libunwind.zig"); | 30 | const libunwind = @import("libs/libunwind.zig"); |
| 29 | const libcxx = @import("libs/libcxx.zig"); | 31 | const libcxx = @import("libs/libcxx.zig"); |
| 30 | const wasi_libc = @import("libs/wasi_libc.zig"); | 32 | const wasi_libc = @import("libs/wasi_libc.zig"); |
| 31 | const fatal = @import("main.zig").fatal; | ||
| 32 | const clangMain = @import("main.zig").clangMain; | 33 | const clangMain = @import("main.zig").clangMain; |
| 33 | const Zcu = @import("Zcu.zig"); | 34 | const Zcu = @import("Zcu.zig"); |
| 34 | const Sema = @import("Sema.zig"); | 35 | const Sema = @import("Sema.zig"); |
| ... | @@ -43,7 +44,6 @@ const LlvmObject = @import("codegen/llvm.zig").Object; | ... | @@ -43,7 +44,6 @@ const LlvmObject = @import("codegen/llvm.zig").Object; |
| 43 | const dev = @import("dev.zig"); | 44 | const dev = @import("dev.zig"); |
| 44 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; | 45 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; |
| 45 | 46 | ||
| 46 | pub const Directory = Cache.Directory; | ||
| 47 | pub const Config = @import("Compilation/Config.zig"); | 47 | pub const Config = @import("Compilation/Config.zig"); |
| 48 | 48 | ||
| 49 | /// General-purpose allocator. Used for both temporary and long-term storage. | 49 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| ... | @@ -75,9 +75,9 @@ bin_file: ?*link.File, | ... | @@ -75,9 +75,9 @@ bin_file: ?*link.File, |
| 75 | /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin) | 75 | /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin) |
| 76 | sysroot: ?[]const u8, | 76 | sysroot: ?[]const u8, |
| 77 | /// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used. | 77 | /// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used. |
| 78 | implib_emit: ?Path, | 78 | implib_emit: ?Cache.Path, |
| 79 | /// This is non-null when `-femit-docs` is provided. | 79 | /// This is non-null when `-femit-docs` is provided. |
| 80 | docs_emit: ?Path, | 80 | docs_emit: ?Cache.Path, |
| 81 | root_name: [:0]const u8, | 81 | root_name: [:0]const u8, |
| 82 | compiler_rt_strat: RtStrat, | 82 | compiler_rt_strat: RtStrat, |
| 83 | ubsan_rt_strat: RtStrat, | 83 | ubsan_rt_strat: RtStrat, |
| ... | @@ -152,11 +152,6 @@ win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.fifo.Linea | ... | @@ -152,11 +152,6 @@ win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.fifo.Linea |
| 152 | pub fn deinit(_: @This()) void {} | 152 | pub fn deinit(_: @This()) void {} |
| 153 | }, | 153 | }, |
| 154 | 154 | ||
| 155 | /// These jobs are to tokenize, parse, and astgen files, which may be outdated | ||
| 156 | /// since the last compilation, as well as scan for `@import` and queue up | ||
| 157 | /// additional jobs corresponding to those new files. | ||
| 158 | astgen_work_queue: std.fifo.LinearFifo(Zcu.File.Index, .Dynamic), | ||
| 159 | |||
| 160 | /// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator. | 155 | /// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator. |
| 161 | /// This data is accessed by multiple threads and is protected by `mutex`. | 156 | /// This data is accessed by multiple threads and is protected by `mutex`. |
| 162 | failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *CObject.Diag.Bundle) = .empty, | 157 | failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *CObject.Diag.Bundle) = .empty, |
| ... | @@ -207,9 +202,8 @@ cache_parent: *Cache, | ... | @@ -207,9 +202,8 @@ cache_parent: *Cache, |
| 207 | parent_whole_cache: ?ParentWholeCache, | 202 | parent_whole_cache: ?ParentWholeCache, |
| 208 | /// Path to own executable for invoking `zig clang`. | 203 | /// Path to own executable for invoking `zig clang`. |
| 209 | self_exe_path: ?[]const u8, | 204 | self_exe_path: ?[]const u8, |
| 210 | zig_lib_directory: Directory, | 205 | /// Owned by the caller of `Compilation.create`. |
| 211 | local_cache_directory: Directory, | 206 | dirs: Directories, |
| 212 | global_cache_directory: Directory, | ||
| 213 | libc_include_dir_list: []const []const u8, | 207 | libc_include_dir_list: []const []const u8, |
| 214 | libc_framework_dir_list: []const []const u8, | 208 | libc_framework_dir_list: []const []const u8, |
| 215 | rc_includes: RcIncludes, | 209 | rc_includes: RcIncludes, |
| ... | @@ -293,7 +287,6 @@ const QueuedJobs = struct { | ... | @@ -293,7 +287,6 @@ const QueuedJobs = struct { |
| 293 | ubsan_rt_lib: bool = false, | 287 | ubsan_rt_lib: bool = false, |
| 294 | ubsan_rt_obj: bool = false, | 288 | ubsan_rt_obj: bool = false, |
| 295 | fuzzer_lib: bool = false, | 289 | fuzzer_lib: bool = false, |
| 296 | update_builtin_zig: bool, | ||
| 297 | musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = @splat(false), | 290 | musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = @splat(false), |
| 298 | glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = @splat(false), | 291 | glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = @splat(false), |
| 299 | freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".fields.len]bool = @splat(false), | 292 | freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".fields.len]bool = @splat(false), |
| ... | @@ -312,12 +305,466 @@ const QueuedJobs = struct { | ... | @@ -312,12 +305,466 @@ const QueuedJobs = struct { |
| 312 | zigc_lib: bool = false, | 305 | zigc_lib: bool = false, |
| 313 | }; | 306 | }; |
| 314 | 307 | ||
| 308 | /// A filesystem path, represented relative to one of a few specific directories where possible. | ||
| 309 | /// Every path (considering symlinks as distinct paths) has a canonical representation in this form. | ||
| 310 | /// This abstraction allows us to: | ||
| 311 | /// * always open files relative to a consistent root on the filesystem | ||
| 312 | /// * detect when two paths correspond to the same file, e.g. for deduplicating `@import`s | ||
| 313 | pub const Path = struct { | ||
| 314 | root: Root, | ||
| 315 | /// This path is always in a normalized form, where: | ||
| 316 | /// * All components are separated by `fs.path.sep` | ||
| 317 | /// * There are no repeated separators (like "foo//bar") | ||
| 318 | /// * There are no "." or ".." components | ||
| 319 | /// * There is no trailing path separator | ||
| 320 | /// | ||
| 321 | /// There is a leading separator iff `root` is `.none` *and* `builtin.target.os.tag != .wasi`. | ||
| 322 | /// | ||
| 323 | /// If this `Path` exactly represents a `Root`, the sub path is "", not ".". | ||
| 324 | sub_path: []u8, | ||
| 325 | |||
| 326 | const Root = enum { | ||
| 327 | /// `sub_path` is relative to the Zig lib directory on `Compilation`. | ||
| 328 | zig_lib, | ||
| 329 | /// `sub_path` is relative to the global cache directory on `Compilation`. | ||
| 330 | global_cache, | ||
| 331 | /// `sub_path` is relative to the local cache directory on `Compilation`. | ||
| 332 | local_cache, | ||
| 333 | /// `sub_path` is not relative to any of the roots listed above. | ||
| 334 | /// It is resolved starting with `Directories.cwd`; so it is an absolute path on most | ||
| 335 | /// targets, but cwd-relative on WASI. We do not make it cwd-relative on other targets | ||
| 336 | /// so that `Path.digest` gives hashes which can be stored in the Zig cache (as they | ||
| 337 | /// don't depend on a specific compiler instance). | ||
| 338 | none, | ||
| 339 | }; | ||
| 340 | |||
| 341 | /// In general, we can only construct canonical `Path`s at runtime, because weird nesting might | ||
| 342 | /// mean that e.g. a sub path inside zig/lib/ is actually in the global cache. However, because | ||
| 343 | /// `Directories` guarantees that `zig_lib` is a distinct path from both cache directories, it's | ||
| 344 | /// okay for us to construct this path, and only this path, as a comptime constant. | ||
| 345 | pub const zig_lib_root: Path = .{ .root = .zig_lib, .sub_path = "" }; | ||
| 346 | |||
| 347 | pub fn deinit(p: Path, gpa: Allocator) void { | ||
| 348 | gpa.free(p.sub_path); | ||
| 349 | } | ||
| 350 | |||
| 351 | /// The returned digest is relocatable across any compiler process using the same lib and cache | ||
| 352 | /// directories; it does not depend on cwd. | ||
| 353 | pub fn digest(p: Path) Cache.BinDigest { | ||
| 354 | var h = Cache.hasher_init; | ||
| 355 | h.update(&.{@intFromEnum(p.root)}); | ||
| 356 | h.update(p.sub_path); | ||
| 357 | return h.finalResult(); | ||
| 358 | } | ||
| 359 | |||
| 360 | /// Given a `Path`, returns the directory handle and sub path to be used to open the path. | ||
| 361 | pub fn openInfo(p: Path, dirs: Directories) struct { fs.Dir, []const u8 } { | ||
| 362 | const dir = switch (p.root) { | ||
| 363 | .none => { | ||
| 364 | const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); | ||
| 365 | return .{ fs.cwd(), cwd_sub_path }; | ||
| 366 | }, | ||
| 367 | .zig_lib => dirs.zig_lib.handle, | ||
| 368 | .global_cache => dirs.global_cache.handle, | ||
| 369 | .local_cache => dirs.local_cache.handle, | ||
| 370 | }; | ||
| 371 | if (p.sub_path.len == 0) return .{ dir, "." }; | ||
| 372 | assert(!fs.path.isAbsolute(p.sub_path)); | ||
| 373 | return .{ dir, p.sub_path }; | ||
| 374 | } | ||
| 375 | |||
| 376 | pub const format = unreachable; // do not format direcetly | ||
| 377 | pub fn fmt(p: Path, comp: *Compilation) Formatter { | ||
| 378 | return .{ .p = p, .comp = comp }; | ||
| 379 | } | ||
| 380 | const Formatter = struct { | ||
| 381 | p: Path, | ||
| 382 | comp: *Compilation, | ||
| 383 | pub fn format(f: Formatter, comptime unused_fmt: []const u8, options: std.fmt.FormatOptions, w: anytype) !void { | ||
| 384 | comptime assert(unused_fmt.len == 0); | ||
| 385 | _ = options; | ||
| 386 | const root_path: []const u8 = switch (f.p.root) { | ||
| 387 | .zig_lib => f.comp.dirs.zig_lib.path orelse ".", | ||
| 388 | .global_cache => f.comp.dirs.global_cache.path orelse ".", | ||
| 389 | .local_cache => f.comp.dirs.local_cache.path orelse ".", | ||
| 390 | .none => { | ||
| 391 | const cwd_sub_path = absToCwdRelative(f.p.sub_path, f.comp.dirs.cwd); | ||
| 392 | try w.writeAll(cwd_sub_path); | ||
| 393 | return; | ||
| 394 | }, | ||
| 395 | }; | ||
| 396 | assert(root_path.len != 0); | ||
| 397 | try w.writeAll(root_path); | ||
| 398 | if (f.p.sub_path.len > 0) { | ||
| 399 | try w.writeByte(fs.path.sep); | ||
| 400 | try w.writeAll(f.p.sub_path); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | }; | ||
| 404 | |||
| 405 | /// Given the `sub_path` of a `Path` with `Path.root == .none`, attempts to convert | ||
| 406 | /// the (absolute) path to a cwd-relative path. Otherwise, returns the absolute path | ||
| 407 | /// unmodified. The returned string is never empty: "" is converted to ".". | ||
| 408 | fn absToCwdRelative(sub_path: []const u8, cwd_path: []const u8) []const u8 { | ||
| 409 | if (builtin.target.os.tag == .wasi) { | ||
| 410 | if (sub_path.len == 0) return "."; | ||
| 411 | assert(!fs.path.isAbsolute(sub_path)); | ||
| 412 | return sub_path; | ||
| 413 | } | ||
| 414 | assert(fs.path.isAbsolute(sub_path)); | ||
| 415 | if (!std.mem.startsWith(u8, sub_path, cwd_path)) return sub_path; | ||
| 416 | if (sub_path.len == cwd_path.len) return "."; // the strings are equal | ||
| 417 | if (sub_path[cwd_path.len] != fs.path.sep) return sub_path; // last component before cwd differs | ||
| 418 | return sub_path[cwd_path.len + 1 ..]; // remove '/path/to/cwd/' prefix | ||
| 419 | } | ||
| 420 | |||
| 421 | /// From an unresolved path (which can be made of multiple not-yet-joined strings), construct a | ||
| 422 | /// canonical `Path`. | ||
| 423 | pub fn fromUnresolved(gpa: Allocator, dirs: Compilation.Directories, unresolved_parts: []const []const u8) Allocator.Error!Path { | ||
| 424 | const resolved = try introspect.resolvePath(gpa, dirs.cwd, unresolved_parts); | ||
| 425 | errdefer gpa.free(resolved); | ||
| 426 | |||
| 427 | // If, for instance, `dirs.local_cache.path` is within the lib dir, it must take priority, | ||
| 428 | // so that we prefer `.root = .local_cache` over `.root = .zig_lib`. The easiest way to do | ||
| 429 | // this is simply to prioritize the longest root path. | ||
| 430 | const PathAndRoot = struct { ?[]const u8, Root }; | ||
| 431 | var roots: [3]PathAndRoot = .{ | ||
| 432 | .{ dirs.zig_lib.path, .zig_lib }, | ||
| 433 | .{ dirs.global_cache.path, .global_cache }, | ||
| 434 | .{ dirs.local_cache.path, .local_cache }, | ||
| 435 | }; | ||
| 436 | // This must be a stable sort, because the global and local cache directories may be the same, in | ||
| 437 | // which case we need to make a consistent choice. | ||
| 438 | std.mem.sort(PathAndRoot, &roots, {}, struct { | ||
| 439 | fn lessThan(_: void, lhs: PathAndRoot, rhs: PathAndRoot) bool { | ||
| 440 | const lhs_path_len = if (lhs[0]) |p| p.len else 0; | ||
| 441 | const rhs_path_len = if (rhs[0]) |p| p.len else 0; | ||
| 442 | return lhs_path_len > rhs_path_len; // '>' instead of '<' to sort descending | ||
| 443 | } | ||
| 444 | }.lessThan); | ||
| 445 | |||
| 446 | for (roots) |path_and_root| { | ||
| 447 | const opt_root_path, const root = path_and_root; | ||
| 448 | const root_path = opt_root_path orelse { | ||
| 449 | // This root is the cwd. | ||
| 450 | if (!fs.path.isAbsolute(resolved)) { | ||
| 451 | return .{ | ||
| 452 | .root = root, | ||
| 453 | .sub_path = resolved, | ||
| 454 | }; | ||
| 455 | } | ||
| 456 | continue; | ||
| 457 | }; | ||
| 458 | if (!mem.startsWith(u8, resolved, root_path)) continue; | ||
| 459 | const sub: []const u8 = if (resolved.len != root_path.len) sub: { | ||
| 460 | // Check the trailing slash, so that we don't match e.g. `/foo/bar` with `/foo/barren` | ||
| 461 | if (resolved[root_path.len] != fs.path.sep) continue; | ||
| 462 | break :sub resolved[root_path.len + 1 ..]; | ||
| 463 | } else ""; | ||
| 464 | const duped = try gpa.dupe(u8, sub); | ||
| 465 | gpa.free(resolved); | ||
| 466 | return .{ .root = root, .sub_path = duped }; | ||
| 467 | } | ||
| 468 | |||
| 469 | // We're not relative to any root, so we will use an absolute path (on targets where they are available). | ||
| 470 | |||
| 471 | if (builtin.target.os.tag == .wasi or fs.path.isAbsolute(resolved)) { | ||
| 472 | // `resolved` is already absolute (or we're on WASI, where absolute paths don't really exist). | ||
| 473 | return .{ .root = .none, .sub_path = resolved }; | ||
| 474 | } | ||
| 475 | |||
| 476 | if (resolved.len == 0) { | ||
| 477 | // We just need the cwd path, no trailing separator. Note that `gpa.free(resolved)` would be a nop. | ||
| 478 | return .{ .root = .none, .sub_path = try gpa.dupe(u8, dirs.cwd) }; | ||
| 479 | } | ||
| 480 | |||
| 481 | // We need to make an absolute path. Because `resolved` came from `introspect.resolvePath`, we can just | ||
| 482 | // join the paths with a simple format string. | ||
| 483 | const abs_path = try std.fmt.allocPrint(gpa, "{s}{c}{s}", .{ dirs.cwd, fs.path.sep, resolved }); | ||
| 484 | gpa.free(resolved); | ||
| 485 | return .{ .root = .none, .sub_path = abs_path }; | ||
| 486 | } | ||
| 487 | |||
| 488 | /// Constructs a canonical `Path` representing `sub_path` relative to `root`. | ||
| 489 | /// | ||
| 490 | /// If `sub_path` is resolved, this is almost like directly constructing a `Path`, but this | ||
| 491 | /// function also canonicalizes the result, which matters because `sub_path` may move us into | ||
| 492 | /// a different root. | ||
| 493 | /// | ||
| 494 | /// For instance, if the Zig lib directory is inside the global cache, passing `root` as | ||
| 495 | /// `.global_cache` could still end up returning a `Path` with `Path.root == .zig_lib`. | ||
| 496 | pub fn fromRoot( | ||
| 497 | gpa: Allocator, | ||
| 498 | dirs: Compilation.Directories, | ||
| 499 | root: Path.Root, | ||
| 500 | sub_path: []const u8, | ||
| 501 | ) Allocator.Error!Path { | ||
| 502 | // Currently, this just wraps `fromUnresolved` for simplicity. A more efficient impl is | ||
| 503 | // probably possible if this function ever ends up impacting performance somehow. | ||
| 504 | return .fromUnresolved(gpa, dirs, &.{ | ||
| 505 | switch (root) { | ||
| 506 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 507 | .global_cache => dirs.global_cache.path orelse "", | ||
| 508 | .local_cache => dirs.local_cache.path orelse "", | ||
| 509 | .none => "", | ||
| 510 | }, | ||
| 511 | sub_path, | ||
| 512 | }); | ||
| 513 | } | ||
| 514 | |||
| 515 | /// Given a `Path` and an (unresolved) sub path relative to it, construct a `Path` representing | ||
| 516 | /// the joined path `p/sub_path`. Note that, like with `fromRoot`, the `sub_path` might cause us | ||
| 517 | /// to move into a different `Path.Root`. | ||
| 518 | pub fn join( | ||
| 519 | p: Path, | ||
| 520 | gpa: Allocator, | ||
| 521 | dirs: Compilation.Directories, | ||
| 522 | sub_path: []const u8, | ||
| 523 | ) Allocator.Error!Path { | ||
| 524 | // Currently, this just wraps `fromUnresolved` for simplicity. A more efficient impl is | ||
| 525 | // probably possible if this function ever ends up impacting performance somehow. | ||
| 526 | return .fromUnresolved(gpa, dirs, &.{ | ||
| 527 | switch (p.root) { | ||
| 528 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 529 | .global_cache => dirs.global_cache.path orelse "", | ||
| 530 | .local_cache => dirs.local_cache.path orelse "", | ||
| 531 | .none => "", | ||
| 532 | }, | ||
| 533 | p.sub_path, | ||
| 534 | sub_path, | ||
| 535 | }); | ||
| 536 | } | ||
| 537 | |||
| 538 | /// Like `join`, but `sub_path` is relative to the dirname of `p` instead of `p` itself. | ||
| 539 | pub fn upJoin( | ||
| 540 | p: Path, | ||
| 541 | gpa: Allocator, | ||
| 542 | dirs: Compilation.Directories, | ||
| 543 | sub_path: []const u8, | ||
| 544 | ) Allocator.Error!Path { | ||
| 545 | return .fromUnresolved(gpa, dirs, &.{ | ||
| 546 | switch (p.root) { | ||
| 547 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 548 | .global_cache => dirs.global_cache.path orelse "", | ||
| 549 | .local_cache => dirs.local_cache.path orelse "", | ||
| 550 | .none => "", | ||
| 551 | }, | ||
| 552 | p.sub_path, | ||
| 553 | "..", | ||
| 554 | sub_path, | ||
| 555 | }); | ||
| 556 | } | ||
| 557 | |||
| 558 | pub fn toCachePath(p: Path, dirs: Directories) Cache.Path { | ||
| 559 | const root_dir: Cache.Directory = switch (p.root) { | ||
| 560 | .zig_lib => dirs.zig_lib, | ||
| 561 | .global_cache => dirs.global_cache, | ||
| 562 | .local_cache => dirs.local_cache, | ||
| 563 | else => { | ||
| 564 | const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); | ||
| 565 | return .{ | ||
| 566 | .root_dir = .cwd(), | ||
| 567 | .sub_path = cwd_sub_path, | ||
| 568 | }; | ||
| 569 | }, | ||
| 570 | }; | ||
| 571 | assert(!fs.path.isAbsolute(p.sub_path)); | ||
| 572 | return .{ | ||
| 573 | .root_dir = root_dir, | ||
| 574 | .sub_path = p.sub_path, | ||
| 575 | }; | ||
| 576 | } | ||
| 577 | |||
| 578 | /// This should not be used for most of the compiler pipeline, but is useful when emitting | ||
| 579 | /// paths from the compilation (e.g. in debug info), because they will not depend on the cwd. | ||
| 580 | /// The returned path is owned by the caller and allocated into `gpa`. | ||
| 581 | pub fn toAbsolute(p: Path, dirs: Directories, gpa: Allocator) Allocator.Error![]u8 { | ||
| 582 | const root_path: []const u8 = switch (p.root) { | ||
| 583 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 584 | .global_cache => dirs.global_cache.path orelse "", | ||
| 585 | .local_cache => dirs.local_cache.path orelse "", | ||
| 586 | .none => "", | ||
| 587 | }; | ||
| 588 | return fs.path.resolve(gpa, &.{ | ||
| 589 | dirs.cwd, | ||
| 590 | root_path, | ||
| 591 | p.sub_path, | ||
| 592 | }); | ||
| 593 | } | ||
| 594 | |||
| 595 | pub fn isNested(inner: Path, outer: Path) union(enum) { | ||
| 596 | /// Value is the sub path, which is a sub-slice of `inner.sub_path`. | ||
| 597 | yes: []const u8, | ||
| 598 | no, | ||
| 599 | different_roots, | ||
| 600 | } { | ||
| 601 | if (inner.root != outer.root) return .different_roots; | ||
| 602 | if (!mem.startsWith(u8, inner.sub_path, outer.sub_path)) return .no; | ||
| 603 | if (inner.sub_path.len == outer.sub_path.len) return .no; | ||
| 604 | if (outer.sub_path.len == 0) return .{ .yes = inner.sub_path }; | ||
| 605 | if (inner.sub_path[outer.sub_path.len] != fs.path.sep) return .no; | ||
| 606 | return .{ .yes = inner.sub_path[outer.sub_path.len + 1 ..] }; | ||
| 607 | } | ||
| 608 | |||
| 609 | /// Returns whether this `Path` is illegal to have as a user-imported `Zcu.File` (including | ||
| 610 | /// as the root of a module). Such paths exist in directories which the Zig compiler treats | ||
| 611 | /// specially, like 'global_cache/b/', which stores 'builtin.zig' files. | ||
| 612 | pub fn isIllegalZigImport(p: Path, gpa: Allocator, dirs: Directories) Allocator.Error!bool { | ||
| 613 | const zig_builtin_dir: Path = try .fromRoot(gpa, dirs, .global_cache, "b"); | ||
| 614 | defer zig_builtin_dir.deinit(gpa); | ||
| 615 | return switch (p.isNested(zig_builtin_dir)) { | ||
| 616 | .yes => true, | ||
| 617 | .no, .different_roots => false, | ||
| 618 | }; | ||
| 619 | } | ||
| 620 | }; | ||
| 621 | |||
| 622 | pub const Directories = struct { | ||
| 623 | /// The string returned by `introspect.getResolvedCwd`. This is typically an absolute path, | ||
| 624 | /// but on WASI is the empty string "" instead, because WASI does not have absolute paths. | ||
| 625 | cwd: []const u8, | ||
| 626 | /// The Zig 'lib' directory. | ||
| 627 | /// `zig_lib.path` is resolved (`introspect.resolvePath`) or `null` for cwd. | ||
| 628 | /// Guaranteed to be a different path from `global_cache` and `local_cache`. | ||
| 629 | zig_lib: Cache.Directory, | ||
| 630 | /// The global Zig cache directory. | ||
| 631 | /// `global_cache.path` is resolved (`introspect.resolvePath`) or `null` for cwd. | ||
| 632 | global_cache: Cache.Directory, | ||
| 633 | /// The local Zig cache directory. | ||
| 634 | /// `local_cache.path` is resolved (`introspect.resolvePath`) or `null` for cwd. | ||
| 635 | /// This may be the same as `global_cache`. | ||
| 636 | local_cache: Cache.Directory, | ||
| 637 | |||
| 638 | pub fn deinit(dirs: *Directories) void { | ||
| 639 | // The local and global caches could be the same. | ||
| 640 | const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; | ||
| 641 | |||
| 642 | dirs.global_cache.handle.close(); | ||
| 643 | if (close_local) dirs.local_cache.handle.close(); | ||
| 644 | dirs.zig_lib.handle.close(); | ||
| 645 | } | ||
| 646 | |||
| 647 | /// Returns a `Directories` where `local_cache` is replaced with `global_cache`, intended for | ||
| 648 | /// use by sub-compilations (e.g. compiler_rt). Do not `deinit` the returned `Directories`; it | ||
| 649 | /// shares handles with `dirs`. | ||
| 650 | pub fn withoutLocalCache(dirs: Directories) Directories { | ||
| 651 | return .{ | ||
| 652 | .cwd = dirs.cwd, | ||
| 653 | .zig_lib = dirs.zig_lib, | ||
| 654 | .global_cache = dirs.global_cache, | ||
| 655 | .local_cache = dirs.global_cache, | ||
| 656 | }; | ||
| 657 | } | ||
| 658 | |||
| 659 | /// Uses `std.process.fatal` on error conditions. | ||
| 660 | pub fn init( | ||
| 661 | arena: Allocator, | ||
| 662 | override_zig_lib: ?[]const u8, | ||
| 663 | override_global_cache: ?[]const u8, | ||
| 664 | local_cache_strat: union(enum) { | ||
| 665 | override: []const u8, | ||
| 666 | search, | ||
| 667 | global, | ||
| 668 | }, | ||
| 669 | wasi_preopens: switch (builtin.target.os.tag) { | ||
| 670 | .wasi => std.fs.wasi.Preopens, | ||
| 671 | else => void, | ||
| 672 | }, | ||
| 673 | self_exe_path: switch (builtin.target.os.tag) { | ||
| 674 | .wasi => void, | ||
| 675 | else => []const u8, | ||
| 676 | }, | ||
| 677 | ) Directories { | ||
| 678 | const wasi = builtin.target.os.tag == .wasi; | ||
| 679 | |||
| 680 | const cwd = introspect.getResolvedCwd(arena) catch |err| { | ||
| 681 | fatal("unable to get cwd: {s}", .{@errorName(err)}); | ||
| 682 | }; | ||
| 683 | |||
| 684 | const zig_lib: Cache.Directory = d: { | ||
| 685 | if (override_zig_lib) |path| break :d openUnresolved(arena, cwd, path, .@"zig lib"); | ||
| 686 | if (wasi) break :d openWasiPreopen(wasi_preopens, "/lib"); | ||
| 687 | break :d introspect.findZigLibDirFromSelfExe(arena, cwd, self_exe_path) catch |err| { | ||
| 688 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | ||
| 689 | }; | ||
| 690 | }; | ||
| 691 | |||
| 692 | const global_cache: Cache.Directory = d: { | ||
| 693 | if (override_global_cache) |path| break :d openUnresolved(arena, cwd, path, .@"global cache"); | ||
| 694 | if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache"); | ||
| 695 | const path = introspect.resolveGlobalCacheDir(arena) catch |err| { | ||
| 696 | fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); | ||
| 697 | }; | ||
| 698 | break :d openUnresolved(arena, cwd, path, .@"global cache"); | ||
| 699 | }; | ||
| 700 | |||
| 701 | const local_cache: Cache.Directory = switch (local_cache_strat) { | ||
| 702 | .override => |path| openUnresolved(arena, cwd, path, .@"local cache"), | ||
| 703 | .search => d: { | ||
| 704 | const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| { | ||
| 705 | fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); | ||
| 706 | }; | ||
| 707 | const path = maybe_path orelse break :d global_cache; | ||
| 708 | break :d openUnresolved(arena, cwd, path, .@"local cache"); | ||
| 709 | }, | ||
| 710 | .global => global_cache, | ||
| 711 | }; | ||
| 712 | |||
| 713 | if (std.mem.eql(u8, zig_lib.path orelse "", global_cache.path orelse "")) { | ||
| 714 | fatal("zig lib directory '{}' cannot be equal to global cache directory '{}'", .{ zig_lib, global_cache }); | ||
| 715 | } | ||
| 716 | if (std.mem.eql(u8, zig_lib.path orelse "", local_cache.path orelse "")) { | ||
| 717 | fatal("zig lib directory '{}' cannot be equal to local cache directory '{}'", .{ zig_lib, local_cache }); | ||
| 718 | } | ||
| 719 | |||
| 720 | return .{ | ||
| 721 | .cwd = cwd, | ||
| 722 | .zig_lib = zig_lib, | ||
| 723 | .global_cache = global_cache, | ||
| 724 | .local_cache = local_cache, | ||
| 725 | }; | ||
| 726 | } | ||
| 727 | fn openWasiPreopen(preopens: std.fs.wasi.Preopens, name: []const u8) Cache.Directory { | ||
| 728 | return .{ | ||
| 729 | .path = if (std.mem.eql(u8, name, ".")) null else name, | ||
| 730 | .handle = .{ | ||
| 731 | .fd = preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), | ||
| 732 | }, | ||
| 733 | }; | ||
| 734 | } | ||
| 735 | fn openUnresolved(arena: Allocator, cwd: []const u8, unresolved_path: []const u8, thing: enum { @"zig lib", @"global cache", @"local cache" }) Cache.Directory { | ||
| 736 | const path = introspect.resolvePath(arena, cwd, &.{unresolved_path}) catch |err| { | ||
| 737 | fatal("unable to resolve {s} directory: {s}", .{ @tagName(thing), @errorName(err) }); | ||
| 738 | }; | ||
| 739 | const nonempty_path = if (path.len == 0) "." else path; | ||
| 740 | const handle_or_err = switch (thing) { | ||
| 741 | .@"zig lib" => std.fs.cwd().openDir(nonempty_path, .{}), | ||
| 742 | .@"global cache", .@"local cache" => std.fs.cwd().makeOpenPath(nonempty_path, .{}), | ||
| 743 | }; | ||
| 744 | return .{ | ||
| 745 | .path = if (path.len == 0) null else path, | ||
| 746 | .handle = handle_or_err catch |err| { | ||
| 747 | const extra_str: []const u8 = e: { | ||
| 748 | if (thing == .@"global cache") switch (err) { | ||
| 749 | error.AccessDenied, error.ReadOnlyFileSystem => break :e "\n" ++ | ||
| 750 | "If this location is not writable then consider specifying an alternative with " ++ | ||
| 751 | "the ZIG_GLOBAL_CACHE_DIR environment variable or the --global-cache-dir option.", | ||
| 752 | else => {}, | ||
| 753 | }; | ||
| 754 | break :e ""; | ||
| 755 | }; | ||
| 756 | fatal("unable to open {s} directory '{s}': {s}{s}", .{ @tagName(thing), nonempty_path, @errorName(err), extra_str }); | ||
| 757 | }, | ||
| 758 | }; | ||
| 759 | } | ||
| 760 | }; | ||
| 761 | |||
| 315 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; | 762 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; |
| 316 | pub const SemaError = Zcu.SemaError; | 763 | pub const SemaError = Zcu.SemaError; |
| 317 | 764 | ||
| 318 | pub const CrtFile = struct { | 765 | pub const CrtFile = struct { |
| 319 | lock: Cache.Lock, | 766 | lock: Cache.Lock, |
| 320 | full_object_path: Path, | 767 | full_object_path: Cache.Path, |
| 321 | 768 | ||
| 322 | pub fn isObject(cf: CrtFile) bool { | 769 | pub fn isObject(cf: CrtFile) bool { |
| 323 | return switch (classifyFileExt(cf.full_object_path.sub_path)) { | 770 | return switch (classifyFileExt(cf.full_object_path.sub_path)) { |
| ... | @@ -430,7 +877,7 @@ pub const CObject = struct { | ... | @@ -430,7 +877,7 @@ pub const CObject = struct { |
| 430 | new, | 877 | new, |
| 431 | success: struct { | 878 | success: struct { |
| 432 | /// The outputted result. `sub_path` owned by gpa. | 879 | /// The outputted result. `sub_path` owned by gpa. |
| 433 | object_path: Path, | 880 | object_path: Cache.Path, |
| 434 | /// This is a file system lock on the cache hash manifest representing this | 881 | /// This is a file system lock on the cache hash manifest representing this |
| 435 | /// object. It prevents other invocations of the Zig compiler from interfering | 882 | /// object. It prevents other invocations of the Zig compiler from interfering |
| 436 | /// with this object until released. | 883 | /// with this object until released. |
| ... | @@ -854,7 +1301,7 @@ pub const MiscError = struct { | ... | @@ -854,7 +1301,7 @@ pub const MiscError = struct { |
| 854 | pub const EmitLoc = struct { | 1301 | pub const EmitLoc = struct { |
| 855 | /// If this is `null` it means the file will be output to the cache directory. | 1302 | /// If this is `null` it means the file will be output to the cache directory. |
| 856 | /// When provided, both the open file handle and the path name must outlive the `Compilation`. | 1303 | /// When provided, both the open file handle and the path name must outlive the `Compilation`. |
| 857 | directory: ?Compilation.Directory, | 1304 | directory: ?Cache.Directory, |
| 858 | /// This may not have sub-directories in it. | 1305 | /// This may not have sub-directories in it. |
| 859 | basename: []const u8, | 1306 | basename: []const u8, |
| 860 | }; | 1307 | }; |
| ... | @@ -977,7 +1424,7 @@ const CacheUse = union(CacheMode) { | ... | @@ -977,7 +1424,7 @@ const CacheUse = union(CacheMode) { |
| 977 | implib_sub_path: ?[]u8, | 1424 | implib_sub_path: ?[]u8, |
| 978 | docs_sub_path: ?[]u8, | 1425 | docs_sub_path: ?[]u8, |
| 979 | lf_open_opts: link.File.OpenOptions, | 1426 | lf_open_opts: link.File.OpenOptions, |
| 980 | tmp_artifact_directory: ?Directory, | 1427 | tmp_artifact_directory: ?Cache.Directory, |
| 981 | /// Prevents other processes from clobbering files in the output directory. | 1428 | /// Prevents other processes from clobbering files in the output directory. |
| 982 | lock: ?Cache.Lock, | 1429 | lock: ?Cache.Lock, |
| 983 | 1430 | ||
| ... | @@ -997,7 +1444,7 @@ const CacheUse = union(CacheMode) { | ... | @@ -997,7 +1444,7 @@ const CacheUse = union(CacheMode) { |
| 997 | 1444 | ||
| 998 | const Incremental = struct { | 1445 | const Incremental = struct { |
| 999 | /// Where build artifacts and incremental compilation metadata serialization go. | 1446 | /// Where build artifacts and incremental compilation metadata serialization go. |
| 1000 | artifact_directory: Compilation.Directory, | 1447 | artifact_directory: Cache.Directory, |
| 1001 | }; | 1448 | }; |
| 1002 | 1449 | ||
| 1003 | fn deinit(cu: CacheUse) void { | 1450 | fn deinit(cu: CacheUse) void { |
| ... | @@ -1013,9 +1460,7 @@ const CacheUse = union(CacheMode) { | ... | @@ -1013,9 +1460,7 @@ const CacheUse = union(CacheMode) { |
| 1013 | }; | 1460 | }; |
| 1014 | 1461 | ||
| 1015 | pub const CreateOptions = struct { | 1462 | pub const CreateOptions = struct { |
| 1016 | zig_lib_directory: Directory, | 1463 | dirs: Directories, |
| 1017 | local_cache_directory: Directory, | ||
| 1018 | global_cache_directory: Directory, | ||
| 1019 | thread_pool: *ThreadPool, | 1464 | thread_pool: *ThreadPool, |
| 1020 | self_exe_path: ?[]const u8 = null, | 1465 | self_exe_path: ?[]const u8 = null, |
| 1021 | 1466 | ||
| ... | @@ -1059,7 +1504,7 @@ pub const CreateOptions = struct { | ... | @@ -1059,7 +1504,7 @@ pub const CreateOptions = struct { |
| 1059 | /// This field is intended to be removed. | 1504 | /// This field is intended to be removed. |
| 1060 | /// The ELF implementation no longer uses this data, however the MachO and COFF | 1505 | /// The ELF implementation no longer uses this data, however the MachO and COFF |
| 1061 | /// implementations still do. | 1506 | /// implementations still do. |
| 1062 | lib_directories: []const Directory = &.{}, | 1507 | lib_directories: []const Cache.Directory = &.{}, |
| 1063 | rpath_list: []const []const u8 = &[0][]const u8{}, | 1508 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 1064 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .empty, | 1509 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .empty, |
| 1065 | c_source_files: []const CSourceFile = &.{}, | 1510 | c_source_files: []const CSourceFile = &.{}, |
| ... | @@ -1195,68 +1640,35 @@ pub const CreateOptions = struct { | ... | @@ -1195,68 +1640,35 @@ pub const CreateOptions = struct { |
| 1195 | }; | 1640 | }; |
| 1196 | 1641 | ||
| 1197 | fn addModuleTableToCacheHash( | 1642 | fn addModuleTableToCacheHash( |
| 1198 | gpa: Allocator, | 1643 | zcu: *Zcu, |
| 1199 | arena: Allocator, | 1644 | arena: Allocator, |
| 1200 | hash: *Cache.HashHelper, | 1645 | hash: *Cache.HashHelper, |
| 1201 | root_mod: *Package.Module, | ||
| 1202 | main_mod: *Package.Module, | ||
| 1203 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, | 1646 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, |
| 1204 | ) (error{OutOfMemory} || std.process.GetCwdError)!void { | 1647 | ) error{ |
| 1205 | var seen_table: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .empty; | 1648 | OutOfMemory, |
| 1206 | defer seen_table.deinit(gpa); | 1649 | Unexpected, |
| 1207 | 1650 | CurrentWorkingDirectoryUnlinked, | |
| 1208 | // root_mod and main_mod may be the same pointer. In fact they usually are. | 1651 | }!void { |
| 1209 | // However in the case of `zig test` or `zig build` they will be different, | 1652 | assert(zcu.module_roots.count() != 0); // module_roots is populated |
| 1210 | // and it's possible for one to not reference the other via the import table. | 1653 | |
| 1211 | try seen_table.put(gpa, root_mod, {}); | 1654 | for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, opt_mod_root_file| { |
| 1212 | try seen_table.put(gpa, main_mod, {}); | 1655 | if (mod == zcu.std_mod) continue; // redundant |
| 1213 | 1656 | if (opt_mod_root_file.unwrap()) |mod_root_file| { | |
| 1214 | const SortByName = struct { | 1657 | if (zcu.fileByIndex(mod_root_file).is_builtin) continue; // redundant |
| 1215 | has_builtin: bool, | ||
| 1216 | names: []const []const u8, | ||
| 1217 | |||
| 1218 | pub fn lessThan(ctx: @This(), lhs: usize, rhs: usize) bool { | ||
| 1219 | return if (ctx.has_builtin and (lhs == 0 or rhs == 0)) | ||
| 1220 | lhs < rhs | ||
| 1221 | else | ||
| 1222 | mem.lessThan(u8, ctx.names[lhs], ctx.names[rhs]); | ||
| 1223 | } | 1658 | } |
| 1224 | }; | ||
| 1225 | |||
| 1226 | var i: usize = 0; | ||
| 1227 | while (i < seen_table.count()) : (i += 1) { | ||
| 1228 | const mod = seen_table.keys()[i]; | ||
| 1229 | if (mod.isBuiltin()) { | ||
| 1230 | // Skip builtin.zig; it is useless as an input, and we don't want to | ||
| 1231 | // have to write it before checking for a cache hit. | ||
| 1232 | continue; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | cache_helpers.addModule(hash, mod); | 1659 | cache_helpers.addModule(hash, mod); |
| 1236 | |||
| 1237 | switch (hash_type) { | 1660 | switch (hash_type) { |
| 1238 | .path_bytes => { | 1661 | .path_bytes => { |
| 1239 | hash.addBytes(mod.root_src_path); | 1662 | hash.add(mod.root.root); |
| 1240 | hash.addOptionalBytes(mod.root.root_dir.path); | ||
| 1241 | hash.addBytes(mod.root.sub_path); | 1663 | hash.addBytes(mod.root.sub_path); |
| 1664 | hash.addBytes(mod.root_src_path); | ||
| 1242 | }, | 1665 | }, |
| 1243 | .files => |man| if (mod.root_src_path.len != 0) { | 1666 | .files => |man| if (mod.root_src_path.len != 0) { |
| 1244 | const pkg_zig_file = try mod.root.joinString(arena, mod.root_src_path); | 1667 | const root_src_path = try mod.root.toCachePath(zcu.comp.dirs).join(arena, mod.root_src_path); |
| 1245 | _ = try man.addFile(pkg_zig_file, null); | 1668 | _ = try man.addFilePath(root_src_path, null); |
| 1246 | }, | 1669 | }, |
| 1247 | } | 1670 | } |
| 1248 | |||
| 1249 | mod.deps.sortUnstable(SortByName{ | ||
| 1250 | .has_builtin = mod.deps.count() >= 1 and | ||
| 1251 | mod.deps.values()[0].isBuiltin(), | ||
| 1252 | .names = mod.deps.keys(), | ||
| 1253 | }); | ||
| 1254 | |||
| 1255 | hash.addListOfBytes(mod.deps.keys()); | 1671 | hash.addListOfBytes(mod.deps.keys()); |
| 1256 | |||
| 1257 | const deps = mod.deps.values(); | ||
| 1258 | try seen_table.ensureUnusedCapacity(gpa, deps.len); | ||
| 1259 | for (deps) |dep| seen_table.putAssumeCapacity(dep, {}); | ||
| 1260 | } | 1672 | } |
| 1261 | } | 1673 | } |
| 1262 | 1674 | ||
| ... | @@ -1310,7 +1722,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1310,7 +1722,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1310 | 1722 | ||
| 1311 | const libc_dirs = try std.zig.LibCDirs.detect( | 1723 | const libc_dirs = try std.zig.LibCDirs.detect( |
| 1312 | arena, | 1724 | arena, |
| 1313 | options.zig_lib_directory.path.?, | 1725 | options.dirs.zig_lib.path.?, |
| 1314 | options.root_mod.resolved_target.result, | 1726 | options.root_mod.resolved_target.result, |
| 1315 | options.root_mod.resolved_target.is_native_abi, | 1727 | options.root_mod.resolved_target.is_native_abi, |
| 1316 | link_libc, | 1728 | link_libc, |
| ... | @@ -1332,11 +1744,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1332,11 +1744,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1332 | // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");` | 1744 | // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");` |
| 1333 | // injected into the object. | 1745 | // injected into the object. |
| 1334 | const compiler_rt_mod = try Package.Module.create(arena, .{ | 1746 | const compiler_rt_mod = try Package.Module.create(arena, .{ |
| 1335 | .global_cache_directory = options.global_cache_directory, | ||
| 1336 | .paths = .{ | 1747 | .paths = .{ |
| 1337 | .root = .{ | 1748 | .root = .zig_lib_root, |
| 1338 | .root_dir = options.zig_lib_directory, | ||
| 1339 | }, | ||
| 1340 | .root_src_path = "compiler_rt.zig", | 1749 | .root_src_path = "compiler_rt.zig", |
| 1341 | }, | 1750 | }, |
| 1342 | .fully_qualified_name = "compiler_rt", | 1751 | .fully_qualified_name = "compiler_rt", |
| ... | @@ -1348,8 +1757,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1348,8 +1757,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1348 | }, | 1757 | }, |
| 1349 | .global = options.config, | 1758 | .global = options.config, |
| 1350 | .parent = options.root_mod, | 1759 | .parent = options.root_mod, |
| 1351 | .builtin_mod = options.root_mod.getBuiltinDependency(), | ||
| 1352 | .builtin_modules = null, // `builtin_mod` is set | ||
| 1353 | }); | 1760 | }); |
| 1354 | try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod); | 1761 | try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod); |
| 1355 | } | 1762 | } |
| ... | @@ -1369,11 +1776,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1369,11 +1776,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1369 | 1776 | ||
| 1370 | if (ubsan_rt_strat == .zcu) { | 1777 | if (ubsan_rt_strat == .zcu) { |
| 1371 | const ubsan_rt_mod = try Package.Module.create(arena, .{ | 1778 | const ubsan_rt_mod = try Package.Module.create(arena, .{ |
| 1372 | .global_cache_directory = options.global_cache_directory, | ||
| 1373 | .paths = .{ | 1779 | .paths = .{ |
| 1374 | .root = .{ | 1780 | .root = .zig_lib_root, |
| 1375 | .root_dir = options.zig_lib_directory, | ||
| 1376 | }, | ||
| 1377 | .root_src_path = "ubsan_rt.zig", | 1781 | .root_src_path = "ubsan_rt.zig", |
| 1378 | }, | 1782 | }, |
| 1379 | .fully_qualified_name = "ubsan_rt", | 1783 | .fully_qualified_name = "ubsan_rt", |
| ... | @@ -1381,8 +1785,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1381,8 +1785,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1381 | .inherited = .{}, | 1785 | .inherited = .{}, |
| 1382 | .global = options.config, | 1786 | .global = options.config, |
| 1383 | .parent = options.root_mod, | 1787 | .parent = options.root_mod, |
| 1384 | .builtin_mod = options.root_mod.getBuiltinDependency(), | ||
| 1385 | .builtin_modules = null, // `builtin_mod` is set | ||
| 1386 | }); | 1788 | }); |
| 1387 | try options.root_mod.deps.putNoClobber(arena, "ubsan_rt", ubsan_rt_mod); | 1789 | try options.root_mod.deps.putNoClobber(arena, "ubsan_rt", ubsan_rt_mod); |
| 1388 | } | 1790 | } |
| ... | @@ -1415,13 +1817,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1415,13 +1817,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1415 | const cache = try arena.create(Cache); | 1817 | const cache = try arena.create(Cache); |
| 1416 | cache.* = .{ | 1818 | cache.* = .{ |
| 1417 | .gpa = gpa, | 1819 | .gpa = gpa, |
| 1418 | .manifest_dir = try options.local_cache_directory.handle.makeOpenPath("h", .{}), | 1820 | .manifest_dir = try options.dirs.local_cache.handle.makeOpenPath("h", .{}), |
| 1419 | }; | 1821 | }; |
| 1420 | // These correspond to std.zig.Server.Message.PathPrefix. | 1822 | // These correspond to std.zig.Server.Message.PathPrefix. |
| 1421 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); | 1823 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); |
| 1422 | cache.addPrefix(options.zig_lib_directory); | 1824 | cache.addPrefix(options.dirs.zig_lib); |
| 1423 | cache.addPrefix(options.local_cache_directory); | 1825 | cache.addPrefix(options.dirs.local_cache); |
| 1424 | cache.addPrefix(options.global_cache_directory); | 1826 | cache.addPrefix(options.dirs.global_cache); |
| 1425 | errdefer cache.manifest_dir.close(); | 1827 | errdefer cache.manifest_dir.close(); |
| 1426 | 1828 | ||
| 1427 | // This is shared hasher state common to zig source and all C source files. | 1829 | // This is shared hasher state common to zig source and all C source files. |
| ... | @@ -1458,26 +1860,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1458,26 +1860,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1458 | // to redundantly happen for each AstGen operation. | 1860 | // to redundantly happen for each AstGen operation. |
| 1459 | const zir_sub_dir = "z"; | 1861 | const zir_sub_dir = "z"; |
| 1460 | 1862 | ||
| 1461 | var local_zir_dir = try options.local_cache_directory.handle.makeOpenPath(zir_sub_dir, .{}); | 1863 | var local_zir_dir = try options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}); |
| 1462 | errdefer local_zir_dir.close(); | 1864 | errdefer local_zir_dir.close(); |
| 1463 | const local_zir_cache: Directory = .{ | 1865 | const local_zir_cache: Cache.Directory = .{ |
| 1464 | .handle = local_zir_dir, | 1866 | .handle = local_zir_dir, |
| 1465 | .path = try options.local_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}), | 1867 | .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}), |
| 1466 | }; | 1868 | }; |
| 1467 | var global_zir_dir = try options.global_cache_directory.handle.makeOpenPath(zir_sub_dir, .{}); | 1869 | var global_zir_dir = try options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}); |
| 1468 | errdefer global_zir_dir.close(); | 1870 | errdefer global_zir_dir.close(); |
| 1469 | const global_zir_cache: Directory = .{ | 1871 | const global_zir_cache: Cache.Directory = .{ |
| 1470 | .handle = global_zir_dir, | 1872 | .handle = global_zir_dir, |
| 1471 | .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}), | 1873 | .path = try options.dirs.global_cache.join(arena, &.{zir_sub_dir}), |
| 1472 | }; | 1874 | }; |
| 1473 | 1875 | ||
| 1474 | const std_mod = options.std_mod orelse try Package.Module.create(arena, .{ | 1876 | const std_mod = options.std_mod orelse try Package.Module.create(arena, .{ |
| 1475 | .global_cache_directory = options.global_cache_directory, | ||
| 1476 | .paths = .{ | 1877 | .paths = .{ |
| 1477 | .root = .{ | 1878 | .root = try .fromRoot(arena, options.dirs, .zig_lib, "std"), |
| 1478 | .root_dir = options.zig_lib_directory, | ||
| 1479 | .sub_path = "std", | ||
| 1480 | }, | ||
| 1481 | .root_src_path = "std.zig", | 1879 | .root_src_path = "std.zig", |
| 1482 | }, | 1880 | }, |
| 1483 | .fully_qualified_name = "std", | 1881 | .fully_qualified_name = "std", |
| ... | @@ -1485,8 +1883,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1485,8 +1883,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1485 | .inherited = .{}, | 1883 | .inherited = .{}, |
| 1486 | .global = options.config, | 1884 | .global = options.config, |
| 1487 | .parent = options.root_mod, | 1885 | .parent = options.root_mod, |
| 1488 | .builtin_mod = options.root_mod.getBuiltinDependency(), | ||
| 1489 | .builtin_modules = null, // `builtin_mod` is set | ||
| 1490 | }); | 1886 | }); |
| 1491 | 1887 | ||
| 1492 | const zcu = try arena.create(Zcu); | 1888 | const zcu = try arena.create(Zcu); |
| ... | @@ -1522,16 +1918,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1522,16 +1918,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1522 | .docs_emit = null, // handled below | 1918 | .docs_emit = null, // handled below |
| 1523 | .root_mod = options.root_mod, | 1919 | .root_mod = options.root_mod, |
| 1524 | .config = options.config, | 1920 | .config = options.config, |
| 1525 | .zig_lib_directory = options.zig_lib_directory, | 1921 | .dirs = options.dirs, |
| 1526 | .local_cache_directory = options.local_cache_directory, | ||
| 1527 | .global_cache_directory = options.global_cache_directory, | ||
| 1528 | .emit_asm = options.emit_asm, | 1922 | .emit_asm = options.emit_asm, |
| 1529 | .emit_llvm_ir = options.emit_llvm_ir, | 1923 | .emit_llvm_ir = options.emit_llvm_ir, |
| 1530 | .emit_llvm_bc = options.emit_llvm_bc, | 1924 | .emit_llvm_bc = options.emit_llvm_bc, |
| 1531 | .work_queues = @splat(.init(gpa)), | 1925 | .work_queues = @splat(.init(gpa)), |
| 1532 | .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), | 1926 | .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), |
| 1533 | .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa) else .{}, | 1927 | .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa) else .{}, |
| 1534 | .astgen_work_queue = std.fifo.LinearFifo(Zcu.File.Index, .Dynamic).init(gpa), | ||
| 1535 | .c_source_files = options.c_source_files, | 1928 | .c_source_files = options.c_source_files, |
| 1536 | .rc_source_files = options.rc_source_files, | 1929 | .rc_source_files = options.rc_source_files, |
| 1537 | .cache_parent = cache, | 1930 | .cache_parent = cache, |
| ... | @@ -1572,9 +1965,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1572,9 +1965,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1572 | .framework_dirs = options.framework_dirs, | 1965 | .framework_dirs = options.framework_dirs, |
| 1573 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, | 1966 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, |
| 1574 | .skip_linker_dependencies = options.skip_linker_dependencies, | 1967 | .skip_linker_dependencies = options.skip_linker_dependencies, |
| 1575 | .queued_jobs = .{ | 1968 | .queued_jobs = .{}, |
| 1576 | .update_builtin_zig = have_zcu, | ||
| 1577 | }, | ||
| 1578 | .function_sections = options.function_sections, | 1969 | .function_sections = options.function_sections, |
| 1579 | .data_sections = options.data_sections, | 1970 | .data_sections = options.data_sections, |
| 1580 | .native_system_include_paths = options.native_system_include_paths, | 1971 | .native_system_include_paths = options.native_system_include_paths, |
| ... | @@ -1596,6 +1987,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1596,6 +1987,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1596 | comp.config.any_sanitize_c = any_sanitize_c; | 1987 | comp.config.any_sanitize_c = any_sanitize_c; |
| 1597 | comp.config.any_fuzz = any_fuzz; | 1988 | comp.config.any_fuzz = any_fuzz; |
| 1598 | 1989 | ||
| 1990 | if (opt_zcu) |zcu| { | ||
| 1991 | // Populate `zcu.module_roots`. | ||
| 1992 | const pt: Zcu.PerThread = .activate(zcu, .main); | ||
| 1993 | defer pt.deactivate(); | ||
| 1994 | try pt.populateModuleRootTable(); | ||
| 1995 | } | ||
| 1996 | |||
| 1599 | const lf_open_opts: link.File.OpenOptions = .{ | 1997 | const lf_open_opts: link.File.OpenOptions = .{ |
| 1600 | .linker_script = options.linker_script, | 1998 | .linker_script = options.linker_script, |
| 1601 | .z_nodelete = options.linker_z_nodelete, | 1999 | .z_nodelete = options.linker_z_nodelete, |
| ... | @@ -1686,7 +2084,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1686,7 +2084,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1686 | // do want to namespace different source file names because they are | 2084 | // do want to namespace different source file names because they are |
| 1687 | // likely different compilations and therefore this would be likely to | 2085 | // likely different compilations and therefore this would be likely to |
| 1688 | // cause cache hits. | 2086 | // cause cache hits. |
| 1689 | try addModuleTableToCacheHash(gpa, arena, &hash, options.root_mod, main_mod, .path_bytes); | 2087 | if (comp.zcu) |zcu| { |
| 2088 | try addModuleTableToCacheHash(zcu, arena, &hash, .path_bytes); | ||
| 2089 | } else { | ||
| 2090 | cache_helpers.addModule(&hash, options.root_mod); | ||
| 2091 | } | ||
| 1690 | 2092 | ||
| 1691 | // In the case of incremental cache mode, this `artifact_directory` | 2093 | // In the case of incremental cache mode, this `artifact_directory` |
| 1692 | // is computed based on a hash of non-linker inputs, and it is where all | 2094 | // is computed based on a hash of non-linker inputs, and it is where all |
| ... | @@ -1695,11 +2097,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1695,11 +2097,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1695 | const digest = hash.final(); | 2097 | const digest = hash.final(); |
| 1696 | 2098 | ||
| 1697 | const artifact_sub_dir = "o" ++ std.fs.path.sep_str ++ digest; | 2099 | const artifact_sub_dir = "o" ++ std.fs.path.sep_str ++ digest; |
| 1698 | var artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{}); | 2100 | var artifact_dir = try options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}); |
| 1699 | errdefer artifact_dir.close(); | 2101 | errdefer artifact_dir.close(); |
| 1700 | const artifact_directory: Directory = .{ | 2102 | const artifact_directory: Cache.Directory = .{ |
| 1701 | .handle = artifact_dir, | 2103 | .handle = artifact_dir, |
| 1702 | .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}), | 2104 | .path = try options.dirs.local_cache.join(arena, &.{artifact_sub_dir}), |
| 1703 | }; | 2105 | }; |
| 1704 | 2106 | ||
| 1705 | const incremental = try arena.create(CacheUse.Incremental); | 2107 | const incremental = try arena.create(CacheUse.Incremental); |
| ... | @@ -1709,7 +2111,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1709,7 +2111,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1709 | comp.cache_use = .{ .incremental = incremental }; | 2111 | comp.cache_use = .{ .incremental = incremental }; |
| 1710 | 2112 | ||
| 1711 | if (options.emit_bin) |emit_bin| { | 2113 | if (options.emit_bin) |emit_bin| { |
| 1712 | const emit: Path = .{ | 2114 | const emit: Cache.Path = .{ |
| 1713 | .root_dir = emit_bin.directory orelse artifact_directory, | 2115 | .root_dir = emit_bin.directory orelse artifact_directory, |
| 1714 | .sub_path = emit_bin.basename, | 2116 | .sub_path = emit_bin.basename, |
| 1715 | }; | 2117 | }; |
| ... | @@ -1998,10 +2400,10 @@ pub fn destroy(comp: *Compilation) void { | ... | @@ -1998,10 +2400,10 @@ pub fn destroy(comp: *Compilation) void { |
| 1998 | if (comp.bin_file) |lf| lf.destroy(); | 2400 | if (comp.bin_file) |lf| lf.destroy(); |
| 1999 | if (comp.zcu) |zcu| zcu.deinit(); | 2401 | if (comp.zcu) |zcu| zcu.deinit(); |
| 2000 | comp.cache_use.deinit(); | 2402 | comp.cache_use.deinit(); |
| 2403 | |||
| 2001 | for (comp.work_queues) |work_queue| work_queue.deinit(); | 2404 | for (comp.work_queues) |work_queue| work_queue.deinit(); |
| 2002 | comp.c_object_work_queue.deinit(); | 2405 | comp.c_object_work_queue.deinit(); |
| 2003 | comp.win32_resource_work_queue.deinit(); | 2406 | comp.win32_resource_work_queue.deinit(); |
| 2004 | comp.astgen_work_queue.deinit(); | ||
| 2005 | 2407 | ||
| 2006 | comp.windows_libs.deinit(gpa); | 2408 | comp.windows_libs.deinit(gpa); |
| 2007 | 2409 | ||
| ... | @@ -2207,15 +2609,15 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2207,15 +2609,15 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2207 | log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name}); | 2609 | log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name}); |
| 2208 | 2610 | ||
| 2209 | // Compile the artifacts to a temporary directory. | 2611 | // Compile the artifacts to a temporary directory. |
| 2210 | const tmp_artifact_directory: Directory = d: { | 2612 | const tmp_artifact_directory: Cache.Directory = d: { |
| 2211 | const s = std.fs.path.sep_str; | 2613 | const s = std.fs.path.sep_str; |
| 2212 | tmp_dir_rand_int = std.crypto.random.int(u64); | 2614 | tmp_dir_rand_int = std.crypto.random.int(u64); |
| 2213 | const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); | 2615 | const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); |
| 2214 | 2616 | ||
| 2215 | const path = try comp.local_cache_directory.join(gpa, &.{tmp_dir_sub_path}); | 2617 | const path = try comp.dirs.local_cache.join(gpa, &.{tmp_dir_sub_path}); |
| 2216 | errdefer gpa.free(path); | 2618 | errdefer gpa.free(path); |
| 2217 | 2619 | ||
| 2218 | const handle = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 2620 | const handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 2219 | errdefer handle.close(); | 2621 | errdefer handle.close(); |
| 2220 | 2622 | ||
| 2221 | break :d .{ | 2623 | break :d .{ |
| ... | @@ -2243,7 +2645,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2243,7 +2645,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2243 | } | 2645 | } |
| 2244 | 2646 | ||
| 2245 | if (whole.bin_sub_path) |sub_path| { | 2647 | if (whole.bin_sub_path) |sub_path| { |
| 2246 | const emit: Path = .{ | 2648 | const emit: Cache.Path = .{ |
| 2247 | .root_dir = tmp_artifact_directory, | 2649 | .root_dir = tmp_artifact_directory, |
| 2248 | .sub_path = std.fs.path.basename(sub_path), | 2650 | .sub_path = std.fs.path.basename(sub_path), |
| 2249 | }; | 2651 | }; |
| ... | @@ -2265,26 +2667,22 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2265,26 +2667,22 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2265 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. | 2667 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. |
| 2266 | // Add a Job for each C object. | 2668 | // Add a Job for each C object. |
| 2267 | try comp.c_object_work_queue.ensureUnusedCapacity(comp.c_object_table.count()); | 2669 | try comp.c_object_work_queue.ensureUnusedCapacity(comp.c_object_table.count()); |
| 2268 | for (comp.c_object_table.keys()) |key| { | 2670 | for (comp.c_object_table.keys()) |c_object| { |
| 2269 | comp.c_object_work_queue.writeItemAssumeCapacity(key); | 2671 | comp.c_object_work_queue.writeItemAssumeCapacity(c_object); |
| 2270 | } | 2672 | try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path})); |
| 2271 | if (comp.file_system_inputs) |fsi| { | ||
| 2272 | for (comp.c_object_table.keys()) |c_object| { | ||
| 2273 | try comp.appendFileSystemInput(fsi, Cache.Path.cwd(), c_object.src.src_path); | ||
| 2274 | } | ||
| 2275 | } | 2673 | } |
| 2276 | 2674 | ||
| 2277 | // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work. | 2675 | // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work. |
| 2278 | // Add a Job for each Win32 resource file. | 2676 | // Add a Job for each Win32 resource file. |
| 2279 | try comp.win32_resource_work_queue.ensureUnusedCapacity(comp.win32_resource_table.count()); | 2677 | try comp.win32_resource_work_queue.ensureUnusedCapacity(comp.win32_resource_table.count()); |
| 2280 | for (comp.win32_resource_table.keys()) |key| { | 2678 | for (comp.win32_resource_table.keys()) |win32_resource| { |
| 2281 | comp.win32_resource_work_queue.writeItemAssumeCapacity(key); | 2679 | comp.win32_resource_work_queue.writeItemAssumeCapacity(win32_resource); |
| 2282 | } | 2680 | switch (win32_resource.src) { |
| 2283 | if (comp.file_system_inputs) |fsi| { | 2681 | .rc => |f| { |
| 2284 | for (comp.win32_resource_table.keys()) |win32_resource| switch (win32_resource.src) { | 2682 | try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{f.src_path})); |
| 2285 | .rc => |f| try comp.appendFileSystemInput(fsi, Cache.Path.cwd(), f.src_path), | 2683 | }, |
| 2286 | .manifest => continue, | 2684 | .manifest => {}, |
| 2287 | }; | 2685 | } |
| 2288 | } | 2686 | } |
| 2289 | 2687 | ||
| 2290 | if (comp.zcu) |zcu| { | 2688 | if (comp.zcu) |zcu| { |
| ... | @@ -2293,69 +2691,26 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2293,69 +2691,26 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2293 | 2691 | ||
| 2294 | zcu.skip_analysis_this_update = false; | 2692 | zcu.skip_analysis_this_update = false; |
| 2295 | 2693 | ||
| 2296 | // Make sure std.zig is inside the import_table. We unconditionally need | 2694 | // TODO: doing this in `resolveReferences` later could avoid adding inputs for dead embedfiles. Investigate! |
| 2297 | // it for start.zig. | 2695 | for (zcu.embed_table.keys()) |embed_file| { |
| 2298 | const std_mod = zcu.std_mod; | 2696 | try comp.appendFileSystemInput(embed_file.path); |
| 2299 | _ = try pt.importPkg(std_mod); | ||
| 2300 | |||
| 2301 | // Normally we rely on importing std to in turn import the root source file | ||
| 2302 | // in the start code, but when using the stage1 backend that won't happen, | ||
| 2303 | // so in order to run AstGen on the root source file we put it into the | ||
| 2304 | // import_table here. | ||
| 2305 | // Likewise, in the case of `zig test`, the test runner is the root source file, | ||
| 2306 | // and so there is nothing to import the main file. | ||
| 2307 | if (comp.config.is_test) { | ||
| 2308 | _ = try pt.importPkg(zcu.main_mod); | ||
| 2309 | } | ||
| 2310 | |||
| 2311 | if (zcu.root_mod.deps.get("ubsan_rt")) |ubsan_rt_mod| { | ||
| 2312 | _ = try pt.importPkg(ubsan_rt_mod); | ||
| 2313 | } | ||
| 2314 | |||
| 2315 | if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | ||
| 2316 | _ = try pt.importPkg(compiler_rt_mod); | ||
| 2317 | } | ||
| 2318 | |||
| 2319 | // Put a work item in for every known source file to detect if | ||
| 2320 | // it changed, and, if so, re-compute ZIR and then queue the job | ||
| 2321 | // to update it. | ||
| 2322 | try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count()); | ||
| 2323 | for (zcu.import_table.values()) |file_index| { | ||
| 2324 | if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue; | ||
| 2325 | comp.astgen_work_queue.writeItemAssumeCapacity(file_index); | ||
| 2326 | } | ||
| 2327 | if (comp.file_system_inputs) |fsi| { | ||
| 2328 | for (zcu.import_table.values()) |file_index| { | ||
| 2329 | const file = zcu.fileByIndex(file_index); | ||
| 2330 | try comp.appendFileSystemInput(fsi, file.mod.root, file.sub_file_path); | ||
| 2331 | } | ||
| 2332 | } | ||
| 2333 | |||
| 2334 | if (comp.file_system_inputs) |fsi| { | ||
| 2335 | const ip = &zcu.intern_pool; | ||
| 2336 | for (zcu.embed_table.values()) |embed_file| { | ||
| 2337 | const sub_file_path = embed_file.sub_file_path.toSlice(ip); | ||
| 2338 | try comp.appendFileSystemInput(fsi, embed_file.owner.root, sub_file_path); | ||
| 2339 | } | ||
| 2340 | } | 2697 | } |
| 2341 | 2698 | ||
| 2342 | zcu.analysis_roots.clear(); | 2699 | zcu.analysis_roots.clear(); |
| 2343 | 2700 | ||
| 2344 | try comp.queueJob(.{ .analyze_mod = std_mod }); | 2701 | zcu.analysis_roots.appendAssumeCapacity(zcu.std_mod); |
| 2345 | zcu.analysis_roots.appendAssumeCapacity(std_mod); | ||
| 2346 | 2702 | ||
| 2347 | if (comp.config.is_test and zcu.main_mod != std_mod) { | 2703 | // Normally we rely on importing std to in turn import the root source file in the start code. |
| 2348 | try comp.queueJob(.{ .analyze_mod = zcu.main_mod }); | 2704 | // However, the main module is distinct from the root module in tests, so that won't happen there. |
| 2705 | if (comp.config.is_test and zcu.main_mod != zcu.std_mod) { | ||
| 2349 | zcu.analysis_roots.appendAssumeCapacity(zcu.main_mod); | 2706 | zcu.analysis_roots.appendAssumeCapacity(zcu.main_mod); |
| 2350 | } | 2707 | } |
| 2351 | 2708 | ||
| 2352 | if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | 2709 | if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { |
| 2353 | try comp.queueJob(.{ .analyze_mod = compiler_rt_mod }); | ||
| 2354 | zcu.analysis_roots.appendAssumeCapacity(compiler_rt_mod); | 2710 | zcu.analysis_roots.appendAssumeCapacity(compiler_rt_mod); |
| 2355 | } | 2711 | } |
| 2356 | 2712 | ||
| 2357 | if (zcu.root_mod.deps.get("ubsan_rt")) |ubsan_rt_mod| { | 2713 | if (zcu.root_mod.deps.get("ubsan_rt")) |ubsan_rt_mod| { |
| 2358 | try comp.queueJob(.{ .analyze_mod = ubsan_rt_mod }); | ||
| 2359 | zcu.analysis_roots.appendAssumeCapacity(ubsan_rt_mod); | 2714 | zcu.analysis_roots.appendAssumeCapacity(ubsan_rt_mod); |
| 2360 | } | 2715 | } |
| 2361 | } | 2716 | } |
| ... | @@ -2451,13 +2806,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2451,13 +2806,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2451 | break :w .no; | 2806 | break :w .no; |
| 2452 | }; | 2807 | }; |
| 2453 | 2808 | ||
| 2454 | renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path) catch |err| { | 2809 | renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| { |
| 2455 | return comp.setMiscFailure( | 2810 | return comp.setMiscFailure( |
| 2456 | .rename_results, | 2811 | .rename_results, |
| 2457 | "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}", | 2812 | "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}", |
| 2458 | .{ | 2813 | .{ |
| 2459 | comp.local_cache_directory, tmp_dir_sub_path, | 2814 | comp.dirs.local_cache, tmp_dir_sub_path, |
| 2460 | comp.local_cache_directory, o_sub_path, | 2815 | comp.dirs.local_cache, o_sub_path, |
| 2461 | @errorName(err), | 2816 | @errorName(err), |
| 2462 | }, | 2817 | }, |
| 2463 | ); | 2818 | ); |
| ... | @@ -2470,7 +2825,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2470,7 +2825,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2470 | // references object file paths. | 2825 | // references object file paths. |
| 2471 | if (comp.bin_file) |lf| { | 2826 | if (comp.bin_file) |lf| { |
| 2472 | lf.emit = .{ | 2827 | lf.emit = .{ |
| 2473 | .root_dir = comp.local_cache_directory, | 2828 | .root_dir = comp.dirs.local_cache, |
| 2474 | .sub_path = whole.bin_sub_path.?, | 2829 | .sub_path = whole.bin_sub_path.?, |
| 2475 | }; | 2830 | }; |
| 2476 | 2831 | ||
| ... | @@ -2486,7 +2841,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2486,7 +2841,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2486 | } | 2841 | } |
| 2487 | 2842 | ||
| 2488 | try flush(comp, arena, .{ | 2843 | try flush(comp, arena, .{ |
| 2489 | .root_dir = comp.local_cache_directory, | 2844 | .root_dir = comp.dirs.local_cache, |
| 2490 | .sub_path = o_sub_path, | 2845 | .sub_path = o_sub_path, |
| 2491 | }, .main, main_progress_node); | 2846 | }, .main, main_progress_node); |
| 2492 | 2847 | ||
| ... | @@ -2515,34 +2870,36 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2515,34 +2870,36 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2515 | } | 2870 | } |
| 2516 | } | 2871 | } |
| 2517 | 2872 | ||
| 2518 | pub fn appendFileSystemInput( | 2873 | pub fn appendFileSystemInput(comp: *Compilation, path: Compilation.Path) Allocator.Error!void { |
| 2519 | comp: *Compilation, | ||
| 2520 | file_system_inputs: *std.ArrayListUnmanaged(u8), | ||
| 2521 | root: Cache.Path, | ||
| 2522 | sub_file_path: []const u8, | ||
| 2523 | ) Allocator.Error!void { | ||
| 2524 | const gpa = comp.gpa; | 2874 | const gpa = comp.gpa; |
| 2875 | const fsi = comp.file_system_inputs orelse return; | ||
| 2525 | const prefixes = comp.cache_parent.prefixes(); | 2876 | const prefixes = comp.cache_parent.prefixes(); |
| 2526 | try file_system_inputs.ensureUnusedCapacity(gpa, root.sub_path.len + sub_file_path.len + 3); | 2877 | |
| 2527 | if (file_system_inputs.items.len > 0) file_system_inputs.appendAssumeCapacity(0); | 2878 | const want_prefix_dir: Cache.Directory = switch (path.root) { |
| 2528 | for (prefixes, 1..) |prefix_directory, i| { | 2879 | .zig_lib => comp.dirs.zig_lib, |
| 2529 | if (prefix_directory.eql(root.root_dir)) { | 2880 | .global_cache => comp.dirs.global_cache, |
| 2530 | file_system_inputs.appendAssumeCapacity(@intCast(i)); | 2881 | .local_cache => comp.dirs.local_cache, |
| 2531 | if (root.sub_path.len > 0) { | 2882 | .none => .cwd(), |
| 2532 | file_system_inputs.appendSliceAssumeCapacity(root.sub_path); | 2883 | }; |
| 2533 | file_system_inputs.appendAssumeCapacity(std.fs.path.sep); | 2884 | const prefix: u8 = for (prefixes, 1..) |prefix_dir, i| { |
| 2534 | } | 2885 | if (prefix_dir.eql(want_prefix_dir)) { |
| 2535 | file_system_inputs.appendSliceAssumeCapacity(sub_file_path); | 2886 | break @intCast(i); |
| 2536 | return; | ||
| 2537 | } | 2887 | } |
| 2538 | } | 2888 | } else std.debug.panic( |
| 2539 | std.debug.panic("missing prefix directory: {}, {s}", .{ root, sub_file_path }); | 2889 | "missing prefix directory '{s}' ('{}') for '{s}'", |
| 2890 | .{ @tagName(path.root), want_prefix_dir, path.sub_path }, | ||
| 2891 | ); | ||
| 2892 | |||
| 2893 | try fsi.ensureUnusedCapacity(gpa, path.sub_path.len + 3); | ||
| 2894 | if (fsi.items.len > 0) fsi.appendAssumeCapacity(0); | ||
| 2895 | fsi.appendAssumeCapacity(prefix); | ||
| 2896 | fsi.appendSliceAssumeCapacity(path.sub_path); | ||
| 2540 | } | 2897 | } |
| 2541 | 2898 | ||
| 2542 | fn flush( | 2899 | fn flush( |
| 2543 | comp: *Compilation, | 2900 | comp: *Compilation, |
| 2544 | arena: Allocator, | 2901 | arena: Allocator, |
| 2545 | default_artifact_directory: Path, | 2902 | default_artifact_directory: Cache.Path, |
| 2546 | tid: Zcu.PerThread.Id, | 2903 | tid: Zcu.PerThread.Id, |
| 2547 | prog_node: std.Progress.Node, | 2904 | prog_node: std.Progress.Node, |
| 2548 | ) !void { | 2905 | ) !void { |
| ... | @@ -2574,7 +2931,7 @@ fn flush( | ... | @@ -2574,7 +2931,7 @@ fn flush( |
| 2574 | /// implementation at the bottom of this function. | 2931 | /// implementation at the bottom of this function. |
| 2575 | /// This function is only called when CacheMode is `whole`. | 2932 | /// This function is only called when CacheMode is `whole`. |
| 2576 | fn renameTmpIntoCache( | 2933 | fn renameTmpIntoCache( |
| 2577 | cache_directory: Compilation.Directory, | 2934 | cache_directory: Cache.Directory, |
| 2578 | tmp_dir_sub_path: []const u8, | 2935 | tmp_dir_sub_path: []const u8, |
| 2579 | o_sub_path: []const u8, | 2936 | o_sub_path: []const u8, |
| 2580 | ) !void { | 2937 | ) !void { |
| ... | @@ -2627,7 +2984,7 @@ fn wholeCacheModeSetBinFilePath( | ... | @@ -2627,7 +2984,7 @@ fn wholeCacheModeSetBinFilePath( |
| 2627 | @memcpy(sub_path[digest_start..][0..digest.len], digest); | 2984 | @memcpy(sub_path[digest_start..][0..digest.len], digest); |
| 2628 | 2985 | ||
| 2629 | comp.implib_emit = .{ | 2986 | comp.implib_emit = .{ |
| 2630 | .root_dir = comp.local_cache_directory, | 2987 | .root_dir = comp.dirs.local_cache, |
| 2631 | .sub_path = sub_path, | 2988 | .sub_path = sub_path, |
| 2632 | }; | 2989 | }; |
| 2633 | } | 2990 | } |
| ... | @@ -2636,7 +2993,7 @@ fn wholeCacheModeSetBinFilePath( | ... | @@ -2636,7 +2993,7 @@ fn wholeCacheModeSetBinFilePath( |
| 2636 | @memcpy(sub_path[digest_start..][0..digest.len], digest); | 2993 | @memcpy(sub_path[digest_start..][0..digest.len], digest); |
| 2637 | 2994 | ||
| 2638 | comp.docs_emit = .{ | 2995 | comp.docs_emit = .{ |
| 2639 | .root_dir = comp.local_cache_directory, | 2996 | .root_dir = comp.dirs.local_cache, |
| 2640 | .sub_path = sub_path, | 2997 | .sub_path = sub_path, |
| 2641 | }; | 2998 | }; |
| 2642 | } | 2999 | } |
| ... | @@ -2661,19 +3018,17 @@ fn addNonIncrementalStuffToCacheManifest( | ... | @@ -2661,19 +3018,17 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2661 | arena: Allocator, | 3018 | arena: Allocator, |
| 2662 | man: *Cache.Manifest, | 3019 | man: *Cache.Manifest, |
| 2663 | ) !void { | 3020 | ) !void { |
| 2664 | const gpa = comp.gpa; | ||
| 2665 | |||
| 2666 | comptime assert(link_hash_implementation_version == 14); | 3021 | comptime assert(link_hash_implementation_version == 14); |
| 2667 | 3022 | ||
| 2668 | if (comp.zcu) |mod| { | 3023 | if (comp.zcu) |zcu| { |
| 2669 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man }); | 3024 | try addModuleTableToCacheHash(zcu, arena, &man.hash, .{ .files = man }); |
| 2670 | 3025 | ||
| 2671 | // Synchronize with other matching comments: ZigOnlyHashStuff | 3026 | // Synchronize with other matching comments: ZigOnlyHashStuff |
| 2672 | man.hash.addListOfBytes(comp.test_filters); | 3027 | man.hash.addListOfBytes(comp.test_filters); |
| 2673 | man.hash.addOptionalBytes(comp.test_name_prefix); | 3028 | man.hash.addOptionalBytes(comp.test_name_prefix); |
| 2674 | man.hash.add(comp.skip_linker_dependencies); | 3029 | man.hash.add(comp.skip_linker_dependencies); |
| 2675 | //man.hash.add(mod.emit_h != null); | 3030 | //man.hash.add(zcu.emit_h != null); |
| 2676 | man.hash.add(mod.error_limit); | 3031 | man.hash.add(zcu.error_limit); |
| 2677 | } else { | 3032 | } else { |
| 2678 | cache_helpers.addModule(&man.hash, comp.root_mod); | 3033 | cache_helpers.addModule(&man.hash, comp.root_mod); |
| 2679 | } | 3034 | } |
| ... | @@ -2839,7 +3194,7 @@ fn emitOthers(comp: *Compilation) void { | ... | @@ -2839,7 +3194,7 @@ fn emitOthers(comp: *Compilation) void { |
| 2839 | pub fn emitLlvmObject( | 3194 | pub fn emitLlvmObject( |
| 2840 | comp: *Compilation, | 3195 | comp: *Compilation, |
| 2841 | arena: Allocator, | 3196 | arena: Allocator, |
| 2842 | default_artifact_directory: Path, | 3197 | default_artifact_directory: Cache.Path, |
| 2843 | bin_emit_loc: ?EmitLoc, | 3198 | bin_emit_loc: ?EmitLoc, |
| 2844 | llvm_object: LlvmObject.Ptr, | 3199 | llvm_object: LlvmObject.Ptr, |
| 2845 | prog_node: std.Progress.Node, | 3200 | prog_node: std.Progress.Node, |
| ... | @@ -2866,7 +3221,7 @@ pub fn emitLlvmObject( | ... | @@ -2866,7 +3221,7 @@ pub fn emitLlvmObject( |
| 2866 | 3221 | ||
| 2867 | fn resolveEmitLoc( | 3222 | fn resolveEmitLoc( |
| 2868 | arena: Allocator, | 3223 | arena: Allocator, |
| 2869 | default_artifact_directory: Path, | 3224 | default_artifact_directory: Cache.Path, |
| 2870 | opt_loc: ?EmitLoc, | 3225 | opt_loc: ?EmitLoc, |
| 2871 | ) Allocator.Error!?[*:0]const u8 { | 3226 | ) Allocator.Error!?[*:0]const u8 { |
| 2872 | const loc = opt_loc orelse return null; | 3227 | const loc = opt_loc orelse return null; |
| ... | @@ -2877,132 +3232,6 @@ fn resolveEmitLoc( | ... | @@ -2877,132 +3232,6 @@ fn resolveEmitLoc( |
| 2877 | return slice.ptr; | 3232 | return slice.ptr; |
| 2878 | } | 3233 | } |
| 2879 | 3234 | ||
| 2880 | fn reportMultiModuleErrors(pt: Zcu.PerThread) !void { | ||
| 2881 | const zcu = pt.zcu; | ||
| 2882 | const gpa = zcu.gpa; | ||
| 2883 | const ip = &zcu.intern_pool; | ||
| 2884 | // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to | ||
| 2885 | // print all of, so we'll cap the number of these to emit. | ||
| 2886 | var num_errors: u32 = 0; | ||
| 2887 | const max_errors = 5; | ||
| 2888 | // Attach the "some omitted" note to the final error message | ||
| 2889 | var last_err: ?*Zcu.ErrorMsg = null; | ||
| 2890 | |||
| 2891 | for (zcu.import_table.values()) |file_index| { | ||
| 2892 | const file = zcu.fileByIndex(file_index); | ||
| 2893 | if (!file.multi_pkg) continue; | ||
| 2894 | |||
| 2895 | num_errors += 1; | ||
| 2896 | if (num_errors > max_errors) continue; | ||
| 2897 | |||
| 2898 | const err = err_blk: { | ||
| 2899 | // Like with errors, let's cap the number of notes to prevent a huge error spew. | ||
| 2900 | const max_notes = 5; | ||
| 2901 | const omitted = file.references.items.len -| max_notes; | ||
| 2902 | const num_notes = file.references.items.len - omitted; | ||
| 2903 | |||
| 2904 | const notes = try gpa.alloc(Zcu.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes); | ||
| 2905 | errdefer gpa.free(notes); | ||
| 2906 | |||
| 2907 | for (notes[0..num_notes], file.references.items[0..num_notes], 0..) |*note, ref, i| { | ||
| 2908 | errdefer for (notes[0..i]) |*n| n.deinit(gpa); | ||
| 2909 | note.* = switch (ref) { | ||
| 2910 | .import => |import| try Zcu.ErrorMsg.init( | ||
| 2911 | gpa, | ||
| 2912 | .{ | ||
| 2913 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2914 | .file = import.file, | ||
| 2915 | .inst = .main_struct_inst, | ||
| 2916 | }), | ||
| 2917 | .offset = .{ .token_abs = import.token }, | ||
| 2918 | }, | ||
| 2919 | "imported from module {s}", | ||
| 2920 | .{zcu.fileByIndex(import.file).mod.fully_qualified_name}, | ||
| 2921 | ), | ||
| 2922 | .root => |pkg| try Zcu.ErrorMsg.init( | ||
| 2923 | gpa, | ||
| 2924 | .{ | ||
| 2925 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2926 | .file = file_index, | ||
| 2927 | .inst = .main_struct_inst, | ||
| 2928 | }), | ||
| 2929 | .offset = .entire_file, | ||
| 2930 | }, | ||
| 2931 | "root of module {s}", | ||
| 2932 | .{pkg.fully_qualified_name}, | ||
| 2933 | ), | ||
| 2934 | }; | ||
| 2935 | } | ||
| 2936 | errdefer for (notes[0..num_notes]) |*n| n.deinit(gpa); | ||
| 2937 | |||
| 2938 | if (omitted > 0) { | ||
| 2939 | notes[num_notes] = try Zcu.ErrorMsg.init( | ||
| 2940 | gpa, | ||
| 2941 | .{ | ||
| 2942 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2943 | .file = file_index, | ||
| 2944 | .inst = .main_struct_inst, | ||
| 2945 | }), | ||
| 2946 | .offset = .entire_file, | ||
| 2947 | }, | ||
| 2948 | "{} more references omitted", | ||
| 2949 | .{omitted}, | ||
| 2950 | ); | ||
| 2951 | } | ||
| 2952 | errdefer if (omitted > 0) notes[num_notes].deinit(gpa); | ||
| 2953 | |||
| 2954 | const err = try Zcu.ErrorMsg.create( | ||
| 2955 | gpa, | ||
| 2956 | .{ | ||
| 2957 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2958 | .file = file_index, | ||
| 2959 | .inst = .main_struct_inst, | ||
| 2960 | }), | ||
| 2961 | .offset = .entire_file, | ||
| 2962 | }, | ||
| 2963 | "file exists in multiple modules", | ||
| 2964 | .{}, | ||
| 2965 | ); | ||
| 2966 | err.notes = notes; | ||
| 2967 | break :err_blk err; | ||
| 2968 | }; | ||
| 2969 | errdefer err.destroy(gpa); | ||
| 2970 | try zcu.failed_files.putNoClobber(gpa, file, err); | ||
| 2971 | last_err = err; | ||
| 2972 | } | ||
| 2973 | |||
| 2974 | // If we omitted any errors, add a note saying that | ||
| 2975 | if (num_errors > max_errors) { | ||
| 2976 | const err = last_err.?; | ||
| 2977 | |||
| 2978 | // There isn't really any meaningful place to put this note, so just attach it to the | ||
| 2979 | // last failed file | ||
| 2980 | var note = try Zcu.ErrorMsg.init( | ||
| 2981 | gpa, | ||
| 2982 | err.src_loc, | ||
| 2983 | "{} more errors omitted", | ||
| 2984 | .{num_errors - max_errors}, | ||
| 2985 | ); | ||
| 2986 | errdefer note.deinit(gpa); | ||
| 2987 | |||
| 2988 | const i = err.notes.len; | ||
| 2989 | err.notes = try gpa.realloc(err.notes, i + 1); | ||
| 2990 | err.notes[i] = note; | ||
| 2991 | } | ||
| 2992 | |||
| 2993 | // Now that we've reported the errors, we need to deal with | ||
| 2994 | // dependencies. Any file referenced by a multi_pkg file should also be | ||
| 2995 | // marked multi_pkg and have its status set to astgen_failure, as it's | ||
| 2996 | // ambiguous which package they should be analyzed as a part of. We need | ||
| 2997 | // to add this flag after reporting the errors however, as otherwise | ||
| 2998 | // we'd get an error for every single downstream file, which wouldn't be | ||
| 2999 | // very useful. | ||
| 3000 | for (zcu.import_table.values()) |file_index| { | ||
| 3001 | const file = zcu.fileByIndex(file_index); | ||
| 3002 | if (file.multi_pkg) file.recursiveMarkMultiPkg(pt); | ||
| 3003 | } | ||
| 3004 | } | ||
| 3005 | |||
| 3006 | /// Having the file open for writing is problematic as far as executing the | 3235 | /// Having the file open for writing is problematic as far as executing the |
| 3007 | /// binary is concerned. This will remove the write flag, or close the file, | 3236 | /// binary is concerned. This will remove the write flag, or close the file, |
| 3008 | /// or whatever is needed so that it can be executed. | 3237 | /// or whatever is needed so that it can be executed. |
| ... | @@ -3326,16 +3555,77 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { | ... | @@ -3326,16 +3555,77 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3326 | } | 3555 | } |
| 3327 | 3556 | ||
| 3328 | if (comp.zcu) |zcu| zcu_errors: { | 3557 | if (comp.zcu) |zcu| zcu_errors: { |
| 3329 | for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| { | 3558 | if (zcu.multi_module_err != null) { |
| 3559 | try zcu.addFileInMultipleModulesError(&bundle); | ||
| 3560 | break :zcu_errors; | ||
| 3561 | } | ||
| 3562 | for (zcu.failed_imports.items) |failed| { | ||
| 3563 | assert(zcu.alive_files.contains(failed.file_index)); // otherwise it wouldn't have been added | ||
| 3564 | const file = zcu.fileByIndex(failed.file_index); | ||
| 3565 | const source = try file.getSource(zcu); | ||
| 3566 | const tree = try file.getTree(zcu); | ||
| 3567 | const start = tree.tokenStart(failed.import_token); | ||
| 3568 | const end = start + tree.tokenSlice(failed.import_token).len; | ||
| 3569 | const loc = std.zig.findLineColumn(source.bytes, start); | ||
| 3570 | try bundle.addRootErrorMessage(.{ | ||
| 3571 | .msg = switch (failed.kind) { | ||
| 3572 | .file_outside_module_root => try bundle.addString("import of file outside module path"), | ||
| 3573 | .illegal_zig_import => try bundle.addString("this compiler implementation does not allow importing files from this directory"), | ||
| 3574 | }, | ||
| 3575 | .src_loc = try bundle.addSourceLocation(.{ | ||
| 3576 | .src_path = try bundle.printString("{}", .{file.path.fmt(comp)}), | ||
| 3577 | .span_start = start, | ||
| 3578 | .span_main = start, | ||
| 3579 | .span_end = @intCast(end), | ||
| 3580 | .line = @intCast(loc.line), | ||
| 3581 | .column = @intCast(loc.column), | ||
| 3582 | .source_line = try bundle.addString(loc.source_line), | ||
| 3583 | }), | ||
| 3584 | .notes_len = 0, | ||
| 3585 | }); | ||
| 3586 | } | ||
| 3587 | |||
| 3588 | // Before iterating `failed_files`, we need to sort it into a consistent order so that error | ||
| 3589 | // messages appear consistently despite different ordering from the AstGen worker pool. File | ||
| 3590 | // paths are a great key for this sort! We are using sorting the `ArrayHashMap` itself to | ||
| 3591 | // make sure it reindexes; that's important because these entries need to be retained for | ||
| 3592 | // future updates. | ||
| 3593 | const FileSortCtx = struct { | ||
| 3594 | zcu: *Zcu, | ||
| 3595 | failed_files_keys: []const Zcu.File.Index, | ||
| 3596 | pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool { | ||
| 3597 | const lhs_path = ctx.zcu.fileByIndex(ctx.failed_files_keys[lhs_index]).path; | ||
| 3598 | const rhs_path = ctx.zcu.fileByIndex(ctx.failed_files_keys[rhs_index]).path; | ||
| 3599 | if (lhs_path.root != rhs_path.root) return @intFromEnum(lhs_path.root) < @intFromEnum(rhs_path.root); | ||
| 3600 | return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt); | ||
| 3601 | } | ||
| 3602 | }; | ||
| 3603 | zcu.failed_files.sort(@as(FileSortCtx, .{ | ||
| 3604 | .zcu = zcu, | ||
| 3605 | .failed_files_keys = zcu.failed_files.keys(), | ||
| 3606 | })); | ||
| 3607 | |||
| 3608 | for (zcu.failed_files.keys(), zcu.failed_files.values()) |file_index, error_msg| { | ||
| 3609 | if (!zcu.alive_files.contains(file_index)) continue; | ||
| 3610 | const file = zcu.fileByIndex(file_index); | ||
| 3611 | const is_retryable = switch (file.status) { | ||
| 3612 | .retryable_failure => true, | ||
| 3613 | .success, .astgen_failure => false, | ||
| 3614 | .never_loaded => unreachable, | ||
| 3615 | }; | ||
| 3330 | if (error_msg) |msg| { | 3616 | if (error_msg) |msg| { |
| 3331 | try addModuleErrorMsg(zcu, &bundle, msg.*, false); | 3617 | assert(is_retryable); |
| 3618 | try addWholeFileError(zcu, &bundle, file_index, msg); | ||
| 3332 | } else { | 3619 | } else { |
| 3333 | // Must be ZIR or Zoir errors. Note that this may include AST errors. | 3620 | assert(!is_retryable); |
| 3334 | _ = try file.getTree(gpa); // Tree must be loaded. | 3621 | // AstGen/ZoirGen succeeded with errors. Note that this may include AST errors. |
| 3622 | _ = try file.getTree(zcu); // Tree must be loaded. | ||
| 3623 | const path = try std.fmt.allocPrint(gpa, "{}", .{file.path.fmt(comp)}); | ||
| 3624 | defer gpa.free(path); | ||
| 3335 | if (file.zir != null) { | 3625 | if (file.zir != null) { |
| 3336 | try addZirErrorMessages(&bundle, file); | 3626 | try bundle.addZirErrorMessages(file.zir.?, file.tree.?, file.source.?, path); |
| 3337 | } else if (file.zoir != null) { | 3627 | } else if (file.zoir != null) { |
| 3338 | try addZoirErrorMessages(&bundle, file); | 3628 | try bundle.addZoirErrorMessages(file.zoir.?, file.tree.?, file.source.?, path); |
| 3339 | } else { | 3629 | } else { |
| 3340 | // Either Zir or Zoir must have been loaded. | 3630 | // Either Zir or Zoir must have been loaded. |
| 3341 | unreachable; | 3631 | unreachable; |
| ... | @@ -3646,20 +3936,16 @@ pub fn addModuleErrorMsg( | ... | @@ -3646,20 +3936,16 @@ pub fn addModuleErrorMsg( |
| 3646 | const gpa = eb.gpa; | 3936 | const gpa = eb.gpa; |
| 3647 | const ip = &zcu.intern_pool; | 3937 | const ip = &zcu.intern_pool; |
| 3648 | const err_src_loc = module_err_msg.src_loc.upgrade(zcu); | 3938 | const err_src_loc = module_err_msg.src_loc.upgrade(zcu); |
| 3649 | const err_source = err_src_loc.file_scope.getSource(gpa) catch |err| { | 3939 | const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| { |
| 3650 | const file_path = try err_src_loc.file_scope.fullPath(gpa); | ||
| 3651 | defer gpa.free(file_path); | ||
| 3652 | try eb.addRootErrorMessage(.{ | 3940 | try eb.addRootErrorMessage(.{ |
| 3653 | .msg = try eb.printString("unable to load '{s}': {s}", .{ | 3941 | .msg = try eb.printString("unable to load '{}': {s}", .{ |
| 3654 | file_path, @errorName(err), | 3942 | err_src_loc.file_scope.path.fmt(zcu.comp), @errorName(err), |
| 3655 | }), | 3943 | }), |
| 3656 | }); | 3944 | }); |
| 3657 | return; | 3945 | return; |
| 3658 | }; | 3946 | }; |
| 3659 | const err_span = try err_src_loc.span(gpa); | 3947 | const err_span = try err_src_loc.span(zcu); |
| 3660 | const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main); | 3948 | const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main); |
| 3661 | const file_path = try err_src_loc.file_scope.fullPath(gpa); | ||
| 3662 | defer gpa.free(file_path); | ||
| 3663 | 3949 | ||
| 3664 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty; | 3950 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty; |
| 3665 | defer ref_traces.deinit(gpa); | 3951 | defer ref_traces.deinit(gpa); |
| ... | @@ -3715,16 +4001,13 @@ pub fn addModuleErrorMsg( | ... | @@ -3715,16 +4001,13 @@ pub fn addModuleErrorMsg( |
| 3715 | } | 4001 | } |
| 3716 | 4002 | ||
| 3717 | const src_loc = try eb.addSourceLocation(.{ | 4003 | const src_loc = try eb.addSourceLocation(.{ |
| 3718 | .src_path = try eb.addString(file_path), | 4004 | .src_path = try eb.printString("{}", .{err_src_loc.file_scope.path.fmt(zcu.comp)}), |
| 3719 | .span_start = err_span.start, | 4005 | .span_start = err_span.start, |
| 3720 | .span_main = err_span.main, | 4006 | .span_main = err_span.main, |
| 3721 | .span_end = err_span.end, | 4007 | .span_end = err_span.end, |
| 3722 | .line = @intCast(err_loc.line), | 4008 | .line = @intCast(err_loc.line), |
| 3723 | .column = @intCast(err_loc.column), | 4009 | .column = @intCast(err_loc.column), |
| 3724 | .source_line = if (err_src_loc.lazy == .entire_file) | 4010 | .source_line = try eb.addString(err_loc.source_line), |
| 3725 | 0 | ||
| 3726 | else | ||
| 3727 | try eb.addString(err_loc.source_line), | ||
| 3728 | .reference_trace_len = @intCast(ref_traces.items.len), | 4011 | .reference_trace_len = @intCast(ref_traces.items.len), |
| 3729 | }); | 4012 | }); |
| 3730 | 4013 | ||
| ... | @@ -3740,11 +4023,9 @@ pub fn addModuleErrorMsg( | ... | @@ -3740,11 +4023,9 @@ pub fn addModuleErrorMsg( |
| 3740 | var last_note_loc: ?std.zig.Loc = null; | 4023 | var last_note_loc: ?std.zig.Loc = null; |
| 3741 | for (module_err_msg.notes) |module_note| { | 4024 | for (module_err_msg.notes) |module_note| { |
| 3742 | const note_src_loc = module_note.src_loc.upgrade(zcu); | 4025 | const note_src_loc = module_note.src_loc.upgrade(zcu); |
| 3743 | const source = try note_src_loc.file_scope.getSource(gpa); | 4026 | const source = try note_src_loc.file_scope.getSource(zcu); |
| 3744 | const span = try note_src_loc.span(gpa); | 4027 | const span = try note_src_loc.span(zcu); |
| 3745 | const loc = std.zig.findLineColumn(source.bytes, span.main); | 4028 | const loc = std.zig.findLineColumn(source.bytes, span.main); |
| 3746 | const note_file_path = try note_src_loc.file_scope.fullPath(gpa); | ||
| 3747 | defer gpa.free(note_file_path); | ||
| 3748 | 4029 | ||
| 3749 | const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?)); | 4030 | const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?)); |
| 3750 | last_note_loc = loc; | 4031 | last_note_loc = loc; |
| ... | @@ -3752,7 +4033,7 @@ pub fn addModuleErrorMsg( | ... | @@ -3752,7 +4033,7 @@ pub fn addModuleErrorMsg( |
| 3752 | const gop = try notes.getOrPutContext(gpa, .{ | 4033 | const gop = try notes.getOrPutContext(gpa, .{ |
| 3753 | .msg = try eb.addString(module_note.msg), | 4034 | .msg = try eb.addString(module_note.msg), |
| 3754 | .src_loc = try eb.addSourceLocation(.{ | 4035 | .src_loc = try eb.addSourceLocation(.{ |
| 3755 | .src_path = try eb.addString(note_file_path), | 4036 | .src_path = try eb.printString("{}", .{note_src_loc.file_scope.path.fmt(zcu.comp)}), |
| 3756 | .span_start = span.start, | 4037 | .span_start = span.start, |
| 3757 | .span_main = span.main, | 4038 | .span_main = span.main, |
| 3758 | .span_end = span.end, | 4039 | .span_end = span.end, |
| ... | @@ -3791,15 +4072,13 @@ fn addReferenceTraceFrame( | ... | @@ -3791,15 +4072,13 @@ fn addReferenceTraceFrame( |
| 3791 | ) !void { | 4072 | ) !void { |
| 3792 | const gpa = zcu.gpa; | 4073 | const gpa = zcu.gpa; |
| 3793 | const src = lazy_src.upgrade(zcu); | 4074 | const src = lazy_src.upgrade(zcu); |
| 3794 | const source = try src.file_scope.getSource(gpa); | 4075 | const source = try src.file_scope.getSource(zcu); |
| 3795 | const span = try src.span(gpa); | 4076 | const span = try src.span(zcu); |
| 3796 | const loc = std.zig.findLineColumn(source.bytes, span.main); | 4077 | const loc = std.zig.findLineColumn(source.bytes, span.main); |
| 3797 | const rt_file_path = try src.file_scope.fullPath(gpa); | ||
| 3798 | defer gpa.free(rt_file_path); | ||
| 3799 | try ref_traces.append(gpa, .{ | 4078 | try ref_traces.append(gpa, .{ |
| 3800 | .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }), | 4079 | .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }), |
| 3801 | .src_loc = try eb.addSourceLocation(.{ | 4080 | .src_loc = try eb.addSourceLocation(.{ |
| 3802 | .src_path = try eb.addString(rt_file_path), | 4081 | .src_path = try eb.printString("{}", .{src.file_scope.path.fmt(zcu.comp)}), |
| 3803 | .span_start = span.start, | 4082 | .span_start = span.start, |
| 3804 | .span_main = span.main, | 4083 | .span_main = span.main, |
| 3805 | .span_end = span.end, | 4084 | .span_end = span.end, |
| ... | @@ -3810,18 +4089,30 @@ fn addReferenceTraceFrame( | ... | @@ -3810,18 +4089,30 @@ fn addReferenceTraceFrame( |
| 3810 | }); | 4089 | }); |
| 3811 | } | 4090 | } |
| 3812 | 4091 | ||
| 3813 | pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void { | 4092 | pub fn addWholeFileError( |
| 3814 | const gpa = eb.gpa; | 4093 | zcu: *Zcu, |
| 3815 | const src_path = try file.fullPath(gpa); | 4094 | eb: *ErrorBundle.Wip, |
| 3816 | defer gpa.free(src_path); | 4095 | file_index: Zcu.File.Index, |
| 3817 | return eb.addZirErrorMessages(file.zir.?, file.tree.?, file.source.?, src_path); | 4096 | msg: []const u8, |
| 3818 | } | 4097 | ) !void { |
| 4098 | // note: "file imported here" on the import reference token | ||
| 4099 | const imported_note: ?ErrorBundle.MessageIndex = switch (zcu.alive_files.get(file_index).?) { | ||
| 4100 | .analysis_root => null, | ||
| 4101 | .import => |import| try eb.addErrorMessage(.{ | ||
| 4102 | .msg = try eb.addString("file imported here"), | ||
| 4103 | .src_loc = try zcu.fileByIndex(import.importer).errorBundleTokenSrc(import.tok, zcu, eb), | ||
| 4104 | }), | ||
| 4105 | }; | ||
| 3819 | 4106 | ||
| 3820 | pub fn addZoirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void { | 4107 | try eb.addRootErrorMessage(.{ |
| 3821 | const gpa = eb.gpa; | 4108 | .msg = try eb.addString(msg), |
| 3822 | const src_path = try file.fullPath(gpa); | 4109 | .src_loc = try zcu.fileByIndex(file_index).errorBundleWholeFileSrc(zcu, eb), |
| 3823 | defer gpa.free(src_path); | 4110 | .notes_len = if (imported_note != null) 1 else 0, |
| 3824 | return eb.addZoirErrorMessages(file.zoir.?, file.tree.?, file.source.?, src_path); | 4111 | }); |
| 4112 | if (imported_note) |n| { | ||
| 4113 | const note_idx = try eb.reserveNotes(1); | ||
| 4114 | eb.extra.items[note_idx] = @intFromEnum(n); | ||
| 4115 | } | ||
| 3825 | } | 4116 | } |
| 3826 | 4117 | ||
| 3827 | pub fn performAllTheWork( | 4118 | pub fn performAllTheWork( |
| ... | @@ -3966,51 +4257,48 @@ fn performAllTheWorkInner( | ... | @@ -3966,51 +4257,48 @@ fn performAllTheWorkInner( |
| 3966 | var astgen_wait_group: WaitGroup = .{}; | 4257 | var astgen_wait_group: WaitGroup = .{}; |
| 3967 | defer astgen_wait_group.wait(); | 4258 | defer astgen_wait_group.wait(); |
| 3968 | 4259 | ||
| 3969 | // builtin.zig is handled specially for two reasons: | 4260 | if (comp.zcu) |zcu| { |
| 3970 | // 1. to avoid race condition of zig processes truncating each other's builtin.zig files | 4261 | const gpa = zcu.gpa; |
| 3971 | // 2. optimization; in the hot path it only incurs a stat() syscall, which happens | 4262 | |
| 3972 | // in the `astgen_wait_group`. | 4263 | // We cannot reference `zcu.import_table` after we spawn any `workerUpdateFile` jobs, |
| 3973 | if (comp.queued_jobs.update_builtin_zig) b: { | 4264 | // because on single-threaded targets the worker will be run eagerly, meaning the |
| 3974 | comp.queued_jobs.update_builtin_zig = false; | 4265 | // `import_table` could be mutated, and not even holding `comp.mutex` will save us. So, |
| 3975 | if (comp.zcu == null) break :b; | 4266 | // build up a list of the files to update *before* we spawn any jobs. |
| 3976 | // TODO put all the modules in a flat array to make them easy to iterate. | 4267 | var astgen_work_items: std.MultiArrayList(struct { |
| 3977 | var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .empty; | 4268 | file_index: Zcu.File.Index, |
| 3978 | defer seen.deinit(comp.gpa); | 4269 | file: *Zcu.File, |
| 3979 | try seen.put(comp.gpa, comp.root_mod, {}); | 4270 | }) = .empty; |
| 3980 | var i: usize = 0; | 4271 | defer astgen_work_items.deinit(gpa); |
| 3981 | while (i < seen.count()) : (i += 1) { | 4272 | // Not every item in `import_table` will need updating, because some are builtin.zig |
| 3982 | const mod = seen.keys()[i]; | 4273 | // files. However, most will, so let's just reserve sufficient capacity upfront. |
| 3983 | for (mod.deps.values()) |dep| | 4274 | try astgen_work_items.ensureTotalCapacity(gpa, zcu.import_table.count()); |
| 3984 | try seen.put(comp.gpa, dep, {}); | 4275 | for (zcu.import_table.keys()) |file_index| { |
| 3985 | 4276 | const file = zcu.fileByIndex(file_index); | |
| 3986 | const file = mod.builtin_file orelse continue; | 4277 | if (file.is_builtin) { |
| 3987 | 4278 | // This is a `builtin.zig`, so updating is redundant. However, we want to make | |
| 3988 | comp.thread_pool.spawnWg(&astgen_wait_group, workerUpdateBuiltinZigFile, .{ | 4279 | // sure the file contents are still correct on disk, since it can improve the |
| 3989 | comp, mod, file, | 4280 | // debugging experience better. That job only needs `file`, so we can kick it |
| 4281 | // off right now. | ||
| 4282 | comp.thread_pool.spawnWg(&astgen_wait_group, workerUpdateBuiltinFile, .{ comp, file }); | ||
| 4283 | continue; | ||
| 4284 | } | ||
| 4285 | astgen_work_items.appendAssumeCapacity(.{ | ||
| 4286 | .file_index = file_index, | ||
| 4287 | .file = file, | ||
| 3990 | }); | 4288 | }); |
| 3991 | } | 4289 | } |
| 3992 | } | ||
| 3993 | 4290 | ||
| 3994 | if (comp.zcu) |zcu| { | 4291 | // Now that we're not going to touch `zcu.import_table` again, we can spawn `workerUpdateFile` jobs. |
| 3995 | { | 4292 | for (astgen_work_items.items(.file_index), astgen_work_items.items(.file)) |file_index, file| { |
| 3996 | // Worker threads may append to zcu.files and zcu.import_table | 4293 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateFile, .{ |
| 3997 | // so we must hold the lock while spawning those tasks, since | 4294 | comp, file, file_index, zir_prog_node, &astgen_wait_group, |
| 3998 | // we access those tables in this loop. | 4295 | }); |
| 3999 | comp.mutex.lock(); | ||
| 4000 | defer comp.mutex.unlock(); | ||
| 4001 | |||
| 4002 | while (comp.astgen_work_queue.readItem()) |file_index| { | ||
| 4003 | // Pre-load these things from our single-threaded context since they | ||
| 4004 | // will be needed by the worker threads. | ||
| 4005 | const path_digest = zcu.filePathDigest(file_index); | ||
| 4006 | const file = zcu.fileByIndex(file_index); | ||
| 4007 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateFile, .{ | ||
| 4008 | comp, file, file_index, path_digest, zir_prog_node, &astgen_wait_group, .root, | ||
| 4009 | }); | ||
| 4010 | } | ||
| 4011 | } | 4296 | } |
| 4012 | 4297 | ||
| 4013 | for (0.., zcu.embed_table.values()) |ef_index_usize, ef| { | 4298 | // On the other hand, it's fine to directly iterate `zcu.embed_table.keys()` here |
| 4299 | // because `workerUpdateEmbedFile` can't invalidate it. The different here is that one | ||
| 4300 | // `@embedFile` can't trigger analysis of a new `@embedFile`! | ||
| 4301 | for (0.., zcu.embed_table.keys()) |ef_index_usize, ef| { | ||
| 4014 | const ef_index: Zcu.EmbedFile.Index = @enumFromInt(ef_index_usize); | 4302 | const ef_index: Zcu.EmbedFile.Index = @enumFromInt(ef_index_usize); |
| 4015 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateEmbedFile, .{ | 4303 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateEmbedFile, .{ |
| 4016 | comp, ef_index, ef, | 4304 | comp, ef_index, ef, |
| ... | @@ -4035,25 +4323,39 @@ fn performAllTheWorkInner( | ... | @@ -4035,25 +4323,39 @@ fn performAllTheWorkInner( |
| 4035 | const pt: Zcu.PerThread = .activate(zcu, .main); | 4323 | const pt: Zcu.PerThread = .activate(zcu, .main); |
| 4036 | defer pt.deactivate(); | 4324 | defer pt.deactivate(); |
| 4037 | 4325 | ||
| 4038 | // If the cache mode is `whole`, then add every source file to the cache manifest. | 4326 | const gpa = zcu.gpa; |
| 4327 | |||
| 4328 | // On an incremental update, a source file might become "dead", in that all imports of | ||
| 4329 | // the file were removed. This could even change what module the file belongs to! As such, | ||
| 4330 | // we do a traversal over the files, to figure out which ones are alive and the modules | ||
| 4331 | // they belong to. | ||
| 4332 | const any_fatal_files = try pt.computeAliveFiles(); | ||
| 4333 | |||
| 4334 | // If the cache mode is `whole`, add every alive source file to the manifest. | ||
| 4039 | switch (comp.cache_use) { | 4335 | switch (comp.cache_use) { |
| 4040 | .whole => |whole| if (whole.cache_manifest) |man| { | 4336 | .whole => |whole| if (whole.cache_manifest) |man| { |
| 4041 | const gpa = zcu.gpa; | 4337 | for (zcu.alive_files.keys()) |file_index| { |
| 4042 | for (zcu.import_table.values()) |file_index| { | ||
| 4043 | const file = zcu.fileByIndex(file_index); | 4338 | const file = zcu.fileByIndex(file_index); |
| 4044 | const source = file.getSource(gpa) catch |err| { | 4339 | |
| 4045 | try pt.reportRetryableFileError(file_index, "unable to load source: {s}", .{@errorName(err)}); | 4340 | switch (file.status) { |
| 4046 | continue; | 4341 | .never_loaded => unreachable, // AstGen tried to load it |
| 4342 | .retryable_failure => continue, // the file cannot be read; this is a guaranteed error | ||
| 4343 | .astgen_failure, .success => {}, // the file was read successfully | ||
| 4344 | } | ||
| 4345 | |||
| 4346 | const path = try file.path.toAbsolute(comp.dirs, gpa); | ||
| 4347 | defer gpa.free(path); | ||
| 4348 | |||
| 4349 | const result = res: { | ||
| 4350 | whole.cache_manifest_mutex.lock(); | ||
| 4351 | defer whole.cache_manifest_mutex.unlock(); | ||
| 4352 | if (file.source) |source| { | ||
| 4353 | break :res man.addFilePostContents(path, source, file.stat); | ||
| 4354 | } else { | ||
| 4355 | break :res man.addFilePost(path); | ||
| 4356 | } | ||
| 4047 | }; | 4357 | }; |
| 4048 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 4358 | result catch |err| switch (err) { |
| 4049 | file.mod.root.root_dir.path orelse ".", | ||
| 4050 | file.mod.root.sub_path, | ||
| 4051 | file.sub_file_path, | ||
| 4052 | }); | ||
| 4053 | errdefer gpa.free(resolved_path); | ||
| 4054 | whole.cache_manifest_mutex.lock(); | ||
| 4055 | defer whole.cache_manifest_mutex.unlock(); | ||
| 4056 | man.addFilePostContents(resolved_path, source.bytes, source.stat) catch |err| switch (err) { | ||
| 4057 | error.OutOfMemory => |e| return e, | 4359 | error.OutOfMemory => |e| return e, |
| 4058 | else => { | 4360 | else => { |
| 4059 | try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)}); | 4361 | try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)}); |
| ... | @@ -4065,23 +4367,14 @@ fn performAllTheWorkInner( | ... | @@ -4065,23 +4367,14 @@ fn performAllTheWorkInner( |
| 4065 | .incremental => {}, | 4367 | .incremental => {}, |
| 4066 | } | 4368 | } |
| 4067 | 4369 | ||
| 4068 | try reportMultiModuleErrors(pt); | 4370 | if (any_fatal_files or |
| 4069 | 4371 | zcu.multi_module_err != null or | |
| 4070 | const any_fatal_files = for (zcu.import_table.values()) |file_index| { | 4372 | zcu.failed_imports.items.len > 0 or |
| 4071 | const file = zcu.fileByIndex(file_index); | 4373 | comp.alloc_failure_occurred) |
| 4072 | switch (file.status) { | 4374 | { |
| 4073 | .never_loaded => unreachable, // everything is loaded by the workers | ||
| 4074 | .retryable_failure, .astgen_failure => break true, | ||
| 4075 | .success => {}, | ||
| 4076 | } | ||
| 4077 | } else false; | ||
| 4078 | |||
| 4079 | if (any_fatal_files or comp.alloc_failure_occurred) { | ||
| 4080 | // We give up right now! No updating of ZIR refs, no nothing. The idea is that this prevents | 4375 | // We give up right now! No updating of ZIR refs, no nothing. The idea is that this prevents |
| 4081 | // us from invalidating lots of incremental dependencies due to files with e.g. parse errors. | 4376 | // us from invalidating lots of incremental dependencies due to files with e.g. parse errors. |
| 4082 | // However, this means our analysis data is invalid, so we want to omit all analysis errors. | 4377 | // However, this means our analysis data is invalid, so we want to omit all analysis errors. |
| 4083 | |||
| 4084 | assert(zcu.failed_files.count() > 0); // we will get an error | ||
| 4085 | zcu.skip_analysis_this_update = true; | 4378 | zcu.skip_analysis_this_update = true; |
| 4086 | return; | 4379 | return; |
| 4087 | } | 4380 | } |
| ... | @@ -4093,6 +4386,11 @@ fn performAllTheWorkInner( | ... | @@ -4093,6 +4386,11 @@ fn performAllTheWorkInner( |
| 4093 | } | 4386 | } |
| 4094 | try zcu.flushRetryableFailures(); | 4387 | try zcu.flushRetryableFailures(); |
| 4095 | 4388 | ||
| 4389 | // It's analysis time! Queue up our initial analysis. | ||
| 4390 | for (zcu.analysis_roots.slice()) |mod| { | ||
| 4391 | try comp.queueJob(.{ .analyze_mod = mod }); | ||
| 4392 | } | ||
| 4393 | |||
| 4096 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | 4394 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); |
| 4097 | zcu.codegen_prog_node = if (comp.bin_file != null) main_progress_node.start("Code Generation", 0) else .none; | 4395 | zcu.codegen_prog_node = if (comp.bin_file != null) main_progress_node.start("Code Generation", 0) else .none; |
| 4098 | } | 4396 | } |
| ... | @@ -4236,7 +4534,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { | ... | @@ -4236,7 +4534,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { |
| 4236 | 4534 | ||
| 4237 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | 4535 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); |
| 4238 | defer pt.deactivate(); | 4536 | defer pt.deactivate(); |
| 4239 | pt.semaPkg(mod) catch |err| switch (err) { | 4537 | pt.semaMod(mod) catch |err| switch (err) { |
| 4240 | error.OutOfMemory => return error.OutOfMemory, | 4538 | error.OutOfMemory => return error.OutOfMemory, |
| 4241 | error.AnalysisFail => return, | 4539 | error.AnalysisFail => return, |
| 4242 | }; | 4540 | }; |
| ... | @@ -4301,7 +4599,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { | ... | @@ -4301,7 +4599,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4301 | 4599 | ||
| 4302 | for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { | 4600 | for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { |
| 4303 | const basename = std.fs.path.basename(sub_path); | 4601 | const basename = std.fs.path.basename(sub_path); |
| 4304 | comp.zig_lib_directory.handle.copyFile(sub_path, out_dir, basename, .{}) catch |err| { | 4602 | comp.dirs.zig_lib.handle.copyFile(sub_path, out_dir, basename, .{}) catch |err| { |
| 4305 | comp.lockAndSetMiscFailure(.docs_copy, "unable to copy {s}: {s}", .{ | 4603 | comp.lockAndSetMiscFailure(.docs_copy, "unable to copy {s}: {s}", .{ |
| 4306 | sub_path, | 4604 | sub_path, |
| 4307 | @errorName(err), | 4605 | @errorName(err), |
| ... | @@ -4338,10 +4636,12 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { | ... | @@ -4338,10 +4636,12 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4338 | 4636 | ||
| 4339 | fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, tar_file: std.fs.File) !void { | 4637 | fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, tar_file: std.fs.File) !void { |
| 4340 | const root = module.root; | 4638 | const root = module.root; |
| 4341 | const sub_path = if (root.sub_path.len == 0) "." else root.sub_path; | 4639 | var mod_dir = d: { |
| 4342 | var mod_dir = root.root_dir.handle.openDir(sub_path, .{ .iterate = true }) catch |err| { | 4640 | const root_dir, const sub_path = root.openInfo(comp.dirs); |
| 4641 | break :d root_dir.openDir(sub_path, .{ .iterate = true }); | ||
| 4642 | } catch |err| { | ||
| 4343 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{}': {s}", .{ | 4643 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{}': {s}", .{ |
| 4344 | root, @errorName(err), | 4644 | root.fmt(comp), @errorName(err), |
| 4345 | }); | 4645 | }); |
| 4346 | }; | 4646 | }; |
| 4347 | defer mod_dir.close(); | 4647 | defer mod_dir.close(); |
| ... | @@ -4363,13 +4663,13 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, | ... | @@ -4363,13 +4663,13 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, |
| 4363 | } | 4663 | } |
| 4364 | var file = mod_dir.openFile(entry.path, .{}) catch |err| { | 4664 | var file = mod_dir.openFile(entry.path, .{}) catch |err| { |
| 4365 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open '{}{s}': {s}", .{ | 4665 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open '{}{s}': {s}", .{ |
| 4366 | root, entry.path, @errorName(err), | 4666 | root.fmt(comp), entry.path, @errorName(err), |
| 4367 | }); | 4667 | }); |
| 4368 | }; | 4668 | }; |
| 4369 | defer file.close(); | 4669 | defer file.close(); |
| 4370 | archiver.writeFile(entry.path, file) catch |err| { | 4670 | archiver.writeFile(entry.path, file) catch |err| { |
| 4371 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive '{}{s}': {s}", .{ | 4671 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive '{}{s}': {s}", .{ |
| 4372 | root, entry.path, @errorName(err), | 4672 | root.fmt(comp), entry.path, @errorName(err), |
| 4373 | }); | 4673 | }); |
| 4374 | }; | 4674 | }; |
| 4375 | } | 4675 | } |
| ... | @@ -4430,13 +4730,11 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4430,13 +4730,11 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4430 | const src_basename = "main.zig"; | 4730 | const src_basename = "main.zig"; |
| 4431 | const root_name = std.fs.path.stem(src_basename); | 4731 | const root_name = std.fs.path.stem(src_basename); |
| 4432 | 4732 | ||
| 4733 | const dirs = comp.dirs.withoutLocalCache(); | ||
| 4734 | |||
| 4433 | const root_mod = try Package.Module.create(arena, .{ | 4735 | const root_mod = try Package.Module.create(arena, .{ |
| 4434 | .global_cache_directory = comp.global_cache_directory, | ||
| 4435 | .paths = .{ | 4736 | .paths = .{ |
| 4436 | .root = .{ | 4737 | .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"), |
| 4437 | .root_dir = comp.zig_lib_directory, | ||
| 4438 | .sub_path = "docs/wasm", | ||
| 4439 | }, | ||
| 4440 | .root_src_path = src_basename, | 4738 | .root_src_path = src_basename, |
| 4441 | }, | 4739 | }, |
| 4442 | .fully_qualified_name = root_name, | 4740 | .fully_qualified_name = root_name, |
| ... | @@ -4447,16 +4745,10 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4447,16 +4745,10 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4447 | .global = config, | 4745 | .global = config, |
| 4448 | .cc_argv = &.{}, | 4746 | .cc_argv = &.{}, |
| 4449 | .parent = null, | 4747 | .parent = null, |
| 4450 | .builtin_mod = null, | ||
| 4451 | .builtin_modules = null, | ||
| 4452 | }); | 4748 | }); |
| 4453 | const walk_mod = try Package.Module.create(arena, .{ | 4749 | const walk_mod = try Package.Module.create(arena, .{ |
| 4454 | .global_cache_directory = comp.global_cache_directory, | ||
| 4455 | .paths = .{ | 4750 | .paths = .{ |
| 4456 | .root = .{ | 4751 | .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"), |
| 4457 | .root_dir = comp.zig_lib_directory, | ||
| 4458 | .sub_path = "docs/wasm", | ||
| 4459 | }, | ||
| 4460 | .root_src_path = "Walk.zig", | 4752 | .root_src_path = "Walk.zig", |
| 4461 | }, | 4753 | }, |
| 4462 | .fully_qualified_name = "Walk", | 4754 | .fully_qualified_name = "Walk", |
| ... | @@ -4467,8 +4759,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4467,8 +4759,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4467 | .global = config, | 4759 | .global = config, |
| 4468 | .cc_argv = &.{}, | 4760 | .cc_argv = &.{}, |
| 4469 | .parent = root_mod, | 4761 | .parent = root_mod, |
| 4470 | .builtin_mod = root_mod.getBuiltinDependency(), | ||
| 4471 | .builtin_modules = null, // `builtin_mod` is set | ||
| 4472 | }); | 4762 | }); |
| 4473 | try root_mod.deps.put(arena, "Walk", walk_mod); | 4763 | try root_mod.deps.put(arena, "Walk", walk_mod); |
| 4474 | const bin_basename = try std.zig.binNameAlloc(arena, .{ | 4764 | const bin_basename = try std.zig.binNameAlloc(arena, .{ |
| ... | @@ -4478,9 +4768,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4478,9 +4768,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4478 | }); | 4768 | }); |
| 4479 | 4769 | ||
| 4480 | const sub_compilation = try Compilation.create(gpa, arena, .{ | 4770 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 4481 | .global_cache_directory = comp.global_cache_directory, | 4771 | .dirs = dirs, |
| 4482 | .local_cache_directory = comp.global_cache_directory, | ||
| 4483 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 4484 | .self_exe_path = comp.self_exe_path, | 4772 | .self_exe_path = comp.self_exe_path, |
| 4485 | .config = config, | 4773 | .config = config, |
| 4486 | .root_mod = root_mod, | 4774 | .root_mod = root_mod, |
| ... | @@ -4517,14 +4805,14 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4517,14 +4805,14 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4517 | }; | 4805 | }; |
| 4518 | defer out_dir.close(); | 4806 | defer out_dir.close(); |
| 4519 | 4807 | ||
| 4520 | sub_compilation.local_cache_directory.handle.copyFile( | 4808 | sub_compilation.dirs.local_cache.handle.copyFile( |
| 4521 | sub_compilation.cache_use.whole.bin_sub_path.?, | 4809 | sub_compilation.cache_use.whole.bin_sub_path.?, |
| 4522 | out_dir, | 4810 | out_dir, |
| 4523 | "main.wasm", | 4811 | "main.wasm", |
| 4524 | .{}, | 4812 | .{}, |
| 4525 | ) catch |err| { | 4813 | ) catch |err| { |
| 4526 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{}{s}' to '{}{s}': {s}", .{ | 4814 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{}{s}' to '{}{s}': {s}", .{ |
| 4527 | sub_compilation.local_cache_directory, | 4815 | sub_compilation.dirs.local_cache, |
| 4528 | sub_compilation.cache_use.whole.bin_sub_path.?, | 4816 | sub_compilation.cache_use.whole.bin_sub_path.?, |
| 4529 | emit.root_dir, | 4817 | emit.root_dir, |
| 4530 | emit.sub_path, | 4818 | emit.sub_path, |
| ... | @@ -4538,28 +4826,23 @@ fn workerUpdateFile( | ... | @@ -4538,28 +4826,23 @@ fn workerUpdateFile( |
| 4538 | comp: *Compilation, | 4826 | comp: *Compilation, |
| 4539 | file: *Zcu.File, | 4827 | file: *Zcu.File, |
| 4540 | file_index: Zcu.File.Index, | 4828 | file_index: Zcu.File.Index, |
| 4541 | path_digest: Cache.BinDigest, | ||
| 4542 | prog_node: std.Progress.Node, | 4829 | prog_node: std.Progress.Node, |
| 4543 | wg: *WaitGroup, | 4830 | wg: *WaitGroup, |
| 4544 | src: Zcu.AstGenSrc, | ||
| 4545 | ) void { | 4831 | ) void { |
| 4546 | const child_prog_node = prog_node.start(file.sub_file_path, 0); | 4832 | const child_prog_node = prog_node.start(std.fs.path.basename(file.path.sub_path), 0); |
| 4547 | defer child_prog_node.end(); | 4833 | defer child_prog_node.end(); |
| 4548 | 4834 | ||
| 4549 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | 4835 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); |
| 4550 | defer pt.deactivate(); | 4836 | defer pt.deactivate(); |
| 4551 | pt.updateFile(file, path_digest) catch |err| switch (err) { | 4837 | pt.updateFile(file_index, file) catch |err| { |
| 4552 | error.AnalysisFail => return, | 4838 | pt.reportRetryableFileError(file_index, "unable to load '{s}': {s}", .{ std.fs.path.basename(file.path.sub_path), @errorName(err) }) catch |oom| switch (oom) { |
| 4553 | else => { | 4839 | error.OutOfMemory => { |
| 4554 | pt.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) { | 4840 | comp.mutex.lock(); |
| 4555 | error.OutOfMemory => { | 4841 | defer comp.mutex.unlock(); |
| 4556 | comp.mutex.lock(); | 4842 | comp.setAllocFailure(); |
| 4557 | defer comp.mutex.unlock(); | 4843 | }, |
| 4558 | comp.setAllocFailure(); | 4844 | }; |
| 4559 | }, | 4845 | return; |
| 4560 | }; | ||
| 4561 | return; | ||
| 4562 | }, | ||
| 4563 | }; | 4846 | }; |
| 4564 | 4847 | ||
| 4565 | switch (file.getMode()) { | 4848 | switch (file.getMode()) { |
| ... | @@ -4567,9 +4850,9 @@ fn workerUpdateFile( | ... | @@ -4567,9 +4850,9 @@ fn workerUpdateFile( |
| 4567 | .zon => return, // ZON can't import anything so we're done | 4850 | .zon => return, // ZON can't import anything so we're done |
| 4568 | } | 4851 | } |
| 4569 | 4852 | ||
| 4570 | // Pre-emptively look for `@import` paths and queue them up. | 4853 | // Discover all imports in the file. Imports of modules we ignore for now since we don't |
| 4571 | // If we experience an error preemptively fetching the | 4854 | // know which module we're in, but imports of file paths might need us to queue up other |
| 4572 | // file, just ignore it and let it happen again later during Sema. | 4855 | // AstGen jobs. |
| 4573 | const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | 4856 | const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; |
| 4574 | if (imports_index != 0) { | 4857 | if (imports_index != 0) { |
| 4575 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index); | 4858 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index); |
| ... | @@ -4581,54 +4864,34 @@ fn workerUpdateFile( | ... | @@ -4581,54 +4864,34 @@ fn workerUpdateFile( |
| 4581 | extra_index = item.end; | 4864 | extra_index = item.end; |
| 4582 | 4865 | ||
| 4583 | const import_path = file.zir.?.nullTerminatedString(item.data.name); | 4866 | const import_path = file.zir.?.nullTerminatedString(item.data.name); |
| 4584 | // `@import("builtin")` is handled specially. | ||
| 4585 | if (mem.eql(u8, import_path, "builtin")) continue; | ||
| 4586 | |||
| 4587 | const import_result, const imported_path_digest = blk: { | ||
| 4588 | comp.mutex.lock(); | ||
| 4589 | defer comp.mutex.unlock(); | ||
| 4590 | 4867 | ||
| 4591 | const res = pt.importFile(file, import_path) catch continue; | 4868 | if (pt.discoverImport(file.path, import_path)) |res| switch (res) { |
| 4592 | if (!res.is_pkg) { | 4869 | .module, .existing_file => {}, |
| 4593 | res.file.addReference(pt.zcu, .{ .import = .{ | 4870 | .new_file => |new| { |
| 4594 | .file = file_index, | 4871 | comp.thread_pool.spawnWgId(wg, workerUpdateFile, .{ |
| 4595 | .token = item.data.token, | 4872 | comp, new.file, new.index, prog_node, wg, |
| 4596 | } }) catch continue; | 4873 | }); |
| 4597 | } | 4874 | }, |
| 4598 | if (res.is_new) if (comp.file_system_inputs) |fsi| { | 4875 | } else |err| switch (err) { |
| 4599 | comp.appendFileSystemInput(fsi, res.file.mod.root, res.file.sub_file_path) catch continue; | 4876 | error.OutOfMemory => { |
| 4600 | }; | 4877 | comp.mutex.lock(); |
| 4601 | const imported_path_digest = pt.zcu.filePathDigest(res.file_index); | 4878 | defer comp.mutex.unlock(); |
| 4602 | break :blk .{ res, imported_path_digest }; | 4879 | comp.setAllocFailure(); |
| 4603 | }; | 4880 | }, |
| 4604 | if (import_result.is_new) { | ||
| 4605 | log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{ | ||
| 4606 | file.sub_file_path, import_path, import_result.file.sub_file_path, | ||
| 4607 | }); | ||
| 4608 | const sub_src: Zcu.AstGenSrc = .{ .import = .{ | ||
| 4609 | .importing_file = file_index, | ||
| 4610 | .import_tok = item.data.token, | ||
| 4611 | } }; | ||
| 4612 | comp.thread_pool.spawnWgId(wg, workerUpdateFile, .{ | ||
| 4613 | comp, import_result.file, import_result.file_index, imported_path_digest, prog_node, wg, sub_src, | ||
| 4614 | }); | ||
| 4615 | } | 4881 | } |
| 4616 | } | 4882 | } |
| 4617 | } | 4883 | } |
| 4618 | } | 4884 | } |
| 4619 | 4885 | ||
| 4620 | fn workerUpdateBuiltinZigFile( | 4886 | fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void { |
| 4621 | comp: *Compilation, | 4887 | Builtin.updateFileOnDisk(file, comp) catch |err| { |
| 4622 | mod: *Package.Module, | ||
| 4623 | file: *Zcu.File, | ||
| 4624 | ) void { | ||
| 4625 | Builtin.populateFile(comp, mod, file) catch |err| { | ||
| 4626 | comp.mutex.lock(); | 4888 | comp.mutex.lock(); |
| 4627 | defer comp.mutex.unlock(); | 4889 | defer comp.mutex.unlock(); |
| 4628 | 4890 | comp.setMiscFailure( | |
| 4629 | comp.setMiscFailure(.write_builtin_zig, "unable to write '{}{s}': {s}", .{ | 4891 | .write_builtin_zig, |
| 4630 | mod.root, mod.root_src_path, @errorName(err), | 4892 | "unable to write '{}': {s}", |
| 4631 | }); | 4893 | .{ file.path.fmt(comp), @errorName(err) }, |
| 4894 | ); | ||
| 4632 | }; | 4895 | }; |
| 4633 | } | 4896 | } |
| 4634 | 4897 | ||
| ... | @@ -4738,10 +5001,10 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module | ... | @@ -4738,10 +5001,10 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module |
| 4738 | 5001 | ||
| 4739 | const tmp_digest = man.hash.peek(); | 5002 | const tmp_digest = man.hash.peek(); |
| 4740 | const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest }); | 5003 | const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest }); |
| 4741 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 5004 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 4742 | defer zig_cache_tmp_dir.close(); | 5005 | defer zig_cache_tmp_dir.close(); |
| 4743 | const cimport_basename = "cimport.h"; | 5006 | const cimport_basename = "cimport.h"; |
| 4744 | const out_h_path = try comp.local_cache_directory.join(arena, &[_][]const u8{ | 5007 | const out_h_path = try comp.dirs.local_cache.join(arena, &[_][]const u8{ |
| 4745 | tmp_dir_sub_path, cimport_basename, | 5008 | tmp_dir_sub_path, cimport_basename, |
| 4746 | }); | 5009 | }); |
| 4747 | const out_dep_path = try std.fmt.allocPrint(arena, "{s}.d", .{out_h_path}); | 5010 | const out_dep_path = try std.fmt.allocPrint(arena, "{s}.d", .{out_h_path}); |
| ... | @@ -4779,7 +5042,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module | ... | @@ -4779,7 +5042,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module |
| 4779 | new_argv[i] = try arena.dupeZ(u8, arg); | 5042 | new_argv[i] = try arena.dupeZ(u8, arg); |
| 4780 | } | 5043 | } |
| 4781 | 5044 | ||
| 4782 | const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"}); | 5045 | const c_headers_dir_path_z = try comp.dirs.zig_lib.joinZ(arena, &.{"include"}); |
| 4783 | var errors = std.zig.ErrorBundle.empty; | 5046 | var errors = std.zig.ErrorBundle.empty; |
| 4784 | errdefer errors.deinit(comp.gpa); | 5047 | errdefer errors.deinit(comp.gpa); |
| 4785 | break :tree translate_c.translate( | 5048 | break :tree translate_c.translate( |
| ... | @@ -4820,7 +5083,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module | ... | @@ -4820,7 +5083,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module |
| 4820 | const bin_digest = man.finalBin(); | 5083 | const bin_digest = man.finalBin(); |
| 4821 | const hex_digest = Cache.binToHex(bin_digest); | 5084 | const hex_digest = Cache.binToHex(bin_digest); |
| 4822 | const o_sub_path = "o" ++ std.fs.path.sep_str ++ hex_digest; | 5085 | const o_sub_path = "o" ++ std.fs.path.sep_str ++ hex_digest; |
| 4823 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5086 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 4824 | defer o_dir.close(); | 5087 | defer o_dir.close(); |
| 4825 | 5088 | ||
| 4826 | var out_zig_file = try o_dir.createFile(cimport_zig_basename, .{}); | 5089 | var out_zig_file = try o_dir.createFile(cimport_zig_basename, .{}); |
| ... | @@ -5226,7 +5489,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -5226,7 +5489,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5226 | // We can't know the digest until we do the C compiler invocation, | 5489 | // We can't know the digest until we do the C compiler invocation, |
| 5227 | // so we need a temporary filename. | 5490 | // so we need a temporary filename. |
| 5228 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); | 5491 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); |
| 5229 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); | 5492 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 5230 | defer zig_cache_tmp_dir.close(); | 5493 | defer zig_cache_tmp_dir.close(); |
| 5231 | 5494 | ||
| 5232 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) | 5495 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) |
| ... | @@ -5362,7 +5625,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -5362,7 +5625,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5362 | // Rename into place. | 5625 | // Rename into place. |
| 5363 | const digest = man.final(); | 5626 | const digest = man.final(); |
| 5364 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 5627 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 5365 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5628 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 5366 | defer o_dir.close(); | 5629 | defer o_dir.close(); |
| 5367 | const tmp_basename = std.fs.path.basename(out_obj_path); | 5630 | const tmp_basename = std.fs.path.basename(out_obj_path); |
| 5368 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); | 5631 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); |
| ... | @@ -5386,7 +5649,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -5386,7 +5649,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5386 | c_object.status = .{ | 5649 | c_object.status = .{ |
| 5387 | .success = .{ | 5650 | .success = .{ |
| 5388 | .object_path = .{ | 5651 | .object_path = .{ |
| 5389 | .root_dir = comp.local_cache_directory, | 5652 | .root_dir = comp.dirs.local_cache, |
| 5390 | .sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, o_basename }), | 5653 | .sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, o_basename }), |
| 5391 | }, | 5654 | }, |
| 5392 | .lock = man.toOwnedLock(), | 5655 | .lock = man.toOwnedLock(), |
| ... | @@ -5449,13 +5712,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5449,13 +5712,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5449 | const digest = man.final(); | 5712 | const digest = man.final(); |
| 5450 | 5713 | ||
| 5451 | const o_sub_path = try std.fs.path.join(arena, &.{ "o", &digest }); | 5714 | const o_sub_path = try std.fs.path.join(arena, &.{ "o", &digest }); |
| 5452 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5715 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 5453 | defer o_dir.close(); | 5716 | defer o_dir.close(); |
| 5454 | 5717 | ||
| 5455 | const in_rc_path = try comp.local_cache_directory.join(comp.gpa, &.{ | 5718 | const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ |
| 5456 | o_sub_path, rc_basename, | 5719 | o_sub_path, rc_basename, |
| 5457 | }); | 5720 | }); |
| 5458 | const out_res_path = try comp.local_cache_directory.join(comp.gpa, &.{ | 5721 | const out_res_path = try comp.dirs.local_cache.join(comp.gpa, &.{ |
| 5459 | o_sub_path, res_basename, | 5722 | o_sub_path, res_basename, |
| 5460 | }); | 5723 | }); |
| 5461 | 5724 | ||
| ... | @@ -5517,7 +5780,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5517,7 +5780,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5517 | 5780 | ||
| 5518 | win32_resource.status = .{ | 5781 | win32_resource.status = .{ |
| 5519 | .success = .{ | 5782 | .success = .{ |
| 5520 | .res_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{ | 5783 | .res_path = try comp.dirs.local_cache.join(comp.gpa, &[_][]const u8{ |
| 5521 | "o", &digest, res_basename, | 5784 | "o", &digest, res_basename, |
| 5522 | }), | 5785 | }), |
| 5523 | .lock = man.toOwnedLock(), | 5786 | .lock = man.toOwnedLock(), |
| ... | @@ -5535,7 +5798,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5535,7 +5798,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5535 | const rc_basename_noext = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; | 5798 | const rc_basename_noext = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; |
| 5536 | 5799 | ||
| 5537 | const digest = if (try man.hit()) man.final() else blk: { | 5800 | const digest = if (try man.hit()) man.final() else blk: { |
| 5538 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); | 5801 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 5539 | defer zig_cache_tmp_dir.close(); | 5802 | defer zig_cache_tmp_dir.close(); |
| 5540 | 5803 | ||
| 5541 | const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); | 5804 | const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); |
| ... | @@ -5605,7 +5868,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5605,7 +5868,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5605 | // Rename into place. | 5868 | // Rename into place. |
| 5606 | const digest = man.final(); | 5869 | const digest = man.final(); |
| 5607 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 5870 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 5608 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5871 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 5609 | defer o_dir.close(); | 5872 | defer o_dir.close(); |
| 5610 | const tmp_basename = std.fs.path.basename(out_res_path); | 5873 | const tmp_basename = std.fs.path.basename(out_res_path); |
| 5611 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); | 5874 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); |
| ... | @@ -5626,7 +5889,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5626,7 +5889,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5626 | 5889 | ||
| 5627 | win32_resource.status = .{ | 5890 | win32_resource.status = .{ |
| 5628 | .success = .{ | 5891 | .success = .{ |
| 5629 | .res_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{ | 5892 | .res_path = try comp.dirs.local_cache.join(comp.gpa, &[_][]const u8{ |
| 5630 | "o", &digest, res_basename, | 5893 | "o", &digest, res_basename, |
| 5631 | }), | 5894 | }), |
| 5632 | .lock = man.toOwnedLock(), | 5895 | .lock = man.toOwnedLock(), |
| ... | @@ -5721,7 +5984,7 @@ fn spawnZigRc( | ... | @@ -5721,7 +5984,7 @@ fn spawnZigRc( |
| 5721 | pub fn tmpFilePath(comp: Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { | 5984 | pub fn tmpFilePath(comp: Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { |
| 5722 | const s = std.fs.path.sep_str; | 5985 | const s = std.fs.path.sep_str; |
| 5723 | const rand_int = std.crypto.random.int(u64); | 5986 | const rand_int = std.crypto.random.int(u64); |
| 5724 | if (comp.local_cache_directory.path) |p| { | 5987 | if (comp.dirs.local_cache.path) |p| { |
| 5725 | return std.fmt.allocPrint(ally, "{s}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix }); | 5988 | return std.fmt.allocPrint(ally, "{s}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix }); |
| 5726 | } else { | 5989 | } else { |
| 5727 | return std.fmt.allocPrint(ally, "tmp" ++ s ++ "{x}-{s}", .{ rand_int, suffix }); | 5990 | return std.fmt.allocPrint(ally, "tmp" ++ s ++ "{x}-{s}", .{ rand_int, suffix }); |
| ... | @@ -5962,12 +6225,12 @@ pub fn addCCArgs( | ... | @@ -5962,12 +6225,12 @@ pub fn addCCArgs( |
| 5962 | if (comp.config.link_libcpp) { | 6225 | if (comp.config.link_libcpp) { |
| 5963 | try argv.append("-isystem"); | 6226 | try argv.append("-isystem"); |
| 5964 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ | 6227 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5965 | comp.zig_lib_directory.path.?, "libcxx", "include", | 6228 | comp.dirs.zig_lib.path.?, "libcxx", "include", |
| 5966 | })); | 6229 | })); |
| 5967 | 6230 | ||
| 5968 | try argv.append("-isystem"); | 6231 | try argv.append("-isystem"); |
| 5969 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ | 6232 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5970 | comp.zig_lib_directory.path.?, "libcxxabi", "include", | 6233 | comp.dirs.zig_lib.path.?, "libcxxabi", "include", |
| 5971 | })); | 6234 | })); |
| 5972 | 6235 | ||
| 5973 | try libcxx.addCxxArgs(comp, arena, argv); | 6236 | try libcxx.addCxxArgs(comp, arena, argv); |
| ... | @@ -5977,7 +6240,7 @@ pub fn addCCArgs( | ... | @@ -5977,7 +6240,7 @@ pub fn addCCArgs( |
| 5977 | // However as noted by @dimenus, appending libc headers before compiler headers breaks | 6240 | // However as noted by @dimenus, appending libc headers before compiler headers breaks |
| 5978 | // intrinsics and other compiler specific items. | 6241 | // intrinsics and other compiler specific items. |
| 5979 | try argv.append("-isystem"); | 6242 | try argv.append("-isystem"); |
| 5980 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" })); | 6243 | try argv.append(try std.fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "include" })); |
| 5981 | 6244 | ||
| 5982 | try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2); | 6245 | try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2); |
| 5983 | for (comp.libc_include_dir_list) |include_dir| { | 6246 | for (comp.libc_include_dir_list) |include_dir| { |
| ... | @@ -5996,7 +6259,7 @@ pub fn addCCArgs( | ... | @@ -5996,7 +6259,7 @@ pub fn addCCArgs( |
| 5996 | if (comp.config.link_libunwind) { | 6259 | if (comp.config.link_libunwind) { |
| 5997 | try argv.append("-isystem"); | 6260 | try argv.append("-isystem"); |
| 5998 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ | 6261 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5999 | comp.zig_lib_directory.path.?, "libunwind", "include", | 6262 | comp.dirs.zig_lib.path.?, "libunwind", "include", |
| 6000 | })); | 6263 | })); |
| 6001 | } | 6264 | } |
| 6002 | 6265 | ||
| ... | @@ -6584,12 +6847,12 @@ test "classifyFileExt" { | ... | @@ -6584,12 +6847,12 @@ test "classifyFileExt" { |
| 6584 | try std.testing.expectEqual(FileExt.zig, classifyFileExt("foo.zig")); | 6847 | try std.testing.expectEqual(FileExt.zig, classifyFileExt("foo.zig")); |
| 6585 | } | 6848 | } |
| 6586 | 6849 | ||
| 6587 | fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) !Path { | 6850 | fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) !Cache.Path { |
| 6588 | return (try crtFilePath(&comp.crt_files, basename)) orelse { | 6851 | return (try crtFilePath(&comp.crt_files, basename)) orelse { |
| 6589 | const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable; | 6852 | const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable; |
| 6590 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir; | 6853 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir; |
| 6591 | const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename }); | 6854 | const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename }); |
| 6592 | return Path.initCwd(full_path); | 6855 | return Cache.Path.initCwd(full_path); |
| 6593 | }; | 6856 | }; |
| 6594 | } | 6857 | } |
| 6595 | 6858 | ||
| ... | @@ -6598,7 +6861,7 @@ pub fn crtFileAsString(comp: *Compilation, arena: Allocator, basename: []const u | ... | @@ -6598,7 +6861,7 @@ pub fn crtFileAsString(comp: *Compilation, arena: Allocator, basename: []const u |
| 6598 | return path.toString(arena); | 6861 | return path.toString(arena); |
| 6599 | } | 6862 | } |
| 6600 | 6863 | ||
| 6601 | fn crtFilePath(crt_files: *std.StringHashMapUnmanaged(CrtFile), basename: []const u8) Allocator.Error!?Path { | 6864 | fn crtFilePath(crt_files: *std.StringHashMapUnmanaged(CrtFile), basename: []const u8) Allocator.Error!?Cache.Path { |
| 6602 | const crt_file = crt_files.get(basename) orelse return null; | 6865 | const crt_file = crt_files.get(basename) orelse return null; |
| 6603 | return crt_file.full_object_path; | 6866 | return crt_file.full_object_path; |
| 6604 | } | 6867 | } |
| ... | @@ -6736,9 +6999,8 @@ fn buildOutputFromZig( | ... | @@ -6736,9 +6999,8 @@ fn buildOutputFromZig( |
| 6736 | }); | 6999 | }); |
| 6737 | 7000 | ||
| 6738 | const root_mod = try Package.Module.create(arena, .{ | 7001 | const root_mod = try Package.Module.create(arena, .{ |
| 6739 | .global_cache_directory = comp.global_cache_directory, | ||
| 6740 | .paths = .{ | 7002 | .paths = .{ |
| 6741 | .root = .{ .root_dir = comp.zig_lib_directory }, | 7003 | .root = .zig_lib_root, |
| 6742 | .root_src_path = src_basename, | 7004 | .root_src_path = src_basename, |
| 6743 | }, | 7005 | }, |
| 6744 | .fully_qualified_name = "root", | 7006 | .fully_qualified_name = "root", |
| ... | @@ -6760,8 +7022,6 @@ fn buildOutputFromZig( | ... | @@ -6760,8 +7022,6 @@ fn buildOutputFromZig( |
| 6760 | .global = config, | 7022 | .global = config, |
| 6761 | .cc_argv = &.{}, | 7023 | .cc_argv = &.{}, |
| 6762 | .parent = null, | 7024 | .parent = null, |
| 6763 | .builtin_mod = null, | ||
| 6764 | .builtin_modules = null, // there is only one module in this compilation | ||
| 6765 | }); | 7025 | }); |
| 6766 | const target = comp.getTarget(); | 7026 | const target = comp.getTarget(); |
| 6767 | const bin_basename = try std.zig.binNameAlloc(arena, .{ | 7027 | const bin_basename = try std.zig.binNameAlloc(arena, .{ |
| ... | @@ -6785,9 +7045,7 @@ fn buildOutputFromZig( | ... | @@ -6785,9 +7045,7 @@ fn buildOutputFromZig( |
| 6785 | }; | 7045 | }; |
| 6786 | 7046 | ||
| 6787 | const sub_compilation = try Compilation.create(gpa, arena, .{ | 7047 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 6788 | .global_cache_directory = comp.global_cache_directory, | 7048 | .dirs = comp.dirs.withoutLocalCache(), |
| 6789 | .local_cache_directory = comp.global_cache_directory, | ||
| 6790 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 6791 | .cache_mode = .whole, | 7049 | .cache_mode = .whole, |
| 6792 | .parent_whole_cache = parent_whole_cache, | 7050 | .parent_whole_cache = parent_whole_cache, |
| 6793 | .self_exe_path = comp.self_exe_path, | 7051 | .self_exe_path = comp.self_exe_path, |
| ... | @@ -6878,9 +7136,8 @@ pub fn build_crt_file( | ... | @@ -6878,9 +7136,8 @@ pub fn build_crt_file( |
| 6878 | }, | 7136 | }, |
| 6879 | }); | 7137 | }); |
| 6880 | const root_mod = try Package.Module.create(arena, .{ | 7138 | const root_mod = try Package.Module.create(arena, .{ |
| 6881 | .global_cache_directory = comp.global_cache_directory, | ||
| 6882 | .paths = .{ | 7139 | .paths = .{ |
| 6883 | .root = .{ .root_dir = comp.zig_lib_directory }, | 7140 | .root = .zig_lib_root, |
| 6884 | .root_src_path = "", | 7141 | .root_src_path = "", |
| 6885 | }, | 7142 | }, |
| 6886 | .fully_qualified_name = "root", | 7143 | .fully_qualified_name = "root", |
| ... | @@ -6908,8 +7165,6 @@ pub fn build_crt_file( | ... | @@ -6908,8 +7165,6 @@ pub fn build_crt_file( |
| 6908 | .global = config, | 7165 | .global = config, |
| 6909 | .cc_argv = &.{}, | 7166 | .cc_argv = &.{}, |
| 6910 | .parent = null, | 7167 | .parent = null, |
| 6911 | .builtin_mod = null, | ||
| 6912 | .builtin_modules = null, // there is only one module in this compilation | ||
| 6913 | }); | 7168 | }); |
| 6914 | 7169 | ||
| 6915 | for (c_source_files) |*item| { | 7170 | for (c_source_files) |*item| { |
| ... | @@ -6917,9 +7172,7 @@ pub fn build_crt_file( | ... | @@ -6917,9 +7172,7 @@ pub fn build_crt_file( |
| 6917 | } | 7172 | } |
| 6918 | 7173 | ||
| 6919 | const sub_compilation = try Compilation.create(gpa, arena, .{ | 7174 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 6920 | .local_cache_directory = comp.global_cache_directory, | 7175 | .dirs = comp.dirs.withoutLocalCache(), |
| 6921 | .global_cache_directory = comp.global_cache_directory, | ||
| 6922 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 6923 | .self_exe_path = comp.self_exe_path, | 7176 | .self_exe_path = comp.self_exe_path, |
| 6924 | .cache_mode = .whole, | 7177 | .cache_mode = .whole, |
| 6925 | .config = config, | 7178 | .config = config, |
| ... | @@ -6962,7 +7215,7 @@ pub fn build_crt_file( | ... | @@ -6962,7 +7215,7 @@ pub fn build_crt_file( |
| 6962 | } | 7215 | } |
| 6963 | } | 7216 | } |
| 6964 | 7217 | ||
| 6965 | pub fn queueLinkTaskMode(comp: *Compilation, path: Path, output_mode: std.builtin.OutputMode) void { | 7218 | pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, output_mode: std.builtin.OutputMode) void { |
| 6966 | comp.queueLinkTasks(switch (output_mode) { | 7219 | comp.queueLinkTasks(switch (output_mode) { |
| 6967 | .Exe => unreachable, | 7220 | .Exe => unreachable, |
| 6968 | .Obj => &.{.{ .load_object = path }}, | 7221 | .Obj => &.{.{ .load_object = path }}, |
| ... | @@ -6983,7 +7236,7 @@ pub fn queueLinkTasks(comp: *Compilation, tasks: []const link.Task) void { | ... | @@ -6983,7 +7236,7 @@ pub fn queueLinkTasks(comp: *Compilation, tasks: []const link.Task) void { |
| 6983 | pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile { | 7236 | pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile { |
| 6984 | return .{ | 7237 | return .{ |
| 6985 | .full_object_path = .{ | 7238 | .full_object_path = .{ |
| 6986 | .root_dir = comp.local_cache_directory, | 7239 | .root_dir = comp.dirs.local_cache, |
| 6987 | .sub_path = try comp.gpa.dupe(u8, comp.cache_use.whole.bin_sub_path.?), | 7240 | .sub_path = try comp.gpa.dupe(u8, comp.cache_use.whole.bin_sub_path.?), |
| 6988 | }, | 7241 | }, |
| 6989 | .lock = comp.cache_use.whole.moveLock(), | 7242 | .lock = comp.cache_use.whole.moveLock(), |
src/InternPool.zig+13| ... | @@ -1723,6 +1723,19 @@ pub const FileIndex = enum(u32) { | ... | @@ -1723,6 +1723,19 @@ pub const FileIndex = enum(u32) { |
| 1723 | .index = @intFromEnum(file_index) & ip.getIndexMask(u32), | 1723 | .index = @intFromEnum(file_index) & ip.getIndexMask(u32), |
| 1724 | }; | 1724 | }; |
| 1725 | } | 1725 | } |
| 1726 | pub fn toOptional(i: FileIndex) Optional { | ||
| 1727 | return @enumFromInt(@intFromEnum(i)); | ||
| 1728 | } | ||
| 1729 | pub const Optional = enum(u32) { | ||
| 1730 | none = std.math.maxInt(u32), | ||
| 1731 | _, | ||
| 1732 | pub fn unwrap(opt: Optional) ?FileIndex { | ||
| 1733 | return switch (opt) { | ||
| 1734 | .none => null, | ||
| 1735 | _ => @enumFromInt(@intFromEnum(opt)), | ||
| 1736 | }; | ||
| 1737 | } | ||
| 1738 | }; | ||
| 1726 | }; | 1739 | }; |
| 1727 | 1740 | ||
| 1728 | const File = struct { | 1741 | const File = struct { |
src/Package/Module.zig+74-148| ... | @@ -1,15 +1,17 @@ | ... | @@ -1,15 +1,17 @@ |
| 1 | //! Corresponds to something that Zig source code can `@import`. | 1 | //! Corresponds to something that Zig source code can `@import`. |
| 2 | 2 | ||
| 3 | /// Only files inside this directory can be imported. | 3 | /// The root directory of the module. Only files inside this directory can be imported. |
| 4 | root: Cache.Path, | 4 | root: Compilation.Path, |
| 5 | /// Relative to `root`. May contain path separators. | 5 | /// Path to the root source file of this module. Relative to `root`. May contain path separators. |
| 6 | root_src_path: []const u8, | 6 | root_src_path: []const u8, |
| 7 | /// Name used in compile errors. Looks like "root.foo.bar". | 7 | /// Name used in compile errors. Looks like "root.foo.bar". |
| 8 | fully_qualified_name: []const u8, | 8 | fully_qualified_name: []const u8, |
| 9 | /// The dependency table of this module. Shared dependencies such as 'std', | 9 | /// The dependency table of this module. The shared dependencies 'std' and |
| 10 | /// 'builtin', and 'root' are not specified in every dependency table, but | 10 | /// 'root' are not specified in every module dependency table, but are stored |
| 11 | /// instead only in the table of `main_mod`. `Module.importFile` is | 11 | /// separately in `Zcu`. 'builtin' is also not stored here, although it is |
| 12 | /// responsible for detecting these names and using the correct package. | 12 | /// not necessarily the same between all modules. Handling of `@import` in |
| 13 | /// the rest of the compiler must detect these special names and use the | ||
| 14 | /// correct module instead of consulting `deps`. | ||
| 13 | deps: Deps = .{}, | 15 | deps: Deps = .{}, |
| 14 | 16 | ||
| 15 | resolved_target: ResolvedTarget, | 17 | resolved_target: ResolvedTarget, |
| ... | @@ -33,25 +35,14 @@ cc_argv: []const []const u8, | ... | @@ -33,25 +35,14 @@ cc_argv: []const []const u8, |
| 33 | structured_cfg: bool, | 35 | structured_cfg: bool, |
| 34 | no_builtin: bool, | 36 | no_builtin: bool, |
| 35 | 37 | ||
| 36 | /// If the module is an `@import("builtin")` module, this is the `File` that | ||
| 37 | /// is preallocated for it. Otherwise this field is null. | ||
| 38 | builtin_file: ?*File, | ||
| 39 | |||
| 40 | pub const Deps = std.StringArrayHashMapUnmanaged(*Module); | 38 | pub const Deps = std.StringArrayHashMapUnmanaged(*Module); |
| 41 | 39 | ||
| 42 | pub fn isBuiltin(m: Module) bool { | ||
| 43 | return m.builtin_file != null; | ||
| 44 | } | ||
| 45 | |||
| 46 | pub const Tree = struct { | 40 | pub const Tree = struct { |
| 47 | /// Each `Package` exposes a `Module` with build.zig as its root source file. | 41 | /// Each `Package` exposes a `Module` with build.zig as its root source file. |
| 48 | build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module), | 42 | build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module), |
| 49 | }; | 43 | }; |
| 50 | 44 | ||
| 51 | pub const CreateOptions = struct { | 45 | pub const CreateOptions = struct { |
| 52 | /// Where to store builtin.zig. The global cache directory is used because | ||
| 53 | /// it is a pure function based on CLI flags. | ||
| 54 | global_cache_directory: Cache.Directory, | ||
| 55 | paths: Paths, | 46 | paths: Paths, |
| 56 | fully_qualified_name: []const u8, | 47 | fully_qualified_name: []const u8, |
| 57 | 48 | ||
| ... | @@ -61,15 +52,8 @@ pub const CreateOptions = struct { | ... | @@ -61,15 +52,8 @@ pub const CreateOptions = struct { |
| 61 | /// If this is null then `resolved_target` must be non-null. | 52 | /// If this is null then `resolved_target` must be non-null. |
| 62 | parent: ?*Package.Module, | 53 | parent: ?*Package.Module, |
| 63 | 54 | ||
| 64 | builtin_mod: ?*Package.Module, | ||
| 65 | |||
| 66 | /// Allocated into the given `arena`. Should be shared across all module creations in a Compilation. | ||
| 67 | /// Ignored if `builtin_mod` is passed or if `!have_zcu`. | ||
| 68 | /// Otherwise, may be `null` only if this Compilation consists of a single module. | ||
| 69 | builtin_modules: ?*std.StringHashMapUnmanaged(*Module), | ||
| 70 | |||
| 71 | pub const Paths = struct { | 55 | pub const Paths = struct { |
| 72 | root: Cache.Path, | 56 | root: Compilation.Path, |
| 73 | /// Relative to `root`. May contain path separators. | 57 | /// Relative to `root`. May contain path separators. |
| 74 | root_src_path: []const u8, | 58 | root_src_path: []const u8, |
| 75 | }; | 59 | }; |
| ... | @@ -401,126 +385,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { | ... | @@ -401,126 +385,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 401 | .cc_argv = options.cc_argv, | 385 | .cc_argv = options.cc_argv, |
| 402 | .structured_cfg = structured_cfg, | 386 | .structured_cfg = structured_cfg, |
| 403 | .no_builtin = no_builtin, | 387 | .no_builtin = no_builtin, |
| 404 | .builtin_file = null, | ||
| 405 | }; | 388 | }; |
| 406 | |||
| 407 | const opt_builtin_mod = options.builtin_mod orelse b: { | ||
| 408 | if (!options.global.have_zcu) break :b null; | ||
| 409 | |||
| 410 | const generated_builtin_source = try Builtin.generate(.{ | ||
| 411 | .target = target, | ||
| 412 | .zig_backend = zig_backend, | ||
| 413 | .output_mode = options.global.output_mode, | ||
| 414 | .link_mode = options.global.link_mode, | ||
| 415 | .unwind_tables = unwind_tables, | ||
| 416 | .is_test = options.global.is_test, | ||
| 417 | .single_threaded = single_threaded, | ||
| 418 | .link_libc = options.global.link_libc, | ||
| 419 | .link_libcpp = options.global.link_libcpp, | ||
| 420 | .optimize_mode = optimize_mode, | ||
| 421 | .error_tracing = error_tracing, | ||
| 422 | .valgrind = valgrind, | ||
| 423 | .sanitize_thread = sanitize_thread, | ||
| 424 | .fuzz = fuzz, | ||
| 425 | .pic = pic, | ||
| 426 | .pie = options.global.pie, | ||
| 427 | .strip = strip, | ||
| 428 | .code_model = code_model, | ||
| 429 | .omit_frame_pointer = omit_frame_pointer, | ||
| 430 | .wasi_exec_model = options.global.wasi_exec_model, | ||
| 431 | }, arena); | ||
| 432 | |||
| 433 | const new = if (options.builtin_modules) |builtins| new: { | ||
| 434 | const gop = try builtins.getOrPut(arena, generated_builtin_source); | ||
| 435 | if (gop.found_existing) break :b gop.value_ptr.*; | ||
| 436 | errdefer builtins.removeByPtr(gop.key_ptr); | ||
| 437 | const new = try arena.create(Module); | ||
| 438 | gop.value_ptr.* = new; | ||
| 439 | break :new new; | ||
| 440 | } else try arena.create(Module); | ||
| 441 | errdefer if (options.builtin_modules) |builtins| assert(builtins.remove(generated_builtin_source)); | ||
| 442 | |||
| 443 | const new_file = try arena.create(File); | ||
| 444 | |||
| 445 | const hex_digest = digest: { | ||
| 446 | var hasher: Cache.Hasher = Cache.hasher_init; | ||
| 447 | hasher.update(generated_builtin_source); | ||
| 448 | |||
| 449 | var bin_digest: Cache.BinDigest = undefined; | ||
| 450 | hasher.final(&bin_digest); | ||
| 451 | |||
| 452 | var hex_digest: Cache.HexDigest = undefined; | ||
| 453 | _ = std.fmt.bufPrint( | ||
| 454 | &hex_digest, | ||
| 455 | "{s}", | ||
| 456 | .{std.fmt.fmtSliceHexLower(&bin_digest)}, | ||
| 457 | ) catch unreachable; | ||
| 458 | |||
| 459 | break :digest hex_digest; | ||
| 460 | }; | ||
| 461 | |||
| 462 | const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ hex_digest); | ||
| 463 | |||
| 464 | new.* = .{ | ||
| 465 | .root = .{ | ||
| 466 | .root_dir = options.global_cache_directory, | ||
| 467 | .sub_path = builtin_sub_path, | ||
| 468 | }, | ||
| 469 | .root_src_path = "builtin.zig", | ||
| 470 | .fully_qualified_name = if (options.parent == null) | ||
| 471 | "builtin" | ||
| 472 | else | ||
| 473 | try std.fmt.allocPrint(arena, "{s}.builtin", .{options.fully_qualified_name}), | ||
| 474 | .resolved_target = .{ | ||
| 475 | .result = target, | ||
| 476 | .is_native_os = resolved_target.is_native_os, | ||
| 477 | .is_native_abi = resolved_target.is_native_abi, | ||
| 478 | .llvm_cpu_features = llvm_cpu_features, | ||
| 479 | }, | ||
| 480 | .optimize_mode = optimize_mode, | ||
| 481 | .single_threaded = single_threaded, | ||
| 482 | .error_tracing = error_tracing, | ||
| 483 | .valgrind = valgrind, | ||
| 484 | .pic = pic, | ||
| 485 | .strip = strip, | ||
| 486 | .omit_frame_pointer = omit_frame_pointer, | ||
| 487 | .stack_check = stack_check, | ||
| 488 | .stack_protector = stack_protector, | ||
| 489 | .code_model = code_model, | ||
| 490 | .red_zone = red_zone, | ||
| 491 | .sanitize_c = sanitize_c, | ||
| 492 | .sanitize_thread = sanitize_thread, | ||
| 493 | .fuzz = fuzz, | ||
| 494 | .unwind_tables = unwind_tables, | ||
| 495 | .cc_argv = &.{}, | ||
| 496 | .structured_cfg = structured_cfg, | ||
| 497 | .no_builtin = no_builtin, | ||
| 498 | .builtin_file = new_file, | ||
| 499 | }; | ||
| 500 | new_file.* = .{ | ||
| 501 | .sub_file_path = "builtin.zig", | ||
| 502 | .stat = undefined, | ||
| 503 | .source = generated_builtin_source, | ||
| 504 | .tree = null, | ||
| 505 | .zir = null, | ||
| 506 | .zoir = null, | ||
| 507 | .status = .never_loaded, | ||
| 508 | .mod = new, | ||
| 509 | }; | ||
| 510 | break :b new; | ||
| 511 | }; | ||
| 512 | |||
| 513 | if (opt_builtin_mod) |builtin_mod| { | ||
| 514 | try mod.deps.ensureUnusedCapacity(arena, 1); | ||
| 515 | mod.deps.putAssumeCapacityNoClobber("builtin", builtin_mod); | ||
| 516 | } | ||
| 517 | |||
| 518 | return mod; | 389 | return mod; |
| 519 | } | 390 | } |
| 520 | 391 | ||
| 521 | /// All fields correspond to `CreateOptions`. | 392 | /// All fields correspond to `CreateOptions`. |
| 522 | pub const LimitedOptions = struct { | 393 | pub const LimitedOptions = struct { |
| 523 | root: Cache.Path, | 394 | root: Compilation.Path, |
| 524 | root_src_path: []const u8, | 395 | root_src_path: []const u8, |
| 525 | fully_qualified_name: []const u8, | 396 | fully_qualified_name: []const u8, |
| 526 | }; | 397 | }; |
| ... | @@ -553,18 +424,73 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P | ... | @@ -553,18 +424,73 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P |
| 553 | .cc_argv = undefined, | 424 | .cc_argv = undefined, |
| 554 | .structured_cfg = undefined, | 425 | .structured_cfg = undefined, |
| 555 | .no_builtin = undefined, | 426 | .no_builtin = undefined, |
| 556 | .builtin_file = null, | ||
| 557 | }; | 427 | }; |
| 558 | return mod; | 428 | return mod; |
| 559 | } | 429 | } |
| 560 | 430 | ||
| 561 | /// Asserts that the module has a builtin module, which is not true for non-zig | 431 | /// Does not ensure that the module's root directory exists on-disk; see `Builtin.updateFileOnDisk` for that task. |
| 562 | /// modules such as ones only used for `@embedFile`, or the root module when | 432 | pub fn createBuiltin(arena: Allocator, opts: Builtin, dirs: Compilation.Directories) Allocator.Error!*Module { |
| 563 | /// there is no Zig Compilation Unit. | 433 | const sub_path = "b" ++ Cache.binToHex(opts.hash()); |
| 564 | pub fn getBuiltinDependency(m: Module) *Module { | 434 | const new = try arena.create(Module); |
| 565 | const result = m.deps.values()[0]; | 435 | new.* = .{ |
| 566 | assert(result.isBuiltin()); | 436 | .root = try .fromRoot(arena, dirs, .global_cache, sub_path), |
| 567 | return result; | 437 | .root_src_path = "builtin.zig", |
| 438 | .fully_qualified_name = "builtin", | ||
| 439 | .resolved_target = .{ | ||
| 440 | .result = opts.target, | ||
| 441 | // These values are not in `opts`, but do not matter because `builtin.zig` contains no runtime code. | ||
| 442 | .is_native_os = false, | ||
| 443 | .is_native_abi = false, | ||
| 444 | .llvm_cpu_features = null, | ||
| 445 | }, | ||
| 446 | .optimize_mode = opts.optimize_mode, | ||
| 447 | .single_threaded = opts.single_threaded, | ||
| 448 | .error_tracing = opts.error_tracing, | ||
| 449 | .valgrind = opts.valgrind, | ||
| 450 | .pic = opts.pic, | ||
| 451 | .strip = opts.strip, | ||
| 452 | .omit_frame_pointer = opts.omit_frame_pointer, | ||
| 453 | .code_model = opts.code_model, | ||
| 454 | .sanitize_thread = opts.sanitize_thread, | ||
| 455 | .fuzz = opts.fuzz, | ||
| 456 | .unwind_tables = opts.unwind_tables, | ||
| 457 | .cc_argv = &.{}, | ||
| 458 | // These values are not in `opts`, but do not matter because `builtin.zig` contains no runtime code. | ||
| 459 | .stack_check = false, | ||
| 460 | .stack_protector = 0, | ||
| 461 | .red_zone = false, | ||
| 462 | .sanitize_c = .off, | ||
| 463 | .structured_cfg = false, | ||
| 464 | .no_builtin = false, | ||
| 465 | }; | ||
| 466 | return new; | ||
| 467 | } | ||
| 468 | |||
| 469 | /// Returns the `Builtin` which forms the contents of `@import("builtin")` for this module. | ||
| 470 | pub fn getBuiltinOptions(m: Module, global: Compilation.Config) Builtin { | ||
| 471 | assert(global.have_zcu); | ||
| 472 | return .{ | ||
| 473 | .target = m.resolved_target.result, | ||
| 474 | .zig_backend = target_util.zigBackend(m.resolved_target.result, global.use_llvm), | ||
| 475 | .output_mode = global.output_mode, | ||
| 476 | .link_mode = global.link_mode, | ||
| 477 | .unwind_tables = m.unwind_tables, | ||
| 478 | .is_test = global.is_test, | ||
| 479 | .single_threaded = m.single_threaded, | ||
| 480 | .link_libc = global.link_libc, | ||
| 481 | .link_libcpp = global.link_libcpp, | ||
| 482 | .optimize_mode = m.optimize_mode, | ||
| 483 | .error_tracing = m.error_tracing, | ||
| 484 | .valgrind = m.valgrind, | ||
| 485 | .sanitize_thread = m.sanitize_thread, | ||
| 486 | .fuzz = m.fuzz, | ||
| 487 | .pic = m.pic, | ||
| 488 | .pie = global.pie, | ||
| 489 | .strip = m.strip, | ||
| 490 | .code_model = m.code_model, | ||
| 491 | .omit_frame_pointer = m.omit_frame_pointer, | ||
| 492 | .wasi_exec_model = global.wasi_exec_model, | ||
| 493 | }; | ||
| 568 | } | 494 | } |
| 569 | 495 | ||
| 570 | const Module = @This(); | 496 | const Module = @This(); |
src/Sema.zig+81-70| ... | @@ -829,7 +829,7 @@ pub const Block = struct { | ... | @@ -829,7 +829,7 @@ pub const Block = struct { |
| 829 | 829 | ||
| 830 | pub fn ownerModule(block: Block) *Package.Module { | 830 | pub fn ownerModule(block: Block) *Package.Module { |
| 831 | const zcu = block.sema.pt.zcu; | 831 | const zcu = block.sema.pt.zcu; |
| 832 | return zcu.namespacePtr(block.namespace).fileScope(zcu).mod; | 832 | return zcu.namespacePtr(block.namespace).fileScope(zcu).mod.?; |
| 833 | } | 833 | } |
| 834 | 834 | ||
| 835 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { | 835 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { |
| ... | @@ -1127,10 +1127,10 @@ fn analyzeBodyInner( | ... | @@ -1127,10 +1127,10 @@ fn analyzeBodyInner( |
| 1127 | 1127 | ||
| 1128 | // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away. | 1128 | // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away. |
| 1129 | if (build_options.enable_logging) { | 1129 | if (build_options.enable_logging) { |
| 1130 | std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: { | 1130 | std.log.scoped(.sema_zir).debug("sema ZIR {} %{d}", .{ path: { |
| 1131 | const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool); | 1131 | const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool); |
| 1132 | const file = zcu.fileByIndex(file_index); | 1132 | const file = zcu.fileByIndex(file_index); |
| 1133 | break :sub_file_path file.sub_file_path; | 1133 | break :path file.path.fmt(zcu.comp); |
| 1134 | }, inst }); | 1134 | }, inst }); |
| 1135 | } | 1135 | } |
| 1136 | 1136 | ||
| ... | @@ -6162,50 +6162,67 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6162,50 +6162,67 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 6162 | } | 6162 | } |
| 6163 | const parent_mod = parent_block.ownerModule(); | 6163 | const parent_mod = parent_block.ownerModule(); |
| 6164 | const digest = Cache.binToHex(c_import_res.digest); | 6164 | const digest = Cache.binToHex(c_import_res.digest); |
| 6165 | const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest); | ||
| 6166 | const c_import_mod = Package.Module.create(comp.arena, .{ | ||
| 6167 | .global_cache_directory = comp.global_cache_directory, | ||
| 6168 | .paths = .{ | ||
| 6169 | .root = .{ | ||
| 6170 | .root_dir = comp.local_cache_directory, | ||
| 6171 | .sub_path = c_import_zig_path, | ||
| 6172 | }, | ||
| 6173 | .root_src_path = "cimport.zig", | ||
| 6174 | }, | ||
| 6175 | .fully_qualified_name = c_import_zig_path, | ||
| 6176 | .cc_argv = parent_mod.cc_argv, | ||
| 6177 | .inherited = .{}, | ||
| 6178 | .global = comp.config, | ||
| 6179 | .parent = parent_mod, | ||
| 6180 | .builtin_mod = parent_mod.getBuiltinDependency(), | ||
| 6181 | .builtin_modules = null, // `builtin_mod` is set | ||
| 6182 | }) catch |err| switch (err) { | ||
| 6183 | // None of these are possible because we are creating a package with | ||
| 6184 | // the exact same configuration as the parent package, which already | ||
| 6185 | // passed these checks. | ||
| 6186 | error.ValgrindUnsupportedOnTarget => unreachable, | ||
| 6187 | error.TargetRequiresSingleThreaded => unreachable, | ||
| 6188 | error.BackendRequiresSingleThreaded => unreachable, | ||
| 6189 | error.TargetRequiresPic => unreachable, | ||
| 6190 | error.PieRequiresPic => unreachable, | ||
| 6191 | error.DynamicLinkingRequiresPic => unreachable, | ||
| 6192 | error.TargetHasNoRedZone => unreachable, | ||
| 6193 | error.StackCheckUnsupportedByTarget => unreachable, | ||
| 6194 | error.StackProtectorUnsupportedByTarget => unreachable, | ||
| 6195 | error.StackProtectorUnavailableWithoutLibC => unreachable, | ||
| 6196 | 6165 | ||
| 6197 | else => |e| return e, | 6166 | const new_file_index = file: { |
| 6198 | }; | 6167 | const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest); |
| 6168 | const c_import_mod = Package.Module.create(comp.arena, .{ | ||
| 6169 | .paths = .{ | ||
| 6170 | .root = try .fromRoot(comp.arena, comp.dirs, .local_cache, c_import_zig_path), | ||
| 6171 | .root_src_path = "cimport.zig", | ||
| 6172 | }, | ||
| 6173 | .fully_qualified_name = c_import_zig_path, | ||
| 6174 | .cc_argv = parent_mod.cc_argv, | ||
| 6175 | .inherited = .{}, | ||
| 6176 | .global = comp.config, | ||
| 6177 | .parent = parent_mod, | ||
| 6178 | }) catch |err| switch (err) { | ||
| 6179 | // None of these are possible because we are creating a package with | ||
| 6180 | // the exact same configuration as the parent package, which already | ||
| 6181 | // passed these checks. | ||
| 6182 | error.ValgrindUnsupportedOnTarget => unreachable, | ||
| 6183 | error.TargetRequiresSingleThreaded => unreachable, | ||
| 6184 | error.BackendRequiresSingleThreaded => unreachable, | ||
| 6185 | error.TargetRequiresPic => unreachable, | ||
| 6186 | error.PieRequiresPic => unreachable, | ||
| 6187 | error.DynamicLinkingRequiresPic => unreachable, | ||
| 6188 | error.TargetHasNoRedZone => unreachable, | ||
| 6189 | error.StackCheckUnsupportedByTarget => unreachable, | ||
| 6190 | error.StackProtectorUnsupportedByTarget => unreachable, | ||
| 6191 | error.StackProtectorUnavailableWithoutLibC => unreachable, | ||
| 6199 | 6192 | ||
| 6200 | const result = pt.importPkg(c_import_mod) catch |err| | 6193 | else => |e| return e, |
| 6201 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6194 | }; |
| 6202 | 6195 | const c_import_file_path: Compilation.Path = try c_import_mod.root.join(gpa, comp.dirs, "cimport.zig"); | |
| 6203 | const path_digest = zcu.filePathDigest(result.file_index); | 6196 | errdefer c_import_file_path.deinit(gpa); |
| 6204 | pt.updateFile(result.file, path_digest) catch |err| | 6197 | const c_import_file = try gpa.create(Zcu.File); |
| 6198 | errdefer gpa.destroy(c_import_file); | ||
| 6199 | const c_import_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ | ||
| 6200 | .bin_digest = c_import_file_path.digest(), | ||
| 6201 | .file = c_import_file, | ||
| 6202 | .root_type = .none, | ||
| 6203 | }); | ||
| 6204 | c_import_file.* = .{ | ||
| 6205 | .status = .never_loaded, | ||
| 6206 | .stat = undefined, | ||
| 6207 | .is_builtin = false, | ||
| 6208 | .path = c_import_file_path, | ||
| 6209 | .source = null, | ||
| 6210 | .tree = null, | ||
| 6211 | .zir = null, | ||
| 6212 | .zoir = null, | ||
| 6213 | .mod = c_import_mod, | ||
| 6214 | .sub_file_path = "cimport.zig", | ||
| 6215 | .module_changed = false, | ||
| 6216 | .prev_zir = null, | ||
| 6217 | .zoir_invalidated = false, | ||
| 6218 | }; | ||
| 6219 | break :file c_import_file_index; | ||
| 6220 | }; | ||
| 6221 | pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err| | ||
| 6205 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6222 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 6206 | 6223 | ||
| 6207 | try pt.ensureFileAnalyzed(result.file_index); | 6224 | try pt.ensureFileAnalyzed(new_file_index); |
| 6208 | const ty = zcu.fileRootType(result.file_index); | 6225 | const ty = zcu.fileRootType(new_file_index); |
| 6209 | try sema.declareDependency(.{ .interned = ty }); | 6226 | try sema.declareDependency(.{ .interned = ty }); |
| 6210 | try sema.addTypeReferenceEntry(src, ty); | 6227 | try sema.addTypeReferenceEntry(src, ty); |
| 6211 | return Air.internedToRef(ty); | 6228 | return Air.internedToRef(ty); |
| ... | @@ -14097,25 +14114,19 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14097,25 +14114,19 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14097 | const operand_src = block.tokenOffset(inst_data.src_tok); | 14114 | const operand_src = block.tokenOffset(inst_data.src_tok); |
| 14098 | const operand = sema.code.nullTerminatedString(extra.path); | 14115 | const operand = sema.code.nullTerminatedString(extra.path); |
| 14099 | 14116 | ||
| 14100 | const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) { | 14117 | const result = pt.doImport(block.getFileScope(zcu), operand) catch |err| switch (err) { |
| 14101 | error.ImportOutsideModulePath => { | 14118 | error.ModuleNotFound => return sema.fail(block, operand_src, "no module named '{s}' available within module '{s}'", .{ |
| 14102 | return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand}); | 14119 | operand, block.getFileScope(zcu).mod.?.fully_qualified_name, |
| 14103 | }, | 14120 | }), |
| 14104 | error.ModuleNotFound => { | 14121 | error.IllegalZigImport => unreachable, // caught before semantic analysis |
| 14105 | return sema.fail(block, operand_src, "no module named '{s}' available within module {s}", .{ | 14122 | error.OutOfMemory => |e| return e, |
| 14106 | operand, block.getFileScope(zcu).mod.fully_qualified_name, | ||
| 14107 | }); | ||
| 14108 | }, | ||
| 14109 | else => { | ||
| 14110 | // TODO: these errors are file system errors; make sure an update() will | ||
| 14111 | // retry this and not cache the file system error, which may be transient. | ||
| 14112 | return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); | ||
| 14113 | }, | ||
| 14114 | }; | 14123 | }; |
| 14115 | switch (result.file.getMode()) { | 14124 | const file_index = result.file; |
| 14125 | const file = zcu.fileByIndex(file_index); | ||
| 14126 | switch (file.getMode()) { | ||
| 14116 | .zig => { | 14127 | .zig => { |
| 14117 | try pt.ensureFileAnalyzed(result.file_index); | 14128 | try pt.ensureFileAnalyzed(file_index); |
| 14118 | const ty = zcu.fileRootType(result.file_index); | 14129 | const ty = zcu.fileRootType(file_index); |
| 14119 | try sema.declareDependency(.{ .interned = ty }); | 14130 | try sema.declareDependency(.{ .interned = ty }); |
| 14120 | try sema.addTypeReferenceEntry(operand_src, ty); | 14131 | try sema.addTypeReferenceEntry(operand_src, ty); |
| 14121 | return Air.internedToRef(ty); | 14132 | return Air.internedToRef(ty); |
| ... | @@ -14129,11 +14140,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14129,11 +14140,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14129 | break :b res_ty.toIntern(); | 14140 | break :b res_ty.toIntern(); |
| 14130 | }; | 14141 | }; |
| 14131 | 14142 | ||
| 14132 | try sema.declareDependency(.{ .zon_file = result.file_index }); | 14143 | try sema.declareDependency(.{ .zon_file = file_index }); |
| 14133 | const interned = try LowerZon.run( | 14144 | const interned = try LowerZon.run( |
| 14134 | sema, | 14145 | sema, |
| 14135 | result.file, | 14146 | file, |
| 14136 | result.file_index, | 14147 | file_index, |
| 14137 | res_ty, | 14148 | res_ty, |
| 14138 | operand_src, | 14149 | operand_src, |
| 14139 | block, | 14150 | block, |
| ... | @@ -17290,10 +17301,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17290,10 +17301,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17290 | const name = name: { | 17301 | const name = name: { |
| 17291 | // TODO: we should probably store this name in the ZIR to avoid this complexity. | 17302 | // TODO: we should probably store this name in the ZIR to avoid this complexity. |
| 17292 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; | 17303 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; |
| 17293 | const tree = file.getTree(sema.gpa) catch |err| { | 17304 | const tree = file.getTree(zcu) catch |err| { |
| 17294 | // In this case we emit a warning + a less precise source location. | 17305 | // In this case we emit a warning + a less precise source location. |
| 17295 | log.warn("unable to load {s}: {s}", .{ | 17306 | log.warn("unable to load {}: {s}", .{ |
| 17296 | file.sub_file_path, @errorName(err), | 17307 | file.path.fmt(zcu.comp), @errorName(err), |
| 17297 | }); | 17308 | }); |
| 17298 | break :name null; | 17309 | break :name null; |
| 17299 | }; | 17310 | }; |
| ... | @@ -17318,10 +17329,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17318,10 +17329,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17318 | const msg = msg: { | 17329 | const msg = msg: { |
| 17319 | const name = name: { | 17330 | const name = name: { |
| 17320 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; | 17331 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; |
| 17321 | const tree = file.getTree(sema.gpa) catch |err| { | 17332 | const tree = file.getTree(zcu) catch |err| { |
| 17322 | // In this case we emit a warning + a less precise source location. | 17333 | // In this case we emit a warning + a less precise source location. |
| 17323 | log.warn("unable to load {s}: {s}", .{ | 17334 | log.warn("unable to load {}: {s}", .{ |
| 17324 | file.sub_file_path, @errorName(err), | 17335 | file.path.fmt(zcu.comp), @errorName(err), |
| 17325 | }); | 17336 | }); |
| 17326 | break :name null; | 17337 | break :name null; |
| 17327 | }; | 17338 | }; |
| ... | @@ -17415,7 +17426,7 @@ fn zirBuiltinSrc( | ... | @@ -17415,7 +17426,7 @@ fn zirBuiltinSrc( |
| 17415 | }; | 17426 | }; |
| 17416 | 17427 | ||
| 17417 | const module_name_val = v: { | 17428 | const module_name_val = v: { |
| 17418 | const module_name = file_scope.mod.fully_qualified_name; | 17429 | const module_name = file_scope.mod.?.fully_qualified_name; |
| 17419 | const array_ty = try pt.intern(.{ .array_type = .{ | 17430 | const array_ty = try pt.intern(.{ .array_type = .{ |
| 17420 | .len = module_name.len, | 17431 | .len = module_name.len, |
| 17421 | .sentinel = .zero_u8, | 17432 | .sentinel = .zero_u8, |
src/Zcu.zig+441-262| ... | @@ -72,9 +72,9 @@ sema_prog_node: std.Progress.Node = std.Progress.Node.none, | ... | @@ -72,9 +72,9 @@ sema_prog_node: std.Progress.Node = std.Progress.Node.none, |
| 72 | codegen_prog_node: std.Progress.Node = std.Progress.Node.none, | 72 | codegen_prog_node: std.Progress.Node = std.Progress.Node.none, |
| 73 | 73 | ||
| 74 | /// Used by AstGen worker to load and store ZIR cache. | 74 | /// Used by AstGen worker to load and store ZIR cache. |
| 75 | global_zir_cache: Compilation.Directory, | 75 | global_zir_cache: Cache.Directory, |
| 76 | /// Used by AstGen worker to load and store ZIR cache. | 76 | /// Used by AstGen worker to load and store ZIR cache. |
| 77 | local_zir_cache: Compilation.Directory, | 77 | local_zir_cache: Cache.Directory, |
| 78 | 78 | ||
| 79 | /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; | 79 | /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; |
| 80 | /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. | 80 | /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. |
| ... | @@ -93,27 +93,72 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { | ... | @@ -93,27 +93,72 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 93 | len: u32, | 93 | len: u32, |
| 94 | }) = .{}, | 94 | }) = .{}, |
| 95 | 95 | ||
| 96 | /// Key is the digest returned by `Builtin.hash`; value is the corresponding module. | ||
| 97 | builtin_modules: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, *Package.Module) = .empty, | ||
| 98 | |||
| 99 | /// Populated as soon as the `Compilation` is created. Guaranteed to contain all modules, even builtin ones. | ||
| 100 | /// Modules whose root file is not a Zig or ZON file have the value `.none`. | ||
| 101 | module_roots: std.AutoArrayHashMapUnmanaged(*Package.Module, File.Index.Optional) = .empty, | ||
| 102 | |||
| 96 | /// The set of all the Zig source files in the Zig Compilation Unit. Tracked in | 103 | /// The set of all the Zig source files in the Zig Compilation Unit. Tracked in |
| 97 | /// order to iterate over it and check which source files have been modified on | 104 | /// order to iterate over it and check which source files have been modified on |
| 98 | /// the file system when an update is requested, as well as to cache `@import` | 105 | /// the file system when an update is requested, as well as to cache `@import` |
| 99 | /// results. | 106 | /// results. |
| 100 | /// | 107 | /// |
| 101 | /// Keys are fully resolved file paths. This table owns the keys and values. | 108 | /// Always accessed through `ImportTableAdapter`, where keys are fully resolved |
| 109 | /// file paths in order to ensure files are properly deduplicated. This table owns | ||
| 110 | /// the keys and values. | ||
| 102 | /// | 111 | /// |
| 103 | /// Protected by Compilation's mutex. | 112 | /// Protected by Compilation's mutex. |
| 104 | /// | 113 | /// |
| 105 | /// Not serialized. This state is reconstructed during the first call to | 114 | /// Not serialized. This state is reconstructed during the first call to |
| 106 | /// `Compilation.update` of the process for a given `Compilation`. | 115 | /// `Compilation.update` of the process for a given `Compilation`. |
| 107 | /// | 116 | import_table: std.ArrayHashMapUnmanaged( |
| 108 | /// Indexes correspond 1:1 to `files`. | 117 | File.Index, |
| 109 | import_table: std.StringArrayHashMapUnmanaged(File.Index) = .empty, | 118 | void, |
| 119 | struct { | ||
| 120 | pub const hash = @compileError("all accesses should be through ImportTableAdapter"); | ||
| 121 | pub const eql = @compileError("all accesses should be through ImportTableAdapter"); | ||
| 122 | }, | ||
| 123 | true, // This is necessary! Without it, the map tries to use its Context to rehash. #21918 | ||
| 124 | ) = .empty, | ||
| 125 | |||
| 126 | /// The set of all files in `import_table` which are "alive" this update, meaning | ||
| 127 | /// they are reachable by traversing imports starting from an analysis root. This | ||
| 128 | /// is usually all files in `import_table`, but some could be omitted if an incremental | ||
| 129 | /// update removes an import, or if a module specified on the CLI is never imported. | ||
| 130 | /// Reconstructed on every update, after AstGen and before Sema. | ||
| 131 | /// Value is why the file is alive. | ||
| 132 | alive_files: std.AutoArrayHashMapUnmanaged(File.Index, File.Reference) = .empty, | ||
| 133 | |||
| 134 | /// If this is populated, a "file exists in multiple modules" error should be emitted. | ||
| 135 | /// This causes file errors to not be shown, because we don't really know which files | ||
| 136 | /// should be alive (because the user has messed up their imports somewhere!). | ||
| 137 | /// Cleared and recomputed every update, after AstGen and before Sema. | ||
| 138 | multi_module_err: ?struct { | ||
| 139 | file: File.Index, | ||
| 140 | modules: [2]*Package.Module, | ||
| 141 | refs: [2]File.Reference, | ||
| 142 | } = null, | ||
| 110 | 143 | ||
| 111 | /// The set of all the files which have been loaded with `@embedFile` in the Module. | 144 | /// The set of all the files which have been loaded with `@embedFile` in the Module. |
| 112 | /// We keep track of this in order to iterate over it and check which files have been | 145 | /// We keep track of this in order to iterate over it and check which files have been |
| 113 | /// modified on the file system when an update is requested, as well as to cache | 146 | /// modified on the file system when an update is requested, as well as to cache |
| 114 | /// `@embedFile` results. | 147 | /// `@embedFile` results. |
| 115 | /// Keys are fully resolved file paths. This table owns the keys and values. | 148 | /// |
| 116 | embed_table: std.StringArrayHashMapUnmanaged(*EmbedFile) = .empty, | 149 | /// Like `import_table`, this is accessed through `EmbedTableAdapter`, so that it is keyed |
| 150 | /// on the `Compilation.Path` of the `EmbedFile`. | ||
| 151 | /// | ||
| 152 | /// This table owns all of the `*EmbedFile` memory, which is allocated into gpa. | ||
| 153 | embed_table: std.ArrayHashMapUnmanaged( | ||
| 154 | *EmbedFile, | ||
| 155 | void, | ||
| 156 | struct { | ||
| 157 | pub const hash = @compileError("all accesses should be through EmbedTableAdapter"); | ||
| 158 | pub const eql = @compileError("all accesses should be through EmbedTableAdapter"); | ||
| 159 | }, | ||
| 160 | true, // This is necessary! Without it, the map tries to use its Context to rehash. #21918 | ||
| 161 | ) = .empty, | ||
| 117 | 162 | ||
| 118 | /// Stores all Type and Value objects. | 163 | /// Stores all Type and Value objects. |
| 119 | /// The idea is that this will be periodically garbage-collected, but such logic | 164 | /// The idea is that this will be periodically garbage-collected, but such logic |
| ... | @@ -147,9 +192,41 @@ compile_logs: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { | ... | @@ -147,9 +192,41 @@ compile_logs: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 147 | }) = .empty, | 192 | }) = .empty, |
| 148 | compile_log_lines: std.ArrayListUnmanaged(CompileLogLine) = .empty, | 193 | compile_log_lines: std.ArrayListUnmanaged(CompileLogLine) = .empty, |
| 149 | free_compile_log_lines: std.ArrayListUnmanaged(CompileLogLine.Index) = .empty, | 194 | free_compile_log_lines: std.ArrayListUnmanaged(CompileLogLine.Index) = .empty, |
| 150 | /// Using a map here for consistency with the other fields here. | 195 | /// This tracks files which triggered errors when generating AST/ZIR/ZOIR. |
| 151 | /// The ErrorMsg memory is owned by the `File`, using Module's general purpose allocator. | 196 | /// If not `null`, the value is a retryable error (the file status is guaranteed |
| 152 | failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .empty, | 197 | /// to be `.retryable_failure`). Otherwise, the file status is `.astgen_failure` |
| 198 | /// or `.success`, and there are ZIR/ZOIR errors which should be printed. | ||
| 199 | /// We just store a `[]u8` instead of a full `*ErrorMsg`, because the source | ||
| 200 | /// location is always the entire file. The `[]u8` memory is owned by the map | ||
| 201 | /// and allocated into `gpa`. | ||
| 202 | failed_files: std.AutoArrayHashMapUnmanaged(File.Index, ?[]u8) = .empty, | ||
| 203 | /// AstGen is not aware of modules, and so cannot determine whether an import | ||
| 204 | /// string makes sense. That is the job of a traversal after AstGen. | ||
| 205 | /// | ||
| 206 | /// There are several ways in which an import can fail: | ||
| 207 | /// | ||
| 208 | /// * It is an import of a file which does not exist. This case is not handled | ||
| 209 | /// by this field, but with a `failed_files` entry on the *imported* file. | ||
| 210 | /// * It is an import of a module which does not exist in the current module's | ||
| 211 | /// dependency table. This happens at `Sema` time, so is not tracked by this | ||
| 212 | /// field. | ||
| 213 | /// * It is an import which reaches outside of the current module's root | ||
| 214 | /// directory. This is tracked by this field. | ||
| 215 | /// * It is an import which reaches into an "illegal import directory". Right now, | ||
| 216 | /// the only such directory is 'global_cache/b/', but in general, these are | ||
| 217 | /// directories the compiler treats specially. This is tracked by this field. | ||
| 218 | /// | ||
| 219 | /// This is a flat array containing all of the relevant errors. It is cleared and | ||
| 220 | /// recomputed on every update. The errors here are fatal, i.e. they block any | ||
| 221 | /// semantic analysis this update. | ||
| 222 | /// | ||
| 223 | /// Allocated into gpa. | ||
| 224 | failed_imports: std.ArrayListUnmanaged(struct { | ||
| 225 | file_index: File.Index, | ||
| 226 | import_string: Zir.NullTerminatedString, | ||
| 227 | import_token: Ast.TokenIndex, | ||
| 228 | kind: enum { file_outside_module_root, illegal_zig_import }, | ||
| 229 | }) = .empty, | ||
| 153 | failed_exports: std.AutoArrayHashMapUnmanaged(Export.Index, *ErrorMsg) = .empty, | 230 | failed_exports: std.AutoArrayHashMapUnmanaged(Export.Index, *ErrorMsg) = .empty, |
| 154 | /// If analysis failed due to a cimport error, the corresponding Clang errors | 231 | /// If analysis failed due to a cimport error, the corresponding Clang errors |
| 155 | /// are stored here. | 232 | /// are stored here. |
| ... | @@ -235,6 +312,32 @@ generation: u32 = 0, | ... | @@ -235,6 +312,32 @@ generation: u32 = 0, |
| 235 | 312 | ||
| 236 | pub const PerThread = @import("Zcu/PerThread.zig"); | 313 | pub const PerThread = @import("Zcu/PerThread.zig"); |
| 237 | 314 | ||
| 315 | pub const ImportTableAdapter = struct { | ||
| 316 | zcu: *const Zcu, | ||
| 317 | pub fn hash(ctx: ImportTableAdapter, path: Compilation.Path) u32 { | ||
| 318 | _ = ctx; | ||
| 319 | return @truncate(std.hash.Wyhash.hash(@intFromEnum(path.root), path.sub_path)); | ||
| 320 | } | ||
| 321 | pub fn eql(ctx: ImportTableAdapter, a_path: Compilation.Path, b_file: File.Index, b_index: usize) bool { | ||
| 322 | _ = b_index; | ||
| 323 | const b_path = ctx.zcu.fileByIndex(b_file).path; | ||
| 324 | return a_path.root == b_path.root and mem.eql(u8, a_path.sub_path, b_path.sub_path); | ||
| 325 | } | ||
| 326 | }; | ||
| 327 | |||
| 328 | pub const EmbedTableAdapter = struct { | ||
| 329 | pub fn hash(ctx: EmbedTableAdapter, path: Compilation.Path) u32 { | ||
| 330 | _ = ctx; | ||
| 331 | return @truncate(std.hash.Wyhash.hash(@intFromEnum(path.root), path.sub_path)); | ||
| 332 | } | ||
| 333 | pub fn eql(ctx: EmbedTableAdapter, a_path: Compilation.Path, b_file: *EmbedFile, b_index: usize) bool { | ||
| 334 | _ = ctx; | ||
| 335 | _ = b_index; | ||
| 336 | const b_path = b_file.path; | ||
| 337 | return a_path.root == b_path.root and mem.eql(u8, a_path.sub_path, b_path.sub_path); | ||
| 338 | } | ||
| 339 | }; | ||
| 340 | |||
| 238 | /// Names of declarations in `std.builtin` whose values are memoized in a `BuiltinDecl.Memoized`. | 341 | /// Names of declarations in `std.builtin` whose values are memoized in a `BuiltinDecl.Memoized`. |
| 239 | /// The name must exactly match the declaration name, as comptime logic is used to compute the namespace accesses. | 342 | /// The name must exactly match the declaration name, as comptime logic is used to compute the namespace accesses. |
| 240 | /// Parent namespaces must be before their children in this enum. For instance, `.Type` must be before `.@"Type.Fn"`. | 343 | /// Parent namespaces must be before their children in this enum. For instance, `.Type` must be before `.@"Type.Fn"`. |
| ... | @@ -732,41 +835,61 @@ pub const Namespace = struct { | ... | @@ -732,41 +835,61 @@ pub const Namespace = struct { |
| 732 | }; | 835 | }; |
| 733 | 836 | ||
| 734 | pub const File = struct { | 837 | pub const File = struct { |
| 735 | /// Relative to the owning package's root source directory. | ||
| 736 | /// Memory is stored in gpa, owned by File. | ||
| 737 | sub_file_path: []const u8, | ||
| 738 | |||
| 739 | status: enum { | 838 | status: enum { |
| 740 | /// We have not yet attempted to load this file. | 839 | /// We have not yet attempted to load this file. |
| 741 | /// `stat` is not populated and may be `undefined`. | 840 | /// `stat` is not populated and may be `undefined`. |
| 742 | never_loaded, | 841 | never_loaded, |
| 743 | /// A filesystem access failed. It should be retried on the next update. | 842 | /// A filesystem access failed. It should be retried on the next update. |
| 744 | /// There is a `failed_files` entry containing a non-`null` message. | 843 | /// There is guaranteed to be a `failed_files` entry with at least one message. |
| 844 | /// ZIR/ZOIR errors should not be emitted as `zir`/`zoir` is not up-to-date. | ||
| 745 | /// `stat` is not populated and may be `undefined`. | 845 | /// `stat` is not populated and may be `undefined`. |
| 746 | retryable_failure, | 846 | retryable_failure, |
| 747 | /// Parsing/AstGen/ZonGen of this file has failed. | 847 | /// This file has failed parsing, AstGen, or ZonGen. |
| 748 | /// There is an error in `zir` or `zoir`. | 848 | /// There is guaranteed to be a `failed_files` entry, which may or may not have messages. |
| 749 | /// There is a `failed_files` entry (with a `null` message). | 849 | /// ZIR/ZOIR errors *should* be emitted as `zir`/`zoir` is up-to-date. |
| 750 | /// `stat` is populated. | 850 | /// `stat` is populated. |
| 751 | astgen_failure, | 851 | astgen_failure, |
| 752 | /// Parsing and AstGen/ZonGen of this file has succeeded. | 852 | /// Parsing and AstGen/ZonGen of this file has succeeded. |
| 853 | /// There may still be a `failed_files` entry, e.g. for non-fatal AstGen errors. | ||
| 753 | /// `stat` is populated. | 854 | /// `stat` is populated. |
| 754 | success, | 855 | success, |
| 755 | }, | 856 | }, |
| 756 | /// Whether this is populated depends on `status`. | 857 | /// Whether this is populated depends on `status`. |
| 757 | stat: Cache.File.Stat, | 858 | stat: Cache.File.Stat, |
| 758 | 859 | ||
| 860 | /// Whether this file is the generated file of a "builtin" module. This matters because those | ||
| 861 | /// files are generated and stored in-nemory rather than being read off-disk. The rest of the | ||
| 862 | /// pipeline generally shouldn't care about this. | ||
| 863 | is_builtin: bool, | ||
| 864 | |||
| 865 | /// The path of this file. It is important that this path has a "canonical form" because files | ||
| 866 | /// are deduplicated based on path; `Compilation.Path` guarantees this. Owned by this `File`, | ||
| 867 | /// allocated into `gpa`. | ||
| 868 | path: Compilation.Path, | ||
| 869 | |||
| 759 | source: ?[:0]const u8, | 870 | source: ?[:0]const u8, |
| 760 | tree: ?Ast, | 871 | tree: ?Ast, |
| 761 | zir: ?Zir, | 872 | zir: ?Zir, |
| 762 | zoir: ?Zoir, | 873 | zoir: ?Zoir, |
| 763 | 874 | ||
| 764 | /// Module that this file is a part of, managed externally. | 875 | /// Module that this file is a part of, managed externally. |
| 765 | mod: *Package.Module, | 876 | /// This is initially `null`. After AstGen, a pass is run to determine which module each |
| 766 | /// Whether this file is a part of multiple packages. This is an error condition which will be reported after AstGen. | 877 | /// file belongs to, at which point this field is set. It is never set to `null` again; |
| 767 | multi_pkg: bool = false, | 878 | /// this is so that if the file starts belonging to a different module instead, we can |
| 768 | /// List of references to this file, used for multi-package errors. | 879 | /// tell, and invalidate dependencies as needed (see `module_changed`). |
| 769 | references: std.ArrayListUnmanaged(File.Reference) = .empty, | 880 | /// During semantic analysis, this is always non-`null` for alive files (i.e. those which |
| 881 | /// have imports targeting them). | ||
| 882 | mod: ?*Package.Module, | ||
| 883 | /// Relative to the root directory of `mod`. If `mod == null`, this field is `undefined`. | ||
| 884 | /// This memory is managed externally and must not be directly freed. | ||
| 885 | /// Its lifetime is at least equal to that of this `File`. | ||
| 886 | sub_file_path: []const u8, | ||
| 887 | |||
| 888 | /// If this file's module identity changes on an incremental update, this flag is set to signal | ||
| 889 | /// to `Zcu.updateZirRefs` that all references to this file must be invalidated. This matters | ||
| 890 | /// because changing your module changes things like your optimization mode and codegen flags, | ||
| 891 | /// so everything needs to be re-done. `updateZirRefs` is responsible for resetting this flag. | ||
| 892 | module_changed: bool, | ||
| 770 | 893 | ||
| 771 | /// The ZIR for this file from the last update with no file failures. As such, this ZIR is never | 894 | /// The ZIR for this file from the last update with no file failures. As such, this ZIR is never |
| 772 | /// failed (although it may have compile errors). | 895 | /// failed (although it may have compile errors). |
| ... | @@ -777,7 +900,7 @@ pub const File = struct { | ... | @@ -777,7 +900,7 @@ pub const File = struct { |
| 777 | /// | 900 | /// |
| 778 | /// In other words, if `TrackedInst`s are tied to ZIR other than what's in the `zir` field, this | 901 | /// In other words, if `TrackedInst`s are tied to ZIR other than what's in the `zir` field, this |
| 779 | /// field is populated with that old ZIR. | 902 | /// field is populated with that old ZIR. |
| 780 | prev_zir: ?*Zir = null, | 903 | prev_zir: ?*Zir, |
| 781 | 904 | ||
| 782 | /// This field serves a similar purpose to `prev_zir`, but for ZOIR. However, since we do not | 905 | /// This field serves a similar purpose to `prev_zir`, but for ZOIR. However, since we do not |
| 783 | /// need to map old ZOIR to new ZOIR -- instead only invalidating dependencies if the ZOIR | 906 | /// need to map old ZOIR to new ZOIR -- instead only invalidating dependencies if the ZOIR |
| ... | @@ -785,27 +908,42 @@ pub const File = struct { | ... | @@ -785,27 +908,42 @@ pub const File = struct { |
| 785 | /// | 908 | /// |
| 786 | /// When `zoir` is updated, this field is set to `true`. In `updateZirRefs`, if this is `true`, | 909 | /// When `zoir` is updated, this field is set to `true`. In `updateZirRefs`, if this is `true`, |
| 787 | /// we invalidate the corresponding `zon_file` dependency, and reset it to `false`. | 910 | /// we invalidate the corresponding `zon_file` dependency, and reset it to `false`. |
| 788 | zoir_invalidated: bool = false, | 911 | zoir_invalidated: bool, |
| 912 | |||
| 913 | pub const Path = struct { | ||
| 914 | root: enum { | ||
| 915 | cwd, | ||
| 916 | fs_root, | ||
| 917 | local_cache, | ||
| 918 | global_cache, | ||
| 919 | lib_dir, | ||
| 920 | }, | ||
| 921 | }; | ||
| 789 | 922 | ||
| 790 | /// A single reference to a file. | 923 | /// A single reference to a file. |
| 791 | pub const Reference = union(enum) { | 924 | pub const Reference = union(enum) { |
| 792 | /// The file is imported directly (i.e. not as a package) with @import. | 925 | analysis_root: *Package.Module, |
| 793 | import: struct { | 926 | import: struct { |
| 794 | file: File.Index, | 927 | importer: Zcu.File.Index, |
| 795 | token: Ast.TokenIndex, | 928 | tok: Ast.TokenIndex, |
| 929 | /// If the file is imported as the root of a module, this is that module. | ||
| 930 | /// `null` means the file was imported directly by path. | ||
| 931 | module: ?*Package.Module, | ||
| 796 | }, | 932 | }, |
| 797 | /// The file is the root of a module. | ||
| 798 | root: *Package.Module, | ||
| 799 | }; | 933 | }; |
| 800 | 934 | ||
| 801 | pub fn getMode(self: File) Ast.Mode { | 935 | pub fn getMode(self: File) Ast.Mode { |
| 802 | if (std.mem.endsWith(u8, self.sub_file_path, ".zon")) { | 936 | // We never create a `File` whose path doesn't give a mode. |
| 937 | return modeFromPath(self.path.sub_path).?; | ||
| 938 | } | ||
| 939 | |||
| 940 | pub fn modeFromPath(path: []const u8) ?Ast.Mode { | ||
| 941 | if (std.mem.endsWith(u8, path, ".zon")) { | ||
| 803 | return .zon; | 942 | return .zon; |
| 804 | } else if (std.mem.endsWith(u8, self.sub_file_path, ".zig")) { | 943 | } else if (std.mem.endsWith(u8, path, ".zig")) { |
| 805 | return .zig; | 944 | return .zig; |
| 806 | } else { | 945 | } else { |
| 807 | // `Module.importFile` rejects all other extensions | 946 | return null; |
| 808 | unreachable; | ||
| 809 | } | 947 | } |
| 810 | } | 948 | } |
| 811 | 949 | ||
| ... | @@ -842,15 +980,18 @@ pub const File = struct { | ... | @@ -842,15 +980,18 @@ pub const File = struct { |
| 842 | stat: Cache.File.Stat, | 980 | stat: Cache.File.Stat, |
| 843 | }; | 981 | }; |
| 844 | 982 | ||
| 845 | pub fn getSource(file: *File, gpa: Allocator) !Source { | 983 | pub fn getSource(file: *File, zcu: *const Zcu) !Source { |
| 984 | const gpa = zcu.gpa; | ||
| 985 | |||
| 846 | if (file.source) |source| return .{ | 986 | if (file.source) |source| return .{ |
| 847 | .bytes = source, | 987 | .bytes = source, |
| 848 | .stat = file.stat, | 988 | .stat = file.stat, |
| 849 | }; | 989 | }; |
| 850 | 990 | ||
| 851 | // Keep track of inode, file size, mtime, hash so we can detect which files | 991 | var f = f: { |
| 852 | // have been modified when an incremental update is requested. | 992 | const dir, const sub_path = file.path.openInfo(zcu.comp.dirs); |
| 853 | var f = try file.mod.root.openFile(file.sub_file_path, .{}); | 993 | break :f try dir.openFile(sub_path, .{}); |
| 994 | }; | ||
| 854 | defer f.close(); | 995 | defer f.close(); |
| 855 | 996 | ||
| 856 | const stat = try f.stat(); | 997 | const stat = try f.stat(); |
| ... | @@ -882,28 +1023,14 @@ pub const File = struct { | ... | @@ -882,28 +1023,14 @@ pub const File = struct { |
| 882 | }; | 1023 | }; |
| 883 | } | 1024 | } |
| 884 | 1025 | ||
| 885 | pub fn getTree(file: *File, gpa: Allocator) !*const Ast { | 1026 | pub fn getTree(file: *File, zcu: *const Zcu) !*const Ast { |
| 886 | if (file.tree) |*tree| return tree; | 1027 | if (file.tree) |*tree| return tree; |
| 887 | 1028 | ||
| 888 | const source = try file.getSource(gpa); | 1029 | const source = try file.getSource(zcu); |
| 889 | file.tree = try .parse(gpa, source.bytes, file.getMode()); | 1030 | file.tree = try .parse(zcu.gpa, source.bytes, file.getMode()); |
| 890 | return &file.tree.?; | 1031 | return &file.tree.?; |
| 891 | } | 1032 | } |
| 892 | 1033 | ||
| 893 | pub fn getZoir(file: *File, zcu: *Zcu) !*const Zoir { | ||
| 894 | if (file.zoir) |*zoir| return zoir; | ||
| 895 | |||
| 896 | const tree = file.tree.?; | ||
| 897 | assert(tree.mode == .zon); | ||
| 898 | |||
| 899 | file.zoir = try ZonGen.generate(zcu.gpa, tree, .{}); | ||
| 900 | if (file.zoir.?.hasCompileErrors()) { | ||
| 901 | try zcu.failed_files.putNoClobber(zcu.gpa, file, null); | ||
| 902 | return error.AnalysisFail; | ||
| 903 | } | ||
| 904 | return &file.zoir.?; | ||
| 905 | } | ||
| 906 | |||
| 907 | pub fn fullyQualifiedNameLen(file: File) usize { | 1034 | pub fn fullyQualifiedNameLen(file: File) usize { |
| 908 | const ext = std.fs.path.extension(file.sub_file_path); | 1035 | const ext = std.fs.path.extension(file.sub_file_path); |
| 909 | return file.sub_file_path.len - ext.len; | 1036 | return file.sub_file_path.len - ext.len; |
| ... | @@ -937,85 +1064,49 @@ pub const File = struct { | ... | @@ -937,85 +1064,49 @@ pub const File = struct { |
| 937 | return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls); | 1064 | return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls); |
| 938 | } | 1065 | } |
| 939 | 1066 | ||
| 940 | pub fn fullPath(file: File, ally: Allocator) ![]u8 { | 1067 | pub const Index = InternPool.FileIndex; |
| 941 | return file.mod.root.joinString(ally, file.sub_file_path); | ||
| 942 | } | ||
| 943 | |||
| 944 | pub fn dumpSrc(file: *File, src: LazySrcLoc) void { | ||
| 945 | const loc = std.zig.findLineColumn(file.source.bytes, src); | ||
| 946 | std.debug.print("{s}:{d}:{d}\n", .{ file.sub_file_path, loc.line + 1, loc.column + 1 }); | ||
| 947 | } | ||
| 948 | |||
| 949 | /// Add a reference to this file during AstGen. | ||
| 950 | pub fn addReference(file: *File, zcu: *Zcu, ref: File.Reference) !void { | ||
| 951 | // Don't add the same module root twice. Note that since we always add module roots at the | ||
| 952 | // front of the references array (see below), this loop is actually O(1) on valid code. | ||
| 953 | if (ref == .root) { | ||
| 954 | for (file.references.items) |other| { | ||
| 955 | switch (other) { | ||
| 956 | .root => |r| if (ref.root == r) return, | ||
| 957 | else => break, // reached the end of the "is-root" references | ||
| 958 | } | ||
| 959 | } | ||
| 960 | } | ||
| 961 | |||
| 962 | switch (ref) { | ||
| 963 | // We put root references at the front of the list both to make the above loop fast and | ||
| 964 | // to make multi-module errors more helpful (since "root-of" notes are generally more | ||
| 965 | // informative than "imported-from" notes). This path is hit very rarely, so the speed | ||
| 966 | // of the insert operation doesn't matter too much. | ||
| 967 | .root => try file.references.insert(zcu.gpa, 0, ref), | ||
| 968 | |||
| 969 | // Other references we'll just put at the end. | ||
| 970 | else => try file.references.append(zcu.gpa, ref), | ||
| 971 | } | ||
| 972 | 1068 | ||
| 973 | const mod = switch (ref) { | 1069 | pub fn errorBundleWholeFileSrc( |
| 974 | .import => |import| zcu.fileByIndex(import.file).mod, | 1070 | file: *File, |
| 975 | .root => |mod| mod, | 1071 | zcu: *const Zcu, |
| 976 | }; | 1072 | eb: *std.zig.ErrorBundle.Wip, |
| 977 | if (mod != file.mod) file.multi_pkg = true; | 1073 | ) !std.zig.ErrorBundle.SourceLocationIndex { |
| 1074 | return eb.addSourceLocation(.{ | ||
| 1075 | .src_path = try eb.printString("{}", .{file.path.fmt(zcu.comp)}), | ||
| 1076 | .span_start = 0, | ||
| 1077 | .span_main = 0, | ||
| 1078 | .span_end = 0, | ||
| 1079 | .line = 0, | ||
| 1080 | .column = 0, | ||
| 1081 | .source_line = 0, | ||
| 1082 | }); | ||
| 978 | } | 1083 | } |
| 979 | 1084 | pub fn errorBundleTokenSrc( | |
| 980 | /// Mark this file and every file referenced by it as multi_pkg and report an | 1085 | file: *File, |
| 981 | /// astgen_failure error for them. AstGen must have completed in its entirety. | 1086 | tok: Ast.TokenIndex, |
| 982 | pub fn recursiveMarkMultiPkg(file: *File, pt: Zcu.PerThread) void { | 1087 | zcu: *const Zcu, |
| 983 | file.multi_pkg = true; | 1088 | eb: *std.zig.ErrorBundle.Wip, |
| 984 | file.status = .astgen_failure; | 1089 | ) !std.zig.ErrorBundle.SourceLocationIndex { |
| 985 | 1090 | const source = try file.getSource(zcu); | |
| 986 | // We can only mark children as failed if the ZIR is loaded, which may not | 1091 | const tree = try file.getTree(zcu); |
| 987 | // be the case if there were other astgen failures in this file | 1092 | const start = tree.tokenStart(tok); |
| 988 | if (file.zir == null) return; | 1093 | const end = start + tree.tokenSlice(tok).len; |
| 989 | 1094 | const loc = std.zig.findLineColumn(source.bytes, start); | |
| 990 | const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | 1095 | return eb.addSourceLocation(.{ |
| 991 | if (imports_index == 0) return; | 1096 | .src_path = try eb.printString("{}", .{file.path.fmt(zcu.comp)}), |
| 992 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index); | 1097 | .span_start = start, |
| 993 | 1098 | .span_main = start, | |
| 994 | var extra_index = extra.end; | 1099 | .span_end = @intCast(end), |
| 995 | for (0..extra.data.imports_len) |_| { | 1100 | .line = @intCast(loc.line), |
| 996 | const item = file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index); | 1101 | .column = @intCast(loc.column), |
| 997 | extra_index = item.end; | 1102 | .source_line = try eb.addString(loc.source_line), |
| 998 | 1103 | }); | |
| 999 | const import_path = file.zir.?.nullTerminatedString(item.data.name); | ||
| 1000 | if (mem.eql(u8, import_path, "builtin")) continue; | ||
| 1001 | |||
| 1002 | const res = pt.importFile(file, import_path) catch continue; | ||
| 1003 | if (!res.is_pkg and !res.file.multi_pkg) { | ||
| 1004 | res.file.recursiveMarkMultiPkg(pt); | ||
| 1005 | } | ||
| 1006 | } | ||
| 1007 | } | 1104 | } |
| 1008 | |||
| 1009 | pub const Index = InternPool.FileIndex; | ||
| 1010 | }; | 1105 | }; |
| 1011 | 1106 | ||
| 1012 | /// Represents the contents of a file loaded with `@embedFile`. | 1107 | /// Represents the contents of a file loaded with `@embedFile`. |
| 1013 | pub const EmbedFile = struct { | 1108 | pub const EmbedFile = struct { |
| 1014 | /// Module that this file is a part of, managed externally. | 1109 | path: Compilation.Path, |
| 1015 | owner: *Package.Module, | ||
| 1016 | /// Relative to the owning module's root directory. | ||
| 1017 | sub_file_path: InternPool.NullTerminatedString, | ||
| 1018 | |||
| 1019 | /// `.none` means the file was not loaded, so `stat` is undefined. | 1110 | /// `.none` means the file was not loaded, so `stat` is undefined. |
| 1020 | val: InternPool.Index, | 1111 | val: InternPool.Index, |
| 1021 | /// If this is `null` and `val` is `.none`, the file has never been loaded. | 1112 | /// If this is `null` and `val` is `.none`, the file has never been loaded. |
| ... | @@ -1025,7 +1116,7 @@ pub const EmbedFile = struct { | ... | @@ -1025,7 +1116,7 @@ pub const EmbedFile = struct { |
| 1025 | pub const Index = enum(u32) { | 1116 | pub const Index = enum(u32) { |
| 1026 | _, | 1117 | _, |
| 1027 | pub fn get(idx: Index, zcu: *const Zcu) *EmbedFile { | 1118 | pub fn get(idx: Index, zcu: *const Zcu) *EmbedFile { |
| 1028 | return zcu.embed_table.values()[@intFromEnum(idx)]; | 1119 | return zcu.embed_table.keys()[@intFromEnum(idx)]; |
| 1029 | } | 1120 | } |
| 1030 | }; | 1121 | }; |
| 1031 | }; | 1122 | }; |
| ... | @@ -1103,32 +1194,31 @@ pub const SrcLoc = struct { | ... | @@ -1103,32 +1194,31 @@ pub const SrcLoc = struct { |
| 1103 | 1194 | ||
| 1104 | pub const Span = Ast.Span; | 1195 | pub const Span = Ast.Span; |
| 1105 | 1196 | ||
| 1106 | pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span { | 1197 | pub fn span(src_loc: SrcLoc, zcu: *const Zcu) !Span { |
| 1107 | switch (src_loc.lazy) { | 1198 | switch (src_loc.lazy) { |
| 1108 | .unneeded => unreachable, | 1199 | .unneeded => unreachable, |
| 1109 | .entire_file => return Span{ .start = 0, .end = 1, .main = 0 }, | ||
| 1110 | 1200 | ||
| 1111 | .byte_abs => |byte_index| return Span{ .start = byte_index, .end = byte_index + 1, .main = byte_index }, | 1201 | .byte_abs => |byte_index| return Span{ .start = byte_index, .end = byte_index + 1, .main = byte_index }, |
| 1112 | 1202 | ||
| 1113 | .token_abs => |tok_index| { | 1203 | .token_abs => |tok_index| { |
| 1114 | const tree = try src_loc.file_scope.getTree(gpa); | 1204 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1115 | const start = tree.tokenStart(tok_index); | 1205 | const start = tree.tokenStart(tok_index); |
| 1116 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1206 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1117 | return Span{ .start = start, .end = end, .main = start }; | 1207 | return Span{ .start = start, .end = end, .main = start }; |
| 1118 | }, | 1208 | }, |
| 1119 | .node_abs => |node| { | 1209 | .node_abs => |node| { |
| 1120 | const tree = try src_loc.file_scope.getTree(gpa); | 1210 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1121 | return tree.nodeToSpan(node); | 1211 | return tree.nodeToSpan(node); |
| 1122 | }, | 1212 | }, |
| 1123 | .byte_offset => |byte_off| { | 1213 | .byte_offset => |byte_off| { |
| 1124 | const tree = try src_loc.file_scope.getTree(gpa); | 1214 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1125 | const tok_index = src_loc.baseSrcToken(); | 1215 | const tok_index = src_loc.baseSrcToken(); |
| 1126 | const start = tree.tokenStart(tok_index) + byte_off; | 1216 | const start = tree.tokenStart(tok_index) + byte_off; |
| 1127 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1217 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1128 | return Span{ .start = start, .end = end, .main = start }; | 1218 | return Span{ .start = start, .end = end, .main = start }; |
| 1129 | }, | 1219 | }, |
| 1130 | .token_offset => |tok_off| { | 1220 | .token_offset => |tok_off| { |
| 1131 | const tree = try src_loc.file_scope.getTree(gpa); | 1221 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1132 | const tok_index = tok_off.toAbsolute(src_loc.baseSrcToken()); | 1222 | const tok_index = tok_off.toAbsolute(src_loc.baseSrcToken()); |
| 1133 | const start = tree.tokenStart(tok_index); | 1223 | const start = tree.tokenStart(tok_index); |
| 1134 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1224 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| ... | @@ -1136,23 +1226,23 @@ pub const SrcLoc = struct { | ... | @@ -1136,23 +1226,23 @@ pub const SrcLoc = struct { |
| 1136 | }, | 1226 | }, |
| 1137 | .node_offset => |traced_off| { | 1227 | .node_offset => |traced_off| { |
| 1138 | const node_off = traced_off.x; | 1228 | const node_off = traced_off.x; |
| 1139 | const tree = try src_loc.file_scope.getTree(gpa); | 1229 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1140 | const node = node_off.toAbsolute(src_loc.base_node); | 1230 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1141 | return tree.nodeToSpan(node); | 1231 | return tree.nodeToSpan(node); |
| 1142 | }, | 1232 | }, |
| 1143 | .node_offset_main_token => |node_off| { | 1233 | .node_offset_main_token => |node_off| { |
| 1144 | const tree = try src_loc.file_scope.getTree(gpa); | 1234 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1145 | const node = node_off.toAbsolute(src_loc.base_node); | 1235 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1146 | const main_token = tree.nodeMainToken(node); | 1236 | const main_token = tree.nodeMainToken(node); |
| 1147 | return tree.tokensToSpan(main_token, main_token, main_token); | 1237 | return tree.tokensToSpan(main_token, main_token, main_token); |
| 1148 | }, | 1238 | }, |
| 1149 | .node_offset_bin_op => |node_off| { | 1239 | .node_offset_bin_op => |node_off| { |
| 1150 | const tree = try src_loc.file_scope.getTree(gpa); | 1240 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1151 | const node = node_off.toAbsolute(src_loc.base_node); | 1241 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1152 | return tree.nodeToSpan(node); | 1242 | return tree.nodeToSpan(node); |
| 1153 | }, | 1243 | }, |
| 1154 | .node_offset_initializer => |node_off| { | 1244 | .node_offset_initializer => |node_off| { |
| 1155 | const tree = try src_loc.file_scope.getTree(gpa); | 1245 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1156 | const node = node_off.toAbsolute(src_loc.base_node); | 1246 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1157 | return tree.tokensToSpan( | 1247 | return tree.tokensToSpan( |
| 1158 | tree.firstToken(node) - 3, | 1248 | tree.firstToken(node) - 3, |
| ... | @@ -1161,7 +1251,7 @@ pub const SrcLoc = struct { | ... | @@ -1161,7 +1251,7 @@ pub const SrcLoc = struct { |
| 1161 | ); | 1251 | ); |
| 1162 | }, | 1252 | }, |
| 1163 | .node_offset_var_decl_ty => |node_off| { | 1253 | .node_offset_var_decl_ty => |node_off| { |
| 1164 | const tree = try src_loc.file_scope.getTree(gpa); | 1254 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1165 | const node = node_off.toAbsolute(src_loc.base_node); | 1255 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1166 | const full = switch (tree.nodeTag(node)) { | 1256 | const full = switch (tree.nodeTag(node)) { |
| 1167 | .global_var_decl, | 1257 | .global_var_decl, |
| ... | @@ -1183,7 +1273,7 @@ pub const SrcLoc = struct { | ... | @@ -1183,7 +1273,7 @@ pub const SrcLoc = struct { |
| 1183 | return Span{ .start = start, .end = end, .main = start }; | 1273 | return Span{ .start = start, .end = end, .main = start }; |
| 1184 | }, | 1274 | }, |
| 1185 | .node_offset_var_decl_align => |node_off| { | 1275 | .node_offset_var_decl_align => |node_off| { |
| 1186 | const tree = try src_loc.file_scope.getTree(gpa); | 1276 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1187 | const node = node_off.toAbsolute(src_loc.base_node); | 1277 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1188 | var buf: [1]Ast.Node.Index = undefined; | 1278 | var buf: [1]Ast.Node.Index = undefined; |
| 1189 | const align_node = if (tree.fullVarDecl(node)) |v| | 1279 | const align_node = if (tree.fullVarDecl(node)) |v| |
| ... | @@ -1195,7 +1285,7 @@ pub const SrcLoc = struct { | ... | @@ -1195,7 +1285,7 @@ pub const SrcLoc = struct { |
| 1195 | return tree.nodeToSpan(align_node); | 1285 | return tree.nodeToSpan(align_node); |
| 1196 | }, | 1286 | }, |
| 1197 | .node_offset_var_decl_section => |node_off| { | 1287 | .node_offset_var_decl_section => |node_off| { |
| 1198 | const tree = try src_loc.file_scope.getTree(gpa); | 1288 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1199 | const node = node_off.toAbsolute(src_loc.base_node); | 1289 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1200 | var buf: [1]Ast.Node.Index = undefined; | 1290 | var buf: [1]Ast.Node.Index = undefined; |
| 1201 | const section_node = if (tree.fullVarDecl(node)) |v| | 1291 | const section_node = if (tree.fullVarDecl(node)) |v| |
| ... | @@ -1207,7 +1297,7 @@ pub const SrcLoc = struct { | ... | @@ -1207,7 +1297,7 @@ pub const SrcLoc = struct { |
| 1207 | return tree.nodeToSpan(section_node); | 1297 | return tree.nodeToSpan(section_node); |
| 1208 | }, | 1298 | }, |
| 1209 | .node_offset_var_decl_addrspace => |node_off| { | 1299 | .node_offset_var_decl_addrspace => |node_off| { |
| 1210 | const tree = try src_loc.file_scope.getTree(gpa); | 1300 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1211 | const node = node_off.toAbsolute(src_loc.base_node); | 1301 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1212 | var buf: [1]Ast.Node.Index = undefined; | 1302 | var buf: [1]Ast.Node.Index = undefined; |
| 1213 | const addrspace_node = if (tree.fullVarDecl(node)) |v| | 1303 | const addrspace_node = if (tree.fullVarDecl(node)) |v| |
| ... | @@ -1219,7 +1309,7 @@ pub const SrcLoc = struct { | ... | @@ -1219,7 +1309,7 @@ pub const SrcLoc = struct { |
| 1219 | return tree.nodeToSpan(addrspace_node); | 1309 | return tree.nodeToSpan(addrspace_node); |
| 1220 | }, | 1310 | }, |
| 1221 | .node_offset_var_decl_init => |node_off| { | 1311 | .node_offset_var_decl_init => |node_off| { |
| 1222 | const tree = try src_loc.file_scope.getTree(gpa); | 1312 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1223 | const node = node_off.toAbsolute(src_loc.base_node); | 1313 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1224 | const init_node = switch (tree.nodeTag(node)) { | 1314 | const init_node = switch (tree.nodeTag(node)) { |
| 1225 | .global_var_decl, | 1315 | .global_var_decl, |
| ... | @@ -1233,14 +1323,14 @@ pub const SrcLoc = struct { | ... | @@ -1233,14 +1323,14 @@ pub const SrcLoc = struct { |
| 1233 | return tree.nodeToSpan(init_node); | 1323 | return tree.nodeToSpan(init_node); |
| 1234 | }, | 1324 | }, |
| 1235 | .node_offset_builtin_call_arg => |builtin_arg| { | 1325 | .node_offset_builtin_call_arg => |builtin_arg| { |
| 1236 | const tree = try src_loc.file_scope.getTree(gpa); | 1326 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1237 | const node = builtin_arg.builtin_call_node.toAbsolute(src_loc.base_node); | 1327 | const node = builtin_arg.builtin_call_node.toAbsolute(src_loc.base_node); |
| 1238 | var buf: [2]Ast.Node.Index = undefined; | 1328 | var buf: [2]Ast.Node.Index = undefined; |
| 1239 | const params = tree.builtinCallParams(&buf, node).?; | 1329 | const params = tree.builtinCallParams(&buf, node).?; |
| 1240 | return tree.nodeToSpan(params[builtin_arg.arg_index]); | 1330 | return tree.nodeToSpan(params[builtin_arg.arg_index]); |
| 1241 | }, | 1331 | }, |
| 1242 | .node_offset_ptrcast_operand => |node_off| { | 1332 | .node_offset_ptrcast_operand => |node_off| { |
| 1243 | const tree = try src_loc.file_scope.getTree(gpa); | 1333 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1244 | 1334 | ||
| 1245 | var node = node_off.toAbsolute(src_loc.base_node); | 1335 | var node = node_off.toAbsolute(src_loc.base_node); |
| 1246 | while (true) { | 1336 | while (true) { |
| ... | @@ -1273,7 +1363,7 @@ pub const SrcLoc = struct { | ... | @@ -1273,7 +1363,7 @@ pub const SrcLoc = struct { |
| 1273 | return tree.nodeToSpan(node); | 1363 | return tree.nodeToSpan(node); |
| 1274 | }, | 1364 | }, |
| 1275 | .node_offset_array_access_index => |node_off| { | 1365 | .node_offset_array_access_index => |node_off| { |
| 1276 | const tree = try src_loc.file_scope.getTree(gpa); | 1366 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1277 | const node = node_off.toAbsolute(src_loc.base_node); | 1367 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1278 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); | 1368 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1279 | }, | 1369 | }, |
| ... | @@ -1282,7 +1372,7 @@ pub const SrcLoc = struct { | ... | @@ -1282,7 +1372,7 @@ pub const SrcLoc = struct { |
| 1282 | .node_offset_slice_end, | 1372 | .node_offset_slice_end, |
| 1283 | .node_offset_slice_sentinel, | 1373 | .node_offset_slice_sentinel, |
| 1284 | => |node_off| { | 1374 | => |node_off| { |
| 1285 | const tree = try src_loc.file_scope.getTree(gpa); | 1375 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1286 | const node = node_off.toAbsolute(src_loc.base_node); | 1376 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1287 | const full = tree.fullSlice(node).?; | 1377 | const full = tree.fullSlice(node).?; |
| 1288 | const part_node = switch (src_loc.lazy) { | 1378 | const part_node = switch (src_loc.lazy) { |
| ... | @@ -1295,14 +1385,14 @@ pub const SrcLoc = struct { | ... | @@ -1295,14 +1385,14 @@ pub const SrcLoc = struct { |
| 1295 | return tree.nodeToSpan(part_node); | 1385 | return tree.nodeToSpan(part_node); |
| 1296 | }, | 1386 | }, |
| 1297 | .node_offset_call_func => |node_off| { | 1387 | .node_offset_call_func => |node_off| { |
| 1298 | const tree = try src_loc.file_scope.getTree(gpa); | 1388 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1299 | const node = node_off.toAbsolute(src_loc.base_node); | 1389 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1300 | var buf: [1]Ast.Node.Index = undefined; | 1390 | var buf: [1]Ast.Node.Index = undefined; |
| 1301 | const full = tree.fullCall(&buf, node).?; | 1391 | const full = tree.fullCall(&buf, node).?; |
| 1302 | return tree.nodeToSpan(full.ast.fn_expr); | 1392 | return tree.nodeToSpan(full.ast.fn_expr); |
| 1303 | }, | 1393 | }, |
| 1304 | .node_offset_field_name => |node_off| { | 1394 | .node_offset_field_name => |node_off| { |
| 1305 | const tree = try src_loc.file_scope.getTree(gpa); | 1395 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1306 | const node = node_off.toAbsolute(src_loc.base_node); | 1396 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1307 | var buf: [1]Ast.Node.Index = undefined; | 1397 | var buf: [1]Ast.Node.Index = undefined; |
| 1308 | const tok_index = switch (tree.nodeTag(node)) { | 1398 | const tok_index = switch (tree.nodeTag(node)) { |
| ... | @@ -1326,7 +1416,7 @@ pub const SrcLoc = struct { | ... | @@ -1326,7 +1416,7 @@ pub const SrcLoc = struct { |
| 1326 | return Span{ .start = start, .end = end, .main = start }; | 1416 | return Span{ .start = start, .end = end, .main = start }; |
| 1327 | }, | 1417 | }, |
| 1328 | .node_offset_field_name_init => |node_off| { | 1418 | .node_offset_field_name_init => |node_off| { |
| 1329 | const tree = try src_loc.file_scope.getTree(gpa); | 1419 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1330 | const node = node_off.toAbsolute(src_loc.base_node); | 1420 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1331 | const tok_index = tree.firstToken(node) - 2; | 1421 | const tok_index = tree.firstToken(node) - 2; |
| 1332 | const start = tree.tokenStart(tok_index); | 1422 | const start = tree.tokenStart(tok_index); |
| ... | @@ -1334,18 +1424,18 @@ pub const SrcLoc = struct { | ... | @@ -1334,18 +1424,18 @@ pub const SrcLoc = struct { |
| 1334 | return Span{ .start = start, .end = end, .main = start }; | 1424 | return Span{ .start = start, .end = end, .main = start }; |
| 1335 | }, | 1425 | }, |
| 1336 | .node_offset_deref_ptr => |node_off| { | 1426 | .node_offset_deref_ptr => |node_off| { |
| 1337 | const tree = try src_loc.file_scope.getTree(gpa); | 1427 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1338 | const node = node_off.toAbsolute(src_loc.base_node); | 1428 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1339 | return tree.nodeToSpan(node); | 1429 | return tree.nodeToSpan(node); |
| 1340 | }, | 1430 | }, |
| 1341 | .node_offset_asm_source => |node_off| { | 1431 | .node_offset_asm_source => |node_off| { |
| 1342 | const tree = try src_loc.file_scope.getTree(gpa); | 1432 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1343 | const node = node_off.toAbsolute(src_loc.base_node); | 1433 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1344 | const full = tree.fullAsm(node).?; | 1434 | const full = tree.fullAsm(node).?; |
| 1345 | return tree.nodeToSpan(full.ast.template); | 1435 | return tree.nodeToSpan(full.ast.template); |
| 1346 | }, | 1436 | }, |
| 1347 | .node_offset_asm_ret_ty => |node_off| { | 1437 | .node_offset_asm_ret_ty => |node_off| { |
| 1348 | const tree = try src_loc.file_scope.getTree(gpa); | 1438 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1349 | const node = node_off.toAbsolute(src_loc.base_node); | 1439 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1350 | const full = tree.fullAsm(node).?; | 1440 | const full = tree.fullAsm(node).?; |
| 1351 | const asm_output = full.outputs[0]; | 1441 | const asm_output = full.outputs[0]; |
| ... | @@ -1353,7 +1443,7 @@ pub const SrcLoc = struct { | ... | @@ -1353,7 +1443,7 @@ pub const SrcLoc = struct { |
| 1353 | }, | 1443 | }, |
| 1354 | 1444 | ||
| 1355 | .node_offset_if_cond => |node_off| { | 1445 | .node_offset_if_cond => |node_off| { |
| 1356 | const tree = try src_loc.file_scope.getTree(gpa); | 1446 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1357 | const node = node_off.toAbsolute(src_loc.base_node); | 1447 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1358 | const src_node = switch (tree.nodeTag(node)) { | 1448 | const src_node = switch (tree.nodeTag(node)) { |
| 1359 | .if_simple, | 1449 | .if_simple, |
| ... | @@ -1381,14 +1471,14 @@ pub const SrcLoc = struct { | ... | @@ -1381,14 +1471,14 @@ pub const SrcLoc = struct { |
| 1381 | return tree.nodeToSpan(src_node); | 1471 | return tree.nodeToSpan(src_node); |
| 1382 | }, | 1472 | }, |
| 1383 | .for_input => |for_input| { | 1473 | .for_input => |for_input| { |
| 1384 | const tree = try src_loc.file_scope.getTree(gpa); | 1474 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1385 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); | 1475 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); |
| 1386 | const for_full = tree.fullFor(node).?; | 1476 | const for_full = tree.fullFor(node).?; |
| 1387 | const src_node = for_full.ast.inputs[for_input.input_index]; | 1477 | const src_node = for_full.ast.inputs[for_input.input_index]; |
| 1388 | return tree.nodeToSpan(src_node); | 1478 | return tree.nodeToSpan(src_node); |
| 1389 | }, | 1479 | }, |
| 1390 | .for_capture_from_input => |node_off| { | 1480 | .for_capture_from_input => |node_off| { |
| 1391 | const tree = try src_loc.file_scope.getTree(gpa); | 1481 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1392 | const input_node = node_off.toAbsolute(src_loc.base_node); | 1482 | const input_node = node_off.toAbsolute(src_loc.base_node); |
| 1393 | // We have to actually linear scan the whole AST to find the for loop | 1483 | // We have to actually linear scan the whole AST to find the for loop |
| 1394 | // that contains this input. | 1484 | // that contains this input. |
| ... | @@ -1429,7 +1519,7 @@ pub const SrcLoc = struct { | ... | @@ -1429,7 +1519,7 @@ pub const SrcLoc = struct { |
| 1429 | } else unreachable; | 1519 | } else unreachable; |
| 1430 | }, | 1520 | }, |
| 1431 | .call_arg => |call_arg| { | 1521 | .call_arg => |call_arg| { |
| 1432 | const tree = try src_loc.file_scope.getTree(gpa); | 1522 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1433 | const node = call_arg.call_node_offset.toAbsolute(src_loc.base_node); | 1523 | const node = call_arg.call_node_offset.toAbsolute(src_loc.base_node); |
| 1434 | var buf: [2]Ast.Node.Index = undefined; | 1524 | var buf: [2]Ast.Node.Index = undefined; |
| 1435 | const call_full = tree.fullCall(buf[0..1], node) orelse { | 1525 | const call_full = tree.fullCall(buf[0..1], node) orelse { |
| ... | @@ -1466,7 +1556,7 @@ pub const SrcLoc = struct { | ... | @@ -1466,7 +1556,7 @@ pub const SrcLoc = struct { |
| 1466 | return tree.nodeToSpan(call_full.ast.params[call_arg.arg_index]); | 1556 | return tree.nodeToSpan(call_full.ast.params[call_arg.arg_index]); |
| 1467 | }, | 1557 | }, |
| 1468 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { | 1558 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { |
| 1469 | const tree = try src_loc.file_scope.getTree(gpa); | 1559 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1470 | const node = fn_proto_param.fn_proto_node_offset.toAbsolute(src_loc.base_node); | 1560 | const node = fn_proto_param.fn_proto_node_offset.toAbsolute(src_loc.base_node); |
| 1471 | var buf: [1]Ast.Node.Index = undefined; | 1561 | var buf: [1]Ast.Node.Index = undefined; |
| 1472 | const full = tree.fullFnProto(&buf, node).?; | 1562 | const full = tree.fullFnProto(&buf, node).?; |
| ... | @@ -1494,17 +1584,17 @@ pub const SrcLoc = struct { | ... | @@ -1494,17 +1584,17 @@ pub const SrcLoc = struct { |
| 1494 | unreachable; | 1584 | unreachable; |
| 1495 | }, | 1585 | }, |
| 1496 | .node_offset_bin_lhs => |node_off| { | 1586 | .node_offset_bin_lhs => |node_off| { |
| 1497 | const tree = try src_loc.file_scope.getTree(gpa); | 1587 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1498 | const node = node_off.toAbsolute(src_loc.base_node); | 1588 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1499 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); | 1589 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); |
| 1500 | }, | 1590 | }, |
| 1501 | .node_offset_bin_rhs => |node_off| { | 1591 | .node_offset_bin_rhs => |node_off| { |
| 1502 | const tree = try src_loc.file_scope.getTree(gpa); | 1592 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1503 | const node = node_off.toAbsolute(src_loc.base_node); | 1593 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1504 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); | 1594 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1505 | }, | 1595 | }, |
| 1506 | .array_cat_lhs, .array_cat_rhs => |cat| { | 1596 | .array_cat_lhs, .array_cat_rhs => |cat| { |
| 1507 | const tree = try src_loc.file_scope.getTree(gpa); | 1597 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1508 | const node = cat.array_cat_offset.toAbsolute(src_loc.base_node); | 1598 | const node = cat.array_cat_offset.toAbsolute(src_loc.base_node); |
| 1509 | const arr_node = if (src_loc.lazy == .array_cat_lhs) | 1599 | const arr_node = if (src_loc.lazy == .array_cat_lhs) |
| 1510 | tree.nodeData(node).node_and_node[0] | 1600 | tree.nodeData(node).node_and_node[0] |
| ... | @@ -1530,20 +1620,20 @@ pub const SrcLoc = struct { | ... | @@ -1530,20 +1620,20 @@ pub const SrcLoc = struct { |
| 1530 | }, | 1620 | }, |
| 1531 | 1621 | ||
| 1532 | .node_offset_try_operand => |node_off| { | 1622 | .node_offset_try_operand => |node_off| { |
| 1533 | const tree = try src_loc.file_scope.getTree(gpa); | 1623 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1534 | const node = node_off.toAbsolute(src_loc.base_node); | 1624 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1535 | return tree.nodeToSpan(tree.nodeData(node).node); | 1625 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1536 | }, | 1626 | }, |
| 1537 | 1627 | ||
| 1538 | .node_offset_switch_operand => |node_off| { | 1628 | .node_offset_switch_operand => |node_off| { |
| 1539 | const tree = try src_loc.file_scope.getTree(gpa); | 1629 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1540 | const node = node_off.toAbsolute(src_loc.base_node); | 1630 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1541 | const condition, _ = tree.nodeData(node).node_and_extra; | 1631 | const condition, _ = tree.nodeData(node).node_and_extra; |
| 1542 | return tree.nodeToSpan(condition); | 1632 | return tree.nodeToSpan(condition); |
| 1543 | }, | 1633 | }, |
| 1544 | 1634 | ||
| 1545 | .node_offset_switch_special_prong => |node_off| { | 1635 | .node_offset_switch_special_prong => |node_off| { |
| 1546 | const tree = try src_loc.file_scope.getTree(gpa); | 1636 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1547 | const switch_node = node_off.toAbsolute(src_loc.base_node); | 1637 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1548 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; | 1638 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1549 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); | 1639 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| ... | @@ -1560,7 +1650,7 @@ pub const SrcLoc = struct { | ... | @@ -1560,7 +1650,7 @@ pub const SrcLoc = struct { |
| 1560 | }, | 1650 | }, |
| 1561 | 1651 | ||
| 1562 | .node_offset_switch_range => |node_off| { | 1652 | .node_offset_switch_range => |node_off| { |
| 1563 | const tree = try src_loc.file_scope.getTree(gpa); | 1653 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1564 | const switch_node = node_off.toAbsolute(src_loc.base_node); | 1654 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1565 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; | 1655 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1566 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); | 1656 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| ... | @@ -1580,28 +1670,28 @@ pub const SrcLoc = struct { | ... | @@ -1580,28 +1670,28 @@ pub const SrcLoc = struct { |
| 1580 | } else unreachable; | 1670 | } else unreachable; |
| 1581 | }, | 1671 | }, |
| 1582 | .node_offset_fn_type_align => |node_off| { | 1672 | .node_offset_fn_type_align => |node_off| { |
| 1583 | const tree = try src_loc.file_scope.getTree(gpa); | 1673 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1584 | const node = node_off.toAbsolute(src_loc.base_node); | 1674 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1585 | var buf: [1]Ast.Node.Index = undefined; | 1675 | var buf: [1]Ast.Node.Index = undefined; |
| 1586 | const full = tree.fullFnProto(&buf, node).?; | 1676 | const full = tree.fullFnProto(&buf, node).?; |
| 1587 | return tree.nodeToSpan(full.ast.align_expr.unwrap().?); | 1677 | return tree.nodeToSpan(full.ast.align_expr.unwrap().?); |
| 1588 | }, | 1678 | }, |
| 1589 | .node_offset_fn_type_addrspace => |node_off| { | 1679 | .node_offset_fn_type_addrspace => |node_off| { |
| 1590 | const tree = try src_loc.file_scope.getTree(gpa); | 1680 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1591 | const node = node_off.toAbsolute(src_loc.base_node); | 1681 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1592 | var buf: [1]Ast.Node.Index = undefined; | 1682 | var buf: [1]Ast.Node.Index = undefined; |
| 1593 | const full = tree.fullFnProto(&buf, node).?; | 1683 | const full = tree.fullFnProto(&buf, node).?; |
| 1594 | return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?); | 1684 | return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?); |
| 1595 | }, | 1685 | }, |
| 1596 | .node_offset_fn_type_section => |node_off| { | 1686 | .node_offset_fn_type_section => |node_off| { |
| 1597 | const tree = try src_loc.file_scope.getTree(gpa); | 1687 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1598 | const node = node_off.toAbsolute(src_loc.base_node); | 1688 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1599 | var buf: [1]Ast.Node.Index = undefined; | 1689 | var buf: [1]Ast.Node.Index = undefined; |
| 1600 | const full = tree.fullFnProto(&buf, node).?; | 1690 | const full = tree.fullFnProto(&buf, node).?; |
| 1601 | return tree.nodeToSpan(full.ast.section_expr.unwrap().?); | 1691 | return tree.nodeToSpan(full.ast.section_expr.unwrap().?); |
| 1602 | }, | 1692 | }, |
| 1603 | .node_offset_fn_type_cc => |node_off| { | 1693 | .node_offset_fn_type_cc => |node_off| { |
| 1604 | const tree = try src_loc.file_scope.getTree(gpa); | 1694 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1605 | const node = node_off.toAbsolute(src_loc.base_node); | 1695 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1606 | var buf: [1]Ast.Node.Index = undefined; | 1696 | var buf: [1]Ast.Node.Index = undefined; |
| 1607 | const full = tree.fullFnProto(&buf, node).?; | 1697 | const full = tree.fullFnProto(&buf, node).?; |
| ... | @@ -1609,14 +1699,14 @@ pub const SrcLoc = struct { | ... | @@ -1609,14 +1699,14 @@ pub const SrcLoc = struct { |
| 1609 | }, | 1699 | }, |
| 1610 | 1700 | ||
| 1611 | .node_offset_fn_type_ret_ty => |node_off| { | 1701 | .node_offset_fn_type_ret_ty => |node_off| { |
| 1612 | const tree = try src_loc.file_scope.getTree(gpa); | 1702 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1613 | const node = node_off.toAbsolute(src_loc.base_node); | 1703 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1614 | var buf: [1]Ast.Node.Index = undefined; | 1704 | var buf: [1]Ast.Node.Index = undefined; |
| 1615 | const full = tree.fullFnProto(&buf, node).?; | 1705 | const full = tree.fullFnProto(&buf, node).?; |
| 1616 | return tree.nodeToSpan(full.ast.return_type.unwrap().?); | 1706 | return tree.nodeToSpan(full.ast.return_type.unwrap().?); |
| 1617 | }, | 1707 | }, |
| 1618 | .node_offset_param => |node_off| { | 1708 | .node_offset_param => |node_off| { |
| 1619 | const tree = try src_loc.file_scope.getTree(gpa); | 1709 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1620 | const node = node_off.toAbsolute(src_loc.base_node); | 1710 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1621 | 1711 | ||
| 1622 | var first_tok = tree.firstToken(node); | 1712 | var first_tok = tree.firstToken(node); |
| ... | @@ -1631,7 +1721,7 @@ pub const SrcLoc = struct { | ... | @@ -1631,7 +1721,7 @@ pub const SrcLoc = struct { |
| 1631 | ); | 1721 | ); |
| 1632 | }, | 1722 | }, |
| 1633 | .token_offset_param => |token_off| { | 1723 | .token_offset_param => |token_off| { |
| 1634 | const tree = try src_loc.file_scope.getTree(gpa); | 1724 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1635 | const main_token = tree.nodeMainToken(src_loc.base_node); | 1725 | const main_token = tree.nodeMainToken(src_loc.base_node); |
| 1636 | const tok_index = token_off.toAbsolute(main_token); | 1726 | const tok_index = token_off.toAbsolute(main_token); |
| 1637 | 1727 | ||
| ... | @@ -1648,14 +1738,14 @@ pub const SrcLoc = struct { | ... | @@ -1648,14 +1738,14 @@ pub const SrcLoc = struct { |
| 1648 | }, | 1738 | }, |
| 1649 | 1739 | ||
| 1650 | .node_offset_anyframe_type => |node_off| { | 1740 | .node_offset_anyframe_type => |node_off| { |
| 1651 | const tree = try src_loc.file_scope.getTree(gpa); | 1741 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1652 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1742 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1653 | _, const child_type = tree.nodeData(parent_node).token_and_node; | 1743 | _, const child_type = tree.nodeData(parent_node).token_and_node; |
| 1654 | return tree.nodeToSpan(child_type); | 1744 | return tree.nodeToSpan(child_type); |
| 1655 | }, | 1745 | }, |
| 1656 | 1746 | ||
| 1657 | .node_offset_lib_name => |node_off| { | 1747 | .node_offset_lib_name => |node_off| { |
| 1658 | const tree = try src_loc.file_scope.getTree(gpa); | 1748 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1659 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1749 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1660 | var buf: [1]Ast.Node.Index = undefined; | 1750 | var buf: [1]Ast.Node.Index = undefined; |
| 1661 | const full = tree.fullFnProto(&buf, parent_node).?; | 1751 | const full = tree.fullFnProto(&buf, parent_node).?; |
| ... | @@ -1666,75 +1756,75 @@ pub const SrcLoc = struct { | ... | @@ -1666,75 +1756,75 @@ pub const SrcLoc = struct { |
| 1666 | }, | 1756 | }, |
| 1667 | 1757 | ||
| 1668 | .node_offset_array_type_len => |node_off| { | 1758 | .node_offset_array_type_len => |node_off| { |
| 1669 | const tree = try src_loc.file_scope.getTree(gpa); | 1759 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1670 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1760 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1671 | 1761 | ||
| 1672 | const full = tree.fullArrayType(parent_node).?; | 1762 | const full = tree.fullArrayType(parent_node).?; |
| 1673 | return tree.nodeToSpan(full.ast.elem_count); | 1763 | return tree.nodeToSpan(full.ast.elem_count); |
| 1674 | }, | 1764 | }, |
| 1675 | .node_offset_array_type_sentinel => |node_off| { | 1765 | .node_offset_array_type_sentinel => |node_off| { |
| 1676 | const tree = try src_loc.file_scope.getTree(gpa); | 1766 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1677 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1767 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1678 | 1768 | ||
| 1679 | const full = tree.fullArrayType(parent_node).?; | 1769 | const full = tree.fullArrayType(parent_node).?; |
| 1680 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); | 1770 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1681 | }, | 1771 | }, |
| 1682 | .node_offset_array_type_elem => |node_off| { | 1772 | .node_offset_array_type_elem => |node_off| { |
| 1683 | const tree = try src_loc.file_scope.getTree(gpa); | 1773 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1684 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1774 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1685 | 1775 | ||
| 1686 | const full = tree.fullArrayType(parent_node).?; | 1776 | const full = tree.fullArrayType(parent_node).?; |
| 1687 | return tree.nodeToSpan(full.ast.elem_type); | 1777 | return tree.nodeToSpan(full.ast.elem_type); |
| 1688 | }, | 1778 | }, |
| 1689 | .node_offset_un_op => |node_off| { | 1779 | .node_offset_un_op => |node_off| { |
| 1690 | const tree = try src_loc.file_scope.getTree(gpa); | 1780 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1691 | const node = node_off.toAbsolute(src_loc.base_node); | 1781 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1692 | return tree.nodeToSpan(tree.nodeData(node).node); | 1782 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1693 | }, | 1783 | }, |
| 1694 | .node_offset_ptr_elem => |node_off| { | 1784 | .node_offset_ptr_elem => |node_off| { |
| 1695 | const tree = try src_loc.file_scope.getTree(gpa); | 1785 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1696 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1786 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1697 | 1787 | ||
| 1698 | const full = tree.fullPtrType(parent_node).?; | 1788 | const full = tree.fullPtrType(parent_node).?; |
| 1699 | return tree.nodeToSpan(full.ast.child_type); | 1789 | return tree.nodeToSpan(full.ast.child_type); |
| 1700 | }, | 1790 | }, |
| 1701 | .node_offset_ptr_sentinel => |node_off| { | 1791 | .node_offset_ptr_sentinel => |node_off| { |
| 1702 | const tree = try src_loc.file_scope.getTree(gpa); | 1792 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1703 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1793 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1704 | 1794 | ||
| 1705 | const full = tree.fullPtrType(parent_node).?; | 1795 | const full = tree.fullPtrType(parent_node).?; |
| 1706 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); | 1796 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1707 | }, | 1797 | }, |
| 1708 | .node_offset_ptr_align => |node_off| { | 1798 | .node_offset_ptr_align => |node_off| { |
| 1709 | const tree = try src_loc.file_scope.getTree(gpa); | 1799 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1710 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1800 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1711 | 1801 | ||
| 1712 | const full = tree.fullPtrType(parent_node).?; | 1802 | const full = tree.fullPtrType(parent_node).?; |
| 1713 | return tree.nodeToSpan(full.ast.align_node.unwrap().?); | 1803 | return tree.nodeToSpan(full.ast.align_node.unwrap().?); |
| 1714 | }, | 1804 | }, |
| 1715 | .node_offset_ptr_addrspace => |node_off| { | 1805 | .node_offset_ptr_addrspace => |node_off| { |
| 1716 | const tree = try src_loc.file_scope.getTree(gpa); | 1806 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1717 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1807 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1718 | 1808 | ||
| 1719 | const full = tree.fullPtrType(parent_node).?; | 1809 | const full = tree.fullPtrType(parent_node).?; |
| 1720 | return tree.nodeToSpan(full.ast.addrspace_node.unwrap().?); | 1810 | return tree.nodeToSpan(full.ast.addrspace_node.unwrap().?); |
| 1721 | }, | 1811 | }, |
| 1722 | .node_offset_ptr_bitoffset => |node_off| { | 1812 | .node_offset_ptr_bitoffset => |node_off| { |
| 1723 | const tree = try src_loc.file_scope.getTree(gpa); | 1813 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1724 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1814 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1725 | 1815 | ||
| 1726 | const full = tree.fullPtrType(parent_node).?; | 1816 | const full = tree.fullPtrType(parent_node).?; |
| 1727 | return tree.nodeToSpan(full.ast.bit_range_start.unwrap().?); | 1817 | return tree.nodeToSpan(full.ast.bit_range_start.unwrap().?); |
| 1728 | }, | 1818 | }, |
| 1729 | .node_offset_ptr_hostsize => |node_off| { | 1819 | .node_offset_ptr_hostsize => |node_off| { |
| 1730 | const tree = try src_loc.file_scope.getTree(gpa); | 1820 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1731 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1821 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1732 | 1822 | ||
| 1733 | const full = tree.fullPtrType(parent_node).?; | 1823 | const full = tree.fullPtrType(parent_node).?; |
| 1734 | return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?); | 1824 | return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?); |
| 1735 | }, | 1825 | }, |
| 1736 | .node_offset_container_tag => |node_off| { | 1826 | .node_offset_container_tag => |node_off| { |
| 1737 | const tree = try src_loc.file_scope.getTree(gpa); | 1827 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1738 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1828 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1739 | 1829 | ||
| 1740 | switch (tree.nodeTag(parent_node)) { | 1830 | switch (tree.nodeTag(parent_node)) { |
| ... | @@ -1757,7 +1847,7 @@ pub const SrcLoc = struct { | ... | @@ -1757,7 +1847,7 @@ pub const SrcLoc = struct { |
| 1757 | } | 1847 | } |
| 1758 | }, | 1848 | }, |
| 1759 | .node_offset_field_default => |node_off| { | 1849 | .node_offset_field_default => |node_off| { |
| 1760 | const tree = try src_loc.file_scope.getTree(gpa); | 1850 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1761 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1851 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1762 | 1852 | ||
| 1763 | const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) { | 1853 | const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) { |
| ... | @@ -1768,7 +1858,7 @@ pub const SrcLoc = struct { | ... | @@ -1768,7 +1858,7 @@ pub const SrcLoc = struct { |
| 1768 | return tree.nodeToSpan(full.ast.value_expr.unwrap().?); | 1858 | return tree.nodeToSpan(full.ast.value_expr.unwrap().?); |
| 1769 | }, | 1859 | }, |
| 1770 | .node_offset_init_ty => |node_off| { | 1860 | .node_offset_init_ty => |node_off| { |
| 1771 | const tree = try src_loc.file_scope.getTree(gpa); | 1861 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1772 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1862 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1773 | 1863 | ||
| 1774 | var buf: [2]Ast.Node.Index = undefined; | 1864 | var buf: [2]Ast.Node.Index = undefined; |
| ... | @@ -1779,7 +1869,7 @@ pub const SrcLoc = struct { | ... | @@ -1779,7 +1869,7 @@ pub const SrcLoc = struct { |
| 1779 | return tree.nodeToSpan(type_expr); | 1869 | return tree.nodeToSpan(type_expr); |
| 1780 | }, | 1870 | }, |
| 1781 | .node_offset_store_ptr => |node_off| { | 1871 | .node_offset_store_ptr => |node_off| { |
| 1782 | const tree = try src_loc.file_scope.getTree(gpa); | 1872 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1783 | const node = node_off.toAbsolute(src_loc.base_node); | 1873 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1784 | 1874 | ||
| 1785 | switch (tree.nodeTag(node)) { | 1875 | switch (tree.nodeTag(node)) { |
| ... | @@ -1806,7 +1896,7 @@ pub const SrcLoc = struct { | ... | @@ -1806,7 +1896,7 @@ pub const SrcLoc = struct { |
| 1806 | } | 1896 | } |
| 1807 | }, | 1897 | }, |
| 1808 | .node_offset_store_operand => |node_off| { | 1898 | .node_offset_store_operand => |node_off| { |
| 1809 | const tree = try src_loc.file_scope.getTree(gpa); | 1899 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1810 | const node = node_off.toAbsolute(src_loc.base_node); | 1900 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1811 | 1901 | ||
| 1812 | switch (tree.nodeTag(node)) { | 1902 | switch (tree.nodeTag(node)) { |
| ... | @@ -1833,7 +1923,7 @@ pub const SrcLoc = struct { | ... | @@ -1833,7 +1923,7 @@ pub const SrcLoc = struct { |
| 1833 | } | 1923 | } |
| 1834 | }, | 1924 | }, |
| 1835 | .node_offset_return_operand => |node_off| { | 1925 | .node_offset_return_operand => |node_off| { |
| 1836 | const tree = try src_loc.file_scope.getTree(gpa); | 1926 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1837 | const node = node_off.toAbsolute(src_loc.base_node); | 1927 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1838 | if (tree.nodeTag(node) == .@"return") { | 1928 | if (tree.nodeTag(node) == .@"return") { |
| 1839 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { | 1929 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { |
| ... | @@ -1847,7 +1937,7 @@ pub const SrcLoc = struct { | ... | @@ -1847,7 +1937,7 @@ pub const SrcLoc = struct { |
| 1847 | .container_field_type, | 1937 | .container_field_type, |
| 1848 | .container_field_align, | 1938 | .container_field_align, |
| 1849 | => |field_idx| { | 1939 | => |field_idx| { |
| 1850 | const tree = try src_loc.file_scope.getTree(gpa); | 1940 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1851 | const node = src_loc.base_node; | 1941 | const node = src_loc.base_node; |
| 1852 | var buf: [2]Ast.Node.Index = undefined; | 1942 | var buf: [2]Ast.Node.Index = undefined; |
| 1853 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1943 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| ... | @@ -1875,7 +1965,7 @@ pub const SrcLoc = struct { | ... | @@ -1875,7 +1965,7 @@ pub const SrcLoc = struct { |
| 1875 | } else unreachable; | 1965 | } else unreachable; |
| 1876 | }, | 1966 | }, |
| 1877 | .tuple_field_type, .tuple_field_init => |field_info| { | 1967 | .tuple_field_type, .tuple_field_init => |field_info| { |
| 1878 | const tree = try src_loc.file_scope.getTree(gpa); | 1968 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1879 | const node = src_loc.base_node; | 1969 | const node = src_loc.base_node; |
| 1880 | var buf: [2]Ast.Node.Index = undefined; | 1970 | var buf: [2]Ast.Node.Index = undefined; |
| 1881 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1971 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| ... | @@ -1889,7 +1979,7 @@ pub const SrcLoc = struct { | ... | @@ -1889,7 +1979,7 @@ pub const SrcLoc = struct { |
| 1889 | }); | 1979 | }); |
| 1890 | }, | 1980 | }, |
| 1891 | .init_elem => |init_elem| { | 1981 | .init_elem => |init_elem| { |
| 1892 | const tree = try src_loc.file_scope.getTree(gpa); | 1982 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1893 | const init_node = init_elem.init_node_offset.toAbsolute(src_loc.base_node); | 1983 | const init_node = init_elem.init_node_offset.toAbsolute(src_loc.base_node); |
| 1894 | var buf: [2]Ast.Node.Index = undefined; | 1984 | var buf: [2]Ast.Node.Index = undefined; |
| 1895 | if (tree.fullArrayInit(&buf, init_node)) |full| { | 1985 | if (tree.fullArrayInit(&buf, init_node)) |full| { |
| ... | @@ -1928,7 +2018,7 @@ pub const SrcLoc = struct { | ... | @@ -1928,7 +2018,7 @@ pub const SrcLoc = struct { |
| 1928 | .init_field_dll_import => "dll_import", | 2018 | .init_field_dll_import => "dll_import", |
| 1929 | else => unreachable, | 2019 | else => unreachable, |
| 1930 | }; | 2020 | }; |
| 1931 | const tree = try src_loc.file_scope.getTree(gpa); | 2021 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1932 | const node = builtin_call_node.toAbsolute(src_loc.base_node); | 2022 | const node = builtin_call_node.toAbsolute(src_loc.base_node); |
| 1933 | var builtin_buf: [2]Ast.Node.Index = undefined; | 2023 | var builtin_buf: [2]Ast.Node.Index = undefined; |
| 1934 | const args = tree.builtinCallParams(&builtin_buf, node).?; | 2024 | const args = tree.builtinCallParams(&builtin_buf, node).?; |
| ... | @@ -1967,7 +2057,7 @@ pub const SrcLoc = struct { | ... | @@ -1967,7 +2057,7 @@ pub const SrcLoc = struct { |
| 1967 | else => unreachable, | 2057 | else => unreachable, |
| 1968 | }; | 2058 | }; |
| 1969 | 2059 | ||
| 1970 | const tree = try src_loc.file_scope.getTree(gpa); | 2060 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1971 | const switch_node = switch_node_offset.toAbsolute(src_loc.base_node); | 2061 | const switch_node = switch_node_offset.toAbsolute(src_loc.base_node); |
| 1972 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; | 2062 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1973 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); | 2063 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| ... | @@ -2062,7 +2152,7 @@ pub const SrcLoc = struct { | ... | @@ -2062,7 +2152,7 @@ pub const SrcLoc = struct { |
| 2062 | } | 2152 | } |
| 2063 | }, | 2153 | }, |
| 2064 | .func_decl_param_comptime => |param_idx| { | 2154 | .func_decl_param_comptime => |param_idx| { |
| 2065 | const tree = try src_loc.file_scope.getTree(gpa); | 2155 | const tree = try src_loc.file_scope.getTree(zcu); |
| 2066 | var buf: [1]Ast.Node.Index = undefined; | 2156 | var buf: [1]Ast.Node.Index = undefined; |
| 2067 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; | 2157 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; |
| 2068 | var param_it = full.iterate(tree); | 2158 | var param_it = full.iterate(tree); |
| ... | @@ -2071,7 +2161,7 @@ pub const SrcLoc = struct { | ... | @@ -2071,7 +2161,7 @@ pub const SrcLoc = struct { |
| 2071 | return tree.tokenToSpan(param.comptime_noalias.?); | 2161 | return tree.tokenToSpan(param.comptime_noalias.?); |
| 2072 | }, | 2162 | }, |
| 2073 | .func_decl_param_ty => |param_idx| { | 2163 | .func_decl_param_ty => |param_idx| { |
| 2074 | const tree = try src_loc.file_scope.getTree(gpa); | 2164 | const tree = try src_loc.file_scope.getTree(zcu); |
| 2075 | var buf: [1]Ast.Node.Index = undefined; | 2165 | var buf: [1]Ast.Node.Index = undefined; |
| 2076 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; | 2166 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; |
| 2077 | var param_it = full.iterate(tree); | 2167 | var param_it = full.iterate(tree); |
| ... | @@ -2100,9 +2190,6 @@ pub const LazySrcLoc = struct { | ... | @@ -2100,9 +2190,6 @@ pub const LazySrcLoc = struct { |
| 2100 | /// value is being set to this tag. | 2190 | /// value is being set to this tag. |
| 2101 | /// `base_node_inst` is unused. | 2191 | /// `base_node_inst` is unused. |
| 2102 | unneeded, | 2192 | unneeded, |
| 2103 | /// Means the source location points to an entire file; not any particular | ||
| 2104 | /// location within the file. `file_scope` union field will be active. | ||
| 2105 | entire_file, | ||
| 2106 | /// The source location points to a byte offset within a source file, | 2193 | /// The source location points to a byte offset within a source file, |
| 2107 | /// offset from 0. The source file is determined contextually. | 2194 | /// offset from 0. The source file is determined contextually. |
| 2108 | byte_abs: u32, | 2195 | byte_abs: u32, |
| ... | @@ -2521,10 +2608,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2521,10 +2608,7 @@ pub const LazySrcLoc = struct { |
| 2521 | 2608 | ||
| 2522 | /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates. | 2609 | /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates. |
| 2523 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { | 2610 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { |
| 2524 | const file, const base_node: Ast.Node.Index = if (lazy.offset == .entire_file) .{ | 2611 | const file, const base_node: Ast.Node.Index = resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; |
| 2525 | zcu.fileByIndex(lazy.base_node_inst.resolveFile(&zcu.intern_pool)), | ||
| 2526 | .root, | ||
| 2527 | } else resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; | ||
| 2528 | return .{ | 2612 | return .{ |
| 2529 | .file_scope = file, | 2613 | .file_scope = file, |
| 2530 | .base_node = base_node, | 2614 | .base_node = base_node, |
| ... | @@ -2544,15 +2628,16 @@ pub const LazySrcLoc = struct { | ... | @@ -2544,15 +2628,16 @@ pub const LazySrcLoc = struct { |
| 2544 | return true; | 2628 | return true; |
| 2545 | }; | 2629 | }; |
| 2546 | if (lhs_src.file_scope != rhs_src.file_scope) { | 2630 | if (lhs_src.file_scope != rhs_src.file_scope) { |
| 2547 | return std.mem.order( | 2631 | const lhs_path = lhs_src.file_scope.path; |
| 2548 | u8, | 2632 | const rhs_path = rhs_src.file_scope.path; |
| 2549 | lhs_src.file_scope.sub_file_path, | 2633 | if (lhs_path.root != rhs_path.root) { |
| 2550 | rhs_src.file_scope.sub_file_path, | 2634 | return @intFromEnum(lhs_path.root) < @intFromEnum(rhs_path.root); |
| 2551 | ).compare(.lt); | 2635 | } |
| 2636 | return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt); | ||
| 2552 | } | 2637 | } |
| 2553 | 2638 | ||
| 2554 | const lhs_span = try lhs_src.span(zcu.gpa); | 2639 | const lhs_span = try lhs_src.span(zcu); |
| 2555 | const rhs_span = try rhs_src.span(zcu.gpa); | 2640 | const rhs_span = try rhs_src.span(zcu); |
| 2556 | return lhs_span.main < rhs_span.main; | 2641 | return lhs_span.main < rhs_span.main; |
| 2557 | } | 2642 | } |
| 2558 | }; | 2643 | }; |
| ... | @@ -2583,16 +2668,16 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2583,16 +2668,16 @@ pub fn deinit(zcu: *Zcu) void { |
| 2583 | 2668 | ||
| 2584 | if (zcu.llvm_object) |llvm_object| llvm_object.deinit(); | 2669 | if (zcu.llvm_object) |llvm_object| llvm_object.deinit(); |
| 2585 | 2670 | ||
| 2586 | for (zcu.import_table.keys()) |key| { | 2671 | zcu.builtin_modules.deinit(gpa); |
| 2587 | gpa.free(key); | 2672 | zcu.module_roots.deinit(gpa); |
| 2588 | } | 2673 | for (zcu.import_table.keys()) |file_index| { |
| 2589 | for (zcu.import_table.values()) |file_index| { | ||
| 2590 | pt.destroyFile(file_index); | 2674 | pt.destroyFile(file_index); |
| 2591 | } | 2675 | } |
| 2592 | zcu.import_table.deinit(gpa); | 2676 | zcu.import_table.deinit(gpa); |
| 2677 | zcu.alive_files.deinit(gpa); | ||
| 2593 | 2678 | ||
| 2594 | for (zcu.embed_table.keys(), zcu.embed_table.values()) |path, embed_file| { | 2679 | for (zcu.embed_table.keys()) |embed_file| { |
| 2595 | gpa.free(path); | 2680 | embed_file.path.deinit(gpa); |
| 2596 | gpa.destroy(embed_file); | 2681 | gpa.destroy(embed_file); |
| 2597 | } | 2682 | } |
| 2598 | zcu.embed_table.deinit(gpa); | 2683 | zcu.embed_table.deinit(gpa); |
| ... | @@ -2610,9 +2695,10 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2610,9 +2695,10 @@ pub fn deinit(zcu: *Zcu) void { |
| 2610 | zcu.failed_types.deinit(gpa); | 2695 | zcu.failed_types.deinit(gpa); |
| 2611 | 2696 | ||
| 2612 | for (zcu.failed_files.values()) |value| { | 2697 | for (zcu.failed_files.values()) |value| { |
| 2613 | if (value) |msg| msg.destroy(gpa); | 2698 | if (value) |msg| gpa.free(msg); |
| 2614 | } | 2699 | } |
| 2615 | zcu.failed_files.deinit(gpa); | 2700 | zcu.failed_files.deinit(gpa); |
| 2701 | zcu.failed_imports.deinit(gpa); | ||
| 2616 | 2702 | ||
| 2617 | for (zcu.failed_exports.values()) |value| { | 2703 | for (zcu.failed_exports.values()) |value| { |
| 2618 | value.destroy(gpa); | 2704 | value.destroy(gpa); |
| ... | @@ -3404,27 +3490,21 @@ pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void | ... | @@ -3404,27 +3490,21 @@ pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void |
| 3404 | zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {}); | 3490 | zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {}); |
| 3405 | } | 3491 | } |
| 3406 | 3492 | ||
| 3407 | pub const ImportFileResult = struct { | 3493 | pub const ImportResult = struct { |
| 3408 | file: *File, | 3494 | /// Whether `file` has been newly created; in other words, whether this is the first import of |
| 3409 | file_index: File.Index, | 3495 | /// this file. This should only be `true` when importing files during AstGen. After that, all |
| 3496 | /// files should have already been discovered. | ||
| 3410 | is_new: bool, | 3497 | is_new: bool, |
| 3411 | is_pkg: bool, | ||
| 3412 | }; | ||
| 3413 | 3498 | ||
| 3414 | pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { | 3499 | /// `file.mod` is not populated by this function, so if `is_new`, then it is `undefined`. |
| 3415 | const want_local_cache = mod == zcu.main_mod; | 3500 | file: *Zcu.File, |
| 3416 | var path_hash: Cache.HashHelper = .{}; | 3501 | file_index: File.Index, |
| 3417 | path_hash.addBytes(build_options.version); | 3502 | |
| 3418 | path_hash.add(builtin.zig_backend); | 3503 | /// If this import was a simple file path, this is `null`; the imported file should exist within |
| 3419 | if (!want_local_cache) { | 3504 | /// the importer's module. Otherwise, it's the module which the import resolved to. This module |
| 3420 | path_hash.addOptionalBytes(mod.root.root_dir.path); | 3505 | /// could match the module of `cur_file`, since a module can depend on itself. |
| 3421 | path_hash.addBytes(mod.root.sub_path); | 3506 | module: ?*Package.Module, |
| 3422 | } | 3507 | }; |
| 3423 | path_hash.addBytes(sub_file_path); | ||
| 3424 | var bin: Cache.BinDigest = undefined; | ||
| 3425 | path_hash.hasher.final(&bin); | ||
| 3426 | return bin; | ||
| 3427 | } | ||
| 3428 | 3508 | ||
| 3429 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of | 3509 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of |
| 3430 | /// this `AnalUnit` will cause them to be re-created (or not). | 3510 | /// this `AnalUnit` will cause them to be re-created (or not). |
| ... | @@ -3938,15 +4018,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv | ... | @@ -3938,15 +4018,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 3938 | 4018 | ||
| 3939 | try type_queue.ensureTotalCapacity(gpa, zcu.analysis_roots.len); | 4019 | try type_queue.ensureTotalCapacity(gpa, zcu.analysis_roots.len); |
| 3940 | for (zcu.analysis_roots.slice()) |mod| { | 4020 | for (zcu.analysis_roots.slice()) |mod| { |
| 3941 | // Logic ripped from `Zcu.PerThread.importPkg`. | 4021 | const file = zcu.module_roots.get(mod).?.unwrap() orelse continue; |
| 3942 | // TODO: this is silly, `Module` should just store a reference to its root `File`. | ||
| 3943 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 3944 | mod.root.root_dir.path orelse ".", | ||
| 3945 | mod.root.sub_path, | ||
| 3946 | mod.root_src_path, | ||
| 3947 | }); | ||
| 3948 | defer gpa.free(resolved_path); | ||
| 3949 | const file = zcu.import_table.get(resolved_path).?; | ||
| 3950 | const root_ty = zcu.fileRootType(file); | 4022 | const root_ty = zcu.fileRootType(file); |
| 3951 | if (root_ty == .none) continue; | 4023 | if (root_ty == .none) continue; |
| 3952 | type_queue.putAssumeCapacityNoClobber(root_ty, null); | 4024 | type_queue.putAssumeCapacityNoClobber(root_ty, null); |
| ... | @@ -4226,8 +4298,8 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co | ... | @@ -4226,8 +4298,8 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co |
| 4226 | .@"comptime" => |cu_id| { | 4298 | .@"comptime" => |cu_id| { |
| 4227 | const cu = ip.getComptimeUnit(cu_id); | 4299 | const cu = ip.getComptimeUnit(cu_id); |
| 4228 | if (cu.zir_index.resolveFull(ip)) |resolved| { | 4300 | if (cu.zir_index.resolveFull(ip)) |resolved| { |
| 4229 | const file_path = zcu.fileByIndex(resolved.file).sub_file_path; | 4301 | const file_path = zcu.fileByIndex(resolved.file).path; |
| 4230 | return writer.print("comptime(inst=('{s}', %{}) [{}])", .{ file_path, @intFromEnum(resolved.inst), @intFromEnum(cu_id) }); | 4302 | return writer.print("comptime(inst=('{}', %{}) [{}])", .{ file_path.fmt(zcu.comp), @intFromEnum(resolved.inst), @intFromEnum(cu_id) }); |
| 4231 | } else { | 4303 | } else { |
| 4232 | return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)}); | 4304 | return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)}); |
| 4233 | } | 4305 | } |
| ... | @@ -4251,8 +4323,8 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com | ... | @@ -4251,8 +4323,8 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com |
| 4251 | const info = ti.resolveFull(ip) orelse { | 4323 | const info = ti.resolveFull(ip) orelse { |
| 4252 | return writer.writeAll("inst(<lost>)"); | 4324 | return writer.writeAll("inst(<lost>)"); |
| 4253 | }; | 4325 | }; |
| 4254 | const file_path = zcu.fileByIndex(info.file).sub_file_path; | 4326 | const file_path = zcu.fileByIndex(info.file).path; |
| 4255 | return writer.print("inst('{s}', %{d})", .{ file_path, @intFromEnum(info.inst) }); | 4327 | return writer.print("inst('{}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) }); |
| 4256 | }, | 4328 | }, |
| 4257 | .nav_val => |nav| { | 4329 | .nav_val => |nav| { |
| 4258 | const fqn = ip.getNav(nav).fqn; | 4330 | const fqn = ip.getNav(nav).fqn; |
| ... | @@ -4268,30 +4340,26 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com | ... | @@ -4268,30 +4340,26 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com |
| 4268 | else => unreachable, | 4340 | else => unreachable, |
| 4269 | }, | 4341 | }, |
| 4270 | .zon_file => |file| { | 4342 | .zon_file => |file| { |
| 4271 | const file_path = zcu.fileByIndex(file).sub_file_path; | 4343 | const file_path = zcu.fileByIndex(file).path; |
| 4272 | return writer.print("zon_file('{s}')", .{file_path}); | 4344 | return writer.print("zon_file('{}')", .{file_path.fmt(zcu.comp)}); |
| 4273 | }, | 4345 | }, |
| 4274 | .embed_file => |ef_idx| { | 4346 | .embed_file => |ef_idx| { |
| 4275 | const ef = ef_idx.get(zcu); | 4347 | const ef = ef_idx.get(zcu); |
| 4276 | return writer.print("embed_file('{s}')", .{std.fs.path.fmtJoin(&.{ | 4348 | return writer.print("embed_file('{}')", .{ef.path.fmt(zcu.comp)}); |
| 4277 | ef.owner.root.root_dir.path orelse "", | ||
| 4278 | ef.owner.root.sub_path, | ||
| 4279 | ef.sub_file_path.toSlice(ip), | ||
| 4280 | })}); | ||
| 4281 | }, | 4349 | }, |
| 4282 | .namespace => |ti| { | 4350 | .namespace => |ti| { |
| 4283 | const info = ti.resolveFull(ip) orelse { | 4351 | const info = ti.resolveFull(ip) orelse { |
| 4284 | return writer.writeAll("namespace(<lost>)"); | 4352 | return writer.writeAll("namespace(<lost>)"); |
| 4285 | }; | 4353 | }; |
| 4286 | const file_path = zcu.fileByIndex(info.file).sub_file_path; | 4354 | const file_path = zcu.fileByIndex(info.file).path; |
| 4287 | return writer.print("namespace('{s}', %{d})", .{ file_path, @intFromEnum(info.inst) }); | 4355 | return writer.print("namespace('{}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) }); |
| 4288 | }, | 4356 | }, |
| 4289 | .namespace_name => |k| { | 4357 | .namespace_name => |k| { |
| 4290 | const info = k.namespace.resolveFull(ip) orelse { | 4358 | const info = k.namespace.resolveFull(ip) orelse { |
| 4291 | return writer.print("namespace(<lost>, '{}')", .{k.name.fmt(ip)}); | 4359 | return writer.print("namespace(<lost>, '{}')", .{k.name.fmt(ip)}); |
| 4292 | }; | 4360 | }; |
| 4293 | const file_path = zcu.fileByIndex(info.file).sub_file_path; | 4361 | const file_path = zcu.fileByIndex(info.file).path; |
| 4294 | return writer.print("namespace('{s}', %{d}, '{}')", .{ file_path, @intFromEnum(info.inst), k.name.fmt(ip) }); | 4362 | return writer.print("namespace('{}', %{d}, '{}')", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst), k.name.fmt(ip) }); |
| 4295 | }, | 4363 | }, |
| 4296 | .memoized_state => return writer.writeAll("memoized_state"), | 4364 | .memoized_state => return writer.writeAll("memoized_state"), |
| 4297 | } | 4365 | } |
| ... | @@ -4508,3 +4576,114 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) | ... | @@ -4508,3 +4576,114 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) |
| 4508 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); | 4576 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4509 | return error.CodegenFail; | 4577 | return error.CodegenFail; |
| 4510 | } | 4578 | } |
| 4579 | |||
| 4580 | /// Asserts that `zcu.multi_module_err != null`. | ||
| 4581 | pub fn addFileInMultipleModulesError( | ||
| 4582 | zcu: *Zcu, | ||
| 4583 | eb: *std.zig.ErrorBundle.Wip, | ||
| 4584 | ) !void { | ||
| 4585 | const gpa = zcu.gpa; | ||
| 4586 | |||
| 4587 | const info = zcu.multi_module_err.?; | ||
| 4588 | const file = info.file; | ||
| 4589 | |||
| 4590 | // error: file exists in modules 'root.foo' and 'root.bar' | ||
| 4591 | // note: files must belong to only one module | ||
| 4592 | // note: file is imported here | ||
| 4593 | // note: which is imported here | ||
| 4594 | // note: which is the root of module 'root.foo' imported here | ||
| 4595 | // note: file is the root of module 'root.bar' imported here | ||
| 4596 | |||
| 4597 | const file_src = try zcu.fileByIndex(file).errorBundleWholeFileSrc(zcu, eb); | ||
| 4598 | const root_msg = try eb.printString("file exists in modules '{s}' and '{s}'", .{ | ||
| 4599 | info.modules[0].fully_qualified_name, | ||
| 4600 | info.modules[1].fully_qualified_name, | ||
| 4601 | }); | ||
| 4602 | |||
| 4603 | var notes: std.ArrayListUnmanaged(std.zig.ErrorBundle.MessageIndex) = .empty; | ||
| 4604 | defer notes.deinit(gpa); | ||
| 4605 | |||
| 4606 | try notes.append(gpa, try eb.addErrorMessage(.{ | ||
| 4607 | .msg = try eb.addString("files must belong to only one module"), | ||
| 4608 | .src_loc = file_src, | ||
| 4609 | })); | ||
| 4610 | |||
| 4611 | try zcu.explainWhyFileIsInModule(eb, &notes, file, info.modules[0], info.refs[0]); | ||
| 4612 | try zcu.explainWhyFileIsInModule(eb, &notes, file, info.modules[1], info.refs[1]); | ||
| 4613 | |||
| 4614 | try eb.addRootErrorMessage(.{ | ||
| 4615 | .msg = root_msg, | ||
| 4616 | .src_loc = file_src, | ||
| 4617 | .notes_len = @intCast(notes.items.len), | ||
| 4618 | }); | ||
| 4619 | const notes_start = try eb.reserveNotes(@intCast(notes.items.len)); | ||
| 4620 | const notes_slice: []std.zig.ErrorBundle.MessageIndex = @ptrCast(eb.extra.items[notes_start..]); | ||
| 4621 | @memcpy(notes_slice, notes.items); | ||
| 4622 | } | ||
| 4623 | |||
| 4624 | fn explainWhyFileIsInModule( | ||
| 4625 | zcu: *Zcu, | ||
| 4626 | eb: *std.zig.ErrorBundle.Wip, | ||
| 4627 | notes_out: *std.ArrayListUnmanaged(std.zig.ErrorBundle.MessageIndex), | ||
| 4628 | file: File.Index, | ||
| 4629 | in_module: *Package.Module, | ||
| 4630 | ref: File.Reference, | ||
| 4631 | ) !void { | ||
| 4632 | const gpa = zcu.gpa; | ||
| 4633 | |||
| 4634 | // error: file is the root of module 'foo' | ||
| 4635 | // | ||
| 4636 | // error: file is imported here by the root of module 'foo' | ||
| 4637 | // | ||
| 4638 | // error: file is imported here | ||
| 4639 | // note: which is imported here | ||
| 4640 | // note: which is imported here by the root of module 'foo' | ||
| 4641 | |||
| 4642 | var import = switch (ref) { | ||
| 4643 | .analysis_root => |mod| { | ||
| 4644 | assert(mod == in_module); | ||
| 4645 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4646 | .msg = try eb.printString("file is the root of module '{s}'", .{mod.fully_qualified_name}), | ||
| 4647 | .src_loc = try zcu.fileByIndex(file).errorBundleWholeFileSrc(zcu, eb), | ||
| 4648 | })); | ||
| 4649 | return; | ||
| 4650 | }, | ||
| 4651 | .import => |import| if (import.module) |mod| { | ||
| 4652 | assert(mod == in_module); | ||
| 4653 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4654 | .msg = try eb.printString("file is the root of module '{s}'", .{mod.fully_qualified_name}), | ||
| 4655 | .src_loc = try zcu.fileByIndex(file).errorBundleWholeFileSrc(zcu, eb), | ||
| 4656 | })); | ||
| 4657 | return; | ||
| 4658 | } else import, | ||
| 4659 | }; | ||
| 4660 | |||
| 4661 | var is_first = true; | ||
| 4662 | while (true) { | ||
| 4663 | const thing: []const u8 = if (is_first) "file" else "which"; | ||
| 4664 | is_first = false; | ||
| 4665 | |||
| 4666 | const import_src = try zcu.fileByIndex(import.importer).errorBundleTokenSrc(import.tok, zcu, eb); | ||
| 4667 | |||
| 4668 | const importer_ref = zcu.alive_files.get(import.importer).?; | ||
| 4669 | const importer_root: ?*Package.Module = switch (importer_ref) { | ||
| 4670 | .analysis_root => |mod| mod, | ||
| 4671 | .import => |i| i.module, | ||
| 4672 | }; | ||
| 4673 | |||
| 4674 | if (importer_root) |m| { | ||
| 4675 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4676 | .msg = try eb.printString("{s} is imported here by the root of module '{s}'", .{ thing, m.fully_qualified_name }), | ||
| 4677 | .src_loc = import_src, | ||
| 4678 | })); | ||
| 4679 | return; | ||
| 4680 | } | ||
| 4681 | |||
| 4682 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4683 | .msg = try eb.printString("{s} is imported here", .{thing}), | ||
| 4684 | .src_loc = import_src, | ||
| 4685 | })); | ||
| 4686 | |||
| 4687 | import = importer_ref.import; | ||
| 4688 | } | ||
| 4689 | } |
src/Zcu/PerThread.zig+529-334| ... | @@ -8,23 +8,26 @@ const Ast = std.zig.Ast; | ... | @@ -8,23 +8,26 @@ const Ast = std.zig.Ast; |
| 8 | const AstGen = std.zig.AstGen; | 8 | const AstGen = std.zig.AstGen; |
| 9 | const BigIntConst = std.math.big.int.Const; | 9 | const BigIntConst = std.math.big.int.Const; |
| 10 | const BigIntMutable = std.math.big.int.Mutable; | 10 | const BigIntMutable = std.math.big.int.Mutable; |
| 11 | const Builtin = @import("../Builtin.zig"); | ||
| 11 | const build_options = @import("build_options"); | 12 | const build_options = @import("build_options"); |
| 12 | const builtin = @import("builtin"); | 13 | const builtin = @import("builtin"); |
| 13 | const Cache = std.Build.Cache; | 14 | const Cache = std.Build.Cache; |
| 14 | const dev = @import("../dev.zig"); | 15 | const dev = @import("../dev.zig"); |
| 15 | const InternPool = @import("../InternPool.zig"); | 16 | const InternPool = @import("../InternPool.zig"); |
| 16 | const AnalUnit = InternPool.AnalUnit; | 17 | const AnalUnit = InternPool.AnalUnit; |
| 17 | const isUpDir = @import("../introspect.zig").isUpDir; | 18 | const introspect = @import("../introspect.zig"); |
| 18 | const Liveness = @import("../Liveness.zig"); | 19 | const Liveness = @import("../Liveness.zig"); |
| 19 | const log = std.log.scoped(.zcu); | 20 | const log = std.log.scoped(.zcu); |
| 20 | const Module = @import("../Package.zig").Module; | 21 | const Module = @import("../Package.zig").Module; |
| 21 | const Sema = @import("../Sema.zig"); | 22 | const Sema = @import("../Sema.zig"); |
| 22 | const std = @import("std"); | 23 | const std = @import("std"); |
| 24 | const mem = std.mem; | ||
| 23 | const target_util = @import("../target.zig"); | 25 | const target_util = @import("../target.zig"); |
| 24 | const trace = @import("../tracy.zig").trace; | 26 | const trace = @import("../tracy.zig").trace; |
| 25 | const Type = @import("../Type.zig"); | 27 | const Type = @import("../Type.zig"); |
| 26 | const Value = @import("../Value.zig"); | 28 | const Value = @import("../Value.zig"); |
| 27 | const Zcu = @import("../Zcu.zig"); | 29 | const Zcu = @import("../Zcu.zig"); |
| 30 | const Compilation = @import("../Compilation.zig"); | ||
| 28 | const Zir = std.zig.Zir; | 31 | const Zir = std.zig.Zir; |
| 29 | const Zoir = std.zig.Zoir; | 32 | const Zoir = std.zig.Zoir; |
| 30 | const ZonGen = std.zig.ZonGen; | 33 | const ZonGen = std.zig.ZonGen; |
| ... | @@ -50,16 +53,9 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | ... | @@ -50,16 +53,9 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { |
| 50 | const zcu = pt.zcu; | 53 | const zcu = pt.zcu; |
| 51 | const gpa = zcu.gpa; | 54 | const gpa = zcu.gpa; |
| 52 | const file = zcu.fileByIndex(file_index); | 55 | const file = zcu.fileByIndex(file_index); |
| 53 | const is_builtin = file.mod.isBuiltin(); | 56 | log.debug("deinit File {}", .{file.path.fmt(zcu.comp)}); |
| 54 | log.debug("deinit File {s}", .{file.sub_file_path}); | 57 | file.path.deinit(gpa); |
| 55 | if (is_builtin) { | 58 | file.unload(gpa); |
| 56 | file.unloadTree(gpa); | ||
| 57 | file.unloadZir(gpa); | ||
| 58 | } else { | ||
| 59 | gpa.free(file.sub_file_path); | ||
| 60 | file.unload(gpa); | ||
| 61 | } | ||
| 62 | file.references.deinit(gpa); | ||
| 63 | if (file.prev_zir) |prev_zir| { | 59 | if (file.prev_zir) |prev_zir| { |
| 64 | prev_zir.deinit(gpa); | 60 | prev_zir.deinit(gpa); |
| 65 | gpa.destroy(prev_zir); | 61 | gpa.destroy(prev_zir); |
| ... | @@ -70,20 +66,19 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | ... | @@ -70,20 +66,19 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { |
| 70 | pub fn destroyFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | 66 | pub fn destroyFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { |
| 71 | const gpa = pt.zcu.gpa; | 67 | const gpa = pt.zcu.gpa; |
| 72 | const file = pt.zcu.fileByIndex(file_index); | 68 | const file = pt.zcu.fileByIndex(file_index); |
| 73 | const is_builtin = file.mod.isBuiltin(); | ||
| 74 | pt.deinitFile(file_index); | 69 | pt.deinitFile(file_index); |
| 75 | if (!is_builtin) gpa.destroy(file); | 70 | gpa.destroy(file); |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | /// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs | 73 | /// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs |
| 79 | /// AstGen as needed. Also updates `file.status`. | 74 | /// AstGen as needed. Also updates `file.status`. Does not assume that `file.mod` |
| 75 | /// is populated. Does not return `error.AnalysisFail` on AstGen failures. | ||
| 80 | pub fn updateFile( | 76 | pub fn updateFile( |
| 81 | pt: Zcu.PerThread, | 77 | pt: Zcu.PerThread, |
| 78 | file_index: Zcu.File.Index, | ||
| 82 | file: *Zcu.File, | 79 | file: *Zcu.File, |
| 83 | path_digest: Cache.BinDigest, | ||
| 84 | ) !void { | 80 | ) !void { |
| 85 | dev.check(.ast_gen); | 81 | dev.check(.ast_gen); |
| 86 | assert(!file.mod.isBuiltin()); | ||
| 87 | 82 | ||
| 88 | const tracy = trace(@src()); | 83 | const tracy = trace(@src()); |
| 89 | defer tracy.end(); | 84 | defer tracy.end(); |
| ... | @@ -93,13 +88,20 @@ pub fn updateFile( | ... | @@ -93,13 +88,20 @@ pub fn updateFile( |
| 93 | const gpa = zcu.gpa; | 88 | const gpa = zcu.gpa; |
| 94 | 89 | ||
| 95 | // In any case we need to examine the stat of the file to determine the course of action. | 90 | // In any case we need to examine the stat of the file to determine the course of action. |
| 96 | var source_file = try file.mod.root.openFile(file.sub_file_path, .{}); | 91 | var source_file = f: { |
| 92 | const dir, const sub_path = file.path.openInfo(comp.dirs); | ||
| 93 | break :f try dir.openFile(sub_path, .{}); | ||
| 94 | }; | ||
| 97 | defer source_file.close(); | 95 | defer source_file.close(); |
| 98 | 96 | ||
| 99 | const stat = try source_file.stat(); | 97 | const stat = try source_file.stat(); |
| 100 | 98 | ||
| 101 | const want_local_cache = file.mod == zcu.main_mod; | 99 | const want_local_cache = switch (file.path.root) { |
| 102 | const hex_digest = Cache.binToHex(path_digest); | 100 | .none, .local_cache => true, |
| 101 | .global_cache, .zig_lib => false, | ||
| 102 | }; | ||
| 103 | |||
| 104 | const hex_digest = Cache.binToHex(file.path.digest()); | ||
| 103 | const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache; | 105 | const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache; |
| 104 | const zir_dir = cache_directory.handle; | 106 | const zir_dir = cache_directory.handle; |
| 105 | 107 | ||
| ... | @@ -107,8 +109,8 @@ pub fn updateFile( | ... | @@ -107,8 +109,8 @@ pub fn updateFile( |
| 107 | var lock: std.fs.File.Lock = switch (file.status) { | 109 | var lock: std.fs.File.Lock = switch (file.status) { |
| 108 | .never_loaded, .retryable_failure => lock: { | 110 | .never_loaded, .retryable_failure => lock: { |
| 109 | // First, load the cached ZIR code, if any. | 111 | // First, load the cached ZIR code, if any. |
| 110 | log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{ | 112 | log.debug("AstGen checking cache: {} (local={}, digest={s})", .{ |
| 111 | file.sub_file_path, want_local_cache, &hex_digest, | 113 | file.path.fmt(comp), want_local_cache, &hex_digest, |
| 112 | }); | 114 | }); |
| 113 | 115 | ||
| 114 | break :lock .shared; | 116 | break :lock .shared; |
| ... | @@ -120,18 +122,18 @@ pub fn updateFile( | ... | @@ -120,18 +122,18 @@ pub fn updateFile( |
| 120 | stat.inode == file.stat.inode; | 122 | stat.inode == file.stat.inode; |
| 121 | 123 | ||
| 122 | if (unchanged_metadata) { | 124 | if (unchanged_metadata) { |
| 123 | log.debug("unmodified metadata of file: {s}", .{file.sub_file_path}); | 125 | log.debug("unmodified metadata of file: {}", .{file.path.fmt(comp)}); |
| 124 | return; | 126 | return; |
| 125 | } | 127 | } |
| 126 | 128 | ||
| 127 | log.debug("metadata changed: {s}", .{file.sub_file_path}); | 129 | log.debug("metadata changed: {}", .{file.path.fmt(comp)}); |
| 128 | 130 | ||
| 129 | break :lock .exclusive; | 131 | break :lock .exclusive; |
| 130 | }, | 132 | }, |
| 131 | }; | 133 | }; |
| 132 | 134 | ||
| 133 | // The old compile error, if any, is no longer relevant. | 135 | // The old compile error, if any, is no longer relevant. |
| 134 | pt.lockAndClearFileCompileError(file); | 136 | pt.lockAndClearFileCompileError(file_index, file); |
| 135 | 137 | ||
| 136 | // If `zir` is not null, and `prev_zir` is null, then `TrackedInst`s are associated with `zir`. | 138 | // If `zir` is not null, and `prev_zir` is null, then `TrackedInst`s are associated with `zir`. |
| 137 | // We need to keep it around! | 139 | // We need to keep it around! |
| ... | @@ -211,12 +213,12 @@ pub fn updateFile( | ... | @@ -211,12 +213,12 @@ pub fn updateFile( |
| 211 | }; | 213 | }; |
| 212 | switch (result) { | 214 | switch (result) { |
| 213 | .success => { | 215 | .success => { |
| 214 | log.debug("AstGen cached success: {s}", .{file.sub_file_path}); | 216 | log.debug("AstGen cached success: {}", .{file.path.fmt(comp)}); |
| 215 | break false; | 217 | break false; |
| 216 | }, | 218 | }, |
| 217 | .invalid => {}, | 219 | .invalid => {}, |
| 218 | .truncated => log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path}), | 220 | .truncated => log.warn("unexpected EOF reading cached ZIR for {}", .{file.path.fmt(comp)}), |
| 219 | .stale => log.debug("AstGen cache stale: {s}", .{file.sub_file_path}), | 221 | .stale => log.debug("AstGen cache stale: {}", .{file.path.fmt(comp)}), |
| 220 | } | 222 | } |
| 221 | 223 | ||
| 222 | // If we already have the exclusive lock then it is our job to update. | 224 | // If we already have the exclusive lock then it is our job to update. |
| ... | @@ -255,22 +257,22 @@ pub fn updateFile( | ... | @@ -255,22 +257,22 @@ pub fn updateFile( |
| 255 | file.zir = try AstGen.generate(gpa, file.tree.?); | 257 | file.zir = try AstGen.generate(gpa, file.tree.?); |
| 256 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { | 258 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { |
| 257 | error.OutOfMemory => |e| return e, | 259 | error.OutOfMemory => |e| return e, |
| 258 | else => log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{ | 260 | else => log.warn("unable to write cached ZIR code for {} to {}{s}: {s}", .{ |
| 259 | file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err), | 261 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 260 | }), | 262 | }), |
| 261 | }; | 263 | }; |
| 262 | }, | 264 | }, |
| 263 | .zon => { | 265 | .zon => { |
| 264 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); | 266 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); |
| 265 | Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { | 267 | Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { |
| 266 | log.warn("unable to write cached ZOIR code for {}{s} to {}{s}: {s}", .{ | 268 | log.warn("unable to write cached ZOIR code for {} to {}{s}: {s}", .{ |
| 267 | file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err), | 269 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 268 | }); | 270 | }); |
| 269 | }; | 271 | }; |
| 270 | }, | 272 | }, |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 273 | log.debug("AstGen fresh success: {s}", .{file.sub_file_path}); | 275 | log.debug("AstGen fresh success: {}", .{file.path.fmt(comp)}); |
| 274 | } | 276 | } |
| 275 | 277 | ||
| 276 | file.stat = .{ | 278 | file.stat = .{ |
| ... | @@ -287,7 +289,7 @@ pub fn updateFile( | ... | @@ -287,7 +289,7 @@ pub fn updateFile( |
| 287 | if (file.zir.?.hasCompileErrors()) { | 289 | if (file.zir.?.hasCompileErrors()) { |
| 288 | comp.mutex.lock(); | 290 | comp.mutex.lock(); |
| 289 | defer comp.mutex.unlock(); | 291 | defer comp.mutex.unlock(); |
| 290 | try zcu.failed_files.putNoClobber(gpa, file, null); | 292 | try zcu.failed_files.putNoClobber(gpa, file_index, null); |
| 291 | } | 293 | } |
| 292 | if (file.zir.?.loweringFailed()) { | 294 | if (file.zir.?.loweringFailed()) { |
| 293 | file.status = .astgen_failure; | 295 | file.status = .astgen_failure; |
| ... | @@ -300,7 +302,7 @@ pub fn updateFile( | ... | @@ -300,7 +302,7 @@ pub fn updateFile( |
| 300 | file.status = .astgen_failure; | 302 | file.status = .astgen_failure; |
| 301 | comp.mutex.lock(); | 303 | comp.mutex.lock(); |
| 302 | defer comp.mutex.unlock(); | 304 | defer comp.mutex.unlock(); |
| 303 | try zcu.failed_files.putNoClobber(gpa, file, null); | 305 | try zcu.failed_files.putNoClobber(gpa, file_index, null); |
| 304 | } else { | 306 | } else { |
| 305 | file.status = .success; | 307 | file.status = .success; |
| 306 | } | 308 | } |
| ... | @@ -310,8 +312,7 @@ pub fn updateFile( | ... | @@ -310,8 +312,7 @@ pub fn updateFile( |
| 310 | switch (file.status) { | 312 | switch (file.status) { |
| 311 | .never_loaded => unreachable, | 313 | .never_loaded => unreachable, |
| 312 | .retryable_failure => unreachable, | 314 | .retryable_failure => unreachable, |
| 313 | .astgen_failure => return error.AnalysisFail, | 315 | .astgen_failure, .success => {}, |
| 314 | .success => return, | ||
| 315 | } | 316 | } |
| 316 | } | 317 | } |
| 317 | 318 | ||
| ... | @@ -388,9 +389,18 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -388,9 +389,18 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 388 | var updated_files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, UpdatedFile) = .empty; | 389 | var updated_files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, UpdatedFile) = .empty; |
| 389 | defer cleanupUpdatedFiles(gpa, &updated_files); | 390 | defer cleanupUpdatedFiles(gpa, &updated_files); |
| 390 | 391 | ||
| 391 | for (zcu.import_table.values()) |file_index| { | 392 | for (zcu.import_table.keys()) |file_index| { |
| 393 | if (!zcu.alive_files.contains(file_index)) continue; | ||
| 392 | const file = zcu.fileByIndex(file_index); | 394 | const file = zcu.fileByIndex(file_index); |
| 393 | assert(file.status == .success); | 395 | assert(file.status == .success); |
| 396 | if (file.module_changed) { | ||
| 397 | try updated_files.putNoClobber(gpa, file_index, .{ | ||
| 398 | .file = file, | ||
| 399 | // We intentionally don't map any instructions here; that's the point, the whole file is outdated! | ||
| 400 | .inst_map = .{}, | ||
| 401 | }); | ||
| 402 | continue; | ||
| 403 | } | ||
| 394 | switch (file.getMode()) { | 404 | switch (file.getMode()) { |
| 395 | .zig => {}, // logic below | 405 | .zig => {}, // logic below |
| 396 | .zon => { | 406 | .zon => { |
| ... | @@ -540,10 +550,12 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -540,10 +550,12 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 540 | for (updated_files.keys(), updated_files.values()) |file_index, updated_file| { | 550 | for (updated_files.keys(), updated_files.values()) |file_index, updated_file| { |
| 541 | const file = updated_file.file; | 551 | const file = updated_file.file; |
| 542 | 552 | ||
| 543 | const prev_zir = file.prev_zir.?; | 553 | if (file.prev_zir) |prev_zir| { |
| 544 | file.prev_zir = null; | 554 | prev_zir.deinit(gpa); |
| 545 | prev_zir.deinit(gpa); | 555 | gpa.destroy(prev_zir); |
| 546 | gpa.destroy(prev_zir); | 556 | file.prev_zir = null; |
| 557 | } | ||
| 558 | file.module_changed = false; | ||
| 547 | 559 | ||
| 548 | // For every file which has changed, re-scan the namespace of the file's root struct type. | 560 | // For every file which has changed, re-scan the namespace of the file's root struct type. |
| 549 | // These types are special-cased because they don't have an enclosing declaration which will | 561 | // These types are special-cased because they don't have an enclosing declaration which will |
| ... | @@ -661,9 +673,9 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) | ... | @@ -661,9 +673,9 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) |
| 661 | // * The type `std`, and its namespace | 673 | // * The type `std`, and its namespace |
| 662 | // * The type `std.builtin`, and its namespace | 674 | // * The type `std.builtin`, and its namespace |
| 663 | // * A semi-reasonable source location | 675 | // * A semi-reasonable source location |
| 664 | const std_file_imported = pt.importPkg(zcu.std_mod) catch return error.AnalysisFail; | 676 | const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?; |
| 665 | try pt.ensureFileAnalyzed(std_file_imported.file_index); | 677 | try pt.ensureFileAnalyzed(std_file_index); |
| 666 | const std_type: Type = .fromInterned(zcu.fileRootType(std_file_imported.file_index)); | 678 | const std_type: Type = .fromInterned(zcu.fileRootType(std_file_index)); |
| 667 | const std_namespace = std_type.getNamespaceIndex(zcu); | 679 | const std_namespace = std_type.getNamespaceIndex(zcu); |
| 668 | try pt.ensureNamespaceUpToDate(std_namespace); | 680 | try pt.ensureNamespaceUpToDate(std_namespace); |
| 669 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); | 681 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); |
| ... | @@ -675,7 +687,7 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) | ... | @@ -675,7 +687,7 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) |
| 675 | try pt.ensureNamespaceUpToDate(builtin_namespace); | 687 | try pt.ensureNamespaceUpToDate(builtin_namespace); |
| 676 | const src: Zcu.LazySrcLoc = .{ | 688 | const src: Zcu.LazySrcLoc = .{ |
| 677 | .base_node_inst = builtin_type.typeDeclInst(zcu).?, | 689 | .base_node_inst = builtin_type.typeDeclInst(zcu).?, |
| 678 | .offset = .entire_file, | 690 | .offset = .{ .byte_abs = 0 }, |
| 679 | }; | 691 | }; |
| 680 | 692 | ||
| 681 | var analysis_arena: std.heap.ArenaAllocator = .init(gpa); | 693 | var analysis_arena: std.heap.ArenaAllocator = .init(gpa); |
| ... | @@ -1250,7 +1262,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr | ... | @@ -1250,7 +1262,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1250 | 1262 | ||
| 1251 | if (!try nav_ty.hasRuntimeBitsSema(pt)) { | 1263 | if (!try nav_ty.hasRuntimeBitsSema(pt)) { |
| 1252 | if (zcu.comp.config.use_llvm) break :queue_codegen; | 1264 | if (zcu.comp.config.use_llvm) break :queue_codegen; |
| 1253 | if (file.mod.strip) break :queue_codegen; | 1265 | if (file.mod.?.strip) break :queue_codegen; |
| 1254 | } | 1266 | } |
| 1255 | 1267 | ||
| 1256 | // This job depends on any resolve_type_fully jobs queued up before it. | 1268 | // This job depends on any resolve_type_fully jobs queued up before it. |
| ... | @@ -1730,13 +1742,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai | ... | @@ -1730,13 +1742,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai |
| 1730 | } | 1742 | } |
| 1731 | } | 1743 | } |
| 1732 | 1744 | ||
| 1733 | /// https://github.com/ziglang/zig/issues/14307 | 1745 | pub fn semaMod(pt: Zcu.PerThread, mod: *Module) !void { |
| 1734 | pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void { | ||
| 1735 | dev.check(.sema); | 1746 | dev.check(.sema); |
| 1736 | const import_file_result = try pt.importPkg(pkg); | 1747 | const file_index = pt.zcu.module_roots.get(mod).?.unwrap().?; |
| 1737 | const root_type = pt.zcu.fileRootType(import_file_result.file_index); | 1748 | const root_type = pt.zcu.fileRootType(file_index); |
| 1738 | if (root_type == .none) { | 1749 | if (root_type == .none) { |
| 1739 | return pt.semaFile(import_file_result.file_index); | 1750 | return pt.semaFile(file_index); |
| 1740 | } | 1751 | } |
| 1741 | } | 1752 | } |
| 1742 | 1753 | ||
| ... | @@ -1808,7 +1819,7 @@ fn createFileRootStruct( | ... | @@ -1808,7 +1819,7 @@ fn createFileRootStruct( |
| 1808 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 1819 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 1809 | codegen_type: { | 1820 | codegen_type: { |
| 1810 | if (zcu.comp.config.use_llvm) break :codegen_type; | 1821 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 1811 | if (file.mod.strip) break :codegen_type; | 1822 | if (file.mod.?.strip) break :codegen_type; |
| 1812 | // This job depends on any resolve_type_fully jobs queued up before it. | 1823 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 1813 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | 1824 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); |
| 1814 | } | 1825 | } |
| ... | @@ -1829,7 +1840,7 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. | ... | @@ -1829,7 +1840,7 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. |
| 1829 | if (file_root_type == .none) return; | 1840 | if (file_root_type == .none) return; |
| 1830 | 1841 | ||
| 1831 | log.debug("updateFileNamespace mod={s} sub_file_path={s}", .{ | 1842 | log.debug("updateFileNamespace mod={s} sub_file_path={s}", .{ |
| 1832 | file.mod.fully_qualified_name, | 1843 | file.mod.?.fully_qualified_name, |
| 1833 | file.sub_file_path, | 1844 | file.sub_file_path, |
| 1834 | }); | 1845 | }); |
| 1835 | 1846 | ||
| ... | @@ -1872,211 +1883,464 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1872,211 +1883,464 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1872 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); | 1883 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); |
| 1873 | } | 1884 | } |
| 1874 | 1885 | ||
| 1875 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) Allocator.Error!Zcu.ImportFileResult { | 1886 | /// Called by AstGen worker threads when an import is seen. If `new_file` is returned, the caller is |
| 1887 | /// then responsible for queueing a new AstGen job for the new file. | ||
| 1888 | /// Assumes that `comp.mutex` is NOT locked. It will be locked by this function where necessary. | ||
| 1889 | pub fn discoverImport( | ||
| 1890 | pt: Zcu.PerThread, | ||
| 1891 | importer_path: Compilation.Path, | ||
| 1892 | import_string: []const u8, | ||
| 1893 | ) Allocator.Error!union(enum) { | ||
| 1894 | module, | ||
| 1895 | existing_file: Zcu.File.Index, | ||
| 1896 | new_file: struct { | ||
| 1897 | index: Zcu.File.Index, | ||
| 1898 | file: *Zcu.File, | ||
| 1899 | }, | ||
| 1900 | } { | ||
| 1876 | const zcu = pt.zcu; | 1901 | const zcu = pt.zcu; |
| 1877 | const gpa = zcu.gpa; | 1902 | const gpa = zcu.gpa; |
| 1878 | 1903 | ||
| 1879 | // The resolved path is used as the key in the import table, to detect if | 1904 | if (!mem.endsWith(u8, import_string, ".zig") and !mem.endsWith(u8, import_string, ".zon")) { |
| 1880 | // an import refers to the same as another, despite different relative paths | 1905 | return .module; |
| 1881 | // or differently mapped package names. | 1906 | } |
| 1882 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 1883 | mod.root.root_dir.path orelse ".", | ||
| 1884 | mod.root.sub_path, | ||
| 1885 | mod.root_src_path, | ||
| 1886 | }); | ||
| 1887 | var keep_resolved_path = false; | ||
| 1888 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 1889 | 1907 | ||
| 1890 | const gop = try zcu.import_table.getOrPut(gpa, resolved_path); | 1908 | const new_path = try importer_path.upJoin(gpa, zcu.comp.dirs, import_string); |
| 1909 | errdefer new_path.deinit(gpa); | ||
| 1910 | |||
| 1911 | // We're about to do a GOP on `import_table`, so we need the mutex. | ||
| 1912 | zcu.comp.mutex.lock(); | ||
| 1913 | defer zcu.comp.mutex.unlock(); | ||
| 1914 | |||
| 1915 | const gop = try zcu.import_table.getOrPutAdapted(gpa, new_path, Zcu.ImportTableAdapter{ .zcu = zcu }); | ||
| 1891 | errdefer _ = zcu.import_table.pop(); | 1916 | errdefer _ = zcu.import_table.pop(); |
| 1892 | if (gop.found_existing) { | 1917 | if (gop.found_existing) { |
| 1893 | const file_index = gop.value_ptr.*; | 1918 | new_path.deinit(gpa); // we didn't need it for `File.path` |
| 1894 | const file = zcu.fileByIndex(file_index); | 1919 | return .{ .existing_file = gop.key_ptr.* }; |
| 1895 | try file.addReference(zcu, .{ .root = mod }); | ||
| 1896 | return .{ | ||
| 1897 | .file = file, | ||
| 1898 | .file_index = file_index, | ||
| 1899 | .is_new = false, | ||
| 1900 | .is_pkg = true, | ||
| 1901 | }; | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | const ip = &zcu.intern_pool; | ||
| 1905 | if (mod.builtin_file) |builtin_file| { | ||
| 1906 | const path_digest = Zcu.computePathDigest(zcu, mod, builtin_file.sub_file_path); | ||
| 1907 | const file_index = try ip.createFile(gpa, pt.tid, .{ | ||
| 1908 | .bin_digest = path_digest, | ||
| 1909 | .file = builtin_file, | ||
| 1910 | .root_type = .none, | ||
| 1911 | }); | ||
| 1912 | keep_resolved_path = true; // It's now owned by import_table. | ||
| 1913 | gop.value_ptr.* = file_index; | ||
| 1914 | try builtin_file.addReference(zcu, .{ .root = mod }); | ||
| 1915 | return .{ | ||
| 1916 | .file = builtin_file, | ||
| 1917 | .file_index = file_index, | ||
| 1918 | .is_new = false, | ||
| 1919 | .is_pkg = true, | ||
| 1920 | }; | ||
| 1921 | } | 1920 | } |
| 1922 | 1921 | ||
| 1923 | const sub_file_path = try gpa.dupe(u8, mod.root_src_path); | 1922 | zcu.import_table.lockPointers(); |
| 1924 | errdefer gpa.free(sub_file_path); | 1923 | defer zcu.import_table.unlockPointers(); |
| 1925 | |||
| 1926 | const comp = zcu.comp; | ||
| 1927 | if (comp.file_system_inputs) |fsi| | ||
| 1928 | try comp.appendFileSystemInput(fsi, mod.root, sub_file_path); | ||
| 1929 | 1924 | ||
| 1930 | const new_file = try gpa.create(Zcu.File); | 1925 | const new_file = try gpa.create(Zcu.File); |
| 1931 | errdefer gpa.destroy(new_file); | 1926 | errdefer gpa.destroy(new_file); |
| 1932 | 1927 | ||
| 1933 | const path_digest = zcu.computePathDigest(mod, sub_file_path); | 1928 | const new_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ |
| 1934 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ | 1929 | .bin_digest = new_path.digest(), |
| 1935 | .bin_digest = path_digest, | ||
| 1936 | .file = new_file, | 1930 | .file = new_file, |
| 1937 | .root_type = .none, | 1931 | .root_type = .none, |
| 1938 | }); | 1932 | }); |
| 1939 | keep_resolved_path = true; // It's now owned by import_table. | 1933 | errdefer comptime unreachable; // because we don't remove the file from the internpool |
| 1940 | gop.value_ptr.* = new_file_index; | 1934 | |
| 1935 | gop.key_ptr.* = new_file_index; | ||
| 1941 | new_file.* = .{ | 1936 | new_file.* = .{ |
| 1942 | .sub_file_path = sub_file_path, | 1937 | .status = .never_loaded, |
| 1938 | .path = new_path, | ||
| 1943 | .stat = undefined, | 1939 | .stat = undefined, |
| 1940 | .is_builtin = false, | ||
| 1944 | .source = null, | 1941 | .source = null, |
| 1945 | .tree = null, | 1942 | .tree = null, |
| 1946 | .zir = null, | 1943 | .zir = null, |
| 1947 | .zoir = null, | 1944 | .zoir = null, |
| 1948 | .status = .never_loaded, | 1945 | .mod = null, |
| 1949 | .mod = mod, | 1946 | .sub_file_path = undefined, |
| 1947 | .module_changed = false, | ||
| 1948 | .prev_zir = null, | ||
| 1949 | .zoir_invalidated = false, | ||
| 1950 | }; | 1950 | }; |
| 1951 | 1951 | ||
| 1952 | try new_file.addReference(zcu, .{ .root = mod }); | 1952 | return .{ .new_file = .{ |
| 1953 | return .{ | 1953 | .index = new_file_index, |
| 1954 | .file = new_file, | 1954 | .file = new_file, |
| 1955 | .file_index = new_file_index, | 1955 | } }; |
| 1956 | .is_new = true, | ||
| 1957 | .is_pkg = true, | ||
| 1958 | }; | ||
| 1959 | } | 1956 | } |
| 1960 | 1957 | ||
| 1961 | /// Called from a worker thread during AstGen (with the Compilation mutex held). | 1958 | pub fn doImport( |
| 1962 | /// Also called from Sema during semantic analysis. | ||
| 1963 | /// Does not attempt to load the file from disk; just returns a corresponding `*Zcu.File`. | ||
| 1964 | pub fn importFile( | ||
| 1965 | pt: Zcu.PerThread, | 1959 | pt: Zcu.PerThread, |
| 1966 | cur_file: *Zcu.File, | 1960 | /// This file must have its `mod` populated. |
| 1961 | importer: *Zcu.File, | ||
| 1967 | import_string: []const u8, | 1962 | import_string: []const u8, |
| 1968 | ) error{ | 1963 | ) error{ |
| 1969 | OutOfMemory, | 1964 | OutOfMemory, |
| 1970 | ModuleNotFound, | 1965 | ModuleNotFound, |
| 1971 | ImportOutsideModulePath, | 1966 | IllegalZigImport, |
| 1972 | CurrentWorkingDirectoryUnlinked, | 1967 | }!struct { |
| 1973 | }!Zcu.ImportFileResult { | 1968 | file: Zcu.File.Index, |
| 1969 | module_root: ?*Module, | ||
| 1970 | } { | ||
| 1974 | const zcu = pt.zcu; | 1971 | const zcu = pt.zcu; |
| 1975 | const mod = cur_file.mod; | 1972 | const gpa = zcu.gpa; |
| 1976 | 1973 | const imported_mod: ?*Module = m: { | |
| 1977 | if (std.mem.eql(u8, import_string, "std")) { | 1974 | if (mem.eql(u8, import_string, "std")) break :m zcu.std_mod; |
| 1978 | return pt.importPkg(zcu.std_mod); | 1975 | if (mem.eql(u8, import_string, "root")) break :m zcu.root_mod; |
| 1979 | } | 1976 | if (mem.eql(u8, import_string, "builtin")) { |
| 1980 | if (std.mem.eql(u8, import_string, "root")) { | 1977 | const opts = importer.mod.?.getBuiltinOptions(zcu.comp.config); |
| 1981 | return pt.importPkg(zcu.root_mod); | 1978 | break :m zcu.builtin_modules.get(opts.hash()).?; |
| 1982 | } | 1979 | } |
| 1983 | if (mod.deps.get(import_string)) |pkg| { | 1980 | break :m importer.mod.?.deps.get(import_string); |
| 1984 | return pt.importPkg(pkg); | 1981 | }; |
| 1982 | if (imported_mod) |mod| { | ||
| 1983 | if (zcu.module_roots.get(mod).?.unwrap()) |file_index| { | ||
| 1984 | return .{ | ||
| 1985 | .file = file_index, | ||
| 1986 | .module_root = mod, | ||
| 1987 | }; | ||
| 1988 | } | ||
| 1985 | } | 1989 | } |
| 1986 | if (!std.mem.endsWith(u8, import_string, ".zig") and | 1990 | if (!std.mem.endsWith(u8, import_string, ".zig") and |
| 1987 | !std.mem.endsWith(u8, import_string, ".zon")) | 1991 | !std.mem.endsWith(u8, import_string, ".zon")) |
| 1988 | { | 1992 | { |
| 1989 | return error.ModuleNotFound; | 1993 | return error.ModuleNotFound; |
| 1990 | } | 1994 | } |
| 1995 | const path = try importer.path.upJoin(gpa, zcu.comp.dirs, import_string); | ||
| 1996 | defer path.deinit(gpa); | ||
| 1997 | if (try path.isIllegalZigImport(gpa, zcu.comp.dirs)) { | ||
| 1998 | return error.IllegalZigImport; | ||
| 1999 | } | ||
| 2000 | return .{ | ||
| 2001 | .file = zcu.import_table.getKeyAdapted(path, Zcu.ImportTableAdapter{ .zcu = zcu }).?, | ||
| 2002 | .module_root = null, | ||
| 2003 | }; | ||
| 2004 | } | ||
| 2005 | /// This is called once during `Compilation.create` and never again. "builtin" modules don't yet | ||
| 2006 | /// exist, so are not added to `module_roots` here. They must be added when they are created. | ||
| 2007 | pub fn populateModuleRootTable(pt: Zcu.PerThread) error{ | ||
| 2008 | OutOfMemory, | ||
| 2009 | /// One of the specified modules had its root source file at an illegal path. | ||
| 2010 | IllegalZigImport, | ||
| 2011 | }!void { | ||
| 2012 | const zcu = pt.zcu; | ||
| 1991 | const gpa = zcu.gpa; | 2013 | const gpa = zcu.gpa; |
| 1992 | 2014 | ||
| 1993 | // The resolved path is used as the key in the import table, to detect if | 2015 | // We'll initially add [mod, undefined] pairs, and when we reach the pair while |
| 1994 | // an import refers to the same as another, despite different relative paths | 2016 | // iterating, rewrite the undefined value. |
| 1995 | // or differently mapped package names. | 2017 | const roots = &zcu.module_roots; |
| 1996 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 2018 | roots.clearRetainingCapacity(); |
| 1997 | mod.root.root_dir.path orelse ".", | 2019 | |
| 1998 | mod.root.sub_path, | 2020 | // Start with: |
| 1999 | cur_file.sub_file_path, | 2021 | // * `std_mod`, which is the main root of analysis |
| 2000 | "..", | 2022 | // * `root_mod`, which is `@import("root")` |
| 2001 | import_string, | 2023 | // * `main_mod`, which is a special analysis root in tests (and otherwise equal to `root_mod`) |
| 2002 | }); | 2024 | // All other modules will be found by traversing their dependency tables. |
| 2025 | try roots.ensureTotalCapacity(gpa, 3); | ||
| 2026 | roots.putAssumeCapacity(zcu.std_mod, undefined); | ||
| 2027 | roots.putAssumeCapacity(zcu.root_mod, undefined); | ||
| 2028 | roots.putAssumeCapacity(zcu.main_mod, undefined); | ||
| 2029 | var i: usize = 0; | ||
| 2030 | while (i < roots.count()) { | ||
| 2031 | const mod = roots.keys()[i]; | ||
| 2032 | try roots.ensureUnusedCapacity(gpa, mod.deps.count()); | ||
| 2033 | for (mod.deps.values()) |dep| { | ||
| 2034 | const gop = roots.getOrPutAssumeCapacity(dep); | ||
| 2035 | _ = gop; // we want to leave the value undefined if it was added | ||
| 2036 | } | ||
| 2003 | 2037 | ||
| 2004 | var keep_resolved_path = false; | 2038 | const root_file_out = &roots.values()[i]; |
| 2005 | defer if (!keep_resolved_path) gpa.free(resolved_path); | 2039 | roots.lockPointers(); |
| 2040 | defer roots.unlockPointers(); | ||
| 2006 | 2041 | ||
| 2007 | const gop = try zcu.import_table.getOrPut(gpa, resolved_path); | 2042 | i += 1; |
| 2008 | errdefer _ = zcu.import_table.pop(); | 2043 | |
| 2009 | if (gop.found_existing) { | 2044 | if (Zcu.File.modeFromPath(mod.root_src_path) == null) { |
| 2010 | const file_index = gop.value_ptr.*; | 2045 | root_file_out.* = .none; |
| 2011 | return .{ | 2046 | continue; |
| 2012 | .file = zcu.fileByIndex(file_index), | 2047 | } |
| 2013 | .file_index = file_index, | 2048 | |
| 2014 | .is_new = false, | 2049 | const path = try mod.root.join(gpa, zcu.comp.dirs, mod.root_src_path); |
| 2015 | .is_pkg = false, | 2050 | errdefer path.deinit(gpa); |
| 2051 | |||
| 2052 | if (try path.isIllegalZigImport(gpa, zcu.comp.dirs)) { | ||
| 2053 | return error.IllegalZigImport; | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | const gop = try zcu.import_table.getOrPutAdapted(gpa, path, Zcu.ImportTableAdapter{ .zcu = zcu }); | ||
| 2057 | errdefer _ = zcu.import_table.pop(); | ||
| 2058 | |||
| 2059 | if (gop.found_existing) { | ||
| 2060 | path.deinit(gpa); | ||
| 2061 | root_file_out.* = gop.key_ptr.*.toOptional(); | ||
| 2062 | continue; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | zcu.import_table.lockPointers(); | ||
| 2066 | defer zcu.import_table.unlockPointers(); | ||
| 2067 | |||
| 2068 | const new_file = try gpa.create(Zcu.File); | ||
| 2069 | errdefer gpa.destroy(new_file); | ||
| 2070 | |||
| 2071 | const new_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ | ||
| 2072 | .bin_digest = path.digest(), | ||
| 2073 | .file = new_file, | ||
| 2074 | .root_type = .none, | ||
| 2075 | }); | ||
| 2076 | errdefer comptime unreachable; // because we don't remove the file from the internpool | ||
| 2077 | |||
| 2078 | gop.key_ptr.* = new_file_index; | ||
| 2079 | root_file_out.* = new_file_index.toOptional(); | ||
| 2080 | new_file.* = .{ | ||
| 2081 | .status = .never_loaded, | ||
| 2082 | .path = path, | ||
| 2083 | .stat = undefined, | ||
| 2084 | .is_builtin = false, | ||
| 2085 | .source = null, | ||
| 2086 | .tree = null, | ||
| 2087 | .zir = null, | ||
| 2088 | .zoir = null, | ||
| 2089 | .mod = null, | ||
| 2090 | .sub_file_path = undefined, | ||
| 2091 | .module_changed = false, | ||
| 2092 | .prev_zir = null, | ||
| 2093 | .zoir_invalidated = false, | ||
| 2016 | }; | 2094 | }; |
| 2017 | } | 2095 | } |
| 2096 | } | ||
| 2018 | 2097 | ||
| 2019 | const ip = &zcu.intern_pool; | 2098 | /// Clears and re-populates `pt.zcu.alive_files`, and determines the module identity of every alive |
| 2099 | /// file. If a file's module changes, its `module_changed` flag is set for `updateZirRefs` to see. | ||
| 2100 | /// Also clears and re-populates `failed_imports` and `multi_module_err` based on the set of alive | ||
| 2101 | /// files. | ||
| 2102 | /// | ||
| 2103 | /// Live files are also added as file system inputs if necessary. | ||
| 2104 | /// | ||
| 2105 | /// Returns whether there is any live file which is failed. Howewver, this function does *not* | ||
| 2106 | /// modify `pt.zcu.skip_analysis_this_update`. | ||
| 2107 | /// | ||
| 2108 | /// If an error is returned, `pt.zcu.alive_files` might contain undefined values. | ||
| 2109 | pub fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool { | ||
| 2110 | const zcu = pt.zcu; | ||
| 2111 | const comp = zcu.comp; | ||
| 2112 | const gpa = zcu.gpa; | ||
| 2020 | 2113 | ||
| 2021 | const new_file = try gpa.create(Zcu.File); | 2114 | var any_fatal_files = false; |
| 2022 | errdefer gpa.destroy(new_file); | 2115 | zcu.multi_module_err = null; |
| 2116 | zcu.failed_imports.clearRetainingCapacity(); | ||
| 2117 | zcu.alive_files.clearRetainingCapacity(); | ||
| 2118 | |||
| 2119 | // This function will iterate the keys of `alive_files`, adding new entries as it discovers | ||
| 2120 | // imports. Once a file is in `alive_files`, it has its `mod` field up-to-date. If conflicting | ||
| 2121 | // imports are discovered for a file, we will set `multi_module_err`. Crucially, this traversal | ||
| 2122 | // is single-threaded, and depends only on the order of the imports map from AstGen, which makes | ||
| 2123 | // its behavior (in terms of which multi module errors are discovered) entirely consistent in a | ||
| 2124 | // multi-threaded environment (where things like file indices could differ between compiler runs). | ||
| 2125 | |||
| 2126 | // The roots of our file liveness analysis will be the analysis roots. | ||
| 2127 | try zcu.alive_files.ensureTotalCapacity(gpa, zcu.analysis_roots.len); | ||
| 2128 | for (zcu.analysis_roots.slice()) |mod| { | ||
| 2129 | const file_index = zcu.module_roots.get(mod).?.unwrap() orelse continue; | ||
| 2130 | const file = zcu.fileByIndex(file_index); | ||
| 2023 | 2131 | ||
| 2024 | const resolved_root_path = try std.fs.path.resolve(gpa, &.{ | 2132 | file.mod = mod; |
| 2025 | mod.root.root_dir.path orelse ".", | 2133 | file.sub_file_path = mod.root_src_path; |
| 2026 | mod.root.sub_path, | ||
| 2027 | }); | ||
| 2028 | defer gpa.free(resolved_root_path); | ||
| 2029 | 2134 | ||
| 2030 | const sub_file_path = p: { | 2135 | zcu.alive_files.putAssumeCapacityNoClobber(file_index, .{ .analysis_root = mod }); |
| 2031 | const relative = std.fs.path.relative(gpa, resolved_root_path, resolved_path) catch |err| switch (err) { | 2136 | } |
| 2032 | error.Unexpected => unreachable, | 2137 | |
| 2033 | else => |e| return e, | 2138 | var live_check_idx: usize = 0; |
| 2034 | }; | 2139 | while (live_check_idx < zcu.alive_files.count()) { |
| 2035 | errdefer gpa.free(relative); | 2140 | const file_idx = zcu.alive_files.keys()[live_check_idx]; |
| 2141 | const file = zcu.fileByIndex(file_idx); | ||
| 2142 | live_check_idx += 1; | ||
| 2036 | 2143 | ||
| 2037 | if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) { | 2144 | switch (file.status) { |
| 2038 | break :p relative; | 2145 | .never_loaded => unreachable, // everything reachable is loaded by the AstGen workers |
| 2146 | .retryable_failure, .astgen_failure => any_fatal_files = true, | ||
| 2147 | .success => {}, | ||
| 2039 | } | 2148 | } |
| 2040 | return error.ImportOutsideModulePath; | ||
| 2041 | }; | ||
| 2042 | errdefer gpa.free(sub_file_path); | ||
| 2043 | 2149 | ||
| 2044 | log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{ | 2150 | try comp.appendFileSystemInput(file.path); |
| 2045 | resolved_root_path, resolved_path, sub_file_path, import_string, | 2151 | |
| 2046 | }); | 2152 | switch (file.getMode()) { |
| 2153 | .zig => {}, // continue to logic below | ||
| 2154 | .zon => continue, // ZON can't import anything | ||
| 2155 | } | ||
| 2156 | |||
| 2157 | if (file.status != .success) continue; // ZIR not valid if there was a file failure | ||
| 2158 | |||
| 2159 | const zir = file.zir.?; | ||
| 2160 | const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | ||
| 2161 | if (imports_index == 0) continue; // this Zig file has no imports | ||
| 2162 | const extra = zir.extraData(Zir.Inst.Imports, imports_index); | ||
| 2163 | var extra_index = extra.end; | ||
| 2164 | try zcu.alive_files.ensureUnusedCapacity(gpa, extra.data.imports_len); | ||
| 2165 | for (0..extra.data.imports_len) |_| { | ||
| 2166 | const item = zir.extraData(Zir.Inst.Imports.Item, extra_index); | ||
| 2167 | extra_index = item.end; | ||
| 2168 | const import_path = zir.nullTerminatedString(item.data.name); | ||
| 2169 | |||
| 2170 | if (std.mem.eql(u8, import_path, "builtin")) { | ||
| 2171 | // We've not necessarily generated builtin modules yet, so `doImport` could fail. Instead, | ||
| 2172 | // create the module here. Then, since we know that `builtin.zig` doesn't have an error and | ||
| 2173 | // has no imports other than 'std', we can just continue onto the next import. | ||
| 2174 | try pt.updateBuiltinModule(file.mod.?.getBuiltinOptions(comp.config)); | ||
| 2175 | continue; | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | const res = pt.doImport(file, import_path) catch |err| switch (err) { | ||
| 2179 | error.OutOfMemory => |e| return e, | ||
| 2180 | error.ModuleNotFound => { | ||
| 2181 | // It'd be nice if this were a file-level error, but allowing this turns out to | ||
| 2182 | // be quite important in practice, e.g. for optional dependencies whose import | ||
| 2183 | // is behind a comptime condition. So, the error here happens in `Sema` instead. | ||
| 2184 | continue; | ||
| 2185 | }, | ||
| 2186 | error.IllegalZigImport => { | ||
| 2187 | try zcu.failed_imports.append(gpa, .{ | ||
| 2188 | .file_index = file_idx, | ||
| 2189 | .import_string = item.data.name, | ||
| 2190 | .import_token = item.data.token, | ||
| 2191 | .kind = .illegal_zig_import, | ||
| 2192 | }); | ||
| 2193 | continue; | ||
| 2194 | }, | ||
| 2195 | }; | ||
| 2196 | |||
| 2197 | // If the import was not of a module, we propagate our own module. | ||
| 2198 | const imported_mod = res.module_root orelse file.mod.?; | ||
| 2199 | const imported_file = zcu.fileByIndex(res.file); | ||
| 2200 | |||
| 2201 | const imported_ref: Zcu.File.Reference = .{ .import = .{ | ||
| 2202 | .importer = file_idx, | ||
| 2203 | .tok = item.data.token, | ||
| 2204 | .module = res.module_root, | ||
| 2205 | } }; | ||
| 2206 | |||
| 2207 | const gop = zcu.alive_files.getOrPutAssumeCapacity(res.file); | ||
| 2208 | if (gop.found_existing) { | ||
| 2209 | // This means `imported_file.mod` is already populated. If it doesn't match | ||
| 2210 | // `imported_mod`, then this file exists in multiple modules. | ||
| 2211 | if (imported_file.mod.? != imported_mod) { | ||
| 2212 | // We only report the first multi-module error we see. Thanks to this traversal | ||
| 2213 | // being deterministic, this doesn't raise consistency issues. Moreover, it's a | ||
| 2214 | // useful behavior; we know that this error can be reached *without* realising | ||
| 2215 | // that any other files are multi-module, so it's probably approximately where | ||
| 2216 | // the problem "begins". Any compilation with a multi-module file is likely to | ||
| 2217 | // have a huge number of them by transitive imports, so just reporting this one | ||
| 2218 | // hopefully keeps the error focused. | ||
| 2219 | zcu.multi_module_err = .{ | ||
| 2220 | .file = file_idx, | ||
| 2221 | .modules = .{ imported_file.mod.?, imported_mod }, | ||
| 2222 | .refs = .{ gop.value_ptr.*, imported_ref }, | ||
| 2223 | }; | ||
| 2224 | // If we discover a multi-module error, it's the only error which matters, and we | ||
| 2225 | // can't discern any useful information about the file's own imports; so just do | ||
| 2226 | // an early exit now we've populated `zcu.multi_module_err`. | ||
| 2227 | return any_fatal_files; | ||
| 2228 | } | ||
| 2229 | continue; | ||
| 2230 | } | ||
| 2231 | // We're the first thing we've found referencing `res.file`. | ||
| 2232 | gop.value_ptr.* = imported_ref; | ||
| 2233 | if (imported_file.mod) |m| { | ||
| 2234 | if (m == imported_mod) { | ||
| 2235 | // Great, the module and sub path are already populated correctly. | ||
| 2236 | continue; | ||
| 2237 | } | ||
| 2238 | } | ||
| 2239 | // We need to set the file's module, meaning we also need to compute its sub path. | ||
| 2240 | // This string is externally managed and has a lifetime at least equal to the | ||
| 2241 | // lifetime of `imported_file`. `null` means the file is outside its module root. | ||
| 2242 | switch (imported_file.path.isNested(imported_mod.root)) { | ||
| 2243 | .yes => |sub_path| { | ||
| 2244 | if (imported_file.mod != null) { | ||
| 2245 | // There was a module from a previous update; instruct `updateZirRefs` to | ||
| 2246 | // invalidate everything. | ||
| 2247 | imported_file.module_changed = true; | ||
| 2248 | } | ||
| 2249 | imported_file.mod = imported_mod; | ||
| 2250 | imported_file.sub_file_path = sub_path; | ||
| 2251 | }, | ||
| 2252 | .different_roots, .no => { | ||
| 2253 | try zcu.failed_imports.append(gpa, .{ | ||
| 2254 | .file_index = file_idx, | ||
| 2255 | .import_string = item.data.name, | ||
| 2256 | .import_token = item.data.token, | ||
| 2257 | .kind = .file_outside_module_root, | ||
| 2258 | }); | ||
| 2259 | _ = zcu.alive_files.pop(); // we failed to populate `mod`/`sub_file_path` | ||
| 2260 | }, | ||
| 2261 | } | ||
| 2262 | } | ||
| 2263 | } | ||
| 2047 | 2264 | ||
| 2265 | return any_fatal_files; | ||
| 2266 | } | ||
| 2267 | |||
| 2268 | /// Ensures that the `@import("builtin")` module corresponding to `opts` is available in | ||
| 2269 | /// `builtin_modules`, and that its file is populated. Also ensures the file on disk is | ||
| 2270 | /// up-to-date, setting a misc failure if updating it fails. | ||
| 2271 | /// Asserts that the imported `builtin.zig` has no ZIR errors, and that it has only one | ||
| 2272 | /// import, which is 'std'. | ||
| 2273 | pub fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!void { | ||
| 2274 | const zcu = pt.zcu; | ||
| 2048 | const comp = zcu.comp; | 2275 | const comp = zcu.comp; |
| 2049 | if (comp.file_system_inputs) |fsi| | 2276 | const gpa = zcu.gpa; |
| 2050 | try comp.appendFileSystemInput(fsi, mod.root, sub_file_path); | ||
| 2051 | 2277 | ||
| 2052 | const path_digest = zcu.computePathDigest(mod, sub_file_path); | 2278 | const gop = try zcu.builtin_modules.getOrPut(gpa, opts.hash()); |
| 2053 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ | 2279 | if (gop.found_existing) return; // the `File` is up-to-date |
| 2054 | .bin_digest = path_digest, | 2280 | errdefer _ = zcu.builtin_modules.pop(); |
| 2055 | .file = new_file, | 2281 | |
| 2056 | .root_type = .none, | 2282 | const mod: *Module = try .createBuiltin(comp.arena, opts, comp.dirs); |
| 2057 | }); | 2283 | assert(std.mem.eql(u8, &mod.getBuiltinOptions(comp.config).hash(), gop.key_ptr)); // builtin is its own builtin |
| 2058 | keep_resolved_path = true; // It's now owned by import_table. | 2284 | |
| 2059 | gop.value_ptr.* = new_file_index; | 2285 | const path = try mod.root.join(gpa, comp.dirs, "builtin.zig"); |
| 2060 | new_file.* = .{ | 2286 | errdefer path.deinit(gpa); |
| 2061 | .sub_file_path = sub_file_path, | ||
| 2062 | 2287 | ||
| 2288 | const file_gop = try zcu.import_table.getOrPutAdapted(gpa, path, Zcu.ImportTableAdapter{ .zcu = zcu }); | ||
| 2289 | // `Compilation.Path.isIllegalZigImport` checks guard file creation, so | ||
| 2290 | // there isn't an `import_table` entry for this path yet. | ||
| 2291 | assert(!file_gop.found_existing); | ||
| 2292 | errdefer _ = zcu.import_table.pop(); | ||
| 2293 | |||
| 2294 | try zcu.module_roots.ensureUnusedCapacity(gpa, 1); | ||
| 2295 | |||
| 2296 | const file = try gpa.create(Zcu.File); | ||
| 2297 | errdefer gpa.destroy(file); | ||
| 2298 | |||
| 2299 | file.* = .{ | ||
| 2063 | .status = .never_loaded, | 2300 | .status = .never_loaded, |
| 2064 | .stat = undefined, | 2301 | .stat = undefined, |
| 2065 | 2302 | .path = path, | |
| 2303 | .is_builtin = true, | ||
| 2066 | .source = null, | 2304 | .source = null, |
| 2067 | .tree = null, | 2305 | .tree = null, |
| 2068 | .zir = null, | 2306 | .zir = null, |
| 2069 | .zoir = null, | 2307 | .zoir = null, |
| 2070 | |||
| 2071 | .mod = mod, | 2308 | .mod = mod, |
| 2309 | .sub_file_path = "builtin.zig", | ||
| 2310 | .module_changed = false, | ||
| 2311 | .prev_zir = null, | ||
| 2312 | .zoir_invalidated = false, | ||
| 2072 | }; | 2313 | }; |
| 2073 | 2314 | ||
| 2074 | return .{ | 2315 | const file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ |
| 2075 | .file = new_file, | 2316 | .bin_digest = path.digest(), |
| 2076 | .file_index = new_file_index, | 2317 | .file = file, |
| 2077 | .is_new = true, | 2318 | .root_type = .none, |
| 2078 | .is_pkg = false, | 2319 | }); |
| 2079 | }; | 2320 | |
| 2321 | gop.value_ptr.* = mod; | ||
| 2322 | file_gop.key_ptr.* = file_index; | ||
| 2323 | zcu.module_roots.putAssumeCapacityNoClobber(mod, file_index.toOptional()); | ||
| 2324 | try opts.populateFile(gpa, file); | ||
| 2325 | |||
| 2326 | assert(file.status == .success); | ||
| 2327 | assert(!file.zir.?.hasCompileErrors()); | ||
| 2328 | { | ||
| 2329 | // Check that it has only one import, which is 'std'. | ||
| 2330 | const imports_idx = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | ||
| 2331 | assert(imports_idx != 0); // there is an import | ||
| 2332 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_idx); | ||
| 2333 | assert(extra.data.imports_len == 1); // there is exactly one import | ||
| 2334 | const item = file.zir.?.extraData(Zir.Inst.Imports.Item, extra.end); | ||
| 2335 | const import_path = file.zir.?.nullTerminatedString(item.data.name); | ||
| 2336 | assert(mem.eql(u8, import_path, "std")); // the single import is of 'std' | ||
| 2337 | } | ||
| 2338 | |||
| 2339 | Builtin.updateFileOnDisk(file, comp) catch |err| comp.setMiscFailure( | ||
| 2340 | .write_builtin_zig, | ||
| 2341 | "unable to write '{}': {s}", | ||
| 2342 | .{ file.path.fmt(comp), @errorName(err) }, | ||
| 2343 | ); | ||
| 2080 | } | 2344 | } |
| 2081 | 2345 | ||
| 2082 | pub fn embedFile( | 2346 | pub fn embedFile( |
| ... | @@ -2091,63 +2355,49 @@ pub fn embedFile( | ... | @@ -2091,63 +2355,49 @@ pub fn embedFile( |
| 2091 | const zcu = pt.zcu; | 2355 | const zcu = pt.zcu; |
| 2092 | const gpa = zcu.gpa; | 2356 | const gpa = zcu.gpa; |
| 2093 | 2357 | ||
| 2094 | if (cur_file.mod.deps.get(import_string)) |mod| { | 2358 | const opt_mod: ?*Module = m: { |
| 2095 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 2359 | if (mem.eql(u8, import_string, "std")) break :m zcu.std_mod; |
| 2096 | mod.root.root_dir.path orelse ".", | 2360 | if (mem.eql(u8, import_string, "root")) break :m zcu.root_mod; |
| 2097 | mod.root.sub_path, | 2361 | if (mem.eql(u8, import_string, "builtin")) { |
| 2098 | mod.root_src_path, | 2362 | const opts = cur_file.mod.?.getBuiltinOptions(zcu.comp.config); |
| 2099 | }); | 2363 | break :m zcu.builtin_modules.get(opts.hash()).?; |
| 2100 | errdefer gpa.free(resolved_path); | 2364 | } |
| 2101 | 2365 | break :m cur_file.mod.?.deps.get(import_string); | |
| 2102 | const gop = try zcu.embed_table.getOrPut(gpa, resolved_path); | 2366 | }; |
| 2103 | errdefer assert(std.mem.eql(u8, zcu.embed_table.pop().?.key, resolved_path)); | 2367 | if (opt_mod) |mod| { |
| 2368 | const path = try mod.root.join(gpa, zcu.comp.dirs, mod.root_src_path); | ||
| 2369 | errdefer path.deinit(gpa); | ||
| 2104 | 2370 | ||
| 2371 | const gop = try zcu.embed_table.getOrPutAdapted(gpa, path, Zcu.EmbedTableAdapter{}); | ||
| 2105 | if (gop.found_existing) { | 2372 | if (gop.found_existing) { |
| 2106 | gpa.free(resolved_path); // we're not using this key | 2373 | path.deinit(gpa); // we're not using this key |
| 2107 | return @enumFromInt(gop.index); | 2374 | return @enumFromInt(gop.index); |
| 2108 | } | 2375 | } |
| 2109 | 2376 | errdefer _ = zcu.embed_table.pop(); | |
| 2110 | gop.value_ptr.* = try pt.newEmbedFile(mod, mod.root_src_path, resolved_path); | 2377 | gop.key_ptr.* = try pt.newEmbedFile(path); |
| 2111 | return @enumFromInt(gop.index); | 2378 | return @enumFromInt(gop.index); |
| 2112 | } | 2379 | } |
| 2113 | 2380 | ||
| 2114 | // The resolved path is used as the key in the table, to detect if a file | 2381 | const embed_file: *Zcu.EmbedFile, const embed_file_idx: Zcu.EmbedFile.Index = ef: { |
| 2115 | // refers to the same as another, despite different relative paths. | 2382 | const path = try cur_file.path.upJoin(gpa, zcu.comp.dirs, import_string); |
| 2116 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 2383 | errdefer path.deinit(gpa); |
| 2117 | cur_file.mod.root.root_dir.path orelse ".", | 2384 | const gop = try zcu.embed_table.getOrPutAdapted(gpa, path, Zcu.EmbedTableAdapter{}); |
| 2118 | cur_file.mod.root.sub_path, | 2385 | if (gop.found_existing) { |
| 2119 | cur_file.sub_file_path, | 2386 | path.deinit(gpa); // we're not using this key |
| 2120 | "..", | 2387 | break :ef .{ gop.key_ptr.*, @enumFromInt(gop.index) }; |
| 2121 | import_string, | 2388 | } else { |
| 2122 | }); | 2389 | errdefer _ = zcu.embed_table.pop(); |
| 2123 | errdefer gpa.free(resolved_path); | 2390 | gop.key_ptr.* = try pt.newEmbedFile(path); |
| 2124 | 2391 | break :ef .{ gop.key_ptr.*, @enumFromInt(gop.index) }; | |
| 2125 | const gop = try zcu.embed_table.getOrPut(gpa, resolved_path); | 2392 | } |
| 2126 | errdefer assert(std.mem.eql(u8, zcu.embed_table.pop().?.key, resolved_path)); | ||
| 2127 | |||
| 2128 | if (gop.found_existing) { | ||
| 2129 | gpa.free(resolved_path); // we're not using this key | ||
| 2130 | return @enumFromInt(gop.index); | ||
| 2131 | } | ||
| 2132 | |||
| 2133 | const resolved_root_path = try std.fs.path.resolve(gpa, &.{ | ||
| 2134 | cur_file.mod.root.root_dir.path orelse ".", | ||
| 2135 | cur_file.mod.root.sub_path, | ||
| 2136 | }); | ||
| 2137 | defer gpa.free(resolved_root_path); | ||
| 2138 | |||
| 2139 | const sub_file_path = std.fs.path.relative(gpa, resolved_root_path, resolved_path) catch |err| switch (err) { | ||
| 2140 | error.Unexpected => unreachable, | ||
| 2141 | else => |e| return e, | ||
| 2142 | }; | 2393 | }; |
| 2143 | defer gpa.free(sub_file_path); | ||
| 2144 | 2394 | ||
| 2145 | if (isUpDir(sub_file_path) or std.fs.path.isAbsolute(sub_file_path)) { | 2395 | switch (embed_file.path.isNested(cur_file.mod.?.root)) { |
| 2146 | return error.ImportOutsideModulePath; | 2396 | .yes => {}, |
| 2397 | .different_roots, .no => return error.ImportOutsideModulePath, | ||
| 2147 | } | 2398 | } |
| 2148 | 2399 | ||
| 2149 | gop.value_ptr.* = try pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path); | 2400 | return embed_file_idx; |
| 2150 | return @enumFromInt(gop.index); | ||
| 2151 | } | 2401 | } |
| 2152 | 2402 | ||
| 2153 | pub fn updateEmbedFile( | 2403 | pub fn updateEmbedFile( |
| ... | @@ -2177,7 +2427,10 @@ fn updateEmbedFileInner( | ... | @@ -2177,7 +2427,10 @@ fn updateEmbedFileInner( |
| 2177 | const gpa = zcu.gpa; | 2427 | const gpa = zcu.gpa; |
| 2178 | const ip = &zcu.intern_pool; | 2428 | const ip = &zcu.intern_pool; |
| 2179 | 2429 | ||
| 2180 | var file = try ef.owner.root.openFile(ef.sub_file_path.toSlice(ip), .{}); | 2430 | var file = f: { |
| 2431 | const dir, const sub_path = ef.path.openInfo(zcu.comp.dirs); | ||
| 2432 | break :f try dir.openFile(sub_path, .{}); | ||
| 2433 | }; | ||
| 2181 | defer file.close(); | 2434 | defer file.close(); |
| 2182 | 2435 | ||
| 2183 | const stat: Cache.File.Stat = .fromFs(try file.stat()); | 2436 | const stat: Cache.File.Stat = .fromFs(try file.stat()); |
| ... | @@ -2232,28 +2485,21 @@ fn updateEmbedFileInner( | ... | @@ -2232,28 +2485,21 @@ fn updateEmbedFileInner( |
| 2232 | ef.stat = stat; | 2485 | ef.stat = stat; |
| 2233 | } | 2486 | } |
| 2234 | 2487 | ||
| 2488 | /// Assumes that `path` is allocated into `gpa`. Takes ownership of `path` on success. | ||
| 2235 | fn newEmbedFile( | 2489 | fn newEmbedFile( |
| 2236 | pt: Zcu.PerThread, | 2490 | pt: Zcu.PerThread, |
| 2237 | mod: *Module, | 2491 | path: Compilation.Path, |
| 2238 | /// The path of the file to embed relative to the root of `mod`. | ||
| 2239 | sub_file_path: []const u8, | ||
| 2240 | /// The resolved path of the file to embed. | ||
| 2241 | resolved_path: []const u8, | ||
| 2242 | ) !*Zcu.EmbedFile { | 2492 | ) !*Zcu.EmbedFile { |
| 2243 | const zcu = pt.zcu; | 2493 | const zcu = pt.zcu; |
| 2244 | const comp = zcu.comp; | 2494 | const comp = zcu.comp; |
| 2245 | const gpa = zcu.gpa; | 2495 | const gpa = zcu.gpa; |
| 2246 | const ip = &zcu.intern_pool; | 2496 | const ip = &zcu.intern_pool; |
| 2247 | 2497 | ||
| 2248 | if (comp.file_system_inputs) |fsi| | ||
| 2249 | try comp.appendFileSystemInput(fsi, mod.root, sub_file_path); | ||
| 2250 | |||
| 2251 | const new_file = try gpa.create(Zcu.EmbedFile); | 2498 | const new_file = try gpa.create(Zcu.EmbedFile); |
| 2252 | errdefer gpa.destroy(new_file); | 2499 | errdefer gpa.destroy(new_file); |
| 2253 | 2500 | ||
| 2254 | new_file.* = .{ | 2501 | new_file.* = .{ |
| 2255 | .owner = mod, | 2502 | .path = path, |
| 2256 | .sub_file_path = try ip.getOrPutString(gpa, pt.tid, sub_file_path, .no_embedded_nulls), | ||
| 2257 | .val = .none, | 2503 | .val = .none, |
| 2258 | .err = null, | 2504 | .err = null, |
| 2259 | .stat = undefined, | 2505 | .stat = undefined, |
| ... | @@ -2262,6 +2508,8 @@ fn newEmbedFile( | ... | @@ -2262,6 +2508,8 @@ fn newEmbedFile( |
| 2262 | var opt_ip_str: ?InternPool.String = null; | 2508 | var opt_ip_str: ?InternPool.String = null; |
| 2263 | try pt.updateEmbedFile(new_file, &opt_ip_str); | 2509 | try pt.updateEmbedFile(new_file, &opt_ip_str); |
| 2264 | 2510 | ||
| 2511 | try comp.appendFileSystemInput(path); | ||
| 2512 | |||
| 2265 | // Add the file contents to the `whole` cache manifest if necessary. | 2513 | // Add the file contents to the `whole` cache manifest if necessary. |
| 2266 | cache: { | 2514 | cache: { |
| 2267 | const whole = switch (zcu.comp.cache_use) { | 2515 | const whole = switch (zcu.comp.cache_use) { |
| ... | @@ -2269,17 +2517,18 @@ fn newEmbedFile( | ... | @@ -2269,17 +2517,18 @@ fn newEmbedFile( |
| 2269 | .incremental => break :cache, | 2517 | .incremental => break :cache, |
| 2270 | }; | 2518 | }; |
| 2271 | const man = whole.cache_manifest orelse break :cache; | 2519 | const man = whole.cache_manifest orelse break :cache; |
| 2272 | const ip_str = opt_ip_str orelse break :cache; | 2520 | const ip_str = opt_ip_str orelse break :cache; // this will be a compile error |
| 2273 | |||
| 2274 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); | ||
| 2275 | errdefer gpa.free(copied_resolved_path); | ||
| 2276 | 2521 | ||
| 2277 | const array_len = Value.fromInterned(new_file.val).typeOf(zcu).childType(zcu).arrayLen(zcu); | 2522 | const array_len = Value.fromInterned(new_file.val).typeOf(zcu).childType(zcu).arrayLen(zcu); |
| 2523 | const contents = ip_str.toSlice(array_len, ip); | ||
| 2524 | |||
| 2525 | const path_str = try path.toAbsolute(comp.dirs, gpa); | ||
| 2526 | defer gpa.free(path_str); | ||
| 2278 | 2527 | ||
| 2279 | whole.cache_manifest_mutex.lock(); | 2528 | whole.cache_manifest_mutex.lock(); |
| 2280 | defer whole.cache_manifest_mutex.unlock(); | 2529 | defer whole.cache_manifest_mutex.unlock(); |
| 2281 | 2530 | ||
| 2282 | man.addFilePostContents(copied_resolved_path, ip_str.toSlice(array_len, ip), new_file.stat) catch |err| switch (err) { | 2531 | man.addFilePostContents(path_str, contents, new_file.stat) catch |err| switch (err) { |
| 2283 | error.Unexpected => unreachable, | 2532 | error.Unexpected => unreachable, |
| 2284 | else => |e| return e, | 2533 | else => |e| return e, |
| 2285 | }; | 2534 | }; |
| ... | @@ -2805,7 +3054,7 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err | ... | @@ -2805,7 +3054,7 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err |
| 2805 | 3054 | ||
| 2806 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. | 3055 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. |
| 2807 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. | 3056 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. |
| 2808 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | 3057 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file_index: Zcu.File.Index, file: *Zcu.File) void { |
| 2809 | const maybe_has_error = switch (file.status) { | 3058 | const maybe_has_error = switch (file.status) { |
| 2810 | .never_loaded => false, | 3059 | .never_loaded => false, |
| 2811 | .retryable_failure => true, | 3060 | .retryable_failure => true, |
| ... | @@ -2829,9 +3078,9 @@ fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | ... | @@ -2829,9 +3078,9 @@ fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 2829 | 3078 | ||
| 2830 | pt.zcu.comp.mutex.lock(); | 3079 | pt.zcu.comp.mutex.lock(); |
| 2831 | defer pt.zcu.comp.mutex.unlock(); | 3080 | defer pt.zcu.comp.mutex.unlock(); |
| 2832 | if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| { | 3081 | if (pt.zcu.failed_files.fetchSwapRemove(file_index)) |kv| { |
| 2833 | assert(maybe_has_error); // the runtime safety case above | 3082 | assert(maybe_has_error); // the runtime safety case above |
| 2834 | if (kv.value) |msg| msg.destroy(pt.zcu.gpa); // delete previous error message | 3083 | if (kv.value) |msg| pt.zcu.gpa.free(msg); // delete previous error message |
| 2835 | } | 3084 | } |
| 2836 | } | 3085 | } |
| 2837 | 3086 | ||
| ... | @@ -3009,8 +3258,8 @@ pub fn populateTestFunctions( | ... | @@ -3009,8 +3258,8 @@ pub fn populateTestFunctions( |
| 3009 | const zcu = pt.zcu; | 3258 | const zcu = pt.zcu; |
| 3010 | const gpa = zcu.gpa; | 3259 | const gpa = zcu.gpa; |
| 3011 | const ip = &zcu.intern_pool; | 3260 | const ip = &zcu.intern_pool; |
| 3012 | const builtin_mod = zcu.root_mod.getBuiltinDependency(); | 3261 | const builtin_mod = zcu.builtin_modules.get(zcu.root_mod.getBuiltinOptions(zcu.comp.config).hash()).?; |
| 3013 | const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index; | 3262 | const builtin_file_index = zcu.module_roots.get(builtin_mod).?.unwrap().?; |
| 3014 | pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) { | 3263 | pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) { |
| 3015 | error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt | 3264 | error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt |
| 3016 | error.OutOfMemory => |e| return e, | 3265 | error.OutOfMemory => |e| return e, |
| ... | @@ -3213,54 +3462,8 @@ pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Inde | ... | @@ -3213,54 +3462,8 @@ pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Inde |
| 3213 | } | 3462 | } |
| 3214 | } | 3463 | } |
| 3215 | 3464 | ||
| 3216 | /// Sets `File.status` of `file_index` to `retryable_failure`, and stores an error in `pt.zcu.failed_files`. | 3465 | /// Stores an error in `pt.zcu.failed_files` for this file, and sets the file |
| 3217 | pub fn reportRetryableAstGenError( | 3466 | /// status to `retryable_failure`. |
| 3218 | pt: Zcu.PerThread, | ||
| 3219 | src: Zcu.AstGenSrc, | ||
| 3220 | file_index: Zcu.File.Index, | ||
| 3221 | err: anyerror, | ||
| 3222 | ) error{OutOfMemory}!void { | ||
| 3223 | const zcu = pt.zcu; | ||
| 3224 | const gpa = zcu.gpa; | ||
| 3225 | const ip = &zcu.intern_pool; | ||
| 3226 | |||
| 3227 | const file = zcu.fileByIndex(file_index); | ||
| 3228 | file.status = .retryable_failure; | ||
| 3229 | |||
| 3230 | const src_loc: Zcu.LazySrcLoc = switch (src) { | ||
| 3231 | .root => .{ | ||
| 3232 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 3233 | .file = file_index, | ||
| 3234 | .inst = .main_struct_inst, | ||
| 3235 | }), | ||
| 3236 | .offset = .entire_file, | ||
| 3237 | }, | ||
| 3238 | .import => |info| .{ | ||
| 3239 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 3240 | .file = info.importing_file, | ||
| 3241 | .inst = .main_struct_inst, | ||
| 3242 | }), | ||
| 3243 | .offset = .{ .token_abs = info.import_tok }, | ||
| 3244 | }, | ||
| 3245 | }; | ||
| 3246 | |||
| 3247 | const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}/{s}': {s}", .{ | ||
| 3248 | file.mod.root, file.sub_file_path, @errorName(err), | ||
| 3249 | }); | ||
| 3250 | errdefer err_msg.destroy(gpa); | ||
| 3251 | |||
| 3252 | zcu.comp.mutex.lock(); | ||
| 3253 | defer zcu.comp.mutex.unlock(); | ||
| 3254 | const gop = try zcu.failed_files.getOrPut(gpa, file); | ||
| 3255 | if (gop.found_existing) { | ||
| 3256 | if (gop.value_ptr.*) |old_err_msg| { | ||
| 3257 | old_err_msg.destroy(gpa); | ||
| 3258 | } | ||
| 3259 | } | ||
| 3260 | gop.value_ptr.* = err_msg; | ||
| 3261 | } | ||
| 3262 | |||
| 3263 | /// Sets `File.status` of `file_index` to `retryable_failure`, and stores an error in `pt.zcu.failed_files`. | ||
| 3264 | pub fn reportRetryableFileError( | 3467 | pub fn reportRetryableFileError( |
| 3265 | pt: Zcu.PerThread, | 3468 | pt: Zcu.PerThread, |
| 3266 | file_index: Zcu.File.Index, | 3469 | file_index: Zcu.File.Index, |
| ... | @@ -3269,35 +3472,27 @@ pub fn reportRetryableFileError( | ... | @@ -3269,35 +3472,27 @@ pub fn reportRetryableFileError( |
| 3269 | ) error{OutOfMemory}!void { | 3472 | ) error{OutOfMemory}!void { |
| 3270 | const zcu = pt.zcu; | 3473 | const zcu = pt.zcu; |
| 3271 | const gpa = zcu.gpa; | 3474 | const gpa = zcu.gpa; |
| 3272 | const ip = &zcu.intern_pool; | ||
| 3273 | 3475 | ||
| 3274 | const file = zcu.fileByIndex(file_index); | 3476 | const file = zcu.fileByIndex(file_index); |
| 3477 | |||
| 3275 | file.status = .retryable_failure; | 3478 | file.status = .retryable_failure; |
| 3276 | 3479 | ||
| 3277 | const err_msg = try Zcu.ErrorMsg.create( | 3480 | const msg = try std.fmt.allocPrint(gpa, format, args); |
| 3278 | gpa, | 3481 | errdefer gpa.free(msg); |
| 3279 | .{ | ||
| 3280 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 3281 | .file = file_index, | ||
| 3282 | .inst = .main_struct_inst, | ||
| 3283 | }), | ||
| 3284 | .offset = .entire_file, | ||
| 3285 | }, | ||
| 3286 | format, | ||
| 3287 | args, | ||
| 3288 | ); | ||
| 3289 | errdefer err_msg.destroy(gpa); | ||
| 3290 | 3482 | ||
| 3291 | zcu.comp.mutex.lock(); | 3483 | const old_msg: ?[]u8 = old_msg: { |
| 3292 | defer zcu.comp.mutex.unlock(); | 3484 | zcu.comp.mutex.lock(); |
| 3485 | defer zcu.comp.mutex.unlock(); | ||
| 3293 | 3486 | ||
| 3294 | const gop = try zcu.failed_files.getOrPut(gpa, file); | 3487 | const gop = try zcu.failed_files.getOrPut(gpa, file_index); |
| 3295 | if (gop.found_existing) { | 3488 | const old: ?[]u8 = if (gop.found_existing) old: { |
| 3296 | if (gop.value_ptr.*) |old_err_msg| { | 3489 | break :old gop.value_ptr.*; |
| 3297 | old_err_msg.destroy(gpa); | 3490 | } else null; |
| 3298 | } | 3491 | gop.value_ptr.* = msg; |
| 3299 | } | 3492 | |
| 3300 | gop.value_ptr.* = err_msg; | 3493 | break :old_msg old; |
| 3494 | }; | ||
| 3495 | if (old_msg) |m| gpa.free(m); | ||
| 3301 | } | 3496 | } |
| 3302 | 3497 | ||
| 3303 | /// Shortcut for calling `intern_pool.get`. | 3498 | /// Shortcut for calling `intern_pool.get`. |
| ... | @@ -3850,7 +4045,7 @@ fn recreateStructType( | ... | @@ -3850,7 +4045,7 @@ fn recreateStructType( |
| 3850 | 4045 | ||
| 3851 | codegen_type: { | 4046 | codegen_type: { |
| 3852 | if (zcu.comp.config.use_llvm) break :codegen_type; | 4047 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3853 | if (file.mod.strip) break :codegen_type; | 4048 | if (file.mod.?.strip) break :codegen_type; |
| 3854 | // This job depends on any resolve_type_fully jobs queued up before it. | 4049 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3855 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | 4050 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); |
| 3856 | } | 4051 | } |
| ... | @@ -3946,7 +4141,7 @@ fn recreateUnionType( | ... | @@ -3946,7 +4141,7 @@ fn recreateUnionType( |
| 3946 | 4141 | ||
| 3947 | codegen_type: { | 4142 | codegen_type: { |
| 3948 | if (zcu.comp.config.use_llvm) break :codegen_type; | 4143 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3949 | if (file.mod.strip) break :codegen_type; | 4144 | if (file.mod.?.strip) break :codegen_type; |
| 3950 | // This job depends on any resolve_type_fully jobs queued up before it. | 4145 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3951 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | 4146 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); |
| 3952 | } | 4147 | } |
src/arch/aarch64/CodeGen.zig+1-1| ... | @@ -333,7 +333,7 @@ pub fn generate( | ... | @@ -333,7 +333,7 @@ pub fn generate( |
| 333 | const func = zcu.funcInfo(func_index); | 333 | const func = zcu.funcInfo(func_index); |
| 334 | const fn_type = Type.fromInterned(func.ty); | 334 | const fn_type = Type.fromInterned(func.ty); |
| 335 | const file_scope = zcu.navFileScope(func.owner_nav); | 335 | const file_scope = zcu.navFileScope(func.owner_nav); |
| 336 | const target = &file_scope.mod.resolved_target.result; | 336 | const target = &file_scope.mod.?.resolved_target.result; |
| 337 | 337 | ||
| 338 | var branch_stack = std.ArrayList(Branch).init(gpa); | 338 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 339 | defer { | 339 | defer { |
src/arch/arm/CodeGen.zig+1-1| ... | @@ -342,7 +342,7 @@ pub fn generate( | ... | @@ -342,7 +342,7 @@ pub fn generate( |
| 342 | const func = zcu.funcInfo(func_index); | 342 | const func = zcu.funcInfo(func_index); |
| 343 | const func_ty = Type.fromInterned(func.ty); | 343 | const func_ty = Type.fromInterned(func.ty); |
| 344 | const file_scope = zcu.navFileScope(func.owner_nav); | 344 | const file_scope = zcu.navFileScope(func.owner_nav); |
| 345 | const target = &file_scope.mod.resolved_target.result; | 345 | const target = &file_scope.mod.?.resolved_target.result; |
| 346 | 346 | ||
| 347 | var branch_stack = std.ArrayList(Branch).init(gpa); | 347 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 348 | defer { | 348 | defer { |
src/arch/riscv64/CodeGen.zig+1-1| ... | @@ -767,7 +767,7 @@ pub fn generate( | ... | @@ -767,7 +767,7 @@ pub fn generate( |
| 767 | const ip = &zcu.intern_pool; | 767 | const ip = &zcu.intern_pool; |
| 768 | const func = zcu.funcInfo(func_index); | 768 | const func = zcu.funcInfo(func_index); |
| 769 | const fn_type = Type.fromInterned(func.ty); | 769 | const fn_type = Type.fromInterned(func.ty); |
| 770 | const mod = zcu.navFileScope(func.owner_nav).mod; | 770 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 771 | 771 | ||
| 772 | var branch_stack = std.ArrayList(Branch).init(gpa); | 772 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 773 | defer { | 773 | defer { |
src/arch/sparc64/CodeGen.zig+1-1| ... | @@ -275,7 +275,7 @@ pub fn generate( | ... | @@ -275,7 +275,7 @@ pub fn generate( |
| 275 | const func = zcu.funcInfo(func_index); | 275 | const func = zcu.funcInfo(func_index); |
| 276 | const func_ty = Type.fromInterned(func.ty); | 276 | const func_ty = Type.fromInterned(func.ty); |
| 277 | const file_scope = zcu.navFileScope(func.owner_nav); | 277 | const file_scope = zcu.navFileScope(func.owner_nav); |
| 278 | const target = &file_scope.mod.resolved_target.result; | 278 | const target = &file_scope.mod.?.resolved_target.result; |
| 279 | 279 | ||
| 280 | var branch_stack = std.ArrayList(Branch).init(gpa); | 280 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 281 | defer { | 281 | defer { |
src/arch/wasm/CodeGen.zig+1-1| ... | @@ -1268,7 +1268,7 @@ pub fn function( | ... | @@ -1268,7 +1268,7 @@ pub fn function( |
| 1268 | const gpa = zcu.gpa; | 1268 | const gpa = zcu.gpa; |
| 1269 | const cg = zcu.funcInfo(func_index); | 1269 | const cg = zcu.funcInfo(func_index); |
| 1270 | const file_scope = zcu.navFileScope(cg.owner_nav); | 1270 | const file_scope = zcu.navFileScope(cg.owner_nav); |
| 1271 | const target = &file_scope.mod.resolved_target.result; | 1271 | const target = &file_scope.mod.?.resolved_target.result; |
| 1272 | const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu); | 1272 | const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu); |
| 1273 | const fn_info = zcu.typeToFunc(fn_ty).?; | 1273 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| 1274 | const ip = &zcu.intern_pool; | 1274 | const ip = &zcu.intern_pool; |
src/arch/x86_64/CodeGen.zig+1-1| ... | @@ -892,7 +892,7 @@ pub fn generate( | ... | @@ -892,7 +892,7 @@ pub fn generate( |
| 892 | const ip = &zcu.intern_pool; | 892 | const ip = &zcu.intern_pool; |
| 893 | const func = zcu.funcInfo(func_index); | 893 | const func = zcu.funcInfo(func_index); |
| 894 | const fn_type: Type = .fromInterned(func.ty); | 894 | const fn_type: Type = .fromInterned(func.ty); |
| 895 | const mod = zcu.navFileScope(func.owner_nav).mod; | 895 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 896 | 896 | ||
| 897 | var function: CodeGen = .{ | 897 | var function: CodeGen = .{ |
| 898 | .gpa = gpa, | 898 | .gpa = gpa, |
src/codegen.zig+4-4| ... | @@ -56,7 +56,7 @@ pub fn generateFunction( | ... | @@ -56,7 +56,7 @@ pub fn generateFunction( |
| 56 | ) CodeGenError!void { | 56 | ) CodeGenError!void { |
| 57 | const zcu = pt.zcu; | 57 | const zcu = pt.zcu; |
| 58 | const func = zcu.funcInfo(func_index); | 58 | const func = zcu.funcInfo(func_index); |
| 59 | const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result; | 59 | const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| 60 | switch (target_util.zigBackend(target, false)) { | 60 | switch (target_util.zigBackend(target, false)) { |
| 61 | else => unreachable, | 61 | else => unreachable, |
| 62 | inline .stage2_aarch64, | 62 | inline .stage2_aarch64, |
| ... | @@ -81,7 +81,7 @@ pub fn generateLazyFunction( | ... | @@ -81,7 +81,7 @@ pub fn generateLazyFunction( |
| 81 | ) CodeGenError!void { | 81 | ) CodeGenError!void { |
| 82 | const zcu = pt.zcu; | 82 | const zcu = pt.zcu; |
| 83 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| | 83 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| |
| 84 | zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.resolved_target.result | 84 | zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result |
| 85 | else | 85 | else |
| 86 | zcu.getTarget(); | 86 | zcu.getTarget(); |
| 87 | switch (target_util.zigBackend(target, false)) { | 87 | switch (target_util.zigBackend(target, false)) { |
| ... | @@ -722,7 +722,7 @@ fn lowerNavRef( | ... | @@ -722,7 +722,7 @@ fn lowerNavRef( |
| 722 | const zcu = pt.zcu; | 722 | const zcu = pt.zcu; |
| 723 | const gpa = zcu.gpa; | 723 | const gpa = zcu.gpa; |
| 724 | const ip = &zcu.intern_pool; | 724 | const ip = &zcu.intern_pool; |
| 725 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 725 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 726 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); | 726 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 727 | const is_obj = lf.comp.config.output_mode == .Obj; | 727 | const is_obj = lf.comp.config.output_mode == .Obj; |
| 728 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); | 728 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); |
| ... | @@ -884,7 +884,7 @@ fn genNavRef( | ... | @@ -884,7 +884,7 @@ fn genNavRef( |
| 884 | else | 884 | else |
| 885 | .{ false, .none, nav.isThreadlocal(ip) }; | 885 | .{ false, .none, nav.isThreadlocal(ip) }; |
| 886 | 886 | ||
| 887 | const single_threaded = zcu.navFileScope(nav_index).mod.single_threaded; | 887 | const single_threaded = zcu.navFileScope(nav_index).mod.?.single_threaded; |
| 888 | const name = nav.name; | 888 | const name = nav.name; |
| 889 | if (lf.cast(.elf)) |elf_file| { | 889 | if (lf.cast(.elf)) |elf_file| { |
| 890 | const zo = elf_file.zigObjectPtr().?; | 890 | const zo = elf_file.zigObjectPtr().?; |
src/codegen/c.zig+1-1| ... | @@ -2670,7 +2670,7 @@ pub fn genTypeDecl( | ... | @@ -2670,7 +2670,7 @@ pub fn genTypeDecl( |
| 2670 | _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{}); | 2670 | _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{}); |
| 2671 | try writer.writeByte(';'); | 2671 | try writer.writeByte(';'); |
| 2672 | const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip); | 2672 | const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip); |
| 2673 | if (!zcu.fileByIndex(file_scope).mod.strip) try writer.print(" /* {} */", .{ | 2673 | if (!zcu.fileByIndex(file_scope).mod.?.strip) try writer.print(" /* {} */", .{ |
| 2674 | ty.containerTypeName(ip).fmt(ip), | 2674 | ty.containerTypeName(ip).fmt(ip), |
| 2675 | }); | 2675 | }); |
| 2676 | try writer.writeByte('\n'); | 2676 | try writer.writeByte('\n'); |
src/codegen/llvm.zig+17-30| ... | @@ -587,13 +587,8 @@ pub const Object = struct { | ... | @@ -587,13 +587,8 @@ pub const Object = struct { |
| 587 | // into the garbage can by converting into absolute paths. What | 587 | // into the garbage can by converting into absolute paths. What |
| 588 | // a terrible tragedy. | 588 | // a terrible tragedy. |
| 589 | const compile_unit_dir = blk: { | 589 | const compile_unit_dir = blk: { |
| 590 | if (comp.zcu) |zcu| m: { | 590 | const zcu = comp.zcu orelse break :blk comp.dirs.cwd; |
| 591 | const d = try zcu.main_mod.root.joinString(arena, ""); | 591 | break :blk try zcu.main_mod.root.toAbsolute(comp.dirs, arena); |
| 592 | if (d.len == 0) break :m; | ||
| 593 | if (std.fs.path.isAbsolute(d)) break :blk d; | ||
| 594 | break :blk std.fs.realpathAlloc(arena, d) catch break :blk d; | ||
| 595 | } | ||
| 596 | break :blk try std.process.getCwdAlloc(arena); | ||
| 597 | }; | 592 | }; |
| 598 | 593 | ||
| 599 | const debug_file = try builder.debugFile( | 594 | const debug_file = try builder.debugFile( |
| ... | @@ -1135,7 +1130,7 @@ pub const Object = struct { | ... | @@ -1135,7 +1130,7 @@ pub const Object = struct { |
| 1135 | const func = zcu.funcInfo(func_index); | 1130 | const func = zcu.funcInfo(func_index); |
| 1136 | const nav = ip.getNav(func.owner_nav); | 1131 | const nav = ip.getNav(func.owner_nav); |
| 1137 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); | 1132 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); |
| 1138 | const owner_mod = zcu.fileByIndex(file_scope).mod; | 1133 | const owner_mod = zcu.fileByIndex(file_scope).mod.?; |
| 1139 | const fn_ty = Type.fromInterned(func.ty); | 1134 | const fn_ty = Type.fromInterned(func.ty); |
| 1140 | const fn_info = zcu.typeToFunc(fn_ty).?; | 1135 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| 1141 | const target = owner_mod.resolved_target.result; | 1136 | const target = owner_mod.resolved_target.result; |
| ... | @@ -1735,20 +1730,14 @@ pub const Object = struct { | ... | @@ -1735,20 +1730,14 @@ pub const Object = struct { |
| 1735 | const gop = try o.debug_file_map.getOrPut(gpa, file_index); | 1730 | const gop = try o.debug_file_map.getOrPut(gpa, file_index); |
| 1736 | errdefer assert(o.debug_file_map.remove(file_index)); | 1731 | errdefer assert(o.debug_file_map.remove(file_index)); |
| 1737 | if (gop.found_existing) return gop.value_ptr.*; | 1732 | if (gop.found_existing) return gop.value_ptr.*; |
| 1738 | const file = o.pt.zcu.fileByIndex(file_index); | 1733 | const zcu = o.pt.zcu; |
| 1734 | const path = zcu.fileByIndex(file_index).path; | ||
| 1735 | const abs_path = try path.toAbsolute(zcu.comp.dirs, gpa); | ||
| 1736 | defer gpa.free(abs_path); | ||
| 1737 | |||
| 1739 | gop.value_ptr.* = try o.builder.debugFile( | 1738 | gop.value_ptr.* = try o.builder.debugFile( |
| 1740 | try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)), | 1739 | try o.builder.metadataString(std.fs.path.basename(abs_path)), |
| 1741 | dir_path: { | 1740 | try o.builder.metadataString(std.fs.path.dirname(abs_path) orelse ""), |
| 1742 | const sub_path = std.fs.path.dirname(file.sub_file_path) orelse ""; | ||
| 1743 | const dir_path = try file.mod.root.joinString(gpa, sub_path); | ||
| 1744 | defer gpa.free(dir_path); | ||
| 1745 | if (std.fs.path.isAbsolute(dir_path)) | ||
| 1746 | break :dir_path try o.builder.metadataString(dir_path); | ||
| 1747 | var abs_buffer: [std.fs.max_path_bytes]u8 = undefined; | ||
| 1748 | const abs_path = std.fs.realpath(dir_path, &abs_buffer) catch | ||
| 1749 | break :dir_path try o.builder.metadataString(dir_path); | ||
| 1750 | break :dir_path try o.builder.metadataString(abs_path); | ||
| 1751 | }, | ||
| 1752 | ); | 1741 | ); |
| 1753 | return gop.value_ptr.*; | 1742 | return gop.value_ptr.*; |
| 1754 | } | 1743 | } |
| ... | @@ -2646,11 +2635,9 @@ pub const Object = struct { | ... | @@ -2646,11 +2635,9 @@ pub const Object = struct { |
| 2646 | const zcu = pt.zcu; | 2635 | const zcu = pt.zcu; |
| 2647 | const ip = &zcu.intern_pool; | 2636 | const ip = &zcu.intern_pool; |
| 2648 | 2637 | ||
| 2649 | const std_mod = zcu.std_mod; | 2638 | const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?; |
| 2650 | const std_file_imported = pt.importPkg(std_mod) catch unreachable; | ||
| 2651 | |||
| 2652 | const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls); | 2639 | const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls); |
| 2653 | const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index)); | 2640 | const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_index)); |
| 2654 | const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu)); | 2641 | const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu)); |
| 2655 | const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?; | 2642 | const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?; |
| 2656 | 2643 | ||
| ... | @@ -2683,7 +2670,7 @@ pub const Object = struct { | ... | @@ -2683,7 +2670,7 @@ pub const Object = struct { |
| 2683 | const ip = &zcu.intern_pool; | 2670 | const ip = &zcu.intern_pool; |
| 2684 | const gpa = o.gpa; | 2671 | const gpa = o.gpa; |
| 2685 | const nav = ip.getNav(nav_index); | 2672 | const nav = ip.getNav(nav_index); |
| 2686 | const owner_mod = zcu.navFileScope(nav_index).mod; | 2673 | const owner_mod = zcu.navFileScope(nav_index).mod.?; |
| 2687 | const ty: Type = .fromInterned(nav.typeOf(ip)); | 2674 | const ty: Type = .fromInterned(nav.typeOf(ip)); |
| 2688 | const gop = try o.nav_map.getOrPut(gpa, nav_index); | 2675 | const gop = try o.nav_map.getOrPut(gpa, nav_index); |
| 2689 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; | 2676 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; |
| ... | @@ -3013,7 +3000,7 @@ pub const Object = struct { | ... | @@ -3013,7 +3000,7 @@ pub const Object = struct { |
| 3013 | if (is_extern) { | 3000 | if (is_extern) { |
| 3014 | variable_index.setLinkage(.external, &o.builder); | 3001 | variable_index.setLinkage(.external, &o.builder); |
| 3015 | variable_index.setUnnamedAddr(.default, &o.builder); | 3002 | variable_index.setUnnamedAddr(.default, &o.builder); |
| 3016 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded) | 3003 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.?.single_threaded) |
| 3017 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 3004 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 3018 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); | 3005 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); |
| 3019 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); | 3006 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); |
| ... | @@ -4514,7 +4501,7 @@ pub const NavGen = struct { | ... | @@ -4514,7 +4501,7 @@ pub const NavGen = struct { |
| 4514 | err_msg: ?*Zcu.ErrorMsg, | 4501 | err_msg: ?*Zcu.ErrorMsg, |
| 4515 | 4502 | ||
| 4516 | fn ownerModule(ng: NavGen) *Package.Module { | 4503 | fn ownerModule(ng: NavGen) *Package.Module { |
| 4517 | return ng.object.pt.zcu.navFileScope(ng.nav_index).mod; | 4504 | return ng.object.pt.zcu.navFileScope(ng.nav_index).mod.?; |
| 4518 | } | 4505 | } |
| 4519 | 4506 | ||
| 4520 | fn todo(ng: *NavGen, comptime format: []const u8, args: anytype) Error { | 4507 | fn todo(ng: *NavGen, comptime format: []const u8, args: anytype) Error { |
| ... | @@ -4557,7 +4544,7 @@ pub const NavGen = struct { | ... | @@ -4557,7 +4544,7 @@ pub const NavGen = struct { |
| 4557 | }, &o.builder); | 4544 | }, &o.builder); |
| 4558 | 4545 | ||
| 4559 | const file_scope = zcu.navFileScopeIndex(nav_index); | 4546 | const file_scope = zcu.navFileScopeIndex(nav_index); |
| 4560 | const mod = zcu.fileByIndex(file_scope).mod; | 4547 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| 4561 | if (is_threadlocal and !mod.single_threaded) | 4548 | if (is_threadlocal and !mod.single_threaded) |
| 4562 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 4549 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 4563 | 4550 | ||
| ... | @@ -5121,7 +5108,7 @@ pub const FuncGen = struct { | ... | @@ -5121,7 +5108,7 @@ pub const FuncGen = struct { |
| 5121 | const func = zcu.funcInfo(inline_func); | 5108 | const func = zcu.funcInfo(inline_func); |
| 5122 | const nav = ip.getNav(func.owner_nav); | 5109 | const nav = ip.getNav(func.owner_nav); |
| 5123 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); | 5110 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); |
| 5124 | const mod = zcu.fileByIndex(file_scope).mod; | 5111 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| 5125 | 5112 | ||
| 5126 | self.file = try o.getDebugFile(file_scope); | 5113 | self.file = try o.getDebugFile(file_scope); |
| 5127 | 5114 |
src/codegen/spirv.zig+1-1| ... | @@ -201,7 +201,7 @@ pub const Object = struct { | ... | @@ -201,7 +201,7 @@ pub const Object = struct { |
| 201 | ) !void { | 201 | ) !void { |
| 202 | const zcu = pt.zcu; | 202 | const zcu = pt.zcu; |
| 203 | const gpa = zcu.gpa; | 203 | const gpa = zcu.gpa; |
| 204 | const structured_cfg = zcu.navFileScope(nav_index).mod.structured_cfg; | 204 | const structured_cfg = zcu.navFileScope(nav_index).mod.?.structured_cfg; |
| 205 | 205 | ||
| 206 | var nav_gen = NavGen{ | 206 | var nav_gen = NavGen{ |
| 207 | .gpa = gpa, | 207 | .gpa = gpa, |
src/crash_report.zig+13-27| ... | @@ -86,15 +86,12 @@ fn dumpStatusReport() !void { | ... | @@ -86,15 +86,12 @@ fn dumpStatusReport() !void { |
| 86 | 86 | ||
| 87 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse { | 87 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse { |
| 88 | const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool)); | 88 | const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool)); |
| 89 | try stderr.writeAll("Analyzing lost instruction in file '"); | 89 | try stderr.print("Analyzing lost instruction in file '{}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)}); |
| 90 | try writeFilePath(file, stderr); | ||
| 91 | try stderr.writeAll("'. This should not happen!\n\n"); | ||
| 92 | return; | 90 | return; |
| 93 | }; | 91 | }; |
| 94 | 92 | ||
| 95 | try stderr.writeAll("Analyzing "); | 93 | try stderr.writeAll("Analyzing "); |
| 96 | try writeFilePath(file, stderr); | 94 | try stderr.print("Analyzing '{}'\n", .{file.path.fmt(zcu.comp)}); |
| 97 | try stderr.writeAll("\n"); | ||
| 98 | 95 | ||
| 99 | print_zir.renderInstructionContext( | 96 | print_zir.renderInstructionContext( |
| 100 | allocator, | 97 | allocator, |
| ... | @@ -108,23 +105,24 @@ fn dumpStatusReport() !void { | ... | @@ -108,23 +105,24 @@ fn dumpStatusReport() !void { |
| 108 | error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"), | 105 | error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"), |
| 109 | else => |e| return e, | 106 | else => |e| return e, |
| 110 | }; | 107 | }; |
| 111 | try stderr.writeAll(" For full context, use the command\n zig ast-check -t "); | 108 | try stderr.print( |
| 112 | try writeFilePath(file, stderr); | 109 | \\ For full context, use the command |
| 113 | try stderr.writeAll("\n\n"); | 110 | \\ zig ast-check -t {} |
| 111 | \\ | ||
| 112 | \\ | ||
| 113 | , .{file.path.fmt(zcu.comp)}); | ||
| 114 | 114 | ||
| 115 | var parent = anal.parent; | 115 | var parent = anal.parent; |
| 116 | while (parent) |curr| { | 116 | while (parent) |curr| { |
| 117 | fba.reset(); | 117 | fba.reset(); |
| 118 | try stderr.writeAll(" in "); | 118 | const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool)); |
| 119 | const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse { | 119 | try stderr.print(" in {}\n", .{cur_block_file.path.fmt(zcu.comp)}); |
| 120 | const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool)); | 120 | _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse { |
| 121 | try writeFilePath(cur_block_file, stderr); | 121 | try stderr.writeAll(" > [lost instruction; this should not happen]\n"); |
| 122 | try stderr.writeAll("\n > [lost instruction; this should not happen]\n"); | ||
| 123 | parent = curr.parent; | 122 | parent = curr.parent; |
| 124 | continue; | 123 | continue; |
| 125 | }; | 124 | }; |
| 126 | try writeFilePath(cur_block_file, stderr); | 125 | try stderr.writeAll(" > "); |
| 127 | try stderr.writeAll("\n > "); | ||
| 128 | print_zir.renderSingleInstruction( | 126 | print_zir.renderSingleInstruction( |
| 129 | allocator, | 127 | allocator, |
| 130 | curr.body[curr.body_index], | 128 | curr.body[curr.body_index], |
| ... | @@ -146,18 +144,6 @@ fn dumpStatusReport() !void { | ... | @@ -146,18 +144,6 @@ fn dumpStatusReport() !void { |
| 146 | 144 | ||
| 147 | var crash_heap: [16 * 4096]u8 = undefined; | 145 | var crash_heap: [16 * 4096]u8 = undefined; |
| 148 | 146 | ||
| 149 | fn writeFilePath(file: *Zcu.File, writer: anytype) !void { | ||
| 150 | if (file.mod.root.root_dir.path) |path| { | ||
| 151 | try writer.writeAll(path); | ||
| 152 | try writer.writeAll(std.fs.path.sep_str); | ||
| 153 | } | ||
| 154 | if (file.mod.root.sub_path.len > 0) { | ||
| 155 | try writer.writeAll(file.mod.root.sub_path); | ||
| 156 | try writer.writeAll(std.fs.path.sep_str); | ||
| 157 | } | ||
| 158 | try writer.writeAll(file.sub_file_path); | ||
| 159 | } | ||
| 160 | |||
| 161 | pub fn compilerPanic(msg: []const u8, maybe_ret_addr: ?usize) noreturn { | 147 | pub fn compilerPanic(msg: []const u8, maybe_ret_addr: ?usize) noreturn { |
| 162 | @branchHint(.cold); | 148 | @branchHint(.cold); |
| 163 | PanicSwitch.preDispatch(); | 149 | PanicSwitch.preDispatch(); |
src/introspect.zig+129-60| ... | @@ -1,15 +1,18 @@ | ... | @@ -1,15 +1,18 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const mem = std.mem; | 3 | const mem = std.mem; |
| 4 | const Allocator = mem.Allocator; | ||
| 4 | const os = std.os; | 5 | const os = std.os; |
| 5 | const fs = std.fs; | 6 | const fs = std.fs; |
| 7 | const Cache = std.Build.Cache; | ||
| 6 | const Compilation = @import("Compilation.zig"); | 8 | const Compilation = @import("Compilation.zig"); |
| 9 | const Package = @import("Package.zig"); | ||
| 7 | const build_options = @import("build_options"); | 10 | const build_options = @import("build_options"); |
| 8 | 11 | ||
| 9 | /// Returns the sub_path that worked, or `null` if none did. | 12 | /// Returns the sub_path that worked, or `null` if none did. |
| 10 | /// The path of the returned Directory is relative to `base`. | 13 | /// The path of the returned Directory is relative to `base`. |
| 11 | /// The handle of the returned Directory is open. | 14 | /// The handle of the returned Directory is open. |
| 12 | fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { | 15 | fn testZigInstallPrefix(base_dir: fs.Dir) ?Cache.Directory { |
| 13 | const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; | 16 | const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; |
| 14 | 17 | ||
| 15 | zig_dir: { | 18 | zig_dir: { |
| ... | @@ -21,7 +24,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { | ... | @@ -21,7 +24,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { |
| 21 | break :zig_dir; | 24 | break :zig_dir; |
| 22 | }; | 25 | }; |
| 23 | file.close(); | 26 | file.close(); |
| 24 | return Compilation.Directory{ .handle = test_zig_dir, .path = lib_zig }; | 27 | return .{ .handle = test_zig_dir, .path = lib_zig }; |
| 25 | } | 28 | } |
| 26 | 29 | ||
| 27 | // Try lib/std/std.zig | 30 | // Try lib/std/std.zig |
| ... | @@ -31,37 +34,50 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { | ... | @@ -31,37 +34,50 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { |
| 31 | return null; | 34 | return null; |
| 32 | }; | 35 | }; |
| 33 | file.close(); | 36 | file.close(); |
| 34 | return Compilation.Directory{ .handle = test_zig_dir, .path = "lib" }; | 37 | return .{ .handle = test_zig_dir, .path = "lib" }; |
| 35 | } | ||
| 36 | |||
| 37 | /// This is a small wrapper around selfExePathAlloc that adds support for WASI | ||
| 38 | /// based on a hard-coded Preopen directory ("/zig") | ||
| 39 | pub fn findZigExePath(allocator: mem.Allocator) ![]u8 { | ||
| 40 | if (builtin.os.tag == .wasi) { | ||
| 41 | @compileError("this function is unsupported on WASI"); | ||
| 42 | } | ||
| 43 | |||
| 44 | return fs.selfExePathAlloc(allocator); | ||
| 45 | } | 38 | } |
| 46 | 39 | ||
| 47 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | 40 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. |
| 48 | pub fn findZigLibDir(gpa: mem.Allocator) !Compilation.Directory { | 41 | pub fn findZigLibDir(gpa: Allocator) !Cache.Directory { |
| 49 | const self_exe_path = try findZigExePath(gpa); | 42 | const cwd_path = try getResolvedCwd(gpa); |
| 43 | defer gpa.free(cwd_path); | ||
| 44 | const self_exe_path = try fs.selfExePathAlloc(gpa); | ||
| 50 | defer gpa.free(self_exe_path); | 45 | defer gpa.free(self_exe_path); |
| 51 | 46 | ||
| 52 | return findZigLibDirFromSelfExe(gpa, self_exe_path); | 47 | return findZigLibDirFromSelfExe(gpa, cwd_path, self_exe_path); |
| 53 | } | 48 | } |
| 54 | 49 | ||
| 55 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | 50 | /// Like `std.process.getCwdAlloc`, but also resolves the path with `std.fs.path.resolve`. This |
| 56 | pub fn findZigLibDirFromSelfExe( | 51 | /// means the path has no repeated separators, no "." or ".." components, and no trailing separator. |
| 57 | allocator: mem.Allocator, | 52 | /// On WASI, "" is returned instead of ".". |
| 58 | self_exe_path: []const u8, | 53 | pub fn getResolvedCwd(gpa: Allocator) error{ |
| 59 | ) error{ | ||
| 60 | OutOfMemory, | 54 | OutOfMemory, |
| 61 | FileNotFound, | ||
| 62 | CurrentWorkingDirectoryUnlinked, | 55 | CurrentWorkingDirectoryUnlinked, |
| 63 | Unexpected, | 56 | Unexpected, |
| 64 | }!Compilation.Directory { | 57 | }![]u8 { |
| 58 | if (builtin.target.os.tag == .wasi) { | ||
| 59 | if (std.debug.runtime_safety) { | ||
| 60 | const cwd = try std.process.getCwdAlloc(gpa); | ||
| 61 | defer gpa.free(cwd); | ||
| 62 | std.debug.assert(mem.eql(u8, cwd, ".")); | ||
| 63 | } | ||
| 64 | return ""; | ||
| 65 | } | ||
| 66 | const cwd = try std.process.getCwdAlloc(gpa); | ||
| 67 | defer gpa.free(cwd); | ||
| 68 | const resolved = try fs.path.resolve(gpa, &.{cwd}); | ||
| 69 | std.debug.assert(fs.path.isAbsolute(resolved)); | ||
| 70 | return resolved; | ||
| 71 | } | ||
| 72 | |||
| 73 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | ||
| 74 | pub fn findZigLibDirFromSelfExe( | ||
| 75 | allocator: Allocator, | ||
| 76 | /// The return value of `getResolvedCwd`. | ||
| 77 | /// Passed as an argument to avoid pointlessly repeating the call. | ||
| 78 | cwd_path: []const u8, | ||
| 79 | self_exe_path: []const u8, | ||
| 80 | ) error{ OutOfMemory, FileNotFound }!Cache.Directory { | ||
| 65 | const cwd = fs.cwd(); | 81 | const cwd = fs.cwd(); |
| 66 | var cur_path: []const u8 = self_exe_path; | 82 | var cur_path: []const u8 = self_exe_path; |
| 67 | while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { | 83 | while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { |
| ... | @@ -69,18 +85,20 @@ pub fn findZigLibDirFromSelfExe( | ... | @@ -69,18 +85,20 @@ pub fn findZigLibDirFromSelfExe( |
| 69 | defer base_dir.close(); | 85 | defer base_dir.close(); |
| 70 | 86 | ||
| 71 | const sub_directory = testZigInstallPrefix(base_dir) orelse continue; | 87 | const sub_directory = testZigInstallPrefix(base_dir) orelse continue; |
| 72 | const p = try fs.path.join(allocator, &[_][]const u8{ dirname, sub_directory.path.? }); | 88 | const p = try fs.path.join(allocator, &.{ dirname, sub_directory.path.? }); |
| 73 | defer allocator.free(p); | 89 | defer allocator.free(p); |
| 74 | return Compilation.Directory{ | 90 | |
| 91 | const resolved = try resolvePath(allocator, cwd_path, &.{p}); | ||
| 92 | return .{ | ||
| 75 | .handle = sub_directory.handle, | 93 | .handle = sub_directory.handle, |
| 76 | .path = try resolvePath(allocator, p), | 94 | .path = if (resolved.len == 0) null else resolved, |
| 77 | }; | 95 | }; |
| 78 | } | 96 | } |
| 79 | return error.FileNotFound; | 97 | return error.FileNotFound; |
| 80 | } | 98 | } |
| 81 | 99 | ||
| 82 | /// Caller owns returned memory. | 100 | /// Caller owns returned memory. |
| 83 | pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 { | 101 | pub fn resolveGlobalCacheDir(allocator: Allocator) ![]u8 { |
| 84 | if (builtin.os.tag == .wasi) | 102 | if (builtin.os.tag == .wasi) |
| 85 | @compileError("on WASI the global cache dir must be resolved with preopens"); | 103 | @compileError("on WASI the global cache dir must be resolved with preopens"); |
| 86 | 104 | ||
| ... | @@ -91,56 +109,107 @@ pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 { | ... | @@ -91,56 +109,107 @@ pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 { |
| 91 | if (builtin.os.tag != .windows) { | 109 | if (builtin.os.tag != .windows) { |
| 92 | if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| { | 110 | if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| { |
| 93 | if (cache_root.len > 0) { | 111 | if (cache_root.len > 0) { |
| 94 | return fs.path.join(allocator, &[_][]const u8{ cache_root, appname }); | 112 | return fs.path.join(allocator, &.{ cache_root, appname }); |
| 95 | } | 113 | } |
| 96 | } | 114 | } |
| 97 | if (std.zig.EnvVar.HOME.getPosix()) |home| { | 115 | if (std.zig.EnvVar.HOME.getPosix()) |home| { |
| 98 | return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname }); | 116 | return fs.path.join(allocator, &.{ home, ".cache", appname }); |
| 99 | } | 117 | } |
| 100 | } | 118 | } |
| 101 | 119 | ||
| 102 | return fs.getAppDataDir(allocator, appname); | 120 | return fs.getAppDataDir(allocator, appname); |
| 103 | } | 121 | } |
| 104 | 122 | ||
| 105 | /// Similar to std.fs.path.resolve, with a few important differences: | 123 | /// Similar to `fs.path.resolve`, but converts to a cwd-relative path, or, if that would |
| 106 | /// * If the input is an absolute path, check it against the cwd and try to | 124 | /// start with a relative up-dir (".."), an absolute path based on the cwd. Also, the cwd |
| 107 | /// convert it to a relative path. | 125 | /// returns the empty string ("") instead of ".". |
| 108 | /// * If the resulting path would start with a relative up-dir ("../"), instead | ||
| 109 | /// return an absolute path based on the cwd. | ||
| 110 | /// * When targeting WASI, fail with an error message if an absolute path is | ||
| 111 | /// used. | ||
| 112 | pub fn resolvePath( | 126 | pub fn resolvePath( |
| 113 | ally: mem.Allocator, | 127 | gpa: Allocator, |
| 114 | p: []const u8, | 128 | /// The return value of `getResolvedCwd`. |
| 115 | ) error{ | 129 | /// Passed as an argument to avoid pointlessly repeating the call. |
| 116 | OutOfMemory, | 130 | cwd_resolved: []const u8, |
| 117 | CurrentWorkingDirectoryUnlinked, | 131 | paths: []const []const u8, |
| 118 | Unexpected, | 132 | ) Allocator.Error![]u8 { |
| 119 | }![]u8 { | 133 | if (builtin.target.os.tag == .wasi) { |
| 120 | if (fs.path.isAbsolute(p)) { | 134 | std.debug.assert(mem.eql(u8, cwd_resolved, "")); |
| 121 | const cwd_path = try std.process.getCwdAlloc(ally); | 135 | const res = try fs.path.resolve(gpa, paths); |
| 122 | defer ally.free(cwd_path); | 136 | if (mem.eql(u8, res, ".")) { |
| 123 | const relative = try fs.path.relative(ally, cwd_path, p); | 137 | gpa.free(res); |
| 124 | if (isUpDir(relative)) { | 138 | return ""; |
| 125 | ally.free(relative); | ||
| 126 | return ally.dupe(u8, p); | ||
| 127 | } else { | ||
| 128 | return relative; | ||
| 129 | } | 139 | } |
| 140 | return res; | ||
| 141 | } | ||
| 142 | |||
| 143 | // Heuristic for a fast path: if no component is absolute and ".." never appears, we just need to resolve `paths`. | ||
| 144 | for (paths) |p| { | ||
| 145 | if (fs.path.isAbsolute(p)) break; // absolute path | ||
| 146 | if (mem.indexOf(u8, p, "..") != null) break; // may contain up-dir | ||
| 130 | } else { | 147 | } else { |
| 131 | const resolved = try fs.path.resolve(ally, &.{p}); | 148 | // no absolute path, no "..". |
| 132 | if (isUpDir(resolved)) { | 149 | const res = try fs.path.resolve(gpa, paths); |
| 133 | ally.free(resolved); | 150 | if (mem.eql(u8, res, ".")) { |
| 134 | const cwd_path = try std.process.getCwdAlloc(ally); | 151 | gpa.free(res); |
| 135 | defer ally.free(cwd_path); | 152 | return ""; |
| 136 | return fs.path.resolve(ally, &.{ cwd_path, p }); | ||
| 137 | } else { | ||
| 138 | return resolved; | ||
| 139 | } | 153 | } |
| 154 | std.debug.assert(!fs.path.isAbsolute(res)); | ||
| 155 | std.debug.assert(!isUpDir(res)); | ||
| 156 | return res; | ||
| 157 | } | ||
| 158 | |||
| 159 | // The fast path failed; resolve the whole thing. | ||
| 160 | // Optimization: `paths` often has just one element. | ||
| 161 | const path_resolved = switch (paths.len) { | ||
| 162 | 0 => unreachable, | ||
| 163 | 1 => try fs.path.resolve(gpa, &.{ cwd_resolved, paths[0] }), | ||
| 164 | else => r: { | ||
| 165 | const all_paths = try gpa.alloc([]const u8, paths.len + 1); | ||
| 166 | defer gpa.free(all_paths); | ||
| 167 | all_paths[0] = cwd_resolved; | ||
| 168 | @memcpy(all_paths[1..], paths); | ||
| 169 | break :r try fs.path.resolve(gpa, all_paths); | ||
| 170 | }, | ||
| 171 | }; | ||
| 172 | errdefer gpa.free(path_resolved); | ||
| 173 | |||
| 174 | std.debug.assert(fs.path.isAbsolute(path_resolved)); | ||
| 175 | std.debug.assert(fs.path.isAbsolute(cwd_resolved)); | ||
| 176 | |||
| 177 | if (!std.mem.startsWith(u8, path_resolved, cwd_resolved)) return path_resolved; // not in cwd | ||
| 178 | if (path_resolved.len == cwd_resolved.len) { | ||
| 179 | // equal to cwd | ||
| 180 | gpa.free(path_resolved); | ||
| 181 | return ""; | ||
| 140 | } | 182 | } |
| 183 | if (path_resolved[cwd_resolved.len] != std.fs.path.sep) return path_resolved; // not in cwd (last component differs) | ||
| 184 | |||
| 185 | // in cwd; extract sub path | ||
| 186 | const sub_path = try gpa.dupe(u8, path_resolved[cwd_resolved.len + 1 ..]); | ||
| 187 | gpa.free(path_resolved); | ||
| 188 | return sub_path; | ||
| 141 | } | 189 | } |
| 142 | 190 | ||
| 143 | /// TODO move this to std.fs.path | 191 | /// TODO move this to std.fs.path |
| 144 | pub fn isUpDir(p: []const u8) bool { | 192 | pub fn isUpDir(p: []const u8) bool { |
| 145 | return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep); | 193 | return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep); |
| 146 | } | 194 | } |
| 195 | |||
| 196 | pub const default_local_zig_cache_basename = ".zig-cache"; | ||
| 197 | |||
| 198 | /// Searches upwards from `cwd` for a directory containing a `build.zig` file. | ||
| 199 | /// If such a directory is found, returns the path to it joined to the `.zig_cache` name. | ||
| 200 | /// Otherwise, returns `null`, indicating no suitable local cache location. | ||
| 201 | pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator.Error!?[]u8 { | ||
| 202 | var cur_dir = cwd; | ||
| 203 | while (true) { | ||
| 204 | const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); | ||
| 205 | if (fs.cwd().access(joined, .{})) |_| { | ||
| 206 | return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); | ||
| 207 | } else |err| switch (err) { | ||
| 208 | error.FileNotFound => { | ||
| 209 | cur_dir = fs.path.dirname(cur_dir) orelse return null; | ||
| 210 | continue; | ||
| 211 | }, | ||
| 212 | else => return null, | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } |
src/libs/freebsd.zig+16-22| ... | @@ -34,7 +34,7 @@ pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile { | ... | @@ -34,7 +34,7 @@ pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile { |
| 34 | 34 | ||
| 35 | fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 35 | fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 36 | return path.join(arena, &.{ | 36 | return path.join(arena, &.{ |
| 37 | comp.zig_lib_directory.path.?, | 37 | comp.dirs.zig_lib.path.?, |
| 38 | "libc" ++ path.sep_str ++ "include", | 38 | "libc" ++ path.sep_str ++ "include", |
| 39 | sub_path, | 39 | sub_path, |
| 40 | }); | 40 | }); |
| ... | @@ -42,7 +42,7 @@ fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]co | ... | @@ -42,7 +42,7 @@ fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]co |
| 42 | 42 | ||
| 43 | fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 43 | fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 44 | return path.join(arena, &.{ | 44 | return path.join(arena, &.{ |
| 45 | comp.zig_lib_directory.path.?, | 45 | comp.dirs.zig_lib.path.?, |
| 46 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "csu", | 46 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "csu", |
| 47 | sub_path, | 47 | sub_path, |
| 48 | }); | 48 | }); |
| ... | @@ -50,7 +50,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const | ... | @@ -50,7 +50,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const |
| 50 | 50 | ||
| 51 | fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 51 | fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 52 | return path.join(arena, &.{ | 52 | return path.join(arena, &.{ |
| 53 | comp.zig_lib_directory.path.?, | 53 | comp.dirs.zig_lib.path.?, |
| 54 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "libc", | 54 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "libc", |
| 55 | sub_path, | 55 | sub_path, |
| 56 | }); | 56 | }); |
| ... | @@ -438,11 +438,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -438,11 +438,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 438 | // Use the global cache directory. | 438 | // Use the global cache directory. |
| 439 | var cache: Cache = .{ | 439 | var cache: Cache = .{ |
| 440 | .gpa = gpa, | 440 | .gpa = gpa, |
| 441 | .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}), | 441 | .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), |
| 442 | }; | 442 | }; |
| 443 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 443 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 444 | cache.addPrefix(comp.zig_lib_directory); | 444 | cache.addPrefix(comp.dirs.zig_lib); |
| 445 | cache.addPrefix(comp.global_cache_directory); | 445 | cache.addPrefix(comp.dirs.global_cache); |
| 446 | defer cache.manifest_dir.close(); | 446 | defer cache.manifest_dir.close(); |
| 447 | 447 | ||
| 448 | var man = cache.obtain(); | 448 | var man = cache.obtain(); |
| ... | @@ -452,7 +452,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -452,7 +452,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 452 | man.hash.add(target.abi); | 452 | man.hash.add(target.abi); |
| 453 | man.hash.add(target_version); | 453 | man.hash.add(target_version); |
| 454 | 454 | ||
| 455 | const full_abilists_path = try comp.zig_lib_directory.join(arena, &.{abilists_path}); | 455 | const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path}); |
| 456 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); | 456 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); |
| 457 | 457 | ||
| 458 | if (try man.hit()) { | 458 | if (try man.hit()) { |
| ... | @@ -461,7 +461,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -461,7 +461,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 461 | return queueSharedObjects(comp, .{ | 461 | return queueSharedObjects(comp, .{ |
| 462 | .lock = man.toOwnedLock(), | 462 | .lock = man.toOwnedLock(), |
| 463 | .dir_path = .{ | 463 | .dir_path = .{ |
| 464 | .root_dir = comp.global_cache_directory, | 464 | .root_dir = comp.dirs.global_cache, |
| 465 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 465 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 466 | }, | 466 | }, |
| 467 | }); | 467 | }); |
| ... | @@ -470,9 +470,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -470,9 +470,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 470 | const digest = man.final(); | 470 | const digest = man.final(); |
| 471 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); | 471 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); |
| 472 | 472 | ||
| 473 | var o_directory: Compilation.Directory = .{ | 473 | var o_directory: Cache.Directory = .{ |
| 474 | .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}), | 474 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 475 | .path = try comp.global_cache_directory.join(arena, &.{o_sub_path}), | 475 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 476 | }; | 476 | }; |
| 477 | defer o_directory.handle.close(); | 477 | defer o_directory.handle.close(); |
| 478 | 478 | ||
| ... | @@ -974,7 +974,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -974,7 +974,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 974 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "stdthreads", etc. | 974 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "stdthreads", etc. |
| 975 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; | 975 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; |
| 976 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); | 976 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); |
| 977 | try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node); | 977 | try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); |
| 978 | } | 978 | } |
| 979 | 979 | ||
| 980 | man.writeManifest() catch |err| { | 980 | man.writeManifest() catch |err| { |
| ... | @@ -984,7 +984,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -984,7 +984,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 984 | return queueSharedObjects(comp, .{ | 984 | return queueSharedObjects(comp, .{ |
| 985 | .lock = man.toOwnedLock(), | 985 | .lock = man.toOwnedLock(), |
| 986 | .dir_path = .{ | 986 | .dir_path = .{ |
| 987 | .root_dir = comp.global_cache_directory, | 987 | .root_dir = comp.dirs.global_cache, |
| 988 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 988 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 989 | }, | 989 | }, |
| 990 | }); | 990 | }); |
| ... | @@ -1023,8 +1023,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { | ... | @@ -1023,8 +1023,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { |
| 1023 | fn buildSharedLib( | 1023 | fn buildSharedLib( |
| 1024 | comp: *Compilation, | 1024 | comp: *Compilation, |
| 1025 | arena: Allocator, | 1025 | arena: Allocator, |
| 1026 | zig_cache_directory: Compilation.Directory, | 1026 | bin_directory: Cache.Directory, |
| 1027 | bin_directory: Compilation.Directory, | ||
| 1028 | asm_file_basename: []const u8, | 1027 | asm_file_basename: []const u8, |
| 1029 | lib: Lib, | 1028 | lib: Lib, |
| 1030 | prog_node: std.Progress.Node, | 1029 | prog_node: std.Progress.Node, |
| ... | @@ -1057,9 +1056,8 @@ fn buildSharedLib( | ... | @@ -1057,9 +1056,8 @@ fn buildSharedLib( |
| 1057 | }); | 1056 | }); |
| 1058 | 1057 | ||
| 1059 | const root_mod = try Module.create(arena, .{ | 1058 | const root_mod = try Module.create(arena, .{ |
| 1060 | .global_cache_directory = comp.global_cache_directory, | ||
| 1061 | .paths = .{ | 1059 | .paths = .{ |
| 1062 | .root = .{ .root_dir = comp.zig_lib_directory }, | 1060 | .root = .zig_lib_root, |
| 1063 | .root_src_path = "", | 1061 | .root_src_path = "", |
| 1064 | }, | 1062 | }, |
| 1065 | .fully_qualified_name = "root", | 1063 | .fully_qualified_name = "root", |
| ... | @@ -1079,8 +1077,6 @@ fn buildSharedLib( | ... | @@ -1079,8 +1077,6 @@ fn buildSharedLib( |
| 1079 | .global = config, | 1077 | .global = config, |
| 1080 | .cc_argv = &.{}, | 1078 | .cc_argv = &.{}, |
| 1081 | .parent = null, | 1079 | .parent = null, |
| 1082 | .builtin_mod = null, | ||
| 1083 | .builtin_modules = null, // there is only one module in this compilation | ||
| 1084 | }); | 1080 | }); |
| 1085 | 1081 | ||
| 1086 | const c_source_files = [1]Compilation.CSourceFile{ | 1082 | const c_source_files = [1]Compilation.CSourceFile{ |
| ... | @@ -1091,9 +1087,7 @@ fn buildSharedLib( | ... | @@ -1091,9 +1087,7 @@ fn buildSharedLib( |
| 1091 | }; | 1087 | }; |
| 1092 | 1088 | ||
| 1093 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | 1089 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ |
| 1094 | .local_cache_directory = zig_cache_directory, | 1090 | .dirs = comp.dirs.withoutLocalCache(), |
| 1095 | .global_cache_directory = comp.global_cache_directory, | ||
| 1096 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 1097 | .thread_pool = comp.thread_pool, | 1091 | .thread_pool = comp.thread_pool, |
| 1098 | .self_exe_path = comp.self_exe_path, | 1092 | .self_exe_path = comp.self_exe_path, |
| 1099 | .cache_mode = .incremental, | 1093 | .cache_mode = .incremental, |
src/libs/glibc.zig+19-29| ... | @@ -365,7 +365,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ | ... | @@ -365,7 +365,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ |
| 365 | const s = path.sep_str; | 365 | const s = path.sep_str; |
| 366 | 366 | ||
| 367 | var result = std.ArrayList(u8).init(arena); | 367 | var result = std.ArrayList(u8).init(arena); |
| 368 | try result.appendSlice(comp.zig_lib_directory.path.?); | 368 | try result.appendSlice(comp.dirs.zig_lib.path orelse "."); |
| 369 | try result.appendSlice(s ++ "libc" ++ s ++ "glibc" ++ s ++ "sysdeps" ++ s); | 369 | try result.appendSlice(s ++ "libc" ++ s ++ "glibc" ++ s ++ "sysdeps" ++ s); |
| 370 | if (is_sparc) { | 370 | if (is_sparc) { |
| 371 | if (is_64) { | 371 | if (is_64) { |
| ... | @@ -439,7 +439,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ | ... | @@ -439,7 +439,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ |
| 439 | } | 439 | } |
| 440 | if (opt_nptl) |nptl| { | 440 | if (opt_nptl) |nptl| { |
| 441 | try args.append("-I"); | 441 | try args.append("-I"); |
| 442 | try args.append(try path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, lib_libc_glibc ++ "sysdeps", nptl })); | 442 | try args.append(try path.join(arena, &.{ comp.dirs.zig_lib.path orelse ".", lib_libc_glibc ++ "sysdeps", nptl })); |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | try args.append("-I"); | 445 | try args.append("-I"); |
| ... | @@ -459,11 +459,11 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ | ... | @@ -459,11 +459,11 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ |
| 459 | try args.append(try lib_path(comp, arena, lib_libc_glibc ++ "sysdeps" ++ s ++ "generic")); | 459 | try args.append(try lib_path(comp, arena, lib_libc_glibc ++ "sysdeps" ++ s ++ "generic")); |
| 460 | 460 | ||
| 461 | try args.append("-I"); | 461 | try args.append("-I"); |
| 462 | try args.append(try path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, lib_libc ++ "glibc" })); | 462 | try args.append(try path.join(arena, &[_][]const u8{ comp.dirs.zig_lib.path orelse ".", lib_libc ++ "glibc" })); |
| 463 | 463 | ||
| 464 | try args.append("-I"); | 464 | try args.append("-I"); |
| 465 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", .{ | 465 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", .{ |
| 466 | comp.zig_lib_directory.path.?, @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi), | 466 | comp.dirs.zig_lib.path orelse ".", @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi), |
| 467 | })); | 467 | })); |
| 468 | 468 | ||
| 469 | try args.append("-I"); | 469 | try args.append("-I"); |
| ... | @@ -472,7 +472,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ | ... | @@ -472,7 +472,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ |
| 472 | const arch_name = std.zig.target.osArchName(target); | 472 | const arch_name = std.zig.target.osArchName(target); |
| 473 | try args.append("-I"); | 473 | try args.append("-I"); |
| 474 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-linux-any", .{ | 474 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-linux-any", .{ |
| 475 | comp.zig_lib_directory.path.?, arch_name, | 475 | comp.dirs.zig_lib.path orelse ".", arch_name, |
| 476 | })); | 476 | })); |
| 477 | 477 | ||
| 478 | try args.append("-I"); | 478 | try args.append("-I"); |
| ... | @@ -626,15 +626,11 @@ fn add_include_dirs_arch( | ... | @@ -626,15 +626,11 @@ fn add_include_dirs_arch( |
| 626 | } | 626 | } |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | fn path_from_lib(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | ||
| 630 | return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path }); | ||
| 631 | } | ||
| 632 | |||
| 633 | const lib_libc = "libc" ++ path.sep_str; | 629 | const lib_libc = "libc" ++ path.sep_str; |
| 634 | const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str; | 630 | const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str; |
| 635 | 631 | ||
| 636 | fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 632 | fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 637 | return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path }); | 633 | return path.join(arena, &.{ comp.dirs.zig_lib.path orelse ".", sub_path }); |
| 638 | } | 634 | } |
| 639 | 635 | ||
| 640 | pub const BuiltSharedObjects = struct { | 636 | pub const BuiltSharedObjects = struct { |
| ... | @@ -678,11 +674,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -678,11 +674,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 678 | // Use the global cache directory. | 674 | // Use the global cache directory. |
| 679 | var cache: Cache = .{ | 675 | var cache: Cache = .{ |
| 680 | .gpa = gpa, | 676 | .gpa = gpa, |
| 681 | .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}), | 677 | .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), |
| 682 | }; | 678 | }; |
| 683 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 679 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 684 | cache.addPrefix(comp.zig_lib_directory); | 680 | cache.addPrefix(comp.dirs.zig_lib); |
| 685 | cache.addPrefix(comp.global_cache_directory); | 681 | cache.addPrefix(comp.dirs.global_cache); |
| 686 | defer cache.manifest_dir.close(); | 682 | defer cache.manifest_dir.close(); |
| 687 | 683 | ||
| 688 | var man = cache.obtain(); | 684 | var man = cache.obtain(); |
| ... | @@ -692,7 +688,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -692,7 +688,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 692 | man.hash.add(target.abi); | 688 | man.hash.add(target.abi); |
| 693 | man.hash.add(target_version); | 689 | man.hash.add(target_version); |
| 694 | 690 | ||
| 695 | const full_abilists_path = try comp.zig_lib_directory.join(arena, &.{abilists_path}); | 691 | const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path}); |
| 696 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); | 692 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); |
| 697 | 693 | ||
| 698 | if (try man.hit()) { | 694 | if (try man.hit()) { |
| ... | @@ -701,7 +697,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -701,7 +697,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 701 | return queueSharedObjects(comp, .{ | 697 | return queueSharedObjects(comp, .{ |
| 702 | .lock = man.toOwnedLock(), | 698 | .lock = man.toOwnedLock(), |
| 703 | .dir_path = .{ | 699 | .dir_path = .{ |
| 704 | .root_dir = comp.global_cache_directory, | 700 | .root_dir = comp.dirs.global_cache, |
| 705 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 701 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 706 | }, | 702 | }, |
| 707 | }); | 703 | }); |
| ... | @@ -710,9 +706,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -710,9 +706,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 710 | const digest = man.final(); | 706 | const digest = man.final(); |
| 711 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); | 707 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); |
| 712 | 708 | ||
| 713 | var o_directory: Compilation.Directory = .{ | 709 | var o_directory: Cache.Directory = .{ |
| 714 | .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}), | 710 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 715 | .path = try comp.global_cache_directory.join(arena, &.{o_sub_path}), | 711 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 716 | }; | 712 | }; |
| 717 | defer o_directory.handle.close(); | 713 | defer o_directory.handle.close(); |
| 718 | 714 | ||
| ... | @@ -1112,7 +1108,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -1112,7 +1108,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 1112 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. | 1108 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. |
| 1113 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; | 1109 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; |
| 1114 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); | 1110 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); |
| 1115 | try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node); | 1111 | try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); |
| 1116 | } | 1112 | } |
| 1117 | 1113 | ||
| 1118 | man.writeManifest() catch |err| { | 1114 | man.writeManifest() catch |err| { |
| ... | @@ -1122,7 +1118,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -1122,7 +1118,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 1122 | return queueSharedObjects(comp, .{ | 1118 | return queueSharedObjects(comp, .{ |
| 1123 | .lock = man.toOwnedLock(), | 1119 | .lock = man.toOwnedLock(), |
| 1124 | .dir_path = .{ | 1120 | .dir_path = .{ |
| 1125 | .root_dir = comp.global_cache_directory, | 1121 | .root_dir = comp.dirs.global_cache, |
| 1126 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 1122 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 1127 | }, | 1123 | }, |
| 1128 | }); | 1124 | }); |
| ... | @@ -1174,8 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { | ... | @@ -1174,8 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { |
| 1174 | fn buildSharedLib( | 1170 | fn buildSharedLib( |
| 1175 | comp: *Compilation, | 1171 | comp: *Compilation, |
| 1176 | arena: Allocator, | 1172 | arena: Allocator, |
| 1177 | zig_cache_directory: Compilation.Directory, | 1173 | bin_directory: Cache.Directory, |
| 1178 | bin_directory: Compilation.Directory, | ||
| 1179 | asm_file_basename: []const u8, | 1174 | asm_file_basename: []const u8, |
| 1180 | lib: Lib, | 1175 | lib: Lib, |
| 1181 | prog_node: std.Progress.Node, | 1176 | prog_node: std.Progress.Node, |
| ... | @@ -1208,9 +1203,8 @@ fn buildSharedLib( | ... | @@ -1208,9 +1203,8 @@ fn buildSharedLib( |
| 1208 | }); | 1203 | }); |
| 1209 | 1204 | ||
| 1210 | const root_mod = try Module.create(arena, .{ | 1205 | const root_mod = try Module.create(arena, .{ |
| 1211 | .global_cache_directory = comp.global_cache_directory, | ||
| 1212 | .paths = .{ | 1206 | .paths = .{ |
| 1213 | .root = .{ .root_dir = comp.zig_lib_directory }, | 1207 | .root = .zig_lib_root, |
| 1214 | .root_src_path = "", | 1208 | .root_src_path = "", |
| 1215 | }, | 1209 | }, |
| 1216 | .fully_qualified_name = "root", | 1210 | .fully_qualified_name = "root", |
| ... | @@ -1230,8 +1224,6 @@ fn buildSharedLib( | ... | @@ -1230,8 +1224,6 @@ fn buildSharedLib( |
| 1230 | .global = config, | 1224 | .global = config, |
| 1231 | .cc_argv = &.{}, | 1225 | .cc_argv = &.{}, |
| 1232 | .parent = null, | 1226 | .parent = null, |
| 1233 | .builtin_mod = null, | ||
| 1234 | .builtin_modules = null, // there is only one module in this compilation | ||
| 1235 | }); | 1227 | }); |
| 1236 | 1228 | ||
| 1237 | const c_source_files = [1]Compilation.CSourceFile{ | 1229 | const c_source_files = [1]Compilation.CSourceFile{ |
| ... | @@ -1242,9 +1234,7 @@ fn buildSharedLib( | ... | @@ -1242,9 +1234,7 @@ fn buildSharedLib( |
| 1242 | }; | 1234 | }; |
| 1243 | 1235 | ||
| 1244 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | 1236 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ |
| 1245 | .local_cache_directory = zig_cache_directory, | 1237 | .dirs = comp.dirs.withoutLocalCache(), |
| 1246 | .global_cache_directory = comp.global_cache_directory, | ||
| 1247 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 1248 | .thread_pool = comp.thread_pool, | 1238 | .thread_pool = comp.thread_pool, |
| 1249 | .self_exe_path = comp.self_exe_path, | 1239 | .self_exe_path = comp.self_exe_path, |
| 1250 | .cache_mode = .incremental, | 1240 | .cache_mode = .incremental, |
src/libs/libcxx.zig+13-23| ... | @@ -134,10 +134,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -134,10 +134,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 134 | .basename = basename, | 134 | .basename = basename, |
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" }); | 137 | const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" }); |
| 138 | const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" }); | 138 | const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" }); |
| 139 | const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" }); | 139 | const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" }); |
| 140 | const cxx_libc_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "libc" }); | 140 | const cxx_libc_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "libc" }); |
| 141 | 141 | ||
| 142 | const optimize_mode = comp.compilerRtOptMode(); | 142 | const optimize_mode = comp.compilerRtOptMode(); |
| 143 | const strip = comp.compilerRtStrip(); | 143 | const strip = comp.compilerRtStrip(); |
| ... | @@ -164,9 +164,8 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -164,9 +164,8 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | const root_mod = Module.create(arena, .{ | 166 | const root_mod = Module.create(arena, .{ |
| 167 | .global_cache_directory = comp.global_cache_directory, | ||
| 168 | .paths = .{ | 167 | .paths = .{ |
| 169 | .root = .{ .root_dir = comp.zig_lib_directory }, | 168 | .root = .zig_lib_root, |
| 170 | .root_src_path = "", | 169 | .root_src_path = "", |
| 171 | }, | 170 | }, |
| 172 | .fully_qualified_name = "root", | 171 | .fully_qualified_name = "root", |
| ... | @@ -188,8 +187,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -188,8 +187,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 188 | .global = config, | 187 | .global = config, |
| 189 | .cc_argv = &.{}, | 188 | .cc_argv = &.{}, |
| 190 | .parent = null, | 189 | .parent = null, |
| 191 | .builtin_mod = null, | ||
| 192 | .builtin_modules = null, // there is only one module in this compilation | ||
| 193 | }) catch |err| { | 190 | }) catch |err| { |
| 194 | comp.setMiscFailure( | 191 | comp.setMiscFailure( |
| 195 | .libcxx, | 192 | .libcxx, |
| ... | @@ -258,7 +255,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -258,7 +255,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 258 | try cache_exempt_flags.append(cxx_libc_include_path); | 255 | try cache_exempt_flags.append(cxx_libc_include_path); |
| 259 | 256 | ||
| 260 | c_source_files.appendAssumeCapacity(.{ | 257 | c_source_files.appendAssumeCapacity(.{ |
| 261 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", cxx_src }), | 258 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", cxx_src }), |
| 262 | .extra_flags = cflags.items, | 259 | .extra_flags = cflags.items, |
| 263 | .cache_exempt_flags = cache_exempt_flags.items, | 260 | .cache_exempt_flags = cache_exempt_flags.items, |
| 264 | .owner = root_mod, | 261 | .owner = root_mod, |
| ... | @@ -266,9 +263,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -266,9 +263,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 266 | } | 263 | } |
| 267 | 264 | ||
| 268 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 265 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 269 | .local_cache_directory = comp.global_cache_directory, | 266 | .dirs = comp.dirs.withoutLocalCache(), |
| 270 | .global_cache_directory = comp.global_cache_directory, | ||
| 271 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 272 | .self_exe_path = comp.self_exe_path, | 267 | .self_exe_path = comp.self_exe_path, |
| 273 | .cache_mode = .whole, | 268 | .cache_mode = .whole, |
| 274 | .config = config, | 269 | .config = config, |
| ... | @@ -344,9 +339,9 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -344,9 +339,9 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 344 | .basename = basename, | 339 | .basename = basename, |
| 345 | }; | 340 | }; |
| 346 | 341 | ||
| 347 | const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" }); | 342 | const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" }); |
| 348 | const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" }); | 343 | const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" }); |
| 349 | const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" }); | 344 | const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" }); |
| 350 | 345 | ||
| 351 | const optimize_mode = comp.compilerRtOptMode(); | 346 | const optimize_mode = comp.compilerRtOptMode(); |
| 352 | const strip = comp.compilerRtStrip(); | 347 | const strip = comp.compilerRtStrip(); |
| ... | @@ -378,9 +373,8 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -378,9 +373,8 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 378 | }; | 373 | }; |
| 379 | 374 | ||
| 380 | const root_mod = Module.create(arena, .{ | 375 | const root_mod = Module.create(arena, .{ |
| 381 | .global_cache_directory = comp.global_cache_directory, | ||
| 382 | .paths = .{ | 376 | .paths = .{ |
| 383 | .root = .{ .root_dir = comp.zig_lib_directory }, | 377 | .root = .zig_lib_root, |
| 384 | .root_src_path = "", | 378 | .root_src_path = "", |
| 385 | }, | 379 | }, |
| 386 | .fully_qualified_name = "root", | 380 | .fully_qualified_name = "root", |
| ... | @@ -403,8 +397,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -403,8 +397,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 403 | .global = config, | 397 | .global = config, |
| 404 | .cc_argv = &.{}, | 398 | .cc_argv = &.{}, |
| 405 | .parent = null, | 399 | .parent = null, |
| 406 | .builtin_mod = null, | ||
| 407 | .builtin_modules = null, // there is only one module in this compilation | ||
| 408 | }) catch |err| { | 400 | }) catch |err| { |
| 409 | comp.setMiscFailure( | 401 | comp.setMiscFailure( |
| 410 | .libcxxabi, | 402 | .libcxxabi, |
| ... | @@ -459,7 +451,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -459,7 +451,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 459 | try cache_exempt_flags.append(cxx_src_include_path); | 451 | try cache_exempt_flags.append(cxx_src_include_path); |
| 460 | 452 | ||
| 461 | c_source_files.appendAssumeCapacity(.{ | 453 | c_source_files.appendAssumeCapacity(.{ |
| 462 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }), | 454 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", cxxabi_src }), |
| 463 | .extra_flags = cflags.items, | 455 | .extra_flags = cflags.items, |
| 464 | .cache_exempt_flags = cache_exempt_flags.items, | 456 | .cache_exempt_flags = cache_exempt_flags.items, |
| 465 | .owner = root_mod, | 457 | .owner = root_mod, |
| ... | @@ -467,9 +459,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -467,9 +459,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 467 | } | 459 | } |
| 468 | 460 | ||
| 469 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 461 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 470 | .local_cache_directory = comp.global_cache_directory, | 462 | .dirs = comp.dirs.withoutLocalCache(), |
| 471 | .global_cache_directory = comp.global_cache_directory, | ||
| 472 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 473 | .self_exe_path = comp.self_exe_path, | 463 | .self_exe_path = comp.self_exe_path, |
| 474 | .cache_mode = .whole, | 464 | .cache_mode = .whole, |
| 475 | .config = config, | 465 | .config = config, |
src/libs/libtsan.zig+12-20| ... | @@ -84,9 +84,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -84,9 +84,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | const root_mod = Module.create(arena, .{ | 86 | const root_mod = Module.create(arena, .{ |
| 87 | .global_cache_directory = comp.global_cache_directory, | ||
| 88 | .paths = .{ | 87 | .paths = .{ |
| 89 | .root = .{ .root_dir = comp.zig_lib_directory }, | 88 | .root = .zig_lib_root, |
| 90 | .root_src_path = "", | 89 | .root_src_path = "", |
| 91 | }, | 90 | }, |
| 92 | .fully_qualified_name = "root", | 91 | .fully_qualified_name = "root", |
| ... | @@ -110,8 +109,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -110,8 +109,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 110 | .global = config, | 109 | .global = config, |
| 111 | .cc_argv = &common_flags, | 110 | .cc_argv = &common_flags, |
| 112 | .parent = null, | 111 | .parent = null, |
| 113 | .builtin_mod = null, | ||
| 114 | .builtin_modules = null, // there is only one module in this compilation | ||
| 115 | }) catch |err| { | 112 | }) catch |err| { |
| 116 | comp.setMiscFailure( | 113 | comp.setMiscFailure( |
| 117 | .libtsan, | 114 | .libtsan, |
| ... | @@ -124,7 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -124,7 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 124 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); | 121 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 125 | try c_source_files.ensureUnusedCapacity(tsan_sources.len); | 122 | try c_source_files.ensureUnusedCapacity(tsan_sources.len); |
| 126 | 123 | ||
| 127 | const tsan_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"libtsan"}); | 124 | const tsan_include_path = try comp.dirs.zig_lib.join(arena, &.{"libtsan"}); |
| 128 | for (tsan_sources) |tsan_src| { | 125 | for (tsan_sources) |tsan_src| { |
| 129 | var cflags = std.ArrayList([]const u8).init(arena); | 126 | var cflags = std.ArrayList([]const u8).init(arena); |
| 130 | 127 | ||
| ... | @@ -134,7 +131,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -134,7 +131,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 134 | try addCcArgs(target, &cflags); | 131 | try addCcArgs(target, &cflags); |
| 135 | 132 | ||
| 136 | c_source_files.appendAssumeCapacity(.{ | 133 | c_source_files.appendAssumeCapacity(.{ |
| 137 | .src_path = try comp.zig_lib_directory.join(arena, &.{ "libtsan", tsan_src }), | 134 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }), |
| 138 | .extra_flags = cflags.items, | 135 | .extra_flags = cflags.items, |
| 139 | .owner = root_mod, | 136 | .owner = root_mod, |
| 140 | }); | 137 | }); |
| ... | @@ -155,7 +152,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -155,7 +152,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 155 | try addCcArgs(target, &cflags); | 152 | try addCcArgs(target, &cflags); |
| 156 | 153 | ||
| 157 | c_source_files.appendAssumeCapacity(.{ | 154 | c_source_files.appendAssumeCapacity(.{ |
| 158 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libtsan", tsan_src }), | 155 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }), |
| 159 | .extra_flags = cflags.items, | 156 | .extra_flags = cflags.items, |
| 160 | .owner = root_mod, | 157 | .owner = root_mod, |
| 161 | }); | 158 | }); |
| ... | @@ -179,14 +176,14 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -179,14 +176,14 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 179 | try cflags.append("-DNDEBUG"); | 176 | try cflags.append("-DNDEBUG"); |
| 180 | 177 | ||
| 181 | c_source_files.appendAssumeCapacity(.{ | 178 | c_source_files.appendAssumeCapacity(.{ |
| 182 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libtsan", asm_source }), | 179 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", asm_source }), |
| 183 | .extra_flags = cflags.items, | 180 | .extra_flags = cflags.items, |
| 184 | .owner = root_mod, | 181 | .owner = root_mod, |
| 185 | }); | 182 | }); |
| 186 | } | 183 | } |
| 187 | 184 | ||
| 188 | try c_source_files.ensureUnusedCapacity(sanitizer_common_sources.len); | 185 | try c_source_files.ensureUnusedCapacity(sanitizer_common_sources.len); |
| 189 | const sanitizer_common_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 186 | const sanitizer_common_include_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 190 | "libtsan", "sanitizer_common", | 187 | "libtsan", "sanitizer_common", |
| 191 | }); | 188 | }); |
| 192 | for (sanitizer_common_sources) |common_src| { | 189 | for (sanitizer_common_sources) |common_src| { |
| ... | @@ -200,7 +197,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -200,7 +197,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 200 | try addCcArgs(target, &cflags); | 197 | try addCcArgs(target, &cflags); |
| 201 | 198 | ||
| 202 | c_source_files.appendAssumeCapacity(.{ | 199 | c_source_files.appendAssumeCapacity(.{ |
| 203 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 200 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 204 | "libtsan", "sanitizer_common", common_src, | 201 | "libtsan", "sanitizer_common", common_src, |
| 205 | }), | 202 | }), |
| 206 | .extra_flags = cflags.items, | 203 | .extra_flags = cflags.items, |
| ... | @@ -224,7 +221,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -224,7 +221,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 224 | try addCcArgs(target, &cflags); | 221 | try addCcArgs(target, &cflags); |
| 225 | 222 | ||
| 226 | c_source_files.appendAssumeCapacity(.{ | 223 | c_source_files.appendAssumeCapacity(.{ |
| 227 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 224 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 228 | "libtsan", "sanitizer_common", c_src, | 225 | "libtsan", "sanitizer_common", c_src, |
| 229 | }), | 226 | }), |
| 230 | .extra_flags = cflags.items, | 227 | .extra_flags = cflags.items, |
| ... | @@ -242,7 +239,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -242,7 +239,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 242 | try addCcArgs(target, &cflags); | 239 | try addCcArgs(target, &cflags); |
| 243 | 240 | ||
| 244 | c_source_files.appendAssumeCapacity(.{ | 241 | c_source_files.appendAssumeCapacity(.{ |
| 245 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 242 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 246 | "libtsan", "sanitizer_common", c_src, | 243 | "libtsan", "sanitizer_common", c_src, |
| 247 | }), | 244 | }), |
| 248 | .extra_flags = cflags.items, | 245 | .extra_flags = cflags.items, |
| ... | @@ -250,10 +247,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -250,10 +247,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 250 | }); | 247 | }); |
| 251 | } | 248 | } |
| 252 | 249 | ||
| 253 | const interception_include_path = try comp.zig_lib_directory.join( | 250 | const interception_include_path = try comp.dirs.zig_lib.join(arena, &.{"interception"}); |
| 254 | arena, | ||
| 255 | &[_][]const u8{"interception"}, | ||
| 256 | ); | ||
| 257 | 251 | ||
| 258 | try c_source_files.ensureUnusedCapacity(interception_sources.len); | 252 | try c_source_files.ensureUnusedCapacity(interception_sources.len); |
| 259 | for (interception_sources) |c_src| { | 253 | for (interception_sources) |c_src| { |
| ... | @@ -268,7 +262,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -268,7 +262,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 268 | try addCcArgs(target, &cflags); | 262 | try addCcArgs(target, &cflags); |
| 269 | 263 | ||
| 270 | c_source_files.appendAssumeCapacity(.{ | 264 | c_source_files.appendAssumeCapacity(.{ |
| 271 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 265 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 272 | "libtsan", "interception", c_src, | 266 | "libtsan", "interception", c_src, |
| 273 | }), | 267 | }), |
| 274 | .extra_flags = cflags.items, | 268 | .extra_flags = cflags.items, |
| ... | @@ -285,9 +279,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -285,9 +279,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 285 | // Workaround for https://github.com/llvm/llvm-project/issues/97627 | 279 | // Workaround for https://github.com/llvm/llvm-project/issues/97627 |
| 286 | const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null; | 280 | const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null; |
| 287 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 281 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 288 | .local_cache_directory = comp.global_cache_directory, | 282 | .dirs = comp.dirs.withoutLocalCache(), |
| 289 | .global_cache_directory = comp.global_cache_directory, | ||
| 290 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 291 | .thread_pool = comp.thread_pool, | 283 | .thread_pool = comp.thread_pool, |
| 292 | .self_exe_path = comp.self_exe_path, | 284 | .self_exe_path = comp.self_exe_path, |
| 293 | .cache_mode = .whole, | 285 | .cache_mode = .whole, |
src/libs/libunwind.zig+4-9| ... | @@ -50,9 +50,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -50,9 +50,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 50 | return error.SubCompilationFailed; | 50 | return error.SubCompilationFailed; |
| 51 | }; | 51 | }; |
| 52 | const root_mod = Module.create(arena, .{ | 52 | const root_mod = Module.create(arena, .{ |
| 53 | .global_cache_directory = comp.global_cache_directory, | ||
| 54 | .paths = .{ | 53 | .paths = .{ |
| 55 | .root = .{ .root_dir = comp.zig_lib_directory }, | 54 | .root = .zig_lib_root, |
| 56 | .root_src_path = "", | 55 | .root_src_path = "", |
| 57 | }, | 56 | }, |
| 58 | .fully_qualified_name = "root", | 57 | .fully_qualified_name = "root", |
| ... | @@ -76,8 +75,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -76,8 +75,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 76 | .global = config, | 75 | .global = config, |
| 77 | .cc_argv = &.{}, | 76 | .cc_argv = &.{}, |
| 78 | .parent = null, | 77 | .parent = null, |
| 79 | .builtin_mod = null, | ||
| 80 | .builtin_modules = null, // there is only one module in this compilation | ||
| 81 | }) catch |err| { | 78 | }) catch |err| { |
| 82 | comp.setMiscFailure( | 79 | comp.setMiscFailure( |
| 83 | .libunwind, | 80 | .libunwind, |
| ... | @@ -118,7 +115,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -118,7 +115,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 118 | else => unreachable, // See `unwind_src_list`. | 115 | else => unreachable, // See `unwind_src_list`. |
| 119 | } | 116 | } |
| 120 | try cflags.append("-I"); | 117 | try cflags.append("-I"); |
| 121 | try cflags.append(try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libunwind", "include" })); | 118 | try cflags.append(try comp.dirs.zig_lib.join(arena, &.{ "libunwind", "include" })); |
| 122 | try cflags.append("-D_LIBUNWIND_HIDE_SYMBOLS"); | 119 | try cflags.append("-D_LIBUNWIND_HIDE_SYMBOLS"); |
| 123 | try cflags.append("-Wa,--noexecstack"); | 120 | try cflags.append("-Wa,--noexecstack"); |
| 124 | try cflags.append("-fvisibility=hidden"); | 121 | try cflags.append("-fvisibility=hidden"); |
| ... | @@ -148,16 +145,14 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -148,16 +145,14 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 148 | } | 145 | } |
| 149 | 146 | ||
| 150 | c_source_files[i] = .{ | 147 | c_source_files[i] = .{ |
| 151 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}), | 148 | .src_path = try comp.dirs.zig_lib.join(arena, &.{unwind_src}), |
| 152 | .extra_flags = cflags.items, | 149 | .extra_flags = cflags.items, |
| 153 | .owner = root_mod, | 150 | .owner = root_mod, |
| 154 | }; | 151 | }; |
| 155 | } | 152 | } |
| 156 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 153 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 154 | .dirs = comp.dirs.withoutLocalCache(), | ||
| 157 | .self_exe_path = comp.self_exe_path, | 155 | .self_exe_path = comp.self_exe_path, |
| 158 | .local_cache_directory = comp.global_cache_directory, | ||
| 159 | .global_cache_directory = comp.global_cache_directory, | ||
| 160 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 161 | .config = config, | 156 | .config = config, |
| 162 | .root_mod = root_mod, | 157 | .root_mod = root_mod, |
| 163 | .cache_mode = .whole, | 158 | .cache_mode = .whole, |
src/libs/mingw.zig+23-23| ... | @@ -40,7 +40,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -40,7 +40,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 40 | } | 40 | } |
| 41 | var files = [_]Compilation.CSourceFile{ | 41 | var files = [_]Compilation.CSourceFile{ |
| 42 | .{ | 42 | .{ |
| 43 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 43 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 44 | "libc", "mingw", "crt", "crtexe.c", | 44 | "libc", "mingw", "crt", "crtexe.c", |
| 45 | }), | 45 | }), |
| 46 | .extra_flags = args.items, | 46 | .extra_flags = args.items, |
| ... | @@ -57,7 +57,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -57,7 +57,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 57 | try addCrtCcArgs(comp, arena, &args); | 57 | try addCrtCcArgs(comp, arena, &args); |
| 58 | var files = [_]Compilation.CSourceFile{ | 58 | var files = [_]Compilation.CSourceFile{ |
| 59 | .{ | 59 | .{ |
| 60 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 60 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 61 | "libc", "mingw", "crt", "crtdll.c", | 61 | "libc", "mingw", "crt", "crtdll.c", |
| 62 | }), | 62 | }), |
| 63 | .extra_flags = args.items, | 63 | .extra_flags = args.items, |
| ... | @@ -78,7 +78,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -78,7 +78,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 78 | 78 | ||
| 79 | for (mingw32_generic_src) |dep| { | 79 | for (mingw32_generic_src) |dep| { |
| 80 | try c_source_files.append(.{ | 80 | try c_source_files.append(.{ |
| 81 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 81 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 82 | "libc", "mingw", dep, | 82 | "libc", "mingw", dep, |
| 83 | }), | 83 | }), |
| 84 | .extra_flags = crt_args.items, | 84 | .extra_flags = crt_args.items, |
| ... | @@ -88,7 +88,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -88,7 +88,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 88 | if (target.cpu.arch.isX86()) { | 88 | if (target.cpu.arch.isX86()) { |
| 89 | for (mingw32_x86_src) |dep| { | 89 | for (mingw32_x86_src) |dep| { |
| 90 | try c_source_files.append(.{ | 90 | try c_source_files.append(.{ |
| 91 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 91 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 92 | "libc", "mingw", dep, | 92 | "libc", "mingw", dep, |
| 93 | }), | 93 | }), |
| 94 | .extra_flags = crt_args.items, | 94 | .extra_flags = crt_args.items, |
| ... | @@ -98,7 +98,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -98,7 +98,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 98 | if (target.cpu.arch == .x86) { | 98 | if (target.cpu.arch == .x86) { |
| 99 | for (mingw32_x86_32_src) |dep| { | 99 | for (mingw32_x86_32_src) |dep| { |
| 100 | try c_source_files.append(.{ | 100 | try c_source_files.append(.{ |
| 101 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 101 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 102 | "libc", "mingw", dep, | 102 | "libc", "mingw", dep, |
| 103 | }), | 103 | }), |
| 104 | .extra_flags = crt_args.items, | 104 | .extra_flags = crt_args.items, |
| ... | @@ -109,7 +109,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -109,7 +109,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 109 | } else if (target.cpu.arch == .thumb) { | 109 | } else if (target.cpu.arch == .thumb) { |
| 110 | for (mingw32_arm_src) |dep| { | 110 | for (mingw32_arm_src) |dep| { |
| 111 | try c_source_files.append(.{ | 111 | try c_source_files.append(.{ |
| 112 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 112 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 113 | "libc", "mingw", dep, | 113 | "libc", "mingw", dep, |
| 114 | }), | 114 | }), |
| 115 | .extra_flags = crt_args.items, | 115 | .extra_flags = crt_args.items, |
| ... | @@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 118 | } | 118 | } |
| 119 | for (mingw32_arm32_src) |dep| { | 119 | for (mingw32_arm32_src) |dep| { |
| 120 | try c_source_files.append(.{ | 120 | try c_source_files.append(.{ |
| 121 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 121 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 122 | "libc", "mingw", dep, | 122 | "libc", "mingw", dep, |
| 123 | }), | 123 | }), |
| 124 | .extra_flags = crt_args.items, | 124 | .extra_flags = crt_args.items, |
| ... | @@ -128,7 +128,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -128,7 +128,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 128 | } else if (target.cpu.arch == .aarch64) { | 128 | } else if (target.cpu.arch == .aarch64) { |
| 129 | for (mingw32_arm_src) |dep| { | 129 | for (mingw32_arm_src) |dep| { |
| 130 | try c_source_files.append(.{ | 130 | try c_source_files.append(.{ |
| 131 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 131 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 132 | "libc", "mingw", dep, | 132 | "libc", "mingw", dep, |
| 133 | }), | 133 | }), |
| 134 | .extra_flags = crt_args.items, | 134 | .extra_flags = crt_args.items, |
| ... | @@ -137,7 +137,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -137,7 +137,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 137 | } | 137 | } |
| 138 | for (mingw32_arm64_src) |dep| { | 138 | for (mingw32_arm64_src) |dep| { |
| 139 | try c_source_files.append(.{ | 139 | try c_source_files.append(.{ |
| 140 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 140 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 141 | "libc", "mingw", dep, | 141 | "libc", "mingw", dep, |
| 142 | }), | 142 | }), |
| 143 | .extra_flags = crt_args.items, | 143 | .extra_flags = crt_args.items, |
| ... | @@ -164,7 +164,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -164,7 +164,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 164 | 164 | ||
| 165 | for (mingw32_winpthreads_src) |dep| { | 165 | for (mingw32_winpthreads_src) |dep| { |
| 166 | try c_source_files.append(.{ | 166 | try c_source_files.append(.{ |
| 167 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 167 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 168 | "libc", "mingw", dep, | 168 | "libc", "mingw", dep, |
| 169 | }), | 169 | }), |
| 170 | .extra_flags = winpthreads_args.items, | 170 | .extra_flags = winpthreads_args.items, |
| ... | @@ -192,7 +192,7 @@ fn addCcArgs( | ... | @@ -192,7 +192,7 @@ fn addCcArgs( |
| 192 | "-D__USE_MINGW_ANSI_STDIO=0", | 192 | "-D__USE_MINGW_ANSI_STDIO=0", |
| 193 | 193 | ||
| 194 | "-isystem", | 194 | "-isystem", |
| 195 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "any-windows-any" }), | 195 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "any-windows-any" }), |
| 196 | }); | 196 | }); |
| 197 | } | 197 | } |
| 198 | 198 | ||
| ... | @@ -219,7 +219,7 @@ fn addCrtCcArgs( | ... | @@ -219,7 +219,7 @@ fn addCrtCcArgs( |
| 219 | "-DHAVE_CONFIG_H", | 219 | "-DHAVE_CONFIG_H", |
| 220 | 220 | ||
| 221 | "-I", | 221 | "-I", |
| 222 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | 222 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "include" }), |
| 223 | }); | 223 | }); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| ... | @@ -232,7 +232,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -232,7 +232,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 232 | defer arena_allocator.deinit(); | 232 | defer arena_allocator.deinit(); |
| 233 | const arena = arena_allocator.allocator(); | 233 | const arena = arena_allocator.allocator(); |
| 234 | 234 | ||
| 235 | const def_file_path = findDef(arena, comp.getTarget(), comp.zig_lib_directory, lib_name) catch |err| switch (err) { | 235 | const def_file_path = findDef(arena, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { |
| 236 | error.FileNotFound => { | 236 | error.FileNotFound => { |
| 237 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); | 237 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); |
| 238 | // In this case we will end up putting foo.lib onto the linker line and letting the linker | 238 | // In this case we will end up putting foo.lib onto the linker line and letting the linker |
| ... | @@ -247,15 +247,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -247,15 +247,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 247 | // Use the global cache directory. | 247 | // Use the global cache directory. |
| 248 | var cache: Cache = .{ | 248 | var cache: Cache = .{ |
| 249 | .gpa = gpa, | 249 | .gpa = gpa, |
| 250 | .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}), | 250 | .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), |
| 251 | }; | 251 | }; |
| 252 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); | 252 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); |
| 253 | cache.addPrefix(comp.zig_lib_directory); | 253 | cache.addPrefix(comp.dirs.zig_lib); |
| 254 | cache.addPrefix(comp.global_cache_directory); | 254 | cache.addPrefix(comp.dirs.global_cache); |
| 255 | defer cache.manifest_dir.close(); | 255 | defer cache.manifest_dir.close(); |
| 256 | 256 | ||
| 257 | cache.hash.addBytes(build_options.version); | 257 | cache.hash.addBytes(build_options.version); |
| 258 | cache.hash.addOptionalBytes(comp.zig_lib_directory.path); | 258 | cache.hash.addOptionalBytes(comp.dirs.zig_lib.path); |
| 259 | cache.hash.add(target.cpu.arch); | 259 | cache.hash.add(target.cpu.arch); |
| 260 | 260 | ||
| 261 | var man = cache.obtain(); | 261 | var man = cache.obtain(); |
| ... | @@ -276,7 +276,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -276,7 +276,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 276 | try comp.crt_files.ensureUnusedCapacity(gpa, 1); | 276 | try comp.crt_files.ensureUnusedCapacity(gpa, 1); |
| 277 | comp.crt_files.putAssumeCapacityNoClobber(final_lib_basename, .{ | 277 | comp.crt_files.putAssumeCapacityNoClobber(final_lib_basename, .{ |
| 278 | .full_object_path = .{ | 278 | .full_object_path = .{ |
| 279 | .root_dir = comp.global_cache_directory, | 279 | .root_dir = comp.dirs.global_cache, |
| 280 | .sub_path = sub_path, | 280 | .sub_path = sub_path, |
| 281 | }, | 281 | }, |
| 282 | .lock = man.toOwnedLock(), | 282 | .lock = man.toOwnedLock(), |
| ... | @@ -286,11 +286,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -286,11 +286,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 286 | 286 | ||
| 287 | const digest = man.final(); | 287 | const digest = man.final(); |
| 288 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 288 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 289 | var o_dir = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 289 | var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 290 | defer o_dir.close(); | 290 | defer o_dir.close(); |
| 291 | 291 | ||
| 292 | const final_def_basename = try std.fmt.allocPrint(arena, "{s}.def", .{lib_name}); | 292 | const final_def_basename = try std.fmt.allocPrint(arena, "{s}.def", .{lib_name}); |
| 293 | const def_final_path = try comp.global_cache_directory.join(arena, &[_][]const u8{ | 293 | const def_final_path = try comp.dirs.global_cache.join(arena, &[_][]const u8{ |
| 294 | "o", &digest, final_def_basename, | 294 | "o", &digest, final_def_basename, |
| 295 | }); | 295 | }); |
| 296 | 296 | ||
| ... | @@ -306,7 +306,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -306,7 +306,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 306 | var aro_comp = aro.Compilation.init(gpa, std.fs.cwd()); | 306 | var aro_comp = aro.Compilation.init(gpa, std.fs.cwd()); |
| 307 | defer aro_comp.deinit(); | 307 | defer aro_comp.deinit(); |
| 308 | 308 | ||
| 309 | const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" }); | 309 | const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" }); |
| 310 | 310 | ||
| 311 | if (comp.verbose_cc) print: { | 311 | if (comp.verbose_cc) print: { |
| 312 | std.debug.lockStdErr(); | 312 | std.debug.lockStdErr(); |
| ... | @@ -350,7 +350,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -350,7 +350,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 350 | if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; | 350 | if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; |
| 351 | const llvm_bindings = @import("../codegen/llvm/bindings.zig"); | 351 | const llvm_bindings = @import("../codegen/llvm/bindings.zig"); |
| 352 | const def_final_path_z = try arena.dupeZ(u8, def_final_path); | 352 | const def_final_path_z = try arena.dupeZ(u8, def_final_path); |
| 353 | const lib_final_path_z = try comp.global_cache_directory.joinZ(arena, &.{lib_final_path}); | 353 | const lib_final_path_z = try comp.dirs.global_cache.joinZ(arena, &.{lib_final_path}); |
| 354 | if (llvm_bindings.WriteImportLibrary( | 354 | if (llvm_bindings.WriteImportLibrary( |
| 355 | def_final_path_z.ptr, | 355 | def_final_path_z.ptr, |
| 356 | @intFromEnum(target.toCoffMachine()), | 356 | @intFromEnum(target.toCoffMachine()), |
| ... | @@ -370,7 +370,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -370,7 +370,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 370 | defer comp.mutex.unlock(); | 370 | defer comp.mutex.unlock(); |
| 371 | try comp.crt_files.putNoClobber(gpa, final_lib_basename, .{ | 371 | try comp.crt_files.putNoClobber(gpa, final_lib_basename, .{ |
| 372 | .full_object_path = .{ | 372 | .full_object_path = .{ |
| 373 | .root_dir = comp.global_cache_directory, | 373 | .root_dir = comp.dirs.global_cache, |
| 374 | .sub_path = lib_final_path, | 374 | .sub_path = lib_final_path, |
| 375 | }, | 375 | }, |
| 376 | .lock = man.toOwnedLock(), | 376 | .lock = man.toOwnedLock(), |
src/libs/musl.zig+16-21| ... | @@ -34,7 +34,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -34,7 +34,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 34 | try args.append("-DCRT"); | 34 | try args.append("-DCRT"); |
| 35 | var files = [_]Compilation.CSourceFile{ | 35 | var files = [_]Compilation.CSourceFile{ |
| 36 | .{ | 36 | .{ |
| 37 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 37 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 38 | "libc", "musl", "crt", "crt1.c", | 38 | "libc", "musl", "crt", "crt1.c", |
| 39 | }), | 39 | }), |
| 40 | .extra_flags = args.items, | 40 | .extra_flags = args.items, |
| ... | @@ -54,7 +54,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -54,7 +54,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 54 | try args.append("-DCRT"); | 54 | try args.append("-DCRT"); |
| 55 | var files = [_]Compilation.CSourceFile{ | 55 | var files = [_]Compilation.CSourceFile{ |
| 56 | .{ | 56 | .{ |
| 57 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 57 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 58 | "libc", "musl", "crt", "rcrt1.c", | 58 | "libc", "musl", "crt", "rcrt1.c", |
| 59 | }), | 59 | }), |
| 60 | .extra_flags = args.items, | 60 | .extra_flags = args.items, |
| ... | @@ -75,7 +75,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -75,7 +75,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 75 | try args.append("-DCRT"); | 75 | try args.append("-DCRT"); |
| 76 | var files = [_]Compilation.CSourceFile{ | 76 | var files = [_]Compilation.CSourceFile{ |
| 77 | .{ | 77 | .{ |
| 78 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 78 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 79 | "libc", "musl", "crt", "Scrt1.c", | 79 | "libc", "musl", "crt", "Scrt1.c", |
| 80 | }), | 80 | }), |
| 81 | .extra_flags = args.items, | 81 | .extra_flags = args.items, |
| ... | @@ -165,7 +165,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -165,7 +165,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 165 | try addCcArgs(comp, arena, &args, ext == .o3); | 165 | try addCcArgs(comp, arena, &args, ext == .o3); |
| 166 | const c_source_file = try c_source_files.addOne(); | 166 | const c_source_file = try c_source_files.addOne(); |
| 167 | c_source_file.* = .{ | 167 | c_source_file.* = .{ |
| 168 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", src_file }), | 168 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libc", src_file }), |
| 169 | .extra_flags = args.items, | 169 | .extra_flags = args.items, |
| 170 | .owner = undefined, | 170 | .owner = undefined, |
| 171 | }; | 171 | }; |
| ... | @@ -220,9 +220,8 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -220,9 +220,8 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 220 | &.{ arch_define, family_define }; | 220 | &.{ arch_define, family_define }; |
| 221 | 221 | ||
| 222 | const root_mod = try Module.create(arena, .{ | 222 | const root_mod = try Module.create(arena, .{ |
| 223 | .global_cache_directory = comp.global_cache_directory, | ||
| 224 | .paths = .{ | 223 | .paths = .{ |
| 225 | .root = .{ .root_dir = comp.zig_lib_directory }, | 224 | .root = .zig_lib_root, |
| 226 | .root_src_path = "", | 225 | .root_src_path = "", |
| 227 | }, | 226 | }, |
| 228 | .fully_qualified_name = "root", | 227 | .fully_qualified_name = "root", |
| ... | @@ -242,14 +241,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -242,14 +241,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 242 | .global = config, | 241 | .global = config, |
| 243 | .cc_argv = cc_argv, | 242 | .cc_argv = cc_argv, |
| 244 | .parent = null, | 243 | .parent = null, |
| 245 | .builtin_mod = null, | ||
| 246 | .builtin_modules = null, // there is only one module in this compilation | ||
| 247 | }); | 244 | }); |
| 248 | 245 | ||
| 249 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | 246 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ |
| 250 | .local_cache_directory = comp.global_cache_directory, | 247 | .dirs = comp.dirs.withoutLocalCache(), |
| 251 | .global_cache_directory = comp.global_cache_directory, | ||
| 252 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 253 | .self_exe_path = comp.self_exe_path, | 248 | .self_exe_path = comp.self_exe_path, |
| 254 | .cache_mode = .whole, | 249 | .cache_mode = .whole, |
| 255 | .config = config, | 250 | .config = config, |
| ... | @@ -266,9 +261,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -266,9 +261,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 266 | .verbose_cimport = comp.verbose_cimport, | 261 | .verbose_cimport = comp.verbose_cimport, |
| 267 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, | 262 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 268 | .clang_passthrough_mode = comp.clang_passthrough_mode, | 263 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 269 | .c_source_files = &[_]Compilation.CSourceFile{ | 264 | .c_source_files = &.{ |
| 270 | .{ | 265 | .{ |
| 271 | .src_path = try comp.zig_lib_directory.join(arena, &.{ "libc", "musl", "libc.S" }), | 266 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "libc.S" }), |
| 272 | .owner = root_mod, | 267 | .owner = root_mod, |
| 273 | }, | 268 | }, |
| 274 | }, | 269 | }, |
| ... | @@ -411,25 +406,25 @@ fn addCcArgs( | ... | @@ -411,25 +406,25 @@ fn addCcArgs( |
| 411 | "-D_XOPEN_SOURCE=700", | 406 | "-D_XOPEN_SOURCE=700", |
| 412 | 407 | ||
| 413 | "-I", | 408 | "-I", |
| 414 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", arch_name }), | 409 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "arch", arch_name }), |
| 415 | 410 | ||
| 416 | "-I", | 411 | "-I", |
| 417 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", "generic" }), | 412 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "arch", "generic" }), |
| 418 | 413 | ||
| 419 | "-I", | 414 | "-I", |
| 420 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "include" }), | 415 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "src", "include" }), |
| 421 | 416 | ||
| 422 | "-I", | 417 | "-I", |
| 423 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "internal" }), | 418 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "src", "internal" }), |
| 424 | 419 | ||
| 425 | "-I", | 420 | "-I", |
| 426 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "include" }), | 421 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "include" }), |
| 427 | 422 | ||
| 428 | "-I", | 423 | "-I", |
| 429 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }), | 424 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }), |
| 430 | 425 | ||
| 431 | "-I", | 426 | "-I", |
| 432 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }), | 427 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }), |
| 433 | 428 | ||
| 434 | o_arg, | 429 | o_arg, |
| 435 | 430 | ||
| ... | @@ -444,7 +439,7 @@ fn addCcArgs( | ... | @@ -444,7 +439,7 @@ fn addCcArgs( |
| 444 | 439 | ||
| 445 | fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 { | 440 | fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 { |
| 446 | const target = comp.getTarget(); | 441 | const target = comp.getTarget(); |
| 447 | return comp.zig_lib_directory.join(arena, &[_][]const u8{ | 442 | return comp.dirs.zig_lib.join(arena, &.{ |
| 448 | "libc", "musl", "crt", std.zig.target.muslArchName(target.cpu.arch, target.abi), basename, | 443 | "libc", "musl", "crt", std.zig.target.muslArchName(target.cpu.arch, target.abi), basename, |
| 449 | }); | 444 | }); |
| 450 | } | 445 | } |
src/libs/wasi_libc.zig+27-27| ... | @@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 81 | try addLibcBottomHalfIncludes(comp, arena, &args); | 81 | try addLibcBottomHalfIncludes(comp, arena, &args); |
| 82 | var files = [_]Compilation.CSourceFile{ | 82 | var files = [_]Compilation.CSourceFile{ |
| 83 | .{ | 83 | .{ |
| 84 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 84 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 85 | "libc", try sanitize(arena, crt1_reactor_src_file), | 85 | "libc", try sanitize(arena, crt1_reactor_src_file), |
| 86 | }), | 86 | }), |
| 87 | .extra_flags = args.items, | 87 | .extra_flags = args.items, |
| ... | @@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 96 | try addLibcBottomHalfIncludes(comp, arena, &args); | 96 | try addLibcBottomHalfIncludes(comp, arena, &args); |
| 97 | var files = [_]Compilation.CSourceFile{ | 97 | var files = [_]Compilation.CSourceFile{ |
| 98 | .{ | 98 | .{ |
| 99 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 99 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 100 | "libc", try sanitize(arena, crt1_command_src_file), | 100 | "libc", try sanitize(arena, crt1_command_src_file), |
| 101 | }), | 101 | }), |
| 102 | .extra_flags = args.items, | 102 | .extra_flags = args.items, |
| ... | @@ -114,7 +114,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -114,7 +114,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 114 | try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true }); | 114 | try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true }); |
| 115 | for (emmalloc_src_files) |file_path| { | 115 | for (emmalloc_src_files) |file_path| { |
| 116 | try libc_sources.append(.{ | 116 | try libc_sources.append(.{ |
| 117 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 117 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 118 | "libc", try sanitize(arena, file_path), | 118 | "libc", try sanitize(arena, file_path), |
| 119 | }), | 119 | }), |
| 120 | .extra_flags = args.items, | 120 | .extra_flags = args.items, |
| ... | @@ -131,7 +131,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -131,7 +131,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 131 | 131 | ||
| 132 | for (libc_bottom_half_src_files) |file_path| { | 132 | for (libc_bottom_half_src_files) |file_path| { |
| 133 | try libc_sources.append(.{ | 133 | try libc_sources.append(.{ |
| 134 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 134 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 135 | "libc", try sanitize(arena, file_path), | 135 | "libc", try sanitize(arena, file_path), |
| 136 | }), | 136 | }), |
| 137 | .extra_flags = args.items, | 137 | .extra_flags = args.items, |
| ... | @@ -148,7 +148,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -148,7 +148,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 148 | 148 | ||
| 149 | for (libc_top_half_src_files) |file_path| { | 149 | for (libc_top_half_src_files) |file_path| { |
| 150 | try libc_sources.append(.{ | 150 | try libc_sources.append(.{ |
| 151 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 151 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 152 | "libc", try sanitize(arena, file_path), | 152 | "libc", try sanitize(arena, file_path), |
| 153 | }), | 153 | }), |
| 154 | .extra_flags = args.items, | 154 | .extra_flags = args.items, |
| ... | @@ -168,7 +168,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -168,7 +168,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 168 | var emu_dl_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 168 | var emu_dl_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 169 | for (emulated_dl_src_files) |file_path| { | 169 | for (emulated_dl_src_files) |file_path| { |
| 170 | try emu_dl_sources.append(.{ | 170 | try emu_dl_sources.append(.{ |
| 171 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 171 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 172 | "libc", try sanitize(arena, file_path), | 172 | "libc", try sanitize(arena, file_path), |
| 173 | }), | 173 | }), |
| 174 | .extra_flags = args.items, | 174 | .extra_flags = args.items, |
| ... | @@ -186,7 +186,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -186,7 +186,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 186 | var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 186 | var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 187 | for (emulated_process_clocks_src_files) |file_path| { | 187 | for (emulated_process_clocks_src_files) |file_path| { |
| 188 | try emu_clocks_sources.append(.{ | 188 | try emu_clocks_sources.append(.{ |
| 189 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 189 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 190 | "libc", try sanitize(arena, file_path), | 190 | "libc", try sanitize(arena, file_path), |
| 191 | }), | 191 | }), |
| 192 | .extra_flags = args.items, | 192 | .extra_flags = args.items, |
| ... | @@ -203,7 +203,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -203,7 +203,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 203 | var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 203 | var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 204 | for (emulated_getpid_src_files) |file_path| { | 204 | for (emulated_getpid_src_files) |file_path| { |
| 205 | try emu_getpid_sources.append(.{ | 205 | try emu_getpid_sources.append(.{ |
| 206 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 206 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 207 | "libc", try sanitize(arena, file_path), | 207 | "libc", try sanitize(arena, file_path), |
| 208 | }), | 208 | }), |
| 209 | .extra_flags = args.items, | 209 | .extra_flags = args.items, |
| ... | @@ -220,7 +220,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -220,7 +220,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 220 | var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 220 | var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 221 | for (emulated_mman_src_files) |file_path| { | 221 | for (emulated_mman_src_files) |file_path| { |
| 222 | try emu_mman_sources.append(.{ | 222 | try emu_mman_sources.append(.{ |
| 223 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 223 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 224 | "libc", try sanitize(arena, file_path), | 224 | "libc", try sanitize(arena, file_path), |
| 225 | }), | 225 | }), |
| 226 | .extra_flags = args.items, | 226 | .extra_flags = args.items, |
| ... | @@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 238 | 238 | ||
| 239 | for (emulated_signal_bottom_half_src_files) |file_path| { | 239 | for (emulated_signal_bottom_half_src_files) |file_path| { |
| 240 | try emu_signal_sources.append(.{ | 240 | try emu_signal_sources.append(.{ |
| 241 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 241 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 242 | "libc", try sanitize(arena, file_path), | 242 | "libc", try sanitize(arena, file_path), |
| 243 | }), | 243 | }), |
| 244 | .extra_flags = args.items, | 244 | .extra_flags = args.items, |
| ... | @@ -255,7 +255,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -255,7 +255,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 255 | 255 | ||
| 256 | for (emulated_signal_top_half_src_files) |file_path| { | 256 | for (emulated_signal_top_half_src_files) |file_path| { |
| 257 | try emu_signal_sources.append(.{ | 257 | try emu_signal_sources.append(.{ |
| 258 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 258 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 259 | "libc", try sanitize(arena, file_path), | 259 | "libc", try sanitize(arena, file_path), |
| 260 | }), | 260 | }), |
| 261 | .extra_flags = args.items, | 261 | .extra_flags = args.items, |
| ... | @@ -316,10 +316,10 @@ fn addCCArgs( | ... | @@ -316,10 +316,10 @@ fn addCCArgs( |
| 316 | "/", | 316 | "/", |
| 317 | 317 | ||
| 318 | "-iwithsysroot", | 318 | "-iwithsysroot", |
| 319 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }), | 319 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }), |
| 320 | 320 | ||
| 321 | "-iwithsysroot", | 321 | "-iwithsysroot", |
| 322 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }), | 322 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }), |
| 323 | 323 | ||
| 324 | "-DBULK_MEMORY_THRESHOLD=32", | 324 | "-DBULK_MEMORY_THRESHOLD=32", |
| 325 | }); | 325 | }); |
| ... | @@ -336,7 +336,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -336,7 +336,7 @@ fn addLibcBottomHalfIncludes( |
| 336 | ) error{OutOfMemory}!void { | 336 | ) error{OutOfMemory}!void { |
| 337 | try args.appendSlice(&[_][]const u8{ | 337 | try args.appendSlice(&[_][]const u8{ |
| 338 | "-I", | 338 | "-I", |
| 339 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 339 | try comp.dirs.zig_lib.join(arena, &.{ |
| 340 | "libc", | 340 | "libc", |
| 341 | "wasi", | 341 | "wasi", |
| 342 | "libc-bottom-half", | 342 | "libc-bottom-half", |
| ... | @@ -345,7 +345,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -345,7 +345,7 @@ fn addLibcBottomHalfIncludes( |
| 345 | }), | 345 | }), |
| 346 | 346 | ||
| 347 | "-I", | 347 | "-I", |
| 348 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 348 | try comp.dirs.zig_lib.join(arena, &.{ |
| 349 | "libc", | 349 | "libc", |
| 350 | "wasi", | 350 | "wasi", |
| 351 | "libc-bottom-half", | 351 | "libc-bottom-half", |
| ... | @@ -355,7 +355,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -355,7 +355,7 @@ fn addLibcBottomHalfIncludes( |
| 355 | }), | 355 | }), |
| 356 | 356 | ||
| 357 | "-I", | 357 | "-I", |
| 358 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 358 | try comp.dirs.zig_lib.join(arena, &.{ |
| 359 | "libc", | 359 | "libc", |
| 360 | "wasi", | 360 | "wasi", |
| 361 | "libc-bottom-half", | 361 | "libc-bottom-half", |
| ... | @@ -364,7 +364,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -364,7 +364,7 @@ fn addLibcBottomHalfIncludes( |
| 364 | }), | 364 | }), |
| 365 | 365 | ||
| 366 | "-I", | 366 | "-I", |
| 367 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 367 | try comp.dirs.zig_lib.join(arena, &.{ |
| 368 | "libc", | 368 | "libc", |
| 369 | "wasi", | 369 | "wasi", |
| 370 | "libc-top-half", | 370 | "libc-top-half", |
| ... | @@ -374,7 +374,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -374,7 +374,7 @@ fn addLibcBottomHalfIncludes( |
| 374 | }), | 374 | }), |
| 375 | 375 | ||
| 376 | "-I", | 376 | "-I", |
| 377 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 377 | try comp.dirs.zig_lib.join(arena, &.{ |
| 378 | "libc", | 378 | "libc", |
| 379 | "musl", | 379 | "musl", |
| 380 | "src", | 380 | "src", |
| ... | @@ -382,7 +382,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -382,7 +382,7 @@ fn addLibcBottomHalfIncludes( |
| 382 | }), | 382 | }), |
| 383 | 383 | ||
| 384 | "-I", | 384 | "-I", |
| 385 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 385 | try comp.dirs.zig_lib.join(arena, &.{ |
| 386 | "libc", | 386 | "libc", |
| 387 | "wasi", | 387 | "wasi", |
| 388 | "libc-top-half", | 388 | "libc-top-half", |
| ... | @@ -392,7 +392,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -392,7 +392,7 @@ fn addLibcBottomHalfIncludes( |
| 392 | }), | 392 | }), |
| 393 | 393 | ||
| 394 | "-I", | 394 | "-I", |
| 395 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 395 | try comp.dirs.zig_lib.join(arena, &.{ |
| 396 | "libc", | 396 | "libc", |
| 397 | "musl", | 397 | "musl", |
| 398 | "src", | 398 | "src", |
| ... | @@ -408,7 +408,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -408,7 +408,7 @@ fn addLibcTopHalfIncludes( |
| 408 | ) error{OutOfMemory}!void { | 408 | ) error{OutOfMemory}!void { |
| 409 | try args.appendSlice(&[_][]const u8{ | 409 | try args.appendSlice(&[_][]const u8{ |
| 410 | "-I", | 410 | "-I", |
| 411 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 411 | try comp.dirs.zig_lib.join(arena, &.{ |
| 412 | "libc", | 412 | "libc", |
| 413 | "wasi", | 413 | "wasi", |
| 414 | "libc-top-half", | 414 | "libc-top-half", |
| ... | @@ -418,7 +418,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -418,7 +418,7 @@ fn addLibcTopHalfIncludes( |
| 418 | }), | 418 | }), |
| 419 | 419 | ||
| 420 | "-I", | 420 | "-I", |
| 421 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 421 | try comp.dirs.zig_lib.join(arena, &.{ |
| 422 | "libc", | 422 | "libc", |
| 423 | "musl", | 423 | "musl", |
| 424 | "src", | 424 | "src", |
| ... | @@ -426,7 +426,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -426,7 +426,7 @@ fn addLibcTopHalfIncludes( |
| 426 | }), | 426 | }), |
| 427 | 427 | ||
| 428 | "-I", | 428 | "-I", |
| 429 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 429 | try comp.dirs.zig_lib.join(arena, &.{ |
| 430 | "libc", | 430 | "libc", |
| 431 | "wasi", | 431 | "wasi", |
| 432 | "libc-top-half", | 432 | "libc-top-half", |
| ... | @@ -436,7 +436,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -436,7 +436,7 @@ fn addLibcTopHalfIncludes( |
| 436 | }), | 436 | }), |
| 437 | 437 | ||
| 438 | "-I", | 438 | "-I", |
| 439 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 439 | try comp.dirs.zig_lib.join(arena, &.{ |
| 440 | "libc", | 440 | "libc", |
| 441 | "musl", | 441 | "musl", |
| 442 | "src", | 442 | "src", |
| ... | @@ -444,7 +444,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -444,7 +444,7 @@ fn addLibcTopHalfIncludes( |
| 444 | }), | 444 | }), |
| 445 | 445 | ||
| 446 | "-I", | 446 | "-I", |
| 447 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 447 | try comp.dirs.zig_lib.join(arena, &.{ |
| 448 | "libc", | 448 | "libc", |
| 449 | "wasi", | 449 | "wasi", |
| 450 | "libc-top-half", | 450 | "libc-top-half", |
| ... | @@ -454,7 +454,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -454,7 +454,7 @@ fn addLibcTopHalfIncludes( |
| 454 | }), | 454 | }), |
| 455 | 455 | ||
| 456 | "-I", | 456 | "-I", |
| 457 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 457 | try comp.dirs.zig_lib.join(arena, &.{ |
| 458 | "libc", | 458 | "libc", |
| 459 | "musl", | 459 | "musl", |
| 460 | "arch", | 460 | "arch", |
| ... | @@ -462,7 +462,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -462,7 +462,7 @@ fn addLibcTopHalfIncludes( |
| 462 | }), | 462 | }), |
| 463 | 463 | ||
| 464 | "-I", | 464 | "-I", |
| 465 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 465 | try comp.dirs.zig_lib.join(arena, &.{ |
| 466 | "libc", | 466 | "libc", |
| 467 | "wasi", | 467 | "wasi", |
| 468 | "libc-top-half", | 468 | "libc-top-half", |
src/link.zig+3-3| ... | @@ -1675,8 +1675,8 @@ pub fn spawnLld( | ... | @@ -1675,8 +1675,8 @@ pub fn spawnLld( |
| 1675 | const rand_int = std.crypto.random.int(u64); | 1675 | const rand_int = std.crypto.random.int(u64); |
| 1676 | const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; | 1676 | const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; |
| 1677 | 1677 | ||
| 1678 | const rsp_file = try comp.local_cache_directory.handle.createFileZ(rsp_path, .{}); | 1678 | const rsp_file = try comp.dirs.local_cache.handle.createFileZ(rsp_path, .{}); |
| 1679 | defer comp.local_cache_directory.handle.deleteFileZ(rsp_path) catch |err| | 1679 | defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err| |
| 1680 | log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); | 1680 | log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); |
| 1681 | { | 1681 | { |
| 1682 | defer rsp_file.close(); | 1682 | defer rsp_file.close(); |
| ... | @@ -1700,7 +1700,7 @@ pub fn spawnLld( | ... | @@ -1700,7 +1700,7 @@ pub fn spawnLld( |
| 1700 | var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint( | 1700 | var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint( |
| 1701 | arena, | 1701 | arena, |
| 1702 | "@{s}", | 1702 | "@{s}", |
| 1703 | .{try comp.local_cache_directory.join(arena, &.{rsp_path})}, | 1703 | .{try comp.dirs.local_cache.join(arena, &.{rsp_path})}, |
| 1704 | ) }, arena); | 1704 | ) }, arena); |
| 1705 | if (comp.clang_passthrough_mode) { | 1705 | if (comp.clang_passthrough_mode) { |
| 1706 | rsp_child.stdin_behavior = .Inherit; | 1706 | rsp_child.stdin_behavior = .Inherit; |
src/link/C.zig+4-4| ... | @@ -206,7 +206,7 @@ pub fn updateFunc( | ... | @@ -206,7 +206,7 @@ pub fn updateFunc( |
| 206 | .dg = .{ | 206 | .dg = .{ |
| 207 | .gpa = gpa, | 207 | .gpa = gpa, |
| 208 | .pt = pt, | 208 | .pt = pt, |
| 209 | .mod = zcu.navFileScope(func.owner_nav).mod, | 209 | .mod = zcu.navFileScope(func.owner_nav).mod.?, |
| 210 | .error_msg = null, | 210 | .error_msg = null, |
| 211 | .pass = .{ .nav = func.owner_nav }, | 211 | .pass = .{ .nav = func.owner_nav }, |
| 212 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, | 212 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, |
| ... | @@ -337,7 +337,7 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l | ... | @@ -337,7 +337,7 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l |
| 337 | .dg = .{ | 337 | .dg = .{ |
| 338 | .gpa = gpa, | 338 | .gpa = gpa, |
| 339 | .pt = pt, | 339 | .pt = pt, |
| 340 | .mod = zcu.navFileScope(nav_index).mod, | 340 | .mod = zcu.navFileScope(nav_index).mod.?, |
| 341 | .error_msg = null, | 341 | .error_msg = null, |
| 342 | .pass = .{ .nav = nav_index }, | 342 | .pass = .{ .nav = nav_index }, |
| 343 | .is_naked_fn = false, | 343 | .is_naked_fn = false, |
| ... | @@ -490,7 +490,7 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: | ... | @@ -490,7 +490,7 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: |
| 490 | 490 | ||
| 491 | for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock( | 491 | for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock( |
| 492 | pt, | 492 | pt, |
| 493 | zcu.navFileScope(nav).mod, | 493 | zcu.navFileScope(nav).mod.?, |
| 494 | &f, | 494 | &f, |
| 495 | av_block, | 495 | av_block, |
| 496 | self.exported_navs.getPtr(nav), | 496 | self.exported_navs.getPtr(nav), |
| ... | @@ -846,7 +846,7 @@ pub fn updateExports( | ... | @@ -846,7 +846,7 @@ pub fn updateExports( |
| 846 | const gpa = zcu.gpa; | 846 | const gpa = zcu.gpa; |
| 847 | const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { | 847 | const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { |
| 848 | .nav => |nav| .{ | 848 | .nav => |nav| .{ |
| 849 | zcu.navFileScope(nav).mod, | 849 | zcu.navFileScope(nav).mod.?, |
| 850 | .{ .nav = nav }, | 850 | .{ .nav = nav }, |
| 851 | self.navs.getPtr(nav).?, | 851 | self.navs.getPtr(nav).?, |
| 852 | (try self.exported_navs.getOrPut(gpa, nav)).value_ptr, | 852 | (try self.exported_navs.getOrPut(gpa, nav)).value_ptr, |
src/link/Coff.zig+1-1| ... | @@ -1392,7 +1392,7 @@ fn updateNavCode( | ... | @@ -1392,7 +1392,7 @@ fn updateNavCode( |
| 1392 | 1392 | ||
| 1393 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); | 1393 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); |
| 1394 | 1394 | ||
| 1395 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 1395 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 1396 | const required_alignment = switch (pt.navAlignment(nav_index)) { | 1396 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| 1397 | .none => target_util.defaultFunctionAlignment(target), | 1397 | .none => target_util.defaultFunctionAlignment(target), |
| 1398 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 1398 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
src/link/Dwarf.zig+17-27| ... | @@ -34,9 +34,7 @@ pub const UpdateError = error{ | ... | @@ -34,9 +34,7 @@ pub const UpdateError = error{ |
| 34 | std.fs.File.PReadError || | 34 | std.fs.File.PReadError || |
| 35 | std.fs.File.PWriteError; | 35 | std.fs.File.PWriteError; |
| 36 | 36 | ||
| 37 | pub const FlushError = | 37 | pub const FlushError = UpdateError; |
| 38 | UpdateError || | ||
| 39 | std.process.GetCwdError; | ||
| 40 | 38 | ||
| 41 | pub const RelocError = | 39 | pub const RelocError = |
| 42 | std.fs.File.PWriteError; | 40 | std.fs.File.PWriteError; |
| ... | @@ -967,7 +965,7 @@ const Entry = struct { | ... | @@ -967,7 +965,7 @@ const Entry = struct { |
| 967 | const ip = &zcu.intern_pool; | 965 | const ip = &zcu.intern_pool; |
| 968 | for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| { | 966 | for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| { |
| 969 | const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index| | 967 | const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index| |
| 970 | dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod) catch unreachable | 968 | dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) catch unreachable |
| 971 | else | 969 | else |
| 972 | .main; | 970 | .main; |
| 973 | if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry) | 971 | if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry) |
| ... | @@ -977,7 +975,7 @@ const Entry = struct { | ... | @@ -977,7 +975,7 @@ const Entry = struct { |
| 977 | }); | 975 | }); |
| 978 | } | 976 | } |
| 979 | for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| { | 977 | for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| { |
| 980 | const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod) catch unreachable; | 978 | const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod.?) catch unreachable; |
| 981 | if (sec.getUnit(nav_unit) == unit and unit.getEntry(other_entry) == entry) | 979 | if (sec.getUnit(nav_unit) == unit and unit.getEntry(other_entry) == entry) |
| 982 | log.err("missing Nav({}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }); | 980 | log.err("missing Nav({}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }); |
| 983 | } | 981 | } |
| ... | @@ -1620,7 +1618,7 @@ pub const WipNav = struct { | ... | @@ -1620,7 +1618,7 @@ pub const WipNav = struct { |
| 1620 | 1618 | ||
| 1621 | const new_func_info = zcu.funcInfo(func); | 1619 | const new_func_info = zcu.funcInfo(func); |
| 1622 | const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav); | 1620 | const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav); |
| 1623 | const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod); | 1621 | const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod.?); |
| 1624 | 1622 | ||
| 1625 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); | 1623 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); |
| 1626 | if (dwarf.incremental()) { | 1624 | if (dwarf.incremental()) { |
| ... | @@ -1810,7 +1808,7 @@ pub const WipNav = struct { | ... | @@ -1810,7 +1808,7 @@ pub const WipNav = struct { |
| 1810 | fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } { | 1808 | fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } { |
| 1811 | const zcu = wip_nav.pt.zcu; | 1809 | const zcu = wip_nav.pt.zcu; |
| 1812 | const ip = &zcu.intern_pool; | 1810 | const ip = &zcu.intern_pool; |
| 1813 | const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod); | 1811 | const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod.?); |
| 1814 | const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index); | 1812 | const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index); |
| 1815 | if (gop.found_existing) return .{ unit, gop.value_ptr.* }; | 1813 | if (gop.found_existing) return .{ unit, gop.value_ptr.* }; |
| 1816 | const entry = try wip_nav.dwarf.addCommonEntry(unit); | 1814 | const entry = try wip_nav.dwarf.addCommonEntry(unit); |
| ... | @@ -1828,7 +1826,7 @@ pub const WipNav = struct { | ... | @@ -1828,7 +1826,7 @@ pub const WipNav = struct { |
| 1828 | const ip = &zcu.intern_pool; | 1826 | const ip = &zcu.intern_pool; |
| 1829 | const maybe_inst_index = ty.typeDeclInst(zcu); | 1827 | const maybe_inst_index = ty.typeDeclInst(zcu); |
| 1830 | const unit = if (maybe_inst_index) |inst_index| | 1828 | const unit = if (maybe_inst_index) |inst_index| |
| 1831 | try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod) | 1829 | try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) |
| 1832 | else | 1830 | else |
| 1833 | .main; | 1831 | .main; |
| 1834 | const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern()); | 1832 | const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern()); |
| ... | @@ -2386,7 +2384,7 @@ fn initWipNavInner( | ... | @@ -2386,7 +2384,7 @@ fn initWipNavInner( |
| 2386 | else => {}, | 2384 | else => {}, |
| 2387 | } | 2385 | } |
| 2388 | 2386 | ||
| 2389 | const unit = try dwarf.getUnit(file.mod); | 2387 | const unit = try dwarf.getUnit(file.mod.?); |
| 2390 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); | 2388 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); |
| 2391 | errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop(); | 2389 | errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop(); |
| 2392 | if (nav_gop.found_existing) { | 2390 | if (nav_gop.found_existing) { |
| ... | @@ -2514,7 +2512,7 @@ fn initWipNavInner( | ... | @@ -2514,7 +2512,7 @@ fn initWipNavInner( |
| 2514 | try wip_nav.infoAddrSym(sym_index, 0); | 2512 | try wip_nav.infoAddrSym(sym_index, 0); |
| 2515 | wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len); | 2513 | wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len); |
| 2516 | try diw.writeInt(u32, 0, dwarf.endian); | 2514 | try diw.writeInt(u32, 0, dwarf.endian); |
| 2517 | const target = file.mod.resolved_target.result; | 2515 | const target = file.mod.?.resolved_target.result; |
| 2518 | try uleb128(diw, switch (nav.status.fully_resolved.alignment) { | 2516 | try uleb128(diw, switch (nav.status.fully_resolved.alignment) { |
| 2519 | .none => target_info.defaultFunctionAlignment(target), | 2517 | .none => target_info.defaultFunctionAlignment(target), |
| 2520 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), | 2518 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), |
| ... | @@ -2726,7 +2724,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -2726,7 +2724,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2726 | var wip_nav: WipNav = .{ | 2724 | var wip_nav: WipNav = .{ |
| 2727 | .dwarf = dwarf, | 2725 | .dwarf = dwarf, |
| 2728 | .pt = pt, | 2726 | .pt = pt, |
| 2729 | .unit = try dwarf.getUnit(file.mod), | 2727 | .unit = try dwarf.getUnit(file.mod.?), |
| 2730 | .entry = undefined, | 2728 | .entry = undefined, |
| 2731 | .any_children = false, | 2729 | .any_children = false, |
| 2732 | .func = .none, | 2730 | .func = .none, |
| ... | @@ -4044,7 +4042,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP | ... | @@ -4044,7 +4042,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP |
| 4044 | 4042 | ||
| 4045 | const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?; | 4043 | const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?; |
| 4046 | const file = zcu.fileByIndex(inst_info.file); | 4044 | const file = zcu.fileByIndex(inst_info.file); |
| 4047 | const unit = try dwarf.getUnit(file.mod); | 4045 | const unit = try dwarf.getUnit(file.mod.?); |
| 4048 | const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file); | 4046 | const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file); |
| 4049 | if (inst_info.inst == .main_struct_inst) { | 4047 | if (inst_info.inst == .main_struct_inst) { |
| 4050 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index); | 4048 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index); |
| ... | @@ -4348,7 +4346,7 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI | ... | @@ -4348,7 +4346,7 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI |
| 4348 | var line_buf: [4]u8 = undefined; | 4346 | var line_buf: [4]u8 = undefined; |
| 4349 | std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian); | 4347 | std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian); |
| 4350 | 4348 | ||
| 4351 | const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod) orelse return); | 4349 | const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod.?) orelse return); |
| 4352 | const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return); | 4350 | const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return); |
| 4353 | try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf)); | 4351 | try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf)); |
| 4354 | } | 4352 | } |
| ... | @@ -4418,18 +4416,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -4418,18 +4416,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4418 | try wip_nav.updateLazy(.unneeded); | 4416 | try wip_nav.updateLazy(.unneeded); |
| 4419 | } | 4417 | } |
| 4420 | 4418 | ||
| 4421 | { | 4419 | for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| { |
| 4422 | const cwd = try std.process.getCwdAlloc(dwarf.gpa); | 4420 | const root_dir_path = try mod.root.toAbsolute(zcu.comp.dirs, dwarf.gpa); |
| 4423 | defer dwarf.gpa.free(cwd); | 4421 | defer dwarf.gpa.free(root_dir_path); |
| 4424 | for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| { | 4422 | mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path); |
| 4425 | const root_dir_path = try std.fs.path.resolve(dwarf.gpa, &.{ | ||
| 4426 | cwd, | ||
| 4427 | mod.root.root_dir.path orelse "", | ||
| 4428 | mod.root.sub_path, | ||
| 4429 | }); | ||
| 4430 | defer dwarf.gpa.free(root_dir_path); | ||
| 4431 | mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path); | ||
| 4432 | } | ||
| 4433 | } | 4423 | } |
| 4434 | 4424 | ||
| 4435 | var header = std.ArrayList(u8).init(dwarf.gpa); | 4425 | var header = std.ArrayList(u8).init(dwarf.gpa); |
| ... | @@ -4687,7 +4677,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -4687,7 +4677,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4687 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | 4677 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); |
| 4688 | dwarf.writeInt( | 4678 | dwarf.writeInt( |
| 4689 | header.addManyAsSliceAssumeCapacity(dir_index_info.bytes), | 4679 | header.addManyAsSliceAssumeCapacity(dir_index_info.bytes), |
| 4690 | mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod).?).?, | 4680 | mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod.?).?) orelse 0, |
| 4691 | ); | 4681 | ); |
| 4692 | unit.cross_section_relocs.appendAssumeCapacity(.{ | 4682 | unit.cross_section_relocs.appendAssumeCapacity(.{ |
| 4693 | .source_off = @intCast(header.items.len), | 4683 | .source_off = @intCast(header.items.len), |
| ... | @@ -4695,7 +4685,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -4695,7 +4685,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4695 | .target_unit = StringSection.unit, | 4685 | .target_unit = StringSection.unit, |
| 4696 | .target_entry = (try dwarf.debug_line_str.addString( | 4686 | .target_entry = (try dwarf.debug_line_str.addString( |
| 4697 | dwarf, | 4687 | dwarf, |
| 4698 | if (file.mod.builtin_file == file) file.source.? else "", | 4688 | if (file.is_builtin) file.source.? else "", |
| 4699 | )).toOptional(), | 4689 | )).toOptional(), |
| 4700 | }); | 4690 | }); |
| 4701 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | 4691 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); |
src/link/Elf/ZigObject.zig+2-2| ... | @@ -1201,7 +1201,7 @@ fn getNavShdrIndex( | ... | @@ -1201,7 +1201,7 @@ fn getNavShdrIndex( |
| 1201 | return osec; | 1201 | return osec; |
| 1202 | } | 1202 | } |
| 1203 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) | 1203 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) |
| 1204 | return switch (zcu.navFileScope(nav_index).mod.optimize_mode) { | 1204 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1205 | .Debug, .ReleaseSafe => { | 1205 | .Debug, .ReleaseSafe => { |
| 1206 | if (self.data_index) |symbol_index| | 1206 | if (self.data_index) |symbol_index| |
| 1207 | return self.symbol(symbol_index).outputShndx(elf_file).?; | 1207 | return self.symbol(symbol_index).outputShndx(elf_file).?; |
| ... | @@ -1271,7 +1271,7 @@ fn updateNavCode( | ... | @@ -1271,7 +1271,7 @@ fn updateNavCode( |
| 1271 | 1271 | ||
| 1272 | log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index }); | 1272 | log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1273 | 1273 | ||
| 1274 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 1274 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 1275 | const required_alignment = switch (pt.navAlignment(nav_index)) { | 1275 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| 1276 | .none => target_util.defaultFunctionAlignment(target), | 1276 | .none => target_util.defaultFunctionAlignment(target), |
| 1277 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 1277 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
src/link/MachO.zig+3-3| ... | @@ -867,11 +867,11 @@ pub fn resolveLibSystem( | ... | @@ -867,11 +867,11 @@ pub fn resolveLibSystem( |
| 867 | success: { | 867 | success: { |
| 868 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { | 868 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { |
| 869 | .sdk => { | 869 | .sdk => { |
| 870 | const dir = try fs.path.join(arena, &[_][]const u8{ comp.sysroot.?, "usr", "lib" }); | 870 | const dir = try fs.path.join(arena, &.{ comp.sysroot.?, "usr", "lib" }); |
| 871 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; | 871 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; |
| 872 | }, | 872 | }, |
| 873 | .vendored => { | 873 | .vendored => { |
| 874 | const dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "darwin" }); | 874 | const dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "darwin" }); |
| 875 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; | 875 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; |
| 876 | }, | 876 | }, |
| 877 | }; | 877 | }; |
| ... | @@ -4406,7 +4406,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi | ... | @@ -4406,7 +4406,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi |
| 4406 | 4406 | ||
| 4407 | const sdk_dir = switch (sdk_layout) { | 4407 | const sdk_dir = switch (sdk_layout) { |
| 4408 | .sdk => comp.sysroot.?, | 4408 | .sdk => comp.sysroot.?, |
| 4409 | .vendored => fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null, | 4409 | .vendored => fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "libc", "darwin" }) catch return null, |
| 4410 | }; | 4410 | }; |
| 4411 | if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| { | 4411 | if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| { |
| 4412 | return parseSdkVersion(ver); | 4412 | return parseSdkVersion(ver); |
src/link/MachO/ZigObject.zig+2-2| ... | @@ -954,7 +954,7 @@ fn updateNavCode( | ... | @@ -954,7 +954,7 @@ fn updateNavCode( |
| 954 | 954 | ||
| 955 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); | 955 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); |
| 956 | 956 | ||
| 957 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 957 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 958 | const required_alignment = switch (pt.navAlignment(nav_index)) { | 958 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| 959 | .none => target_util.defaultFunctionAlignment(target), | 959 | .none => target_util.defaultFunctionAlignment(target), |
| 960 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 960 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| ... | @@ -1184,7 +1184,7 @@ fn getNavOutputSection( | ... | @@ -1184,7 +1184,7 @@ fn getNavOutputSection( |
| 1184 | } | 1184 | } |
| 1185 | if (is_const) return macho_file.zig_const_sect_index.?; | 1185 | if (is_const) return macho_file.zig_const_sect_index.?; |
| 1186 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) | 1186 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) |
| 1187 | return switch (zcu.navFileScope(nav_index).mod.optimize_mode) { | 1187 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1188 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, | 1188 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, |
| 1189 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, | 1189 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, |
| 1190 | }; | 1190 | }; |
src/link/Plan9.zig+9-13| ... | @@ -315,8 +315,9 @@ pub fn createEmpty( | ... | @@ -315,8 +315,9 @@ pub fn createEmpty( |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void { | 317 | fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void { |
| 318 | const gpa = self.base.comp.gpa; | 318 | const comp = self.base.comp; |
| 319 | const zcu = self.base.comp.zcu.?; | 319 | const gpa = comp.gpa; |
| 320 | const zcu = comp.zcu.?; | ||
| 320 | const file_scope = zcu.navFileScopeIndex(nav_index); | 321 | const file_scope = zcu.navFileScopeIndex(nav_index); |
| 321 | const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope); | 322 | const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope); |
| 322 | if (fn_map_res.found_existing) { | 323 | if (fn_map_res.found_existing) { |
| ... | @@ -345,14 +346,11 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void | ... | @@ -345,14 +346,11 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void |
| 345 | try a.writer().writeInt(u16, 1, .big); | 346 | try a.writer().writeInt(u16, 1, .big); |
| 346 | 347 | ||
| 347 | // getting the full file path | 348 | // getting the full file path |
| 348 | // TODO don't call getcwd here, that is inappropriate | 349 | { |
| 349 | var buf: [std.fs.max_path_bytes]u8 = undefined; | 350 | const full_path = try file.path.toAbsolute(comp.dirs, gpa); |
| 350 | const full_path = try std.fs.path.join(arena, &.{ | 351 | defer gpa.free(full_path); |
| 351 | file.mod.root.root_dir.path orelse try std.posix.getcwd(&buf), | 352 | try self.addPathComponents(full_path, &a); |
| 352 | file.mod.root.sub_path, | 353 | } |
| 353 | file.sub_file_path, | ||
| 354 | }); | ||
| 355 | try self.addPathComponents(full_path, &a); | ||
| 356 | 354 | ||
| 357 | // null terminate | 355 | // null terminate |
| 358 | try a.append(0); | 356 | try a.append(0); |
| ... | @@ -437,9 +435,7 @@ pub fn updateFunc( | ... | @@ -437,9 +435,7 @@ pub fn updateFunc( |
| 437 | .start_line = dbg_info_output.start_line.?, | 435 | .start_line = dbg_info_output.start_line.?, |
| 438 | .end_line = dbg_info_output.end_line, | 436 | .end_line = dbg_info_output.end_line, |
| 439 | }; | 437 | }; |
| 440 | // The awkward error handling here is due to putFn calling `std.posix.getcwd` which it should not do. | 438 | try self.putFn(func.owner_nav, out); |
| 441 | self.putFn(func.owner_nav, out) catch |err| | ||
| 442 | return zcu.codegenFail(func.owner_nav, "failed to put fn: {s}", .{@errorName(err)}); | ||
| 443 | return self.updateFinish(pt, func.owner_nav); | 439 | return self.updateFinish(pt, func.owner_nav); |
| 444 | } | 440 | } |
| 445 | 441 |
src/main.zig+228-549| ... | @@ -63,19 +63,7 @@ pub fn wasi_cwd() std.os.wasi.fd_t { | ... | @@ -63,19 +63,7 @@ pub fn wasi_cwd() std.os.wasi.fd_t { |
| 63 | return cwd_fd; | 63 | return cwd_fd; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | fn getWasiPreopen(name: []const u8) Directory { | 66 | const fatal = std.process.fatal; |
| 67 | return .{ | ||
| 68 | .path = name, | ||
| 69 | .handle = .{ | ||
| 70 | .fd = wasi_preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | } | ||
| 74 | |||
| 75 | pub fn fatal(comptime format: []const u8, args: anytype) noreturn { | ||
| 76 | std.log.err(format, args); | ||
| 77 | process.exit(1); | ||
| 78 | } | ||
| 79 | 67 | ||
| 80 | /// Shaming all the locations that inappropriately use an O(N) search algorithm. | 68 | /// Shaming all the locations that inappropriately use an O(N) search algorithm. |
| 81 | /// Please delete this and fix the compilation errors! | 69 | /// Please delete this and fix the compilation errors! |
| ... | @@ -136,7 +124,6 @@ const debug_usage = normal_usage ++ | ... | @@ -136,7 +124,6 @@ const debug_usage = normal_usage ++ |
| 136 | ; | 124 | ; |
| 137 | 125 | ||
| 138 | const usage = if (build_options.enable_debug_extensions) debug_usage else normal_usage; | 126 | const usage = if (build_options.enable_debug_extensions) debug_usage else normal_usage; |
| 139 | const default_local_zig_cache_basename = ".zig-cache"; | ||
| 140 | 127 | ||
| 141 | var log_scopes: std.ArrayListUnmanaged([]const u8) = .empty; | 128 | var log_scopes: std.ArrayListUnmanaged([]const u8) = .empty; |
| 142 | 129 | ||
| ... | @@ -377,13 +364,13 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -377,13 +364,13 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 377 | dev.check(.help_command); | 364 | dev.check(.help_command); |
| 378 | return io.getStdOut().writeAll(usage); | 365 | return io.getStdOut().writeAll(usage); |
| 379 | } else if (mem.eql(u8, cmd, "ast-check")) { | 366 | } else if (mem.eql(u8, cmd, "ast-check")) { |
| 380 | return cmdAstCheck(gpa, arena, cmd_args); | 367 | return cmdAstCheck(arena, cmd_args); |
| 381 | } else if (mem.eql(u8, cmd, "detect-cpu")) { | 368 | } else if (mem.eql(u8, cmd, "detect-cpu")) { |
| 382 | return cmdDetectCpu(gpa, arena, cmd_args); | 369 | return cmdDetectCpu(cmd_args); |
| 383 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) { | 370 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) { |
| 384 | return cmdChangelist(gpa, arena, cmd_args); | 371 | return cmdChangelist(arena, cmd_args); |
| 385 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) { | 372 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) { |
| 386 | return cmdDumpZir(gpa, arena, cmd_args); | 373 | return cmdDumpZir(arena, cmd_args); |
| 387 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "llvm-ints")) { | 374 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "llvm-ints")) { |
| 388 | return cmdDumpLlvmInts(gpa, arena, cmd_args); | 375 | return cmdDumpLlvmInts(gpa, arena, cmd_args); |
| 389 | } else { | 376 | } else { |
| ... | @@ -809,7 +796,8 @@ const Framework = struct { | ... | @@ -809,7 +796,8 @@ const Framework = struct { |
| 809 | }; | 796 | }; |
| 810 | 797 | ||
| 811 | const CliModule = struct { | 798 | const CliModule = struct { |
| 812 | paths: Package.Module.CreateOptions.Paths, | 799 | root_path: []const u8, |
| 800 | root_src_path: []const u8, | ||
| 813 | cc_argv: []const []const u8, | 801 | cc_argv: []const []const u8, |
| 814 | inherited: Package.Module.CreateOptions.Inherited, | 802 | inherited: Package.Module.CreateOptions.Inherited, |
| 815 | target_arch_os_abi: ?[]const u8, | 803 | target_arch_os_abi: ?[]const u8, |
| ... | @@ -976,7 +964,7 @@ fn buildOutputType( | ... | @@ -976,7 +964,7 @@ fn buildOutputType( |
| 976 | // error output consistent. "root" is special. | 964 | // error output consistent. "root" is special. |
| 977 | var create_module: CreateModule = .{ | 965 | var create_module: CreateModule = .{ |
| 978 | // Populated just before the call to `createModule`. | 966 | // Populated just before the call to `createModule`. |
| 979 | .global_cache_directory = undefined, | 967 | .dirs = undefined, |
| 980 | .object_format = null, | 968 | .object_format = null, |
| 981 | .dynamic_linker = null, | 969 | .dynamic_linker = null, |
| 982 | .modules = .{}, | 970 | .modules = .{}, |
| ... | @@ -1859,7 +1847,7 @@ fn buildOutputType( | ... | @@ -1859,7 +1847,7 @@ fn buildOutputType( |
| 1859 | } else root_src_file = arg; | 1847 | } else root_src_file = arg; |
| 1860 | }, | 1848 | }, |
| 1861 | .def, .unknown => { | 1849 | .def, .unknown => { |
| 1862 | if (std.ascii.eqlIgnoreCase(".xml", std.fs.path.extension(arg))) { | 1850 | if (std.ascii.eqlIgnoreCase(".xml", fs.path.extension(arg))) { |
| 1863 | warn("embedded manifest files must have the extension '.manifest'", .{}); | 1851 | warn("embedded manifest files must have the extension '.manifest'", .{}); |
| 1864 | } | 1852 | } |
| 1865 | fatal("unrecognized file extension of parameter '{s}'", .{arg}); | 1853 | fatal("unrecognized file extension of parameter '{s}'", .{arg}); |
| ... | @@ -2924,13 +2912,14 @@ fn buildOutputType( | ... | @@ -2924,13 +2912,14 @@ fn buildOutputType( |
| 2924 | } | 2912 | } |
| 2925 | 2913 | ||
| 2926 | implicit_root_mod: { | 2914 | implicit_root_mod: { |
| 2927 | const unresolved_src_path = b: { | 2915 | const src_path = b: { |
| 2928 | if (root_src_file) |src_path| { | 2916 | if (root_src_file) |src_path| { |
| 2929 | if (create_module.modules.count() != 0) { | 2917 | if (create_module.modules.count() != 0) { |
| 2930 | fatal("main module provided both by '-M{s}={}{s}' and by positional argument '{s}'", .{ | 2918 | fatal("main module provided both by '-M{s}={s}{c}{s}' and by positional argument '{s}'", .{ |
| 2931 | create_module.modules.keys()[0], | 2919 | create_module.modules.keys()[0], |
| 2932 | create_module.modules.values()[0].paths.root, | 2920 | create_module.modules.values()[0].root_path, |
| 2933 | create_module.modules.values()[0].paths.root_src_path, | 2921 | fs.path.sep, |
| 2922 | create_module.modules.values()[0].root_src_path, | ||
| 2934 | src_path, | 2923 | src_path, |
| 2935 | }); | 2924 | }); |
| 2936 | } | 2925 | } |
| ... | @@ -2987,20 +2976,14 @@ fn buildOutputType( | ... | @@ -2987,20 +2976,14 @@ fn buildOutputType( |
| 2987 | if (mod_opts.error_tracing == true) | 2976 | if (mod_opts.error_tracing == true) |
| 2988 | create_module.opts.any_error_tracing = true; | 2977 | create_module.opts.any_error_tracing = true; |
| 2989 | 2978 | ||
| 2990 | const src_path = try introspect.resolvePath(arena, unresolved_src_path); | ||
| 2991 | const name = switch (arg_mode) { | 2979 | const name = switch (arg_mode) { |
| 2992 | .zig_test => "test", | 2980 | .zig_test => "test", |
| 2993 | .build, .cc, .cpp, .translate_c, .zig_test_obj, .run => fs.path.stem(fs.path.basename(src_path)), | 2981 | .build, .cc, .cpp, .translate_c, .zig_test_obj, .run => fs.path.stem(fs.path.basename(src_path)), |
| 2994 | }; | 2982 | }; |
| 2995 | 2983 | ||
| 2996 | try create_module.modules.put(arena, name, .{ | 2984 | try create_module.modules.put(arena, name, .{ |
| 2997 | .paths = .{ | 2985 | .root_path = fs.path.dirname(src_path) orelse ".", |
| 2998 | .root = .{ | 2986 | .root_src_path = fs.path.basename(src_path), |
| 2999 | .root_dir = Cache.Directory.cwd(), | ||
| 3000 | .sub_path = fs.path.dirname(src_path) orelse "", | ||
| 3001 | }, | ||
| 3002 | .root_src_path = fs.path.basename(src_path), | ||
| 3003 | }, | ||
| 3004 | .cc_argv = try cc_argv.toOwnedSlice(arena), | 2987 | .cc_argv = try cc_argv.toOwnedSlice(arena), |
| 3005 | .inherited = mod_opts, | 2988 | .inherited = mod_opts, |
| 3006 | .target_arch_os_abi = target_arch_os_abi, | 2989 | .target_arch_os_abi = target_arch_os_abi, |
| ... | @@ -3036,85 +3019,50 @@ fn buildOutputType( | ... | @@ -3036,85 +3019,50 @@ fn buildOutputType( |
| 3036 | }); | 3019 | }); |
| 3037 | } | 3020 | } |
| 3038 | 3021 | ||
| 3039 | const self_exe_path: ?[]const u8 = if (!process.can_spawn) | 3022 | const self_exe_path = switch (native_os) { |
| 3040 | null | 3023 | .wasi => {}, |
| 3041 | else | 3024 | else => fs.selfExePathAlloc(arena) catch |err| { |
| 3042 | introspect.findZigExePath(arena) catch |err| { | ||
| 3043 | fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); | 3025 | fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); |
| 3044 | }; | 3026 | }, |
| 3045 | |||
| 3046 | var zig_lib_directory: Directory = d: { | ||
| 3047 | if (override_lib_dir) |unresolved_lib_dir| { | ||
| 3048 | const lib_dir = try introspect.resolvePath(arena, unresolved_lib_dir); | ||
| 3049 | break :d .{ | ||
| 3050 | .path = lib_dir, | ||
| 3051 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | ||
| 3052 | fatal("unable to open zig lib directory '{s}': {s}", .{ lib_dir, @errorName(err) }); | ||
| 3053 | }, | ||
| 3054 | }; | ||
| 3055 | } else if (native_os == .wasi) { | ||
| 3056 | break :d getWasiPreopen("/lib"); | ||
| 3057 | } else if (self_exe_path) |p| { | ||
| 3058 | break :d introspect.findZigLibDirFromSelfExe(arena, p) catch |err| { | ||
| 3059 | fatal("unable to find zig installation directory '{s}': {s}", .{ p, @errorName(err) }); | ||
| 3060 | }; | ||
| 3061 | } else { | ||
| 3062 | unreachable; | ||
| 3063 | } | ||
| 3064 | }; | 3027 | }; |
| 3065 | defer zig_lib_directory.handle.close(); | ||
| 3066 | 3028 | ||
| 3067 | var global_cache_directory: Directory = l: { | 3029 | // This `init` calls `fatal` on error. |
| 3068 | if (override_global_cache_dir) |p| { | 3030 | var dirs: Compilation.Directories = .init( |
| 3069 | break :l .{ | 3031 | arena, |
| 3070 | .handle = try fs.cwd().makeOpenPath(p, .{}), | 3032 | override_lib_dir, |
| 3071 | .path = p, | 3033 | override_global_cache_dir, |
| 3034 | s: { | ||
| 3035 | if (override_local_cache_dir) |p| break :s .{ .override = p }; | ||
| 3036 | break :s switch (arg_mode) { | ||
| 3037 | .run => .global, | ||
| 3038 | else => .search, | ||
| 3072 | }; | 3039 | }; |
| 3073 | } | 3040 | }, |
| 3074 | if (native_os == .wasi) { | 3041 | if (native_os == .wasi) wasi_preopens, |
| 3075 | break :l getWasiPreopen("/cache"); | 3042 | self_exe_path, |
| 3076 | } | 3043 | ); |
| 3077 | const p = try introspect.resolveGlobalCacheDir(arena); | 3044 | defer dirs.deinit(); |
| 3078 | break :l .{ | ||
| 3079 | .handle = try fs.cwd().makeOpenPath(p, .{}), | ||
| 3080 | .path = p, | ||
| 3081 | }; | ||
| 3082 | }; | ||
| 3083 | defer global_cache_directory.handle.close(); | ||
| 3084 | 3045 | ||
| 3085 | if (linker_optimization) |o| { | 3046 | if (linker_optimization) |o| { |
| 3086 | warn("ignoring deprecated linker optimization setting '{s}'", .{o}); | 3047 | warn("ignoring deprecated linker optimization setting '{s}'", .{o}); |
| 3087 | } | 3048 | } |
| 3088 | 3049 | ||
| 3089 | create_module.global_cache_directory = global_cache_directory; | 3050 | create_module.dirs = dirs; |
| 3090 | create_module.opts.emit_llvm_ir = emit_llvm_ir != .no; | 3051 | create_module.opts.emit_llvm_ir = emit_llvm_ir != .no; |
| 3091 | create_module.opts.emit_llvm_bc = emit_llvm_bc != .no; | 3052 | create_module.opts.emit_llvm_bc = emit_llvm_bc != .no; |
| 3092 | create_module.opts.emit_bin = emit_bin != .no; | 3053 | create_module.opts.emit_bin = emit_bin != .no; |
| 3093 | create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0; | 3054 | create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0; |
| 3094 | 3055 | ||
| 3095 | var builtin_modules: std.StringHashMapUnmanaged(*Package.Module) = .empty; | 3056 | const main_mod = try createModule(gpa, arena, &create_module, 0, null, color); |
| 3096 | // `builtin_modules` allocated into `arena`, so no deinit | ||
| 3097 | const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory, &builtin_modules, color); | ||
| 3098 | for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| { | 3057 | for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| { |
| 3099 | if (cli_mod.resolved == null) | 3058 | if (cli_mod.resolved == null) |
| 3100 | fatal("module '{s}' declared but not used", .{key}); | 3059 | fatal("module '{s}' declared but not used", .{key}); |
| 3101 | } | 3060 | } |
| 3102 | 3061 | ||
| 3103 | // When you're testing std, the main module is std. In that case, | 3062 | // When you're testing std, the main module is std, and we need to avoid duplicating the module. |
| 3104 | // we'll just set the std module to the main one, since avoiding | 3063 | const main_mod_is_std = main_mod.root.root == .zig_lib and |
| 3105 | // the errors caused by duplicating it is more effort than it's | 3064 | mem.eql(u8, main_mod.root.sub_path, "std") and |
| 3106 | // worth. | 3065 | mem.eql(u8, main_mod.root_src_path, "std.zig"); |
| 3107 | const main_mod_is_std = m: { | ||
| 3108 | const std_path = try fs.path.resolve(arena, &.{ | ||
| 3109 | zig_lib_directory.path orelse ".", "std", "std.zig", | ||
| 3110 | }); | ||
| 3111 | const main_path = try fs.path.resolve(arena, &.{ | ||
| 3112 | main_mod.root.root_dir.path orelse ".", | ||
| 3113 | main_mod.root.sub_path, | ||
| 3114 | main_mod.root_src_path, | ||
| 3115 | }); | ||
| 3116 | break :m mem.eql(u8, main_path, std_path); | ||
| 3117 | }; | ||
| 3118 | 3066 | ||
| 3119 | const std_mod = m: { | 3067 | const std_mod = m: { |
| 3120 | if (main_mod_is_std) break :m main_mod; | 3068 | if (main_mod_is_std) break :m main_mod; |
| ... | @@ -3126,12 +3074,8 @@ fn buildOutputType( | ... | @@ -3126,12 +3074,8 @@ fn buildOutputType( |
| 3126 | .zig_test, .zig_test_obj => root_mod: { | 3074 | .zig_test, .zig_test_obj => root_mod: { |
| 3127 | const test_mod = if (test_runner_path) |test_runner| test_mod: { | 3075 | const test_mod = if (test_runner_path) |test_runner| test_mod: { |
| 3128 | const test_mod = try Package.Module.create(arena, .{ | 3076 | const test_mod = try Package.Module.create(arena, .{ |
| 3129 | .global_cache_directory = global_cache_directory, | ||
| 3130 | .paths = .{ | 3077 | .paths = .{ |
| 3131 | .root = .{ | 3078 | .root = try .fromUnresolved(arena, dirs, &.{fs.path.dirname(test_runner) orelse "."}), |
| 3132 | .root_dir = Cache.Directory.cwd(), | ||
| 3133 | .sub_path = fs.path.dirname(test_runner) orelse "", | ||
| 3134 | }, | ||
| 3135 | .root_src_path = fs.path.basename(test_runner), | 3079 | .root_src_path = fs.path.basename(test_runner), |
| 3136 | }, | 3080 | }, |
| 3137 | .fully_qualified_name = "root", | 3081 | .fully_qualified_name = "root", |
| ... | @@ -3139,18 +3083,12 @@ fn buildOutputType( | ... | @@ -3139,18 +3083,12 @@ fn buildOutputType( |
| 3139 | .inherited = .{}, | 3083 | .inherited = .{}, |
| 3140 | .global = create_module.resolved_options, | 3084 | .global = create_module.resolved_options, |
| 3141 | .parent = main_mod, | 3085 | .parent = main_mod, |
| 3142 | .builtin_mod = main_mod.getBuiltinDependency(), | ||
| 3143 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 3144 | }); | 3086 | }); |
| 3145 | test_mod.deps = try main_mod.deps.clone(arena); | 3087 | test_mod.deps = try main_mod.deps.clone(arena); |
| 3146 | break :test_mod test_mod; | 3088 | break :test_mod test_mod; |
| 3147 | } else try Package.Module.create(arena, .{ | 3089 | } else try Package.Module.create(arena, .{ |
| 3148 | .global_cache_directory = global_cache_directory, | ||
| 3149 | .paths = .{ | 3090 | .paths = .{ |
| 3150 | .root = .{ | 3091 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 3151 | .root_dir = zig_lib_directory, | ||
| 3152 | .sub_path = "compiler", | ||
| 3153 | }, | ||
| 3154 | .root_src_path = "test_runner.zig", | 3092 | .root_src_path = "test_runner.zig", |
| 3155 | }, | 3093 | }, |
| 3156 | .fully_qualified_name = "root", | 3094 | .fully_qualified_name = "root", |
| ... | @@ -3158,8 +3096,6 @@ fn buildOutputType( | ... | @@ -3158,8 +3096,6 @@ fn buildOutputType( |
| 3158 | .inherited = .{}, | 3096 | .inherited = .{}, |
| 3159 | .global = create_module.resolved_options, | 3097 | .global = create_module.resolved_options, |
| 3160 | .parent = main_mod, | 3098 | .parent = main_mod, |
| 3161 | .builtin_mod = main_mod.getBuiltinDependency(), | ||
| 3162 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 3163 | }); | 3099 | }); |
| 3164 | 3100 | ||
| 3165 | break :root_mod test_mod; | 3101 | break :root_mod test_mod; |
| ... | @@ -3469,50 +3405,6 @@ fn buildOutputType( | ... | @@ -3469,50 +3405,6 @@ fn buildOutputType( |
| 3469 | }); | 3405 | }); |
| 3470 | defer thread_pool.deinit(); | 3406 | defer thread_pool.deinit(); |
| 3471 | 3407 | ||
| 3472 | var cleanup_local_cache_dir: ?fs.Dir = null; | ||
| 3473 | defer if (cleanup_local_cache_dir) |*dir| dir.close(); | ||
| 3474 | |||
| 3475 | var local_cache_directory: Directory = l: { | ||
| 3476 | if (override_local_cache_dir) |local_cache_dir_path| { | ||
| 3477 | const dir = try fs.cwd().makeOpenPath(local_cache_dir_path, .{}); | ||
| 3478 | cleanup_local_cache_dir = dir; | ||
| 3479 | break :l .{ | ||
| 3480 | .handle = dir, | ||
| 3481 | .path = local_cache_dir_path, | ||
| 3482 | }; | ||
| 3483 | } | ||
| 3484 | if (arg_mode == .run) { | ||
| 3485 | break :l global_cache_directory; | ||
| 3486 | } | ||
| 3487 | |||
| 3488 | // search upwards from cwd until we find directory with build.zig | ||
| 3489 | const cwd_path = try process.getCwdAlloc(arena); | ||
| 3490 | var dirname: []const u8 = cwd_path; | ||
| 3491 | while (true) { | ||
| 3492 | const joined_path = try fs.path.join(arena, &.{ | ||
| 3493 | dirname, Package.build_zig_basename, | ||
| 3494 | }); | ||
| 3495 | if (fs.cwd().access(joined_path, .{})) |_| { | ||
| 3496 | const cache_dir_path = try fs.path.join(arena, &.{ dirname, default_local_zig_cache_basename }); | ||
| 3497 | const dir = try fs.cwd().makeOpenPath(cache_dir_path, .{}); | ||
| 3498 | cleanup_local_cache_dir = dir; | ||
| 3499 | break :l .{ .handle = dir, .path = cache_dir_path }; | ||
| 3500 | } else |err| switch (err) { | ||
| 3501 | error.FileNotFound => { | ||
| 3502 | dirname = fs.path.dirname(dirname) orelse { | ||
| 3503 | break :l global_cache_directory; | ||
| 3504 | }; | ||
| 3505 | continue; | ||
| 3506 | }, | ||
| 3507 | else => break :l global_cache_directory, | ||
| 3508 | } | ||
| 3509 | } | ||
| 3510 | |||
| 3511 | // Otherwise we really don't have a reasonable place to put the local cache directory, | ||
| 3512 | // so we utilize the global one. | ||
| 3513 | break :l global_cache_directory; | ||
| 3514 | }; | ||
| 3515 | |||
| 3516 | for (create_module.c_source_files.items) |*src| { | 3408 | for (create_module.c_source_files.items) |*src| { |
| 3517 | if (!mem.eql(u8, src.src_path, "-")) continue; | 3409 | if (!mem.eql(u8, src.src_path, "-")) continue; |
| 3518 | 3410 | ||
| ... | @@ -3524,14 +3416,14 @@ fn buildOutputType( | ... | @@ -3524,14 +3416,14 @@ fn buildOutputType( |
| 3524 | const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{ | 3416 | const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{ |
| 3525 | std.crypto.random.int(u64), ext.canonicalName(target), | 3417 | std.crypto.random.int(u64), ext.canonicalName(target), |
| 3526 | }); | 3418 | }); |
| 3527 | try local_cache_directory.handle.makePath("tmp"); | 3419 | try dirs.local_cache.handle.makePath("tmp"); |
| 3528 | 3420 | ||
| 3529 | // Note that in one of the happy paths, execve() is used to switch to | 3421 | // Note that in one of the happy paths, execve() is used to switch to |
| 3530 | // clang in which case any cleanup logic that exists for this temporary | 3422 | // clang in which case any cleanup logic that exists for this temporary |
| 3531 | // file will not run and this temp file will be leaked. The filename | 3423 | // file will not run and this temp file will be leaked. The filename |
| 3532 | // will be a hash of its contents — so multiple invocations of | 3424 | // will be a hash of its contents — so multiple invocations of |
| 3533 | // `zig cc -` will result in the same temp file name. | 3425 | // `zig cc -` will result in the same temp file name. |
| 3534 | var f = try local_cache_directory.handle.createFile(dump_path, .{}); | 3426 | var f = try dirs.local_cache.handle.createFile(dump_path, .{}); |
| 3535 | defer f.close(); | 3427 | defer f.close(); |
| 3536 | 3428 | ||
| 3537 | // Re-using the hasher from Cache, since the functional requirements | 3429 | // Re-using the hasher from Cache, since the functional requirements |
| ... | @@ -3550,10 +3442,10 @@ fn buildOutputType( | ... | @@ -3550,10 +3442,10 @@ fn buildOutputType( |
| 3550 | std.fmt.fmtSliceHexLower(&bin_digest), | 3442 | std.fmt.fmtSliceHexLower(&bin_digest), |
| 3551 | ext.canonicalName(target), | 3443 | ext.canonicalName(target), |
| 3552 | }); | 3444 | }); |
| 3553 | try local_cache_directory.handle.rename(dump_path, sub_path); | 3445 | try dirs.local_cache.handle.rename(dump_path, sub_path); |
| 3554 | 3446 | ||
| 3555 | // Convert `sub_path` to be relative to current working directory. | 3447 | // Convert `sub_path` to be relative to current working directory. |
| 3556 | src.src_path = try local_cache_directory.join(arena, &.{sub_path}); | 3448 | src.src_path = try dirs.local_cache.join(arena, &.{sub_path}); |
| 3557 | } | 3449 | } |
| 3558 | 3450 | ||
| 3559 | if (build_options.have_llvm and emit_asm != .no) { | 3451 | if (build_options.have_llvm and emit_asm != .no) { |
| ... | @@ -3595,11 +3487,12 @@ fn buildOutputType( | ... | @@ -3595,11 +3487,12 @@ fn buildOutputType( |
| 3595 | defer file_system_inputs.deinit(gpa); | 3487 | defer file_system_inputs.deinit(gpa); |
| 3596 | 3488 | ||
| 3597 | const comp = Compilation.create(gpa, arena, .{ | 3489 | const comp = Compilation.create(gpa, arena, .{ |
| 3598 | .zig_lib_directory = zig_lib_directory, | 3490 | .dirs = dirs, |
| 3599 | .local_cache_directory = local_cache_directory, | ||
| 3600 | .global_cache_directory = global_cache_directory, | ||
| 3601 | .thread_pool = &thread_pool, | 3491 | .thread_pool = &thread_pool, |
| 3602 | .self_exe_path = self_exe_path, | 3492 | .self_exe_path = switch (native_os) { |
| 3493 | .wasi => null, | ||
| 3494 | else => self_exe_path, | ||
| 3495 | }, | ||
| 3603 | .config = create_module.resolved_options, | 3496 | .config = create_module.resolved_options, |
| 3604 | .root_name = root_name, | 3497 | .root_name = root_name, |
| 3605 | .sysroot = create_module.sysroot, | 3498 | .sysroot = create_module.sysroot, |
| ... | @@ -3757,14 +3650,17 @@ fn buildOutputType( | ... | @@ -3757,14 +3650,17 @@ fn buildOutputType( |
| 3757 | error.ExportTableAndImportTableConflict => { | 3650 | error.ExportTableAndImportTableConflict => { |
| 3758 | fatal("--import-table and --export-table may not be used together", .{}); | 3651 | fatal("--import-table and --export-table may not be used together", .{}); |
| 3759 | }, | 3652 | }, |
| 3653 | error.IllegalZigImport => { | ||
| 3654 | fatal("this compiler implementation does not support importing the root source file of a provided module", .{}); | ||
| 3655 | }, | ||
| 3760 | else => fatal("unable to create compilation: {s}", .{@errorName(err)}), | 3656 | else => fatal("unable to create compilation: {s}", .{@errorName(err)}), |
| 3761 | }; | 3657 | }; |
| 3762 | var comp_destroyed = false; | 3658 | var comp_destroyed = false; |
| 3763 | defer if (!comp_destroyed) comp.destroy(); | 3659 | defer if (!comp_destroyed) comp.destroy(); |
| 3764 | 3660 | ||
| 3765 | if (show_builtin) { | 3661 | if (show_builtin) { |
| 3766 | const builtin_mod = comp.root_mod.getBuiltinDependency(); | 3662 | const builtin_opts = comp.root_mod.getBuiltinOptions(comp.config); |
| 3767 | const source = builtin_mod.builtin_file.?.source.?; | 3663 | const source = try builtin_opts.generate(arena); |
| 3768 | return std.io.getStdOut().writeAll(source); | 3664 | return std.io.getStdOut().writeAll(source); |
| 3769 | } | 3665 | } |
| 3770 | switch (listen) { | 3666 | switch (listen) { |
| ... | @@ -3844,7 +3740,7 @@ fn buildOutputType( | ... | @@ -3844,7 +3740,7 @@ fn buildOutputType( |
| 3844 | c_code_directory.path orelse ".", c_code_loc.basename, | 3740 | c_code_directory.path orelse ".", c_code_loc.basename, |
| 3845 | }); | 3741 | }); |
| 3846 | try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" }); | 3742 | try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" }); |
| 3847 | if (zig_lib_directory.path) |p| { | 3743 | if (dirs.zig_lib.path) |p| { |
| 3848 | try test_exec_args.appendSlice(arena, &.{ "-I", p }); | 3744 | try test_exec_args.appendSlice(arena, &.{ "-I", p }); |
| 3849 | } | 3745 | } |
| 3850 | 3746 | ||
| ... | @@ -3875,7 +3771,7 @@ fn buildOutputType( | ... | @@ -3875,7 +3771,7 @@ fn buildOutputType( |
| 3875 | gpa, | 3771 | gpa, |
| 3876 | arena, | 3772 | arena, |
| 3877 | test_exec_args.items, | 3773 | test_exec_args.items, |
| 3878 | self_exe_path.?, | 3774 | self_exe_path, |
| 3879 | arg_mode, | 3775 | arg_mode, |
| 3880 | &target, | 3776 | &target, |
| 3881 | &comp_destroyed, | 3777 | &comp_destroyed, |
| ... | @@ -3890,7 +3786,7 @@ fn buildOutputType( | ... | @@ -3890,7 +3786,7 @@ fn buildOutputType( |
| 3890 | } | 3786 | } |
| 3891 | 3787 | ||
| 3892 | const CreateModule = struct { | 3788 | const CreateModule = struct { |
| 3893 | global_cache_directory: Cache.Directory, | 3789 | dirs: Compilation.Directories, |
| 3894 | modules: std.StringArrayHashMapUnmanaged(CliModule), | 3790 | modules: std.StringArrayHashMapUnmanaged(CliModule), |
| 3895 | opts: Compilation.Config.Options, | 3791 | opts: Compilation.Config.Options, |
| 3896 | dynamic_linker: ?[]const u8, | 3792 | dynamic_linker: ?[]const u8, |
| ... | @@ -3937,8 +3833,6 @@ fn createModule( | ... | @@ -3937,8 +3833,6 @@ fn createModule( |
| 3937 | create_module: *CreateModule, | 3833 | create_module: *CreateModule, |
| 3938 | index: usize, | 3834 | index: usize, |
| 3939 | parent: ?*Package.Module, | 3835 | parent: ?*Package.Module, |
| 3940 | zig_lib_directory: Cache.Directory, | ||
| 3941 | builtin_modules: *std.StringHashMapUnmanaged(*Package.Module), | ||
| 3942 | color: std.zig.Color, | 3836 | color: std.zig.Color, |
| 3943 | ) Allocator.Error!*Package.Module { | 3837 | ) Allocator.Error!*Package.Module { |
| 3944 | const cli_mod = &create_module.modules.values()[index]; | 3838 | const cli_mod = &create_module.modules.values()[index]; |
| ... | @@ -4069,7 +3963,7 @@ fn createModule( | ... | @@ -4069,7 +3963,7 @@ fn createModule( |
| 4069 | } | 3963 | } |
| 4070 | 3964 | ||
| 4071 | if (target.isMinGW()) { | 3965 | if (target.isMinGW()) { |
| 4072 | const exists = mingw.libExists(arena, target, zig_lib_directory, lib_name) catch |err| { | 3966 | const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| { |
| 4073 | fatal("failed to check zig installation for DLL import libs: {s}", .{ | 3967 | fatal("failed to check zig installation for DLL import libs: {s}", .{ |
| 4074 | @errorName(err), | 3968 | @errorName(err), |
| 4075 | }); | 3969 | }); |
| ... | @@ -4225,17 +4119,19 @@ fn createModule( | ... | @@ -4225,17 +4119,19 @@ fn createModule( |
| 4225 | }; | 4119 | }; |
| 4226 | } | 4120 | } |
| 4227 | 4121 | ||
| 4122 | const root: Compilation.Path = try .fromUnresolved(arena, create_module.dirs, &.{cli_mod.root_path}); | ||
| 4123 | |||
| 4228 | const mod = Package.Module.create(arena, .{ | 4124 | const mod = Package.Module.create(arena, .{ |
| 4229 | .global_cache_directory = create_module.global_cache_directory, | 4125 | .paths = .{ |
| 4230 | .paths = cli_mod.paths, | 4126 | .root = root, |
| 4127 | .root_src_path = cli_mod.root_src_path, | ||
| 4128 | }, | ||
| 4231 | .fully_qualified_name = name, | 4129 | .fully_qualified_name = name, |
| 4232 | 4130 | ||
| 4233 | .cc_argv = cli_mod.cc_argv, | 4131 | .cc_argv = cli_mod.cc_argv, |
| 4234 | .inherited = cli_mod.inherited, | 4132 | .inherited = cli_mod.inherited, |
| 4235 | .global = create_module.resolved_options, | 4133 | .global = create_module.resolved_options, |
| 4236 | .parent = parent, | 4134 | .parent = parent, |
| 4237 | .builtin_mod = null, | ||
| 4238 | .builtin_modules = builtin_modules, | ||
| 4239 | }) catch |err| switch (err) { | 4135 | }) catch |err| switch (err) { |
| 4240 | error.ValgrindUnsupportedOnTarget => fatal("unable to create module '{s}': valgrind does not support the selected target CPU architecture", .{name}), | 4136 | error.ValgrindUnsupportedOnTarget => fatal("unable to create module '{s}': valgrind does not support the selected target CPU architecture", .{name}), |
| 4241 | error.TargetRequiresSingleThreaded => fatal("unable to create module '{s}': the selected target does not support multithreading", .{name}), | 4137 | error.TargetRequiresSingleThreaded => fatal("unable to create module '{s}': the selected target does not support multithreading", .{name}), |
| ... | @@ -4258,7 +4154,7 @@ fn createModule( | ... | @@ -4258,7 +4154,7 @@ fn createModule( |
| 4258 | for (cli_mod.deps) |dep| { | 4154 | for (cli_mod.deps) |dep| { |
| 4259 | const dep_index = create_module.modules.getIndex(dep.value) orelse | 4155 | const dep_index = create_module.modules.getIndex(dep.value) orelse |
| 4260 | fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key }); | 4156 | fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key }); |
| 4261 | const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, zig_lib_directory, builtin_modules, color); | 4157 | const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, color); |
| 4262 | try mod.deps.put(arena, dep.key, dep_mod); | 4158 | try mod.deps.put(arena, dep.key, dep_mod); |
| 4263 | } | 4159 | } |
| 4264 | 4160 | ||
| ... | @@ -4544,15 +4440,13 @@ fn runOrTestHotSwap( | ... | @@ -4544,15 +4440,13 @@ fn runOrTestHotSwap( |
| 4544 | // tmp zig-cache and use it to spawn the child process. This way we are free to update | 4440 | // tmp zig-cache and use it to spawn the child process. This way we are free to update |
| 4545 | // the binary with each requested hot update. | 4441 | // the binary with each requested hot update. |
| 4546 | .windows => blk: { | 4442 | .windows => blk: { |
| 4547 | try lf.emit.root_dir.handle.copyFile(lf.emit.sub_path, comp.local_cache_directory.handle, lf.emit.sub_path, .{}); | 4443 | try lf.emit.root_dir.handle.copyFile(lf.emit.sub_path, comp.dirs.local_cache.handle, lf.emit.sub_path, .{}); |
| 4548 | break :blk try fs.path.join(gpa, &[_][]const u8{ | 4444 | break :blk try fs.path.join(gpa, &.{ comp.dirs.local_cache.path orelse ".", lf.emit.sub_path }); |
| 4549 | comp.local_cache_directory.path orelse ".", lf.emit.sub_path, | ||
| 4550 | }); | ||
| 4551 | }, | 4445 | }, |
| 4552 | 4446 | ||
| 4553 | // A naive `directory.join` here will indeed get the correct path to the binary, | 4447 | // A naive `directory.join` here will indeed get the correct path to the binary, |
| 4554 | // however, in the case of cwd, we actually want `./foo` so that the path can be executed. | 4448 | // however, in the case of cwd, we actually want `./foo` so that the path can be executed. |
| 4555 | else => try fs.path.join(gpa, &[_][]const u8{ | 4449 | else => try fs.path.join(gpa, &.{ |
| 4556 | lf.emit.root_dir.path orelse ".", lf.emit.sub_path, | 4450 | lf.emit.root_dir.path orelse ".", lf.emit.sub_path, |
| 4557 | }), | 4451 | }), |
| 4558 | }; | 4452 | }; |
| ... | @@ -4679,7 +4573,7 @@ fn cmdTranslateC( | ... | @@ -4679,7 +4573,7 @@ fn cmdTranslateC( |
| 4679 | }, | 4573 | }, |
| 4680 | } | 4574 | } |
| 4681 | 4575 | ||
| 4682 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); | 4576 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 4683 | defer zig_cache_tmp_dir.close(); | 4577 | defer zig_cache_tmp_dir.close(); |
| 4684 | 4578 | ||
| 4685 | const ext = Compilation.classifyFileExt(c_source_file.src_path); | 4579 | const ext = Compilation.classifyFileExt(c_source_file.src_path); |
| ... | @@ -4735,7 +4629,7 @@ fn cmdTranslateC( | ... | @@ -4735,7 +4629,7 @@ fn cmdTranslateC( |
| 4735 | new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg); | 4629 | new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg); |
| 4736 | } | 4630 | } |
| 4737 | 4631 | ||
| 4738 | const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"}); | 4632 | const c_headers_dir_path_z = try comp.dirs.zig_lib.joinZ(arena, &.{"include"}); |
| 4739 | var errors = std.zig.ErrorBundle.empty; | 4633 | var errors = std.zig.ErrorBundle.empty; |
| 4740 | var tree = translate_c.translate( | 4634 | var tree = translate_c.translate( |
| 4741 | comp.gpa, | 4635 | comp.gpa, |
| ... | @@ -4787,7 +4681,7 @@ fn cmdTranslateC( | ... | @@ -4787,7 +4681,7 @@ fn cmdTranslateC( |
| 4787 | 4681 | ||
| 4788 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &hex_digest }); | 4682 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &hex_digest }); |
| 4789 | 4683 | ||
| 4790 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 4684 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 4791 | defer o_dir.close(); | 4685 | defer o_dir.close(); |
| 4792 | 4686 | ||
| 4793 | var zig_file = try o_dir.createFile(translated_zig_basename, .{}); | 4687 | var zig_file = try o_dir.createFile(translated_zig_basename, .{}); |
| ... | @@ -4808,9 +4702,9 @@ fn cmdTranslateC( | ... | @@ -4808,9 +4702,9 @@ fn cmdTranslateC( |
| 4808 | p.digest = bin_digest; | 4702 | p.digest = bin_digest; |
| 4809 | p.errors = std.zig.ErrorBundle.empty; | 4703 | p.errors = std.zig.ErrorBundle.empty; |
| 4810 | } else { | 4704 | } else { |
| 4811 | const out_zig_path = try fs.path.join(arena, &[_][]const u8{ "o", &hex_digest, translated_zig_basename }); | 4705 | const out_zig_path = try fs.path.join(arena, &.{ "o", &hex_digest, translated_zig_basename }); |
| 4812 | const zig_file = comp.local_cache_directory.handle.openFile(out_zig_path, .{}) catch |err| { | 4706 | const zig_file = comp.dirs.local_cache.handle.openFile(out_zig_path, .{}) catch |err| { |
| 4813 | const path = comp.local_cache_directory.path orelse "."; | 4707 | const path = comp.dirs.local_cache.path orelse "."; |
| 4814 | fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{ path, fs.path.sep_str, out_zig_path, @errorName(err) }); | 4708 | fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{ path, fs.path.sep_str, out_zig_path, @errorName(err) }); |
| 4815 | }; | 4709 | }; |
| 4816 | defer zig_file.close(); | 4710 | defer zig_file.close(); |
| ... | @@ -4854,7 +4748,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4854,7 +4748,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4854 | var templates = findTemplates(gpa, arena); | 4748 | var templates = findTemplates(gpa, arena); |
| 4855 | defer templates.deinit(); | 4749 | defer templates.deinit(); |
| 4856 | 4750 | ||
| 4857 | const cwd_path = try process.getCwdAlloc(arena); | 4751 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 4858 | const cwd_basename = fs.path.basename(cwd_path); | 4752 | const cwd_basename = fs.path.basename(cwd_path); |
| 4859 | const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename); | 4753 | const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename); |
| 4860 | 4754 | ||
| ... | @@ -4952,7 +4846,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4952,7 +4846,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4952 | const argv_index_exe = child_argv.items.len; | 4846 | const argv_index_exe = child_argv.items.len; |
| 4953 | _ = try child_argv.addOne(); | 4847 | _ = try child_argv.addOne(); |
| 4954 | 4848 | ||
| 4955 | const self_exe_path = try introspect.findZigExePath(arena); | 4849 | const self_exe_path = try fs.selfExePathAlloc(arena); |
| 4956 | try child_argv.append(self_exe_path); | 4850 | try child_argv.append(self_exe_path); |
| 4957 | 4851 | ||
| 4958 | const argv_index_zig_lib_dir = child_argv.items.len; | 4852 | const argv_index_zig_lib_dir = child_argv.items.len; |
| ... | @@ -5169,60 +5063,30 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5169,60 +5063,30 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5169 | 5063 | ||
| 5170 | process.raiseFileDescriptorLimit(); | 5064 | process.raiseFileDescriptorLimit(); |
| 5171 | 5065 | ||
| 5172 | var zig_lib_directory: Directory = if (override_lib_dir) |lib_dir| .{ | 5066 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 5173 | .path = lib_dir, | ||
| 5174 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | ||
| 5175 | fatal("unable to open zig lib directory from 'zig-lib-dir' argument: '{s}': {s}", .{ lib_dir, @errorName(err) }); | ||
| 5176 | }, | ||
| 5177 | } else introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | ||
| 5178 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | ||
| 5179 | }; | ||
| 5180 | defer zig_lib_directory.handle.close(); | ||
| 5181 | |||
| 5182 | const cwd_path = try process.getCwdAlloc(arena); | ||
| 5183 | child_argv.items[argv_index_zig_lib_dir] = zig_lib_directory.path orelse cwd_path; | ||
| 5184 | |||
| 5185 | const build_root = try findBuildRoot(arena, .{ | 5067 | const build_root = try findBuildRoot(arena, .{ |
| 5186 | .cwd_path = cwd_path, | 5068 | .cwd_path = cwd_path, |
| 5187 | .build_file = build_file, | 5069 | .build_file = build_file, |
| 5188 | }); | 5070 | }); |
| 5189 | child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path; | ||
| 5190 | |||
| 5191 | var global_cache_directory: Directory = l: { | ||
| 5192 | const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); | ||
| 5193 | const dir = fs.cwd().makeOpenPath(p, .{}) catch |err| { | ||
| 5194 | const base_msg = "unable to open or create the global Zig cache at '{s}': {s}.{s}"; | ||
| 5195 | const extra = "\nIf this location is not writable then consider specifying an " ++ | ||
| 5196 | "alternative with the ZIG_GLOBAL_CACHE_DIR environment variable or the " ++ | ||
| 5197 | "--global-cache-dir option."; | ||
| 5198 | const show_extra = err == error.AccessDenied or err == error.ReadOnlyFileSystem; | ||
| 5199 | fatal(base_msg, .{ p, @errorName(err), if (show_extra) extra else "" }); | ||
| 5200 | }; | ||
| 5201 | break :l .{ | ||
| 5202 | .handle = dir, | ||
| 5203 | .path = p, | ||
| 5204 | }; | ||
| 5205 | }; | ||
| 5206 | defer global_cache_directory.handle.close(); | ||
| 5207 | 5071 | ||
| 5208 | child_argv.items[argv_index_global_cache_dir] = global_cache_directory.path orelse cwd_path; | 5072 | // This `init` calls `fatal` on error. |
| 5209 | 5073 | var dirs: Compilation.Directories = .init( | |
| 5210 | var local_cache_directory: Directory = l: { | 5074 | arena, |
| 5211 | if (override_local_cache_dir) |local_cache_dir_path| { | 5075 | override_lib_dir, |
| 5212 | break :l .{ | 5076 | override_global_cache_dir, |
| 5213 | .handle = try fs.cwd().makeOpenPath(local_cache_dir_path, .{}), | 5077 | .{ .override = path: { |
| 5214 | .path = local_cache_dir_path, | 5078 | if (override_local_cache_dir) |d| break :path d; |
| 5215 | }; | 5079 | break :path try build_root.directory.join(arena, &.{introspect.default_local_zig_cache_basename}); |
| 5216 | } | 5080 | } }, |
| 5217 | const cache_dir_path = try build_root.directory.join(arena, &.{default_local_zig_cache_basename}); | 5081 | {}, |
| 5218 | break :l .{ | 5082 | self_exe_path, |
| 5219 | .handle = try build_root.directory.handle.makeOpenPath(default_local_zig_cache_basename, .{}), | 5083 | ); |
| 5220 | .path = cache_dir_path, | 5084 | defer dirs.deinit(); |
| 5221 | }; | ||
| 5222 | }; | ||
| 5223 | defer local_cache_directory.handle.close(); | ||
| 5224 | 5085 | ||
| 5225 | child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path; | 5086 | child_argv.items[argv_index_zig_lib_dir] = dirs.zig_lib.path orelse cwd_path; |
| 5087 | child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path; | ||
| 5088 | child_argv.items[argv_index_global_cache_dir] = dirs.global_cache.path orelse cwd_path; | ||
| 5089 | child_argv.items[argv_index_cache_dir] = dirs.local_cache.path orelse cwd_path; | ||
| 5226 | 5090 | ||
| 5227 | var thread_pool: ThreadPool = undefined; | 5091 | var thread_pool: ThreadPool = undefined; |
| 5228 | try thread_pool.init(.{ | 5092 | try thread_pool.init(.{ |
| ... | @@ -5250,16 +5114,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5250,16 +5114,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5250 | // big block here to ensure the cleanup gets run when we extract out our argv. | 5114 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 5251 | { | 5115 | { |
| 5252 | const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_build_runner) |runner| .{ | 5116 | const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_build_runner) |runner| .{ |
| 5253 | .root = .{ | 5117 | .root = try .fromUnresolved(arena, dirs, &.{fs.path.dirname(runner) orelse "."}), |
| 5254 | .root_dir = Cache.Directory.cwd(), | ||
| 5255 | .sub_path = fs.path.dirname(runner) orelse "", | ||
| 5256 | }, | ||
| 5257 | .root_src_path = fs.path.basename(runner), | 5118 | .root_src_path = fs.path.basename(runner), |
| 5258 | } else .{ | 5119 | } else .{ |
| 5259 | .root = .{ | 5120 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 5260 | .root_dir = zig_lib_directory, | ||
| 5261 | .sub_path = "compiler", | ||
| 5262 | }, | ||
| 5263 | .root_src_path = "build_runner.zig", | 5121 | .root_src_path = "build_runner.zig", |
| 5264 | }; | 5122 | }; |
| 5265 | 5123 | ||
| ... | @@ -5272,7 +5130,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5272,7 +5130,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5272 | }); | 5130 | }); |
| 5273 | 5131 | ||
| 5274 | const root_mod = try Package.Module.create(arena, .{ | 5132 | const root_mod = try Package.Module.create(arena, .{ |
| 5275 | .global_cache_directory = global_cache_directory, | ||
| 5276 | .paths = main_mod_paths, | 5133 | .paths = main_mod_paths, |
| 5277 | .fully_qualified_name = "root", | 5134 | .fully_qualified_name = "root", |
| 5278 | .cc_argv = &.{}, | 5135 | .cc_argv = &.{}, |
| ... | @@ -5281,16 +5138,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5281,16 +5138,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5281 | }, | 5138 | }, |
| 5282 | .global = config, | 5139 | .global = config, |
| 5283 | .parent = null, | 5140 | .parent = null, |
| 5284 | .builtin_mod = null, | ||
| 5285 | .builtin_modules = null, // all modules will inherit this one's builtin | ||
| 5286 | }); | 5141 | }); |
| 5287 | 5142 | ||
| 5288 | const builtin_mod = root_mod.getBuiltinDependency(); | ||
| 5289 | |||
| 5290 | const build_mod = try Package.Module.create(arena, .{ | 5143 | const build_mod = try Package.Module.create(arena, .{ |
| 5291 | .global_cache_directory = global_cache_directory, | ||
| 5292 | .paths = .{ | 5144 | .paths = .{ |
| 5293 | .root = .{ .root_dir = build_root.directory }, | 5145 | .root = try .fromUnresolved(arena, dirs, &.{build_root.directory.path orelse "."}), |
| 5294 | .root_src_path = build_root.build_zig_basename, | 5146 | .root_src_path = build_root.build_zig_basename, |
| 5295 | }, | 5147 | }, |
| 5296 | .fully_qualified_name = "root.@build", | 5148 | .fully_qualified_name = "root.@build", |
| ... | @@ -5298,8 +5150,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5298,8 +5150,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5298 | .inherited = .{}, | 5150 | .inherited = .{}, |
| 5299 | .global = config, | 5151 | .global = config, |
| 5300 | .parent = root_mod, | 5152 | .parent = root_mod, |
| 5301 | .builtin_mod = builtin_mod, | ||
| 5302 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 5303 | }); | 5153 | }); |
| 5304 | 5154 | ||
| 5305 | var cleanup_build_dir: ?fs.Dir = null; | 5155 | var cleanup_build_dir: ?fs.Dir = null; |
| ... | @@ -5312,7 +5162,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5312,7 +5162,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5312 | var job_queue: Package.Fetch.JobQueue = .{ | 5162 | var job_queue: Package.Fetch.JobQueue = .{ |
| 5313 | .http_client = &http_client, | 5163 | .http_client = &http_client, |
| 5314 | .thread_pool = &thread_pool, | 5164 | .thread_pool = &thread_pool, |
| 5315 | .global_cache = global_cache_directory, | 5165 | .global_cache = dirs.global_cache, |
| 5316 | .read_only = false, | 5166 | .read_only = false, |
| 5317 | .recursive = true, | 5167 | .recursive = true, |
| 5318 | .debug_hash = false, | 5168 | .debug_hash = false, |
| ... | @@ -5340,14 +5190,16 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5340,14 +5190,16 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5340 | try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); | 5190 | try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); |
| 5341 | try job_queue.table.ensureUnusedCapacity(gpa, 1); | 5191 | try job_queue.table.ensureUnusedCapacity(gpa, 1); |
| 5342 | 5192 | ||
| 5193 | const phantom_package_root: Cache.Path = .{ .root_dir = build_root.directory }; | ||
| 5194 | |||
| 5343 | var fetch: Package.Fetch = .{ | 5195 | var fetch: Package.Fetch = .{ |
| 5344 | .arena = std.heap.ArenaAllocator.init(gpa), | 5196 | .arena = std.heap.ArenaAllocator.init(gpa), |
| 5345 | .location = .{ .relative_path = build_mod.root }, | 5197 | .location = .{ .relative_path = phantom_package_root }, |
| 5346 | .location_tok = 0, | 5198 | .location_tok = 0, |
| 5347 | .hash_tok = .none, | 5199 | .hash_tok = .none, |
| 5348 | .name_tok = 0, | 5200 | .name_tok = 0, |
| 5349 | .lazy_status = .eager, | 5201 | .lazy_status = .eager, |
| 5350 | .parent_package_root = build_mod.root, | 5202 | .parent_package_root = phantom_package_root, |
| 5351 | .parent_manifest_ast = null, | 5203 | .parent_manifest_ast = null, |
| 5352 | .prog_node = fetch_prog_node, | 5204 | .prog_node = fetch_prog_node, |
| 5353 | .job_queue = &job_queue, | 5205 | .job_queue = &job_queue, |
| ... | @@ -5371,7 +5223,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5371,7 +5223,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5371 | job_queue.all_fetches.appendAssumeCapacity(&fetch); | 5223 | job_queue.all_fetches.appendAssumeCapacity(&fetch); |
| 5372 | 5224 | ||
| 5373 | job_queue.table.putAssumeCapacityNoClobber( | 5225 | job_queue.table.putAssumeCapacityNoClobber( |
| 5374 | Package.Fetch.relativePathDigest(build_mod.root, global_cache_directory), | 5226 | Package.Fetch.relativePathDigest(phantom_package_root, dirs.global_cache), |
| 5375 | &fetch, | 5227 | &fetch, |
| 5376 | ); | 5228 | ); |
| 5377 | 5229 | ||
| ... | @@ -5397,9 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5397,9 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5397 | arena, | 5249 | arena, |
| 5398 | source_buf.items, | 5250 | source_buf.items, |
| 5399 | root_mod, | 5251 | root_mod, |
| 5400 | global_cache_directory, | 5252 | dirs, |
| 5401 | local_cache_directory, | ||
| 5402 | builtin_mod, | ||
| 5403 | config, | 5253 | config, |
| 5404 | ); | 5254 | ); |
| 5405 | 5255 | ||
| ... | @@ -5416,10 +5266,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5416,10 +5266,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5416 | if (!f.has_build_zig) | 5266 | if (!f.has_build_zig) |
| 5417 | continue; | 5267 | continue; |
| 5418 | const hash_slice = hash.toSlice(); | 5268 | const hash_slice = hash.toSlice(); |
| 5269 | const mod_root_path = try f.package_root.toString(arena); | ||
| 5419 | const m = try Package.Module.create(arena, .{ | 5270 | const m = try Package.Module.create(arena, .{ |
| 5420 | .global_cache_directory = global_cache_directory, | ||
| 5421 | .paths = .{ | 5271 | .paths = .{ |
| 5422 | .root = try f.package_root.clone(arena), | 5272 | .root = try .fromUnresolved(arena, dirs, &.{mod_root_path}), |
| 5423 | .root_src_path = Package.build_zig_basename, | 5273 | .root_src_path = Package.build_zig_basename, |
| 5424 | }, | 5274 | }, |
| 5425 | .fully_qualified_name = try std.fmt.allocPrint( | 5275 | .fully_qualified_name = try std.fmt.allocPrint( |
| ... | @@ -5431,8 +5281,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5431,8 +5281,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5431 | .inherited = .{}, | 5281 | .inherited = .{}, |
| 5432 | .global = config, | 5282 | .global = config, |
| 5433 | .parent = root_mod, | 5283 | .parent = root_mod, |
| 5434 | .builtin_mod = builtin_mod, | ||
| 5435 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 5436 | }); | 5284 | }); |
| 5437 | const hash_cloned = try arena.dupe(u8, hash_slice); | 5285 | const hash_cloned = try arena.dupe(u8, hash_slice); |
| 5438 | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); | 5286 | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); |
| ... | @@ -5449,7 +5297,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5449,7 +5297,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5449 | for (dep_names, man.dependencies.values()) |name, dep| { | 5297 | for (dep_names, man.dependencies.values()) |name, dep| { |
| 5450 | const dep_digest = Package.Fetch.depDigest( | 5298 | const dep_digest = Package.Fetch.depDigest( |
| 5451 | f.package_root, | 5299 | f.package_root, |
| 5452 | global_cache_directory, | 5300 | dirs.global_cache, |
| 5453 | dep, | 5301 | dep, |
| 5454 | ) orelse continue; | 5302 | ) orelse continue; |
| 5455 | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; | 5303 | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; |
| ... | @@ -5461,18 +5309,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5461,18 +5309,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5461 | } else try createEmptyDependenciesModule( | 5309 | } else try createEmptyDependenciesModule( |
| 5462 | arena, | 5310 | arena, |
| 5463 | root_mod, | 5311 | root_mod, |
| 5464 | global_cache_directory, | 5312 | dirs, |
| 5465 | local_cache_directory, | ||
| 5466 | builtin_mod, | ||
| 5467 | config, | 5313 | config, |
| 5468 | ); | 5314 | ); |
| 5469 | 5315 | ||
| 5470 | try root_mod.deps.put(arena, "@build", build_mod); | 5316 | try root_mod.deps.put(arena, "@build", build_mod); |
| 5471 | 5317 | ||
| 5472 | const comp = Compilation.create(gpa, arena, .{ | 5318 | const comp = Compilation.create(gpa, arena, .{ |
| 5473 | .zig_lib_directory = zig_lib_directory, | 5319 | .dirs = dirs, |
| 5474 | .local_cache_directory = local_cache_directory, | ||
| 5475 | .global_cache_directory = global_cache_directory, | ||
| 5476 | .root_name = "build", | 5320 | .root_name = "build", |
| 5477 | .config = config, | 5321 | .config = config, |
| 5478 | .root_mod = root_mod, | 5322 | .root_mod = root_mod, |
| ... | @@ -5507,7 +5351,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5507,7 +5351,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5507 | // above, and thus the output file is already closed. | 5351 | // above, and thus the output file is already closed. |
| 5508 | //try comp.makeBinFileExecutable(); | 5352 | //try comp.makeBinFileExecutable(); |
| 5509 | child_argv.items[argv_index_exe] = | 5353 | child_argv.items[argv_index_exe] = |
| 5510 | try local_cache_directory.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); | 5354 | try dirs.local_cache.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); |
| 5511 | } | 5355 | } |
| 5512 | 5356 | ||
| 5513 | if (process.can_spawn) { | 5357 | if (process.can_spawn) { |
| ... | @@ -5539,12 +5383,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5539,12 +5383,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5539 | // that are missing. | 5383 | // that are missing. |
| 5540 | const s = fs.path.sep_str; | 5384 | const s = fs.path.sep_str; |
| 5541 | const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce; | 5385 | const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce; |
| 5542 | const stdout = local_cache_directory.handle.readFileAlloc(arena, tmp_sub_path, 50 * 1024 * 1024) catch |err| { | 5386 | const stdout = dirs.local_cache.handle.readFileAlloc(arena, tmp_sub_path, 50 * 1024 * 1024) catch |err| { |
| 5543 | fatal("unable to read results of configure phase from '{}{s}': {s}", .{ | 5387 | fatal("unable to read results of configure phase from '{}{s}': {s}", .{ |
| 5544 | local_cache_directory, tmp_sub_path, @errorName(err), | 5388 | dirs.local_cache, tmp_sub_path, @errorName(err), |
| 5545 | }); | 5389 | }); |
| 5546 | }; | 5390 | }; |
| 5547 | local_cache_directory.handle.deleteFile(tmp_sub_path) catch {}; | 5391 | dirs.local_cache.handle.deleteFile(tmp_sub_path) catch {}; |
| 5548 | 5392 | ||
| 5549 | var it = mem.splitScalar(u8, stdout, '\n'); | 5393 | var it = mem.splitScalar(u8, stdout, '\n'); |
| 5550 | var any_errors = false; | 5394 | var any_errors = false; |
| ... | @@ -5633,7 +5477,7 @@ fn jitCmd( | ... | @@ -5633,7 +5477,7 @@ fn jitCmd( |
| 5633 | .basename = exe_basename, | 5477 | .basename = exe_basename, |
| 5634 | }; | 5478 | }; |
| 5635 | 5479 | ||
| 5636 | const self_exe_path = introspect.findZigExePath(arena) catch |err| { | 5480 | const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { |
| 5637 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); | 5481 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); |
| 5638 | }; | 5482 | }; |
| 5639 | 5483 | ||
| ... | @@ -5645,24 +5489,16 @@ fn jitCmd( | ... | @@ -5645,24 +5489,16 @@ fn jitCmd( |
| 5645 | const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); | 5489 | const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); |
| 5646 | const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); | 5490 | const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); |
| 5647 | 5491 | ||
| 5648 | var zig_lib_directory: Directory = if (override_lib_dir) |lib_dir| .{ | 5492 | // This `init` calls `fatal` on error. |
| 5649 | .path = lib_dir, | 5493 | var dirs: Compilation.Directories = .init( |
| 5650 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | 5494 | arena, |
| 5651 | fatal("unable to open zig lib directory from 'zig-lib-dir' argument: '{s}': {s}", .{ lib_dir, @errorName(err) }); | 5495 | override_lib_dir, |
| 5652 | }, | 5496 | override_global_cache_dir, |
| 5653 | } else introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | 5497 | .global, |
| 5654 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | 5498 | if (native_os == .wasi) wasi_preopens, |
| 5655 | }; | 5499 | self_exe_path, |
| 5656 | defer zig_lib_directory.handle.close(); | 5500 | ); |
| 5657 | 5501 | defer dirs.deinit(); | |
| 5658 | var global_cache_directory: Directory = l: { | ||
| 5659 | const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); | ||
| 5660 | break :l .{ | ||
| 5661 | .handle = try fs.cwd().makeOpenPath(p, .{}), | ||
| 5662 | .path = p, | ||
| 5663 | }; | ||
| 5664 | }; | ||
| 5665 | defer global_cache_directory.handle.close(); | ||
| 5666 | 5502 | ||
| 5667 | var thread_pool: ThreadPool = undefined; | 5503 | var thread_pool: ThreadPool = undefined; |
| 5668 | try thread_pool.init(.{ | 5504 | try thread_pool.init(.{ |
| ... | @@ -5680,10 +5516,7 @@ fn jitCmd( | ... | @@ -5680,10 +5516,7 @@ fn jitCmd( |
| 5680 | // big block here to ensure the cleanup gets run when we extract out our argv. | 5516 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 5681 | { | 5517 | { |
| 5682 | const main_mod_paths: Package.Module.CreateOptions.Paths = .{ | 5518 | const main_mod_paths: Package.Module.CreateOptions.Paths = .{ |
| 5683 | .root = .{ | 5519 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 5684 | .root_dir = zig_lib_directory, | ||
| 5685 | .sub_path = "compiler", | ||
| 5686 | }, | ||
| 5687 | .root_src_path = options.root_src_path, | 5520 | .root_src_path = options.root_src_path, |
| 5688 | }; | 5521 | }; |
| 5689 | 5522 | ||
| ... | @@ -5698,7 +5531,6 @@ fn jitCmd( | ... | @@ -5698,7 +5531,6 @@ fn jitCmd( |
| 5698 | }); | 5531 | }); |
| 5699 | 5532 | ||
| 5700 | const root_mod = try Package.Module.create(arena, .{ | 5533 | const root_mod = try Package.Module.create(arena, .{ |
| 5701 | .global_cache_directory = global_cache_directory, | ||
| 5702 | .paths = main_mod_paths, | 5534 | .paths = main_mod_paths, |
| 5703 | .fully_qualified_name = "root", | 5535 | .fully_qualified_name = "root", |
| 5704 | .cc_argv = &.{}, | 5536 | .cc_argv = &.{}, |
| ... | @@ -5709,18 +5541,12 @@ fn jitCmd( | ... | @@ -5709,18 +5541,12 @@ fn jitCmd( |
| 5709 | }, | 5541 | }, |
| 5710 | .global = config, | 5542 | .global = config, |
| 5711 | .parent = null, | 5543 | .parent = null, |
| 5712 | .builtin_mod = null, | ||
| 5713 | .builtin_modules = null, // all modules will inherit this one's builtin | ||
| 5714 | }); | 5544 | }); |
| 5715 | 5545 | ||
| 5716 | if (options.depend_on_aro) { | 5546 | if (options.depend_on_aro) { |
| 5717 | const aro_mod = try Package.Module.create(arena, .{ | 5547 | const aro_mod = try Package.Module.create(arena, .{ |
| 5718 | .global_cache_directory = global_cache_directory, | ||
| 5719 | .paths = .{ | 5548 | .paths = .{ |
| 5720 | .root = .{ | 5549 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler/aro"), |
| 5721 | .root_dir = zig_lib_directory, | ||
| 5722 | .sub_path = "compiler/aro", | ||
| 5723 | }, | ||
| 5724 | .root_src_path = "aro.zig", | 5550 | .root_src_path = "aro.zig", |
| 5725 | }, | 5551 | }, |
| 5726 | .fully_qualified_name = "aro", | 5552 | .fully_qualified_name = "aro", |
| ... | @@ -5732,16 +5558,12 @@ fn jitCmd( | ... | @@ -5732,16 +5558,12 @@ fn jitCmd( |
| 5732 | }, | 5558 | }, |
| 5733 | .global = config, | 5559 | .global = config, |
| 5734 | .parent = null, | 5560 | .parent = null, |
| 5735 | .builtin_mod = root_mod.getBuiltinDependency(), | ||
| 5736 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 5737 | }); | 5561 | }); |
| 5738 | try root_mod.deps.put(arena, "aro", aro_mod); | 5562 | try root_mod.deps.put(arena, "aro", aro_mod); |
| 5739 | } | 5563 | } |
| 5740 | 5564 | ||
| 5741 | const comp = Compilation.create(gpa, arena, .{ | 5565 | const comp = Compilation.create(gpa, arena, .{ |
| 5742 | .zig_lib_directory = zig_lib_directory, | 5566 | .dirs = dirs, |
| 5743 | .local_cache_directory = global_cache_directory, | ||
| 5744 | .global_cache_directory = global_cache_directory, | ||
| 5745 | .root_name = options.cmd_name, | 5567 | .root_name = options.cmd_name, |
| 5746 | .config = config, | 5568 | .config = config, |
| 5747 | .root_mod = root_mod, | 5569 | .root_mod = root_mod, |
| ... | @@ -5778,16 +5600,16 @@ fn jitCmd( | ... | @@ -5778,16 +5600,16 @@ fn jitCmd( |
| 5778 | }; | 5600 | }; |
| 5779 | } | 5601 | } |
| 5780 | 5602 | ||
| 5781 | const exe_path = try global_cache_directory.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); | 5603 | const exe_path = try dirs.global_cache.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); |
| 5782 | child_argv.appendAssumeCapacity(exe_path); | 5604 | child_argv.appendAssumeCapacity(exe_path); |
| 5783 | } | 5605 | } |
| 5784 | 5606 | ||
| 5785 | if (options.prepend_zig_lib_dir_path) | 5607 | if (options.prepend_zig_lib_dir_path) |
| 5786 | child_argv.appendAssumeCapacity(zig_lib_directory.path.?); | 5608 | child_argv.appendAssumeCapacity(dirs.zig_lib.path.?); |
| 5787 | if (options.prepend_zig_exe_path) | 5609 | if (options.prepend_zig_exe_path) |
| 5788 | child_argv.appendAssumeCapacity(self_exe_path); | 5610 | child_argv.appendAssumeCapacity(self_exe_path); |
| 5789 | if (options.prepend_global_cache_path) | 5611 | if (options.prepend_global_cache_path) |
| 5790 | child_argv.appendAssumeCapacity(global_cache_directory.path.?); | 5612 | child_argv.appendAssumeCapacity(dirs.global_cache.path.?); |
| 5791 | 5613 | ||
| 5792 | child_argv.appendSliceAssumeCapacity(args); | 5614 | child_argv.appendSliceAssumeCapacity(args); |
| 5793 | 5615 | ||
| ... | @@ -6270,7 +6092,6 @@ const usage_ast_check = | ... | @@ -6270,7 +6092,6 @@ const usage_ast_check = |
| 6270 | ; | 6092 | ; |
| 6271 | 6093 | ||
| 6272 | fn cmdAstCheck( | 6094 | fn cmdAstCheck( |
| 6273 | gpa: Allocator, | ||
| 6274 | arena: Allocator, | 6095 | arena: Allocator, |
| 6275 | args: []const []const u8, | 6096 | args: []const []const u8, |
| 6276 | ) !void { | 6097 | ) !void { |
| ... | @@ -6281,7 +6102,7 @@ fn cmdAstCheck( | ... | @@ -6281,7 +6102,7 @@ fn cmdAstCheck( |
| 6281 | var color: Color = .auto; | 6102 | var color: Color = .auto; |
| 6282 | var want_output_text = false; | 6103 | var want_output_text = false; |
| 6283 | var force_zon = false; | 6104 | var force_zon = false; |
| 6284 | var zig_source_file: ?[]const u8 = null; | 6105 | var zig_source_path: ?[]const u8 = null; |
| 6285 | 6106 | ||
| 6286 | var i: usize = 0; | 6107 | var i: usize = 0; |
| 6287 | while (i < args.len) : (i += 1) { | 6108 | while (i < args.len) : (i += 1) { |
| ... | @@ -6306,96 +6127,55 @@ fn cmdAstCheck( | ... | @@ -6306,96 +6127,55 @@ fn cmdAstCheck( |
| 6306 | } else { | 6127 | } else { |
| 6307 | fatal("unrecognized parameter: '{s}'", .{arg}); | 6128 | fatal("unrecognized parameter: '{s}'", .{arg}); |
| 6308 | } | 6129 | } |
| 6309 | } else if (zig_source_file == null) { | 6130 | } else if (zig_source_path == null) { |
| 6310 | zig_source_file = arg; | 6131 | zig_source_path = arg; |
| 6311 | } else { | 6132 | } else { |
| 6312 | fatal("extra positional parameter: '{s}'", .{arg}); | 6133 | fatal("extra positional parameter: '{s}'", .{arg}); |
| 6313 | } | 6134 | } |
| 6314 | } | 6135 | } |
| 6315 | 6136 | ||
| 6316 | var file: Zcu.File = .{ | 6137 | const display_path = zig_source_path orelse "<stdin>"; |
| 6317 | .status = .never_loaded, | 6138 | const source: [:0]const u8 = s: { |
| 6318 | .sub_file_path = undefined, | 6139 | var f = if (zig_source_path) |p| file: { |
| 6319 | .stat = undefined, | 6140 | break :file fs.cwd().openFile(p, .{}) catch |err| { |
| 6320 | .source = null, | 6141 | fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6321 | .tree = null, | 6142 | }; |
| 6322 | .zir = null, | 6143 | } else io.getStdIn(); |
| 6323 | .zoir = null, | 6144 | defer if (zig_source_path != null) f.close(); |
| 6324 | .mod = undefined, | 6145 | break :s std.zig.readSourceFileToEndAlloc(arena, f, null) catch |err| { |
| 6325 | }; | 6146 | fatal("unable to load file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6326 | if (zig_source_file) |file_name| { | ||
| 6327 | var f = fs.cwd().openFile(file_name, .{}) catch |err| { | ||
| 6328 | fatal("unable to open file for ast-check '{s}': {s}", .{ file_name, @errorName(err) }); | ||
| 6329 | }; | ||
| 6330 | defer f.close(); | ||
| 6331 | |||
| 6332 | const stat = try f.stat(); | ||
| 6333 | |||
| 6334 | if (stat.size > std.zig.max_src_size) | ||
| 6335 | return error.FileTooBig; | ||
| 6336 | |||
| 6337 | const source = try arena.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0); | ||
| 6338 | const amt = try f.readAll(source); | ||
| 6339 | if (amt != stat.size) | ||
| 6340 | return error.UnexpectedEndOfFile; | ||
| 6341 | |||
| 6342 | file.sub_file_path = file_name; | ||
| 6343 | file.source = source; | ||
| 6344 | file.stat = .{ | ||
| 6345 | .size = stat.size, | ||
| 6346 | .inode = stat.inode, | ||
| 6347 | .mtime = stat.mtime, | ||
| 6348 | }; | ||
| 6349 | } else { | ||
| 6350 | const stdin = io.getStdIn(); | ||
| 6351 | const source = std.zig.readSourceFileToEndAlloc(arena, stdin, null) catch |err| { | ||
| 6352 | fatal("unable to read stdin: {}", .{err}); | ||
| 6353 | }; | 6147 | }; |
| 6354 | file.sub_file_path = "<stdin>"; | 6148 | }; |
| 6355 | file.source = source; | ||
| 6356 | file.stat.size = source.len; | ||
| 6357 | } | ||
| 6358 | 6149 | ||
| 6359 | const mode: Ast.Mode = mode: { | 6150 | const mode: Ast.Mode = mode: { |
| 6360 | if (force_zon) break :mode .zon; | 6151 | if (force_zon) break :mode .zon; |
| 6361 | if (zig_source_file) |name| { | 6152 | if (zig_source_path) |path| { |
| 6362 | if (mem.endsWith(u8, name, ".zon")) { | 6153 | if (mem.endsWith(u8, path, ".zon")) { |
| 6363 | break :mode .zon; | 6154 | break :mode .zon; |
| 6364 | } | 6155 | } |
| 6365 | } | 6156 | } |
| 6366 | break :mode .zig; | 6157 | break :mode .zig; |
| 6367 | }; | 6158 | }; |
| 6368 | 6159 | ||
| 6369 | file.mod = try Package.Module.createLimited(arena, .{ | 6160 | const tree = try Ast.parse(arena, source, mode); |
| 6370 | .root = Path.cwd(), | ||
| 6371 | .root_src_path = file.sub_file_path, | ||
| 6372 | .fully_qualified_name = "root", | ||
| 6373 | }); | ||
| 6374 | |||
| 6375 | file.tree = try Ast.parse(gpa, file.source.?, mode); | ||
| 6376 | defer file.tree.?.deinit(gpa); | ||
| 6377 | 6161 | ||
| 6378 | switch (mode) { | 6162 | switch (mode) { |
| 6379 | .zig => { | 6163 | .zig => { |
| 6380 | file.zir = try AstGen.generate(gpa, file.tree.?); | 6164 | const zir = try AstGen.generate(arena, tree); |
| 6381 | defer file.zir.?.deinit(gpa); | ||
| 6382 | 6165 | ||
| 6383 | if (file.zir.?.hasCompileErrors()) { | 6166 | if (zir.hasCompileErrors()) { |
| 6384 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6167 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6385 | try wip_errors.init(gpa); | 6168 | try wip_errors.init(arena); |
| 6386 | defer wip_errors.deinit(); | 6169 | try wip_errors.addZirErrorMessages(zir, tree, source, display_path); |
| 6387 | try Compilation.addZirErrorMessages(&wip_errors, &file); | ||
| 6388 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6170 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6389 | defer error_bundle.deinit(gpa); | ||
| 6390 | error_bundle.renderToStdErr(color.renderOptions()); | 6171 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6391 | 6172 | if (zir.loweringFailed()) { | |
| 6392 | if (file.zir.?.loweringFailed()) { | ||
| 6393 | process.exit(1); | 6173 | process.exit(1); |
| 6394 | } | 6174 | } |
| 6395 | } | 6175 | } |
| 6396 | 6176 | ||
| 6397 | if (!want_output_text) { | 6177 | if (!want_output_text) { |
| 6398 | if (file.zir.?.hasCompileErrors()) { | 6178 | if (zir.hasCompileErrors()) { |
| 6399 | process.exit(1); | 6179 | process.exit(1); |
| 6400 | } else { | 6180 | } else { |
| 6401 | return cleanExit(); | 6181 | return cleanExit(); |
| ... | @@ -6407,20 +6187,20 @@ fn cmdAstCheck( | ... | @@ -6407,20 +6187,20 @@ fn cmdAstCheck( |
| 6407 | 6187 | ||
| 6408 | { | 6188 | { |
| 6409 | const token_bytes = @sizeOf(Ast.TokenList) + | 6189 | const token_bytes = @sizeOf(Ast.TokenList) + |
| 6410 | file.tree.?.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset)); | 6190 | tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset)); |
| 6411 | const tree_bytes = @sizeOf(Ast) + file.tree.?.nodes.len * | 6191 | const tree_bytes = @sizeOf(Ast) + tree.nodes.len * |
| 6412 | (@sizeOf(Ast.Node.Tag) + | 6192 | (@sizeOf(Ast.Node.Tag) + |
| 6413 | @sizeOf(Ast.TokenIndex) + | 6193 | @sizeOf(Ast.TokenIndex) + |
| 6414 | // Here we don't use @sizeOf(Ast.Node.Data) because it would include | 6194 | // Here we don't use @sizeOf(Ast.Node.Data) because it would include |
| 6415 | // the debug safety tag but we want to measure release size. | 6195 | // the debug safety tag but we want to measure release size. |
| 6416 | 8); | 6196 | 8); |
| 6417 | const instruction_bytes = file.zir.?.instructions.len * | 6197 | const instruction_bytes = zir.instructions.len * |
| 6418 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include | 6198 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| 6419 | // the debug safety tag but we want to measure release size. | 6199 | // the debug safety tag but we want to measure release size. |
| 6420 | (@sizeOf(Zir.Inst.Tag) + 8); | 6200 | (@sizeOf(Zir.Inst.Tag) + 8); |
| 6421 | const extra_bytes = file.zir.?.extra.len * @sizeOf(u32); | 6201 | const extra_bytes = zir.extra.len * @sizeOf(u32); |
| 6422 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + | 6202 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + |
| 6423 | file.zir.?.string_bytes.len * @sizeOf(u8); | 6203 | zir.string_bytes.len * @sizeOf(u8); |
| 6424 | const stdout = io.getStdOut(); | 6204 | const stdout = io.getStdOut(); |
| 6425 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; | 6205 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; |
| 6426 | // zig fmt: off | 6206 | // zig fmt: off |
| ... | @@ -6434,44 +6214,33 @@ fn cmdAstCheck( | ... | @@ -6434,44 +6214,33 @@ fn cmdAstCheck( |
| 6434 | \\# Extra Data Items: {d} ({}) | 6214 | \\# Extra Data Items: {d} ({}) |
| 6435 | \\ | 6215 | \\ |
| 6436 | , .{ | 6216 | , .{ |
| 6437 | fmtIntSizeBin(file.source.?.len), | 6217 | fmtIntSizeBin(source.len), |
| 6438 | file.tree.?.tokens.len, fmtIntSizeBin(token_bytes), | 6218 | tree.tokens.len, fmtIntSizeBin(token_bytes), |
| 6439 | file.tree.?.nodes.len, fmtIntSizeBin(tree_bytes), | 6219 | tree.nodes.len, fmtIntSizeBin(tree_bytes), |
| 6440 | fmtIntSizeBin(total_bytes), | 6220 | fmtIntSizeBin(total_bytes), |
| 6441 | file.zir.?.instructions.len, fmtIntSizeBin(instruction_bytes), | 6221 | zir.instructions.len, fmtIntSizeBin(instruction_bytes), |
| 6442 | fmtIntSizeBin(file.zir.?.string_bytes.len), | 6222 | fmtIntSizeBin(zir.string_bytes.len), |
| 6443 | file.zir.?.extra.len, fmtIntSizeBin(extra_bytes), | 6223 | zir.extra.len, fmtIntSizeBin(extra_bytes), |
| 6444 | }); | 6224 | }); |
| 6445 | // zig fmt: on | 6225 | // zig fmt: on |
| 6446 | } | 6226 | } |
| 6447 | 6227 | ||
| 6448 | try @import("print_zir.zig").renderAsTextToFile(gpa, &file, io.getStdOut()); | 6228 | try @import("print_zir.zig").renderAsTextToFile(arena, tree, zir, io.getStdOut()); |
| 6449 | 6229 | ||
| 6450 | if (file.zir.?.hasCompileErrors()) { | 6230 | if (zir.hasCompileErrors()) { |
| 6451 | process.exit(1); | 6231 | process.exit(1); |
| 6452 | } else { | 6232 | } else { |
| 6453 | return cleanExit(); | 6233 | return cleanExit(); |
| 6454 | } | 6234 | } |
| 6455 | }, | 6235 | }, |
| 6456 | .zon => { | 6236 | .zon => { |
| 6457 | const zoir = try ZonGen.generate(gpa, file.tree.?, .{}); | 6237 | const zoir = try ZonGen.generate(arena, tree, .{}); |
| 6458 | defer zoir.deinit(gpa); | ||
| 6459 | |||
| 6460 | if (zoir.hasCompileErrors()) { | 6238 | if (zoir.hasCompileErrors()) { |
| 6461 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6239 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6462 | try wip_errors.init(gpa); | 6240 | try wip_errors.init(arena); |
| 6463 | defer wip_errors.deinit(); | 6241 | try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path); |
| 6464 | |||
| 6465 | { | ||
| 6466 | const src_path = try file.fullPath(gpa); | ||
| 6467 | defer gpa.free(src_path); | ||
| 6468 | try wip_errors.addZoirErrorMessages(zoir, file.tree.?, file.source.?, src_path); | ||
| 6469 | } | ||
| 6470 | |||
| 6471 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6242 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6472 | defer error_bundle.deinit(gpa); | ||
| 6473 | error_bundle.renderToStdErr(color.renderOptions()); | 6243 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6474 | |||
| 6475 | process.exit(1); | 6244 | process.exit(1); |
| 6476 | } | 6245 | } |
| 6477 | 6246 | ||
| ... | @@ -6489,16 +6258,9 @@ fn cmdAstCheck( | ... | @@ -6489,16 +6258,9 @@ fn cmdAstCheck( |
| 6489 | } | 6258 | } |
| 6490 | } | 6259 | } |
| 6491 | 6260 | ||
| 6492 | fn cmdDetectCpu( | 6261 | fn cmdDetectCpu(args: []const []const u8) !void { |
| 6493 | gpa: Allocator, | ||
| 6494 | arena: Allocator, | ||
| 6495 | args: []const []const u8, | ||
| 6496 | ) !void { | ||
| 6497 | dev.check(.detect_cpu_command); | 6262 | dev.check(.detect_cpu_command); |
| 6498 | 6263 | ||
| 6499 | _ = gpa; | ||
| 6500 | _ = arena; | ||
| 6501 | |||
| 6502 | const detect_cpu_usage = | 6264 | const detect_cpu_usage = |
| 6503 | \\Usage: zig detect-cpu [--llvm] | 6265 | \\Usage: zig detect-cpu [--llvm] |
| 6504 | \\ | 6266 | \\ |
| ... | @@ -6676,13 +6438,11 @@ fn cmdDumpLlvmInts( | ... | @@ -6676,13 +6438,11 @@ fn cmdDumpLlvmInts( |
| 6676 | 6438 | ||
| 6677 | /// This is only enabled for debug builds. | 6439 | /// This is only enabled for debug builds. |
| 6678 | fn cmdDumpZir( | 6440 | fn cmdDumpZir( |
| 6679 | gpa: Allocator, | ||
| 6680 | arena: Allocator, | 6441 | arena: Allocator, |
| 6681 | args: []const []const u8, | 6442 | args: []const []const u8, |
| 6682 | ) !void { | 6443 | ) !void { |
| 6683 | dev.check(.dump_zir_command); | 6444 | dev.check(.dump_zir_command); |
| 6684 | 6445 | ||
| 6685 | _ = arena; | ||
| 6686 | const Zir = std.zig.Zir; | 6446 | const Zir = std.zig.Zir; |
| 6687 | 6447 | ||
| 6688 | const cache_file = args[0]; | 6448 | const cache_file = args[0]; |
| ... | @@ -6692,26 +6452,16 @@ fn cmdDumpZir( | ... | @@ -6692,26 +6452,16 @@ fn cmdDumpZir( |
| 6692 | }; | 6452 | }; |
| 6693 | defer f.close(); | 6453 | defer f.close(); |
| 6694 | 6454 | ||
| 6695 | var file: Zcu.File = .{ | 6455 | const zir = try Zcu.loadZirCache(arena, f); |
| 6696 | .status = .never_loaded, | ||
| 6697 | .sub_file_path = undefined, | ||
| 6698 | .stat = undefined, | ||
| 6699 | .source = null, | ||
| 6700 | .tree = null, | ||
| 6701 | .zir = try Zcu.loadZirCache(gpa, f), | ||
| 6702 | .zoir = null, | ||
| 6703 | .mod = undefined, | ||
| 6704 | }; | ||
| 6705 | defer file.zir.?.deinit(gpa); | ||
| 6706 | 6456 | ||
| 6707 | { | 6457 | { |
| 6708 | const instruction_bytes = file.zir.?.instructions.len * | 6458 | const instruction_bytes = zir.instructions.len * |
| 6709 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include | 6459 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| 6710 | // the debug safety tag but we want to measure release size. | 6460 | // the debug safety tag but we want to measure release size. |
| 6711 | (@sizeOf(Zir.Inst.Tag) + 8); | 6461 | (@sizeOf(Zir.Inst.Tag) + 8); |
| 6712 | const extra_bytes = file.zir.?.extra.len * @sizeOf(u32); | 6462 | const extra_bytes = zir.extra.len * @sizeOf(u32); |
| 6713 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + | 6463 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + |
| 6714 | file.zir.?.string_bytes.len * @sizeOf(u8); | 6464 | zir.string_bytes.len * @sizeOf(u8); |
| 6715 | const stdout = io.getStdOut(); | 6465 | const stdout = io.getStdOut(); |
| 6716 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; | 6466 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; |
| 6717 | // zig fmt: off | 6467 | // zig fmt: off |
| ... | @@ -6723,19 +6473,18 @@ fn cmdDumpZir( | ... | @@ -6723,19 +6473,18 @@ fn cmdDumpZir( |
| 6723 | \\ | 6473 | \\ |
| 6724 | , .{ | 6474 | , .{ |
| 6725 | fmtIntSizeBin(total_bytes), | 6475 | fmtIntSizeBin(total_bytes), |
| 6726 | file.zir.?.instructions.len, fmtIntSizeBin(instruction_bytes), | 6476 | zir.instructions.len, fmtIntSizeBin(instruction_bytes), |
| 6727 | fmtIntSizeBin(file.zir.?.string_bytes.len), | 6477 | fmtIntSizeBin(zir.string_bytes.len), |
| 6728 | file.zir.?.extra.len, fmtIntSizeBin(extra_bytes), | 6478 | zir.extra.len, fmtIntSizeBin(extra_bytes), |
| 6729 | }); | 6479 | }); |
| 6730 | // zig fmt: on | 6480 | // zig fmt: on |
| 6731 | } | 6481 | } |
| 6732 | 6482 | ||
| 6733 | return @import("print_zir.zig").renderAsTextToFile(gpa, &file, io.getStdOut()); | 6483 | return @import("print_zir.zig").renderAsTextToFile(arena, null, zir, io.getStdOut()); |
| 6734 | } | 6484 | } |
| 6735 | 6485 | ||
| 6736 | /// This is only enabled for debug builds. | 6486 | /// This is only enabled for debug builds. |
| 6737 | fn cmdChangelist( | 6487 | fn cmdChangelist( |
| 6738 | gpa: Allocator, | ||
| 6739 | arena: Allocator, | 6488 | arena: Allocator, |
| 6740 | args: []const []const u8, | 6489 | args: []const []const u8, |
| 6741 | ) !void { | 6490 | ) !void { |
| ... | @@ -6744,101 +6493,50 @@ fn cmdChangelist( | ... | @@ -6744,101 +6493,50 @@ fn cmdChangelist( |
| 6744 | const color: Color = .auto; | 6493 | const color: Color = .auto; |
| 6745 | const Zir = std.zig.Zir; | 6494 | const Zir = std.zig.Zir; |
| 6746 | 6495 | ||
| 6747 | const old_source_file = args[0]; | 6496 | const old_source_path = args[0]; |
| 6748 | const new_source_file = args[1]; | 6497 | const new_source_path = args[1]; |
| 6749 | 6498 | ||
| 6750 | var f = fs.cwd().openFile(old_source_file, .{}) catch |err| { | 6499 | const old_source = source: { |
| 6751 | fatal("unable to open old source file for comparison '{s}': {s}", .{ old_source_file, @errorName(err) }); | 6500 | var f = fs.cwd().openFile(old_source_path, .{}) catch |err| |
| 6501 | fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); | ||
| 6502 | defer f.close(); | ||
| 6503 | break :source std.zig.readSourceFileToEndAlloc(arena, f, std.zig.max_src_size) catch |err| | ||
| 6504 | fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); | ||
| 6752 | }; | 6505 | }; |
| 6753 | defer f.close(); | 6506 | const new_source = source: { |
| 6754 | 6507 | var f = fs.cwd().openFile(new_source_path, .{}) catch |err| | |
| 6755 | const stat = try f.stat(); | 6508 | fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6756 | 6509 | defer f.close(); | |
| 6757 | if (stat.size > std.zig.max_src_size) | 6510 | break :source std.zig.readSourceFileToEndAlloc(arena, f, std.zig.max_src_size) catch |err| |
| 6758 | return error.FileTooBig; | 6511 | fatal("unable to read new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6759 | |||
| 6760 | var file: Zcu.File = .{ | ||
| 6761 | .status = .never_loaded, | ||
| 6762 | .sub_file_path = old_source_file, | ||
| 6763 | .stat = .{ | ||
| 6764 | .size = stat.size, | ||
| 6765 | .inode = stat.inode, | ||
| 6766 | .mtime = stat.mtime, | ||
| 6767 | }, | ||
| 6768 | .source = null, | ||
| 6769 | .tree = null, | ||
| 6770 | .zir = null, | ||
| 6771 | .zoir = null, | ||
| 6772 | .mod = undefined, | ||
| 6773 | }; | 6512 | }; |
| 6774 | 6513 | ||
| 6775 | file.mod = try Package.Module.createLimited(arena, .{ | 6514 | const old_tree = try Ast.parse(arena, old_source, .zig); |
| 6776 | .root = Path.cwd(), | 6515 | const old_zir = try AstGen.generate(arena, old_tree); |
| 6777 | .root_src_path = file.sub_file_path, | ||
| 6778 | .fully_qualified_name = "root", | ||
| 6779 | }); | ||
| 6780 | |||
| 6781 | const source = try arena.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0); | ||
| 6782 | const amt = try f.readAll(source); | ||
| 6783 | if (amt != stat.size) | ||
| 6784 | return error.UnexpectedEndOfFile; | ||
| 6785 | file.source = source; | ||
| 6786 | |||
| 6787 | file.tree = try Ast.parse(gpa, file.source.?, .zig); | ||
| 6788 | defer file.tree.?.deinit(gpa); | ||
| 6789 | |||
| 6790 | file.zir = try AstGen.generate(gpa, file.tree.?); | ||
| 6791 | defer file.zir.?.deinit(gpa); | ||
| 6792 | 6516 | ||
| 6793 | if (file.zir.?.loweringFailed()) { | 6517 | if (old_zir.loweringFailed()) { |
| 6794 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6518 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6795 | try wip_errors.init(gpa); | 6519 | try wip_errors.init(arena); |
| 6796 | defer wip_errors.deinit(); | 6520 | try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path); |
| 6797 | try Compilation.addZirErrorMessages(&wip_errors, &file); | ||
| 6798 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6521 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6799 | defer error_bundle.deinit(gpa); | ||
| 6800 | error_bundle.renderToStdErr(color.renderOptions()); | 6522 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6801 | process.exit(1); | 6523 | process.exit(1); |
| 6802 | } | 6524 | } |
| 6803 | 6525 | ||
| 6804 | var new_f = fs.cwd().openFile(new_source_file, .{}) catch |err| { | 6526 | const new_tree = try Ast.parse(arena, new_source, .zig); |
| 6805 | fatal("unable to open new source file for comparison '{s}': {s}", .{ new_source_file, @errorName(err) }); | 6527 | const new_zir = try AstGen.generate(arena, new_tree); |
| 6806 | }; | ||
| 6807 | defer new_f.close(); | ||
| 6808 | |||
| 6809 | const new_stat = try new_f.stat(); | ||
| 6810 | |||
| 6811 | if (new_stat.size > std.zig.max_src_size) | ||
| 6812 | return error.FileTooBig; | ||
| 6813 | |||
| 6814 | const new_source = try arena.allocSentinel(u8, @as(usize, @intCast(new_stat.size)), 0); | ||
| 6815 | const new_amt = try new_f.readAll(new_source); | ||
| 6816 | if (new_amt != new_stat.size) | ||
| 6817 | return error.UnexpectedEndOfFile; | ||
| 6818 | 6528 | ||
| 6819 | var new_tree = try Ast.parse(gpa, new_source, .zig); | 6529 | if (new_zir.loweringFailed()) { |
| 6820 | defer new_tree.deinit(gpa); | ||
| 6821 | |||
| 6822 | var old_zir = file.zir.?; | ||
| 6823 | defer old_zir.deinit(gpa); | ||
| 6824 | file.zir = null; | ||
| 6825 | file.zir = try AstGen.generate(gpa, new_tree); | ||
| 6826 | |||
| 6827 | if (file.zir.?.loweringFailed()) { | ||
| 6828 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6530 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6829 | try wip_errors.init(gpa); | 6531 | try wip_errors.init(arena); |
| 6830 | defer wip_errors.deinit(); | 6532 | try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path); |
| 6831 | try Compilation.addZirErrorMessages(&wip_errors, &file); | ||
| 6832 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6533 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6833 | defer error_bundle.deinit(gpa); | ||
| 6834 | error_bundle.renderToStdErr(color.renderOptions()); | 6534 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6835 | process.exit(1); | 6535 | process.exit(1); |
| 6836 | } | 6536 | } |
| 6837 | 6537 | ||
| 6838 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; | 6538 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; |
| 6839 | defer inst_map.deinit(gpa); | 6539 | try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); |
| 6840 | |||
| 6841 | try Zcu.mapOldZirToNew(gpa, old_zir, file.zir.?, &inst_map); | ||
| 6842 | 6540 | ||
| 6843 | var bw = io.bufferedWriter(io.getStdOut().writer()); | 6541 | var bw = io.bufferedWriter(io.getStdOut().writer()); |
| 6844 | const stdout = bw.writer(); | 6542 | const stdout = bw.writer(); |
| ... | @@ -7315,7 +7013,7 @@ fn cmdFetch( | ... | @@ -7315,7 +7013,7 @@ fn cmdFetch( |
| 7315 | }, | 7013 | }, |
| 7316 | }; | 7014 | }; |
| 7317 | 7015 | ||
| 7318 | const cwd_path = try process.getCwdAlloc(arena); | 7016 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 7319 | 7017 | ||
| 7320 | var build_root = try findBuildRoot(arena, .{ | 7018 | var build_root = try findBuildRoot(arena, .{ |
| 7321 | .cwd_path = cwd_path, | 7019 | .cwd_path = cwd_path, |
| ... | @@ -7447,9 +7145,7 @@ fn cmdFetch( | ... | @@ -7447,9 +7145,7 @@ fn cmdFetch( |
| 7447 | fn createEmptyDependenciesModule( | 7145 | fn createEmptyDependenciesModule( |
| 7448 | arena: Allocator, | 7146 | arena: Allocator, |
| 7449 | main_mod: *Package.Module, | 7147 | main_mod: *Package.Module, |
| 7450 | global_cache_directory: Cache.Directory, | 7148 | dirs: Compilation.Directories, |
| 7451 | local_cache_directory: Cache.Directory, | ||
| 7452 | builtin_mod: *Package.Module, | ||
| 7453 | global_options: Compilation.Config, | 7149 | global_options: Compilation.Config, |
| 7454 | ) !void { | 7150 | ) !void { |
| 7455 | var source = std.ArrayList(u8).init(arena); | 7151 | var source = std.ArrayList(u8).init(arena); |
| ... | @@ -7458,9 +7154,7 @@ fn createEmptyDependenciesModule( | ... | @@ -7458,9 +7154,7 @@ fn createEmptyDependenciesModule( |
| 7458 | arena, | 7154 | arena, |
| 7459 | source.items, | 7155 | source.items, |
| 7460 | main_mod, | 7156 | main_mod, |
| 7461 | global_cache_directory, | 7157 | dirs, |
| 7462 | local_cache_directory, | ||
| 7463 | builtin_mod, | ||
| 7464 | global_options, | 7158 | global_options, |
| 7465 | ); | 7159 | ); |
| 7466 | } | 7160 | } |
| ... | @@ -7471,9 +7165,7 @@ fn createDependenciesModule( | ... | @@ -7471,9 +7165,7 @@ fn createDependenciesModule( |
| 7471 | arena: Allocator, | 7165 | arena: Allocator, |
| 7472 | source: []const u8, | 7166 | source: []const u8, |
| 7473 | main_mod: *Package.Module, | 7167 | main_mod: *Package.Module, |
| 7474 | global_cache_directory: Cache.Directory, | 7168 | dirs: Compilation.Directories, |
| 7475 | local_cache_directory: Cache.Directory, | ||
| 7476 | builtin_mod: *Package.Module, | ||
| 7477 | global_options: Compilation.Config, | 7169 | global_options: Compilation.Config, |
| 7478 | ) !*Package.Module { | 7170 | ) !*Package.Module { |
| 7479 | // Atomically create the file in a directory named after the hash of its contents. | 7171 | // Atomically create the file in a directory named after the hash of its contents. |
| ... | @@ -7481,7 +7173,7 @@ fn createDependenciesModule( | ... | @@ -7481,7 +7173,7 @@ fn createDependenciesModule( |
| 7481 | const rand_int = std.crypto.random.int(u64); | 7173 | const rand_int = std.crypto.random.int(u64); |
| 7482 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); | 7174 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); |
| 7483 | { | 7175 | { |
| 7484 | var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 7176 | var tmp_dir = try dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 7485 | defer tmp_dir.close(); | 7177 | defer tmp_dir.close(); |
| 7486 | try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); | 7178 | try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); |
| 7487 | } | 7179 | } |
| ... | @@ -7493,18 +7185,14 @@ fn createDependenciesModule( | ... | @@ -7493,18 +7185,14 @@ fn createDependenciesModule( |
| 7493 | 7185 | ||
| 7494 | const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); | 7186 | const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); |
| 7495 | try Package.Fetch.renameTmpIntoCache( | 7187 | try Package.Fetch.renameTmpIntoCache( |
| 7496 | local_cache_directory.handle, | 7188 | dirs.local_cache.handle, |
| 7497 | tmp_dir_sub_path, | 7189 | tmp_dir_sub_path, |
| 7498 | o_dir_sub_path, | 7190 | o_dir_sub_path, |
| 7499 | ); | 7191 | ); |
| 7500 | 7192 | ||
| 7501 | const deps_mod = try Package.Module.create(arena, .{ | 7193 | const deps_mod = try Package.Module.create(arena, .{ |
| 7502 | .global_cache_directory = global_cache_directory, | ||
| 7503 | .paths = .{ | 7194 | .paths = .{ |
| 7504 | .root = .{ | 7195 | .root = try .fromRoot(arena, dirs, .local_cache, o_dir_sub_path), |
| 7505 | .root_dir = local_cache_directory, | ||
| 7506 | .sub_path = o_dir_sub_path, | ||
| 7507 | }, | ||
| 7508 | .root_src_path = basename, | 7196 | .root_src_path = basename, |
| 7509 | }, | 7197 | }, |
| 7510 | .fully_qualified_name = "root.@dependencies", | 7198 | .fully_qualified_name = "root.@dependencies", |
| ... | @@ -7512,8 +7200,6 @@ fn createDependenciesModule( | ... | @@ -7512,8 +7200,6 @@ fn createDependenciesModule( |
| 7512 | .cc_argv = &.{}, | 7200 | .cc_argv = &.{}, |
| 7513 | .inherited = .{}, | 7201 | .inherited = .{}, |
| 7514 | .global = global_options, | 7202 | .global = global_options, |
| 7515 | .builtin_mod = builtin_mod, | ||
| 7516 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 7517 | }); | 7203 | }); |
| 7518 | try main_mod.deps.put(arena, "@dependencies", deps_mod); | 7204 | try main_mod.deps.put(arena, "@dependencies", deps_mod); |
| 7519 | return deps_mod; | 7205 | return deps_mod; |
| ... | @@ -7536,7 +7222,7 @@ const FindBuildRootOptions = struct { | ... | @@ -7536,7 +7222,7 @@ const FindBuildRootOptions = struct { |
| 7536 | }; | 7222 | }; |
| 7537 | 7223 | ||
| 7538 | fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { | 7224 | fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { |
| 7539 | const cwd_path = options.cwd_path orelse try process.getCwdAlloc(arena); | 7225 | const cwd_path = options.cwd_path orelse try introspect.getResolvedCwd(arena); |
| 7540 | const build_zig_basename = if (options.build_file) |bf| | 7226 | const build_zig_basename = if (options.build_file) |bf| |
| 7541 | fs.path.basename(bf) | 7227 | fs.path.basename(bf) |
| 7542 | else | 7228 | else |
| ... | @@ -7723,10 +7409,13 @@ const Templates = struct { | ... | @@ -7723,10 +7409,13 @@ const Templates = struct { |
| 7723 | }; | 7409 | }; |
| 7724 | 7410 | ||
| 7725 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { | 7411 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { |
| 7726 | const self_exe_path = introspect.findZigExePath(arena) catch |err| { | 7412 | const cwd_path = introspect.getResolvedCwd(arena) catch |err| { |
| 7413 | fatal("unable to get cwd: {s}", .{@errorName(err)}); | ||
| 7414 | }; | ||
| 7415 | const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { | ||
| 7727 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); | 7416 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); |
| 7728 | }; | 7417 | }; |
| 7729 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | 7418 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, cwd_path, self_exe_path) catch |err| { |
| 7730 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | 7419 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); |
| 7731 | }; | 7420 | }; |
| 7732 | 7421 | ||
| ... | @@ -7783,8 +7472,8 @@ fn handleModArg( | ... | @@ -7783,8 +7472,8 @@ fn handleModArg( |
| 7783 | const gop = try create_module.modules.getOrPut(arena, mod_name); | 7472 | const gop = try create_module.modules.getOrPut(arena, mod_name); |
| 7784 | 7473 | ||
| 7785 | if (gop.found_existing) { | 7474 | if (gop.found_existing) { |
| 7786 | fatal("unable to add module '{s}': already exists as '{s}'", .{ | 7475 | fatal("unable to add module '{s}': already exists as '{s}{c}{s}'", .{ |
| 7787 | mod_name, gop.value_ptr.paths.root_src_path, | 7476 | mod_name, gop.value_ptr.root_path, fs.path.sep, gop.value_ptr.root_src_path, |
| 7788 | }); | 7477 | }); |
| 7789 | } | 7478 | } |
| 7790 | 7479 | ||
| ... | @@ -7811,24 +7500,14 @@ fn handleModArg( | ... | @@ -7811,24 +7500,14 @@ fn handleModArg( |
| 7811 | if (mod_opts.error_tracing == true) | 7500 | if (mod_opts.error_tracing == true) |
| 7812 | create_module.opts.any_error_tracing = true; | 7501 | create_module.opts.any_error_tracing = true; |
| 7813 | 7502 | ||
| 7503 | const root_path: []const u8, const root_src_path: []const u8 = if (opt_root_src_orig) |path| root: { | ||
| 7504 | create_module.opts.have_zcu = true; | ||
| 7505 | break :root .{ fs.path.dirname(path) orelse ".", fs.path.basename(path) }; | ||
| 7506 | } else .{ ".", "" }; | ||
| 7507 | |||
| 7814 | gop.value_ptr.* = .{ | 7508 | gop.value_ptr.* = .{ |
| 7815 | .paths = p: { | 7509 | .root_path = root_path, |
| 7816 | if (opt_root_src_orig) |root_src_orig| { | 7510 | .root_src_path = root_src_path, |
| 7817 | create_module.opts.have_zcu = true; | ||
| 7818 | const root_src = try introspect.resolvePath(arena, root_src_orig); | ||
| 7819 | break :p .{ | ||
| 7820 | .root = .{ | ||
| 7821 | .root_dir = Cache.Directory.cwd(), | ||
| 7822 | .sub_path = fs.path.dirname(root_src) orelse "", | ||
| 7823 | }, | ||
| 7824 | .root_src_path = fs.path.basename(root_src), | ||
| 7825 | }; | ||
| 7826 | } | ||
| 7827 | break :p .{ | ||
| 7828 | .root = .{ .root_dir = Cache.Directory.cwd() }, | ||
| 7829 | .root_src_path = "", | ||
| 7830 | }; | ||
| 7831 | }, | ||
| 7832 | .cc_argv = try cc_argv.toOwnedSlice(arena), | 7511 | .cc_argv = try cc_argv.toOwnedSlice(arena), |
| 7833 | .inherited = mod_opts.*, | 7512 | .inherited = mod_opts.*, |
| 7834 | .target_arch_os_abi = target_arch_os_abi.*, | 7513 | .target_arch_os_abi = target_arch_os_abi.*, |
src/print_env.zig+4-3| ... | @@ -2,13 +2,14 @@ const std = @import("std"); | ... | @@ -2,13 +2,14 @@ const std = @import("std"); |
| 2 | const build_options = @import("build_options"); | 2 | const build_options = @import("build_options"); |
| 3 | const introspect = @import("introspect.zig"); | 3 | const introspect = @import("introspect.zig"); |
| 4 | const Allocator = std.mem.Allocator; | 4 | const Allocator = std.mem.Allocator; |
| 5 | const fatal = @import("main.zig").fatal; | 5 | const fatal = std.process.fatal; |
| 6 | 6 | ||
| 7 | pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void { | 7 | pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void { |
| 8 | _ = args; | 8 | _ = args; |
| 9 | const self_exe_path = try introspect.findZigExePath(arena); | 9 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 10 | const self_exe_path = try std.fs.selfExePathAlloc(arena); | ||
| 10 | 11 | ||
| 11 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | 12 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, cwd_path, self_exe_path) catch |err| { |
| 12 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); | 13 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); |
| 13 | }; | 14 | }; |
| 14 | defer zig_lib_directory.handle.close(); | 15 | defer zig_lib_directory.handle.close(); |
src/print_targets.zig+1-1| ... | @@ -3,13 +3,13 @@ const fs = std.fs; | ... | @@ -3,13 +3,13 @@ const fs = std.fs; |
| 3 | const io = std.io; | 3 | const io = std.io; |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| 5 | const meta = std.meta; | 5 | const meta = std.meta; |
| 6 | const fatal = std.process.fatal; | ||
| 6 | const Allocator = std.mem.Allocator; | 7 | const Allocator = std.mem.Allocator; |
| 7 | const Target = std.Target; | 8 | const Target = std.Target; |
| 8 | const target = @import("target.zig"); | 9 | const target = @import("target.zig"); |
| 9 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 10 | const glibc = @import("libs/glibc.zig"); | 11 | const glibc = @import("libs/glibc.zig"); |
| 11 | const introspect = @import("introspect.zig"); | 12 | const introspect = @import("introspect.zig"); |
| 12 | const fatal = @import("main.zig").fatal; | ||
| 13 | 13 | ||
| 14 | pub fn cmdTargets( | 14 | pub fn cmdTargets( |
| 15 | allocator: Allocator, | 15 | allocator: Allocator, |
src/print_zir.zig+14-13| ... | @@ -12,7 +12,8 @@ const LazySrcLoc = Zcu.LazySrcLoc; | ... | @@ -12,7 +12,8 @@ const LazySrcLoc = Zcu.LazySrcLoc; |
| 12 | /// Write human-readable, debug formatted ZIR code to a file. | 12 | /// Write human-readable, debug formatted ZIR code to a file. |
| 13 | pub fn renderAsTextToFile( | 13 | pub fn renderAsTextToFile( |
| 14 | gpa: Allocator, | 14 | gpa: Allocator, |
| 15 | scope_file: *Zcu.File, | 15 | tree: ?Ast, |
| 16 | zir: Zir, | ||
| 16 | fs_file: std.fs.File, | 17 | fs_file: std.fs.File, |
| 17 | ) !void { | 18 | ) !void { |
| 18 | var arena = std.heap.ArenaAllocator.init(gpa); | 19 | var arena = std.heap.ArenaAllocator.init(gpa); |
| ... | @@ -21,8 +22,8 @@ pub fn renderAsTextToFile( | ... | @@ -21,8 +22,8 @@ pub fn renderAsTextToFile( |
| 21 | var writer: Writer = .{ | 22 | var writer: Writer = .{ |
| 22 | .gpa = gpa, | 23 | .gpa = gpa, |
| 23 | .arena = arena.allocator(), | 24 | .arena = arena.allocator(), |
| 24 | .file = scope_file, | 25 | .tree = tree, |
| 25 | .code = scope_file.zir.?, | 26 | .code = zir, |
| 26 | .indent = 0, | 27 | .indent = 0, |
| 27 | .parent_decl_node = .root, | 28 | .parent_decl_node = .root, |
| 28 | .recurse_decls = true, | 29 | .recurse_decls = true, |
| ... | @@ -36,18 +37,18 @@ pub fn renderAsTextToFile( | ... | @@ -36,18 +37,18 @@ pub fn renderAsTextToFile( |
| 36 | try stream.print("%{d} ", .{@intFromEnum(main_struct_inst)}); | 37 | try stream.print("%{d} ", .{@intFromEnum(main_struct_inst)}); |
| 37 | try writer.writeInstToStream(stream, main_struct_inst); | 38 | try writer.writeInstToStream(stream, main_struct_inst); |
| 38 | try stream.writeAll("\n"); | 39 | try stream.writeAll("\n"); |
| 39 | const imports_index = scope_file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | 40 | const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)]; |
| 40 | if (imports_index != 0) { | 41 | if (imports_index != 0) { |
| 41 | try stream.writeAll("Imports:\n"); | 42 | try stream.writeAll("Imports:\n"); |
| 42 | 43 | ||
| 43 | const extra = scope_file.zir.?.extraData(Zir.Inst.Imports, imports_index); | 44 | const extra = zir.extraData(Zir.Inst.Imports, imports_index); |
| 44 | var extra_index = extra.end; | 45 | var extra_index = extra.end; |
| 45 | 46 | ||
| 46 | for (0..extra.data.imports_len) |_| { | 47 | for (0..extra.data.imports_len) |_| { |
| 47 | const item = scope_file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index); | 48 | const item = zir.extraData(Zir.Inst.Imports.Item, extra_index); |
| 48 | extra_index = item.end; | 49 | extra_index = item.end; |
| 49 | 50 | ||
| 50 | const import_path = scope_file.zir.?.nullTerminatedString(item.data.name); | 51 | const import_path = zir.nullTerminatedString(item.data.name); |
| 51 | try stream.print(" @import(\"{}\") ", .{ | 52 | try stream.print(" @import(\"{}\") ", .{ |
| 52 | std.zig.fmtEscapes(import_path), | 53 | std.zig.fmtEscapes(import_path), |
| 53 | }); | 54 | }); |
| ... | @@ -74,7 +75,7 @@ pub fn renderInstructionContext( | ... | @@ -74,7 +75,7 @@ pub fn renderInstructionContext( |
| 74 | var writer: Writer = .{ | 75 | var writer: Writer = .{ |
| 75 | .gpa = gpa, | 76 | .gpa = gpa, |
| 76 | .arena = arena.allocator(), | 77 | .arena = arena.allocator(), |
| 77 | .file = scope_file, | 78 | .tree = scope_file.tree, |
| 78 | .code = scope_file.zir.?, | 79 | .code = scope_file.zir.?, |
| 79 | .indent = if (indent < 2) 2 else indent, | 80 | .indent = if (indent < 2) 2 else indent, |
| 80 | .parent_decl_node = parent_decl_node, | 81 | .parent_decl_node = parent_decl_node, |
| ... | @@ -106,7 +107,7 @@ pub fn renderSingleInstruction( | ... | @@ -106,7 +107,7 @@ pub fn renderSingleInstruction( |
| 106 | var writer: Writer = .{ | 107 | var writer: Writer = .{ |
| 107 | .gpa = gpa, | 108 | .gpa = gpa, |
| 108 | .arena = arena.allocator(), | 109 | .arena = arena.allocator(), |
| 109 | .file = scope_file, | 110 | .tree = scope_file.tree, |
| 110 | .code = scope_file.zir.?, | 111 | .code = scope_file.zir.?, |
| 111 | .indent = indent, | 112 | .indent = indent, |
| 112 | .parent_decl_node = parent_decl_node, | 113 | .parent_decl_node = parent_decl_node, |
| ... | @@ -121,7 +122,7 @@ pub fn renderSingleInstruction( | ... | @@ -121,7 +122,7 @@ pub fn renderSingleInstruction( |
| 121 | const Writer = struct { | 122 | const Writer = struct { |
| 122 | gpa: Allocator, | 123 | gpa: Allocator, |
| 123 | arena: Allocator, | 124 | arena: Allocator, |
| 124 | file: *Zcu.File, | 125 | tree: ?Ast, |
| 125 | code: Zir, | 126 | code: Zir, |
| 126 | indent: u32, | 127 | indent: u32, |
| 127 | parent_decl_node: Ast.Node.Index, | 128 | parent_decl_node: Ast.Node.Index, |
| ... | @@ -2761,7 +2762,7 @@ const Writer = struct { | ... | @@ -2761,7 +2762,7 @@ const Writer = struct { |
| 2761 | } | 2762 | } |
| 2762 | 2763 | ||
| 2763 | fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void { | 2764 | fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void { |
| 2764 | const tree = self.file.tree orelse return; | 2765 | const tree = self.tree orelse return; |
| 2765 | const abs_node = src_node.toAbsolute(self.parent_decl_node); | 2766 | const abs_node = src_node.toAbsolute(self.parent_decl_node); |
| 2766 | const src_span = tree.nodeToSpan(abs_node); | 2767 | const src_span = tree.nodeToSpan(abs_node); |
| 2767 | const start = self.line_col_cursor.find(tree.source, src_span.start); | 2768 | const start = self.line_col_cursor.find(tree.source, src_span.start); |
| ... | @@ -2773,7 +2774,7 @@ const Writer = struct { | ... | @@ -2773,7 +2774,7 @@ const Writer = struct { |
| 2773 | } | 2774 | } |
| 2774 | 2775 | ||
| 2775 | fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void { | 2776 | fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void { |
| 2776 | const tree = self.file.tree orelse return; | 2777 | const tree = self.tree orelse return; |
| 2777 | const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node)); | 2778 | const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node)); |
| 2778 | const span_start = tree.tokenStart(abs_tok); | 2779 | const span_start = tree.tokenStart(abs_tok); |
| 2779 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len)); | 2780 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len)); |
| ... | @@ -2786,7 +2787,7 @@ const Writer = struct { | ... | @@ -2786,7 +2787,7 @@ const Writer = struct { |
| 2786 | } | 2787 | } |
| 2787 | 2788 | ||
| 2788 | fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void { | 2789 | fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void { |
| 2789 | const tree = self.file.tree orelse return; | 2790 | const tree = self.tree orelse return; |
| 2790 | const span_start = tree.tokenStart(src_tok); | 2791 | const span_start = tree.tokenStart(src_tok); |
| 2791 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); | 2792 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); |
| 2792 | const start = self.line_col_cursor.find(tree.source, span_start); | 2793 | const start = self.line_col_cursor.find(tree.source, span_start); |
test/cases/compile_errors/bad_import.zig+2-3| ... | @@ -3,7 +3,6 @@ const bogus = @import( | ... | @@ -3,7 +3,6 @@ const bogus = @import( |
| 3 | ); | 3 | ); |
| 4 | 4 | ||
| 5 | // error | 5 | // error |
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | 6 | // |
| 9 | // bogus-does-not-exist.zig': FileNotFound | 7 | // bogus-does-not-exist.zig:1:1: error: unable to load 'bogus-does-not-exist.zig': FileNotFound |
| 8 | // :2:5: note: file imported here |
test/cases/compile_errors/import_of_missing_module.zig created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | const foo = @import("foo"); | ||
| 2 | comptime { | ||
| 3 | _ = foo; | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // | ||
| 8 | // :1:21: error: no module named 'foo' available within module 'root' | ||
test/cases/compile_errors/import_of_missing_package.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const foo = @import("foo"); | ||
| 2 | comptime { | ||
| 3 | _ = foo; | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage2 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // :1:21: error: no module named 'foo' available within module root | ||
test/cases/compile_errors/import_outside_module_path.zig created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | comptime { | ||
| 2 | _ = @import("../a.zig"); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // | ||
| 7 | // :2:17: error: import of file outside module path | ||
test/cases/compile_errors/import_outside_package.zig deleted-8| ... | @@ -1,8 +0,0 @@ | ||
| 1 | export fn a() usize { | ||
| 2 | return @import("../../above.zig").len; | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // target=native | ||
| 7 | // | ||
| 8 | // :2:20: error: import of file outside module path: '../../above.zig' | ||
test/cases/compile_errors/import_outside_package_path.zig deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | comptime { | ||
| 2 | _ = @import("../a.zig"); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // :2:17: error: import of file outside module path: '../a.zig' | ||
test/compile_errors.zig+4-3| ... | @@ -126,9 +126,10 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { | ... | @@ -126,9 +126,10 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { |
| 126 | \\ _ = @import("foo.zig"); | 126 | \\ _ = @import("foo.zig"); |
| 127 | \\} | 127 | \\} |
| 128 | , &[_][]const u8{ | 128 | , &[_][]const u8{ |
| 129 | ":1:1: error: file exists in multiple modules", | 129 | ":1:1: error: file exists in modules 'foo' and 'root'", |
| 130 | ":1:1: note: root of module foo", | 130 | ":1:1: note: files must belong to only one module", |
| 131 | ":3:17: note: imported from module root", | 131 | ":1:1: note: file is the root of module 'foo'", |
| 132 | ":3:17: note: file is imported here by the root of module 'root'", | ||
| 132 | }); | 133 | }); |
| 133 | case.addSourceFile("foo.zig", | 134 | case.addSourceFile("foo.zig", |
| 134 | \\const dummy = 0; | 135 | \\const dummy = 0; |
test/incremental/bad_import created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | #target=x86_64-linux-selfhosted | ||
| 2 | #target=x86_64-linux-cbe | ||
| 3 | #target=x86_64-windows-cbe | ||
| 4 | #target=wasm32-wasi-selfhosted | ||
| 5 | |||
| 6 | #update=initial version | ||
| 7 | #file=main.zig | ||
| 8 | pub fn main() !void { | ||
| 9 | _ = @import("foo.zig"); | ||
| 10 | try std.io.getStdOut().writeAll("success\n"); | ||
| 11 | } | ||
| 12 | const std = @import("std"); | ||
| 13 | #file=foo.zig | ||
| 14 | comptime { | ||
| 15 | _ = @import("bad.zig"); | ||
| 16 | } | ||
| 17 | #expect_error=bad.zig:1:1: error: unable to load 'bad.zig': FileNotFound | ||
| 18 | #expect_error=foo.zig:2:17: note: file imported here | ||
| 19 | |||
| 20 | #update=change bad import | ||
| 21 | #file=foo.zig | ||
| 22 | comptime { | ||
| 23 | _ = @import("this_is/not_real.zig"); | ||
| 24 | } | ||
| 25 | #expect_error=this_is/not_real.zig:1:1: error: unable to load 'not_real.zig': FileNotFound | ||
| 26 | #expect_error=foo.zig:2:17: note: file imported here | ||
| 27 | |||
| 28 | #update=remove import of 'foo.zig' | ||
| 29 | #file=main.zig | ||
| 30 | pub fn main() !void { | ||
| 31 | //_ = @import("foo.zig"); | ||
| 32 | try std.io.getStdOut().writeAll("success\n"); | ||
| 33 | } | ||
| 34 | const std = @import("std"); | ||
| 35 | #expect_stdout="success\n" | ||
test/incremental/change_module created+65| ... | @@ -0,0 +1,65 @@ | ||
| 1 | #target=x86_64-linux-selfhosted | ||
| 2 | #target=x86_64-linux-cbe | ||
| 3 | #target=x86_64-windows-cbe | ||
| 4 | #target=wasm32-wasi-selfhosted | ||
| 5 | #module=foo=foo.zig | ||
| 6 | |||
| 7 | #update=initial version | ||
| 8 | #file=main.zig | ||
| 9 | pub fn main() void { | ||
| 10 | _ = @import("foo"); | ||
| 11 | //_ = @import("other.zig"); | ||
| 12 | } | ||
| 13 | #file=foo.zig | ||
| 14 | comptime { | ||
| 15 | _ = @import("other.zig"); | ||
| 16 | } | ||
| 17 | #file=other.zig | ||
| 18 | fn f() void { | ||
| 19 | @compileLog(@src().module); | ||
| 20 | } | ||
| 21 | comptime { | ||
| 22 | f(); | ||
| 23 | } | ||
| 24 | #expect_error=other.zig:2:5: error: found compile log statement | ||
| 25 | #expect_compile_log=@as([:0]const u8, "foo"[0..3]) | ||
| 26 | |||
| 27 | #update=change module of other.zig | ||
| 28 | #file=main.zig | ||
| 29 | pub fn main() void { | ||
| 30 | _ = @import("foo"); | ||
| 31 | _ = @import("other.zig"); | ||
| 32 | } | ||
| 33 | #file=foo.zig | ||
| 34 | comptime { | ||
| 35 | //_ = @import("other.zig"); | ||
| 36 | } | ||
| 37 | #expect_error=other.zig:2:5: error: found compile log statement | ||
| 38 | #expect_compile_log=@as([:0]const u8, "root"[0..4]) | ||
| 39 | |||
| 40 | #update=put other.zig in both modules | ||
| 41 | #file=main.zig | ||
| 42 | pub fn main() void { | ||
| 43 | _ = @import("foo"); | ||
| 44 | _ = @import("other.zig"); | ||
| 45 | } | ||
| 46 | #file=foo.zig | ||
| 47 | comptime { | ||
| 48 | _ = @import("other.zig"); | ||
| 49 | } | ||
| 50 | #expect_error=foo.zig:1:1: error: file exists in modules 'root' and 'foo' | ||
| 51 | #expect_error=foo.zig:1:1: note: files must belong to only one module | ||
| 52 | #expect_error=main.zig:3:17: note: file is imported here by the root of module 'root' | ||
| 53 | #expect_error=foo.zig:2:17: note: file is imported here by the root of module 'foo' | ||
| 54 | |||
| 55 | #update=put other.zig in no modules | ||
| 56 | #file=main.zig | ||
| 57 | pub fn main() void { | ||
| 58 | _ = @import("foo"); | ||
| 59 | //_ = @import("other.zig"); | ||
| 60 | } | ||
| 61 | #file=foo.zig | ||
| 62 | comptime { | ||
| 63 | //_ = @import("other.zig"); | ||
| 64 | } | ||
| 65 | #expect_stdout="" | ||
test/incremental/change_zon_file+4-2| ... | @@ -20,7 +20,8 @@ pub fn main() !void { | ... | @@ -20,7 +20,8 @@ pub fn main() !void { |
| 20 | 20 | ||
| 21 | #update=delete file | 21 | #update=delete file |
| 22 | #rm_file=message.zon | 22 | #rm_file=message.zon |
| 23 | #expect_error=message.zon:1:1: error: unable to load './message.zon': FileNotFound | 23 | #expect_error=message.zon:1:1: error: unable to load 'message.zon': FileNotFound |
| 24 | #expect_error=main.zig:2:37: note: file imported here | ||
| 24 | 25 | ||
| 25 | #update=remove reference to ZON file | 26 | #update=remove reference to ZON file |
| 26 | #file=main.zig | 27 | #file=main.zig |
| ... | @@ -29,7 +30,8 @@ const message: []const u8 = @import("message.zon"); | ... | @@ -29,7 +30,8 @@ const message: []const u8 = @import("message.zon"); |
| 29 | pub fn main() !void { | 30 | pub fn main() !void { |
| 30 | try std.io.getStdOut().writeAll("a hardcoded string\n"); | 31 | try std.io.getStdOut().writeAll("a hardcoded string\n"); |
| 31 | } | 32 | } |
| 32 | #expect_error=message.zon:1:1: error: unable to load './message.zon': FileNotFound | 33 | #expect_error=message.zon:1:1: error: unable to load 'message.zon': FileNotFound |
| 34 | #expect_error=main.zig:2:37: note: file imported here | ||
| 33 | 35 | ||
| 34 | #update=recreate ZON file | 36 | #update=recreate ZON file |
| 35 | #file=message.zon | 37 | #file=message.zon |