diff --git a/stage0/sema.zig b/stage0/sema.zig index 44b9119fdf..f85dc39e7b 100644 --- a/stage0/sema.zig +++ b/stage0/sema.zig @@ -8,19 +8,19 @@ const Compilation = zig_internals.Compilation; const Package = zig_internals.Package; /// Result of running the real Zig sema pipeline via Compilation. -/// Owns the Compilation, Directories, thread pool, temp dir, and arena. +/// Owns the Compilation, Directories, thread pool, and arena. pub const ZigSemaResult = struct { comp: *Compilation, dirs: Compilation.Directories, - tmp_dir: std.testing.TmpDir, arena_state: std.heap.ArenaAllocator, - thread_pool: std.Thread.Pool, + thread_pool: *std.Thread.Pool, + gpa: Allocator, pub fn deinit(self: *ZigSemaResult) void { self.comp.destroy(); self.dirs.deinit(); self.thread_pool.deinit(); - self.tmp_dir.cleanup(); + self.gpa.destroy(self.thread_pool); self.arena_state.deinit(); } }; @@ -32,25 +32,18 @@ pub fn zigSema(gpa: Allocator, src_path: []const u8) !ZigSemaResult { errdefer arena_state.deinit(); const arena = arena_state.allocator(); - // Set up temp dir for Compilation cache. - var tmp_dir = std.testing.tmpDir(.{}); - errdefer tmp_dir.cleanup(); - - // Resolve paths. - const cwd_path = try std.fs.cwd().realpathAlloc(arena, "."); - const zig_lib_path = try std.fs.path.join(arena, &.{ cwd_path, "lib" }); - const zig_lib_handle = try std.fs.cwd().openDir("lib", .{}); - const tmp_path = try tmp_dir.dir.realpathAlloc(arena, "."); - const cache_path = try std.fmt.allocPrint(arena, "{s}/.cache", .{tmp_path}); - try tmp_dir.dir.makeDir(".cache"); - const cache_handle = try tmp_dir.dir.openDir(".cache", .{}); - - var dirs = Compilation.Directories{ - .cwd = cwd_path, - .zig_lib = .{ .path = zig_lib_path, .handle = zig_lib_handle }, - .global_cache = .{ .path = cache_path, .handle = cache_handle }, - .local_cache = .{ .path = cache_path, .handle = cache_handle }, - }; + // Use the real Zig cache directories: ~/.cache/zig (global) and .zig-cache (local). + // Point zig_lib at zig-out/lib/zig/ (the installed copy) rather than lib/ (the source + // tree) to avoid "file exists in modules 'root' and 'std'" when compiling source files + // that live under lib/. + var dirs: Compilation.Directories = .init( + arena, + "zig-out/lib/zig", + null, + .search, + {}, + "", + ); errdefer dirs.deinit(); // Hardcode x86_64-linux-musl target. @@ -96,14 +89,21 @@ pub fn zigSema(gpa: Allocator, src_path: []const u8) !ZigSemaResult { .parent = null, }); - var thread_pool: std.Thread.Pool = undefined; + // Heap-allocate the thread pool so its address stays stable after zigSema + // returns. The worker threads hold references to the Pool's internal + // condvar/mutex; a by-value copy would leave them waiting on a stale address. + const thread_pool = try gpa.create(std.Thread.Pool); + thread_pool.* = undefined; try thread_pool.init(.{ .allocator = gpa, .n_jobs = 1, .track_ids = true, .stack_size = 60 << 20, }); - errdefer thread_pool.deinit(); + errdefer { + thread_pool.deinit(); + gpa.destroy(thread_pool); + } var create_diag: Compilation.CreateDiagnostic = undefined; const comp = Compilation.create(gpa, arena, &create_diag, .{ @@ -112,7 +112,7 @@ pub fn zigSema(gpa: Allocator, src_path: []const u8) !ZigSemaResult { .config = config, .root_mod = root_mod, .emit_bin = .no, - .thread_pool = &thread_pool, + .thread_pool = thread_pool, .cache_mode = .whole, }) catch |err| switch (err) { error.CreateFail => { @@ -135,8 +135,8 @@ pub fn zigSema(gpa: Allocator, src_path: []const u8) !ZigSemaResult { return .{ .comp = comp, .dirs = dirs, - .tmp_dir = tmp_dir, .arena_state = arena_state, .thread_pool = thread_pool, + .gpa = gpa, }; }