From aafddc2ea13e40a8262d9378aeca2e097a37ac03 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 5 Dec 2025 19:08:37 -0800 Subject: update all occurrences of close() to close(io) --- src/codegen/llvm.zig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 5dc55b74f6..cb4fe0459f 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -799,6 +799,7 @@ pub const Object = struct { pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ LinkFailure, OutOfMemory }!void { const zcu = pt.zcu; const comp = zcu.comp; + const io = comp.io; const diags = &comp.link_diags; { @@ -979,7 +980,7 @@ pub const Object = struct { if (options.pre_bc_path) |path| { var file = std.fs.cwd().createFile(path, .{}) catch |err| return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); - defer file.close(); + defer file.close(io); const ptr: [*]const u8 = @ptrCast(bitcode.ptr); file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| @@ -992,7 +993,7 @@ pub const Object = struct { if (options.post_bc_path) |path| { var file = std.fs.cwd().createFile(path, .{}) catch |err| return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); - defer file.close(); + defer file.close(io); const ptr: [*]const u8 = @ptrCast(bitcode.ptr); file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| -- cgit v1.2.3 From f53248a40936ebc9aaf75ddbd16e67ebec05ab84 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 13:39:09 -0800 Subject: update all std.fs.cwd() to std.Io.Dir.cwd() --- lib/compiler/aro/aro/Compilation.zig | 8 +- lib/compiler/aro/aro/Driver.zig | 10 +-- lib/compiler/aro/aro/Parser.zig | 27 +++---- lib/compiler/aro/aro/Preprocessor.zig | 6 +- lib/compiler/aro/aro/Tokenizer.zig | 5 +- lib/compiler/aro/aro/Value.zig | 11 +-- lib/compiler/aro/main.zig | 2 +- lib/compiler/objcopy.zig | 4 +- lib/compiler/reduce.zig | 6 +- lib/compiler/resinator/cli.zig | 2 +- lib/compiler/resinator/compile.zig | 4 +- lib/compiler/resinator/main.zig | 22 +++--- lib/compiler/std-docs.zig | 2 +- lib/compiler/translate-c/main.zig | 8 +- lib/std/Build.zig | 10 +-- lib/std/Build/Cache.zig | 8 +- lib/std/Build/Step.zig | 17 ++-- lib/std/Build/Step/CheckFile.zig | 4 +- lib/std/Build/Step/ConfigHeader.zig | 8 +- lib/std/Build/Step/Options.zig | 15 ++-- lib/std/Build/Step/Run.zig | 2 +- lib/std/Build/Watch.zig | 16 ++-- lib/std/Io/File.zig | 8 ++ lib/std/Io/Threaded.zig | 9 +-- lib/std/Io/Writer.zig | 6 +- lib/std/Io/net/test.zig | 2 +- lib/std/Io/test.zig | 10 +-- lib/std/Thread.zig | 4 +- lib/std/crypto/Certificate/Bundle/macos.zig | 2 +- lib/std/crypto/codecs/asn1/test.zig | 4 +- lib/std/debug.zig | 20 ++--- lib/std/debug/ElfFile.zig | 2 +- lib/std/debug/MachOFile.zig | 2 +- lib/std/debug/SelfInfo/Elf.zig | 19 +++-- lib/std/debug/SelfInfo/MachO.zig | 2 +- lib/std/debug/SelfInfo/Windows.zig | 4 +- lib/std/dynamic_library.zig | 8 +- lib/std/fs/test.zig | 116 +++++++++++++--------------- lib/std/os/linux/IoUring.zig | 24 +++--- lib/std/os/linux/test.zig | 6 +- lib/std/os/windows.zig | 4 +- lib/std/posix.zig | 14 ++-- lib/std/posix/test.zig | 52 ++++++------- lib/std/process/Child.zig | 2 +- lib/std/std.zig | 2 +- lib/std/tar.zig | 14 ++-- lib/std/testing.zig | 2 +- lib/std/zig/LibCInstallation.zig | 12 +-- lib/std/zig/WindowsSdk.zig | 2 +- lib/std/zig/system.zig | 6 +- lib/std/zig/system/darwin/macos.zig | 7 +- lib/std/zip.zig | 4 +- src/Compilation.zig | 20 ++--- src/Package/Fetch.zig | 12 +-- src/Package/Fetch/git.zig | 12 +-- src/Zcu/PerThread.zig | 4 +- src/codegen/llvm.zig | 17 ++-- src/fmt.zig | 6 +- src/introspect.zig | 4 +- src/libs/freebsd.zig | 12 +-- src/libs/glibc.zig | 16 ++-- src/libs/mingw.zig | 17 ++-- src/libs/netbsd.zig | 12 +-- src/link/C.zig | 4 +- src/link/Coff.zig | 6 +- src/link/Elf.zig | 4 +- src/link/Lld.zig | 4 +- src/link/MachO.zig | 14 ++-- src/link/MachO/CodeSignature.zig | 2 +- src/link/SpirV.zig | 3 +- src/link/Wasm.zig | 4 +- src/main.zig | 36 ++++----- 72 files changed, 398 insertions(+), 377 deletions(-) (limited to 'src/codegen') diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index 09e4861d13..b3e4d5544d 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -2253,7 +2253,7 @@ test "addSourceFromBuffer" { var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); const source = try comp.addSourceFromBuffer("path", str); @@ -2267,7 +2267,7 @@ test "addSourceFromBuffer" { var arena: std.heap.ArenaAllocator = .init(allocator); defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(allocator, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); _ = try comp.addSourceFromBuffer("path", "spliced\\\nbuffer\n"); @@ -2313,7 +2313,7 @@ test "addSourceFromBuffer - exhaustive check for carriage return elimination" { var buf: [alphabet.len]u8 = @splat(alphabet[0]); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var source_count: u32 = 0; @@ -2341,7 +2341,7 @@ test "ignore BOM at beginning of file" { const Test = struct { fn run(arena: Allocator, buf: []const u8) !void { var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); const source = try comp.addSourceFromBuffer("file.c", buf); diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index f933e3ce52..fec3cea0f8 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -1327,7 +1327,7 @@ fn processSource( const dep_file_name = try d.getDepFileName(source, writer_buf[0..std.fs.max_name_bytes]); const file = if (dep_file_name) |path| - d.comp.cwd.createFile(path, .{}) catch |er| + d.comp.cwd.createFile(io, path, .{}) catch |er| return d.fatal("unable to create dependency file '{s}': {s}", .{ path, errorDescription(er) }) else Io.File.stdout(); @@ -1352,7 +1352,7 @@ fn processSource( } const file = if (d.output_name) |some| - d.comp.cwd.createFile(some, .{}) catch |er| + d.comp.cwd.createFile(io, some, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) else Io.File.stdout(); @@ -1405,7 +1405,7 @@ fn processSource( defer assembly.deinit(gpa); if (d.only_preprocess_and_compile) { - const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(io, out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); defer out_file.close(io); @@ -1419,7 +1419,7 @@ fn processSource( // then assemble to out_file_name var assembly_name_buf: [std.fs.max_name_bytes]u8 = undefined; const assembly_out_file_name = try d.getRandomFilename(&assembly_name_buf, ".s"); - const out_file = d.comp.cwd.createFile(assembly_out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(io, assembly_out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ assembly_out_file_name, errorDescription(er) }); defer out_file.close(io); assembly.writeToFile(out_file) catch |er| @@ -1455,7 +1455,7 @@ fn processSource( }; defer obj.deinit(); - const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(io, out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); defer out_file.close(io); diff --git a/lib/compiler/aro/aro/Parser.zig b/lib/compiler/aro/aro/Parser.zig index 4a89e0d460..fc21ee4d0b 100644 --- a/lib/compiler/aro/aro/Parser.zig +++ b/lib/compiler/aro/aro/Parser.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; const Allocator = mem.Allocator; const assert = std.debug.assert; @@ -211,7 +212,7 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca const prev_total = p.diagnostics.total; var sf = std.heap.stackFallback(1024, p.comp.gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); if (!char_info.isC99IdChar(codepoint)) { @@ -425,7 +426,7 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) if (p.diagnostics.effectiveKind(diagnostic) == .off) return; var sf = std.heap.stackFallback(1024, p.comp.gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); p.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory; @@ -447,7 +448,7 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) }, p.pp.expansionSlice(tok_i), true); } -fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !void { +fn formatArgs(p: *Parser, w: *Io.Writer, fmt: []const u8, args: anytype) !void { var i: usize = 0; inline for (std.meta.fields(@TypeOf(args))) |arg_info| { const arg = @field(args, arg_info.name); @@ -476,13 +477,13 @@ fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !vo try w.writeAll(fmt[i..]); } -fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize { +fn formatTokenId(w: *Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize { const i = Diagnostics.templateIndex(w, fmt, "{tok_id}"); try w.writeAll(tok_id.symbol()); return i; } -fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize { +fn formatQualType(p: *Parser, w: *Io.Writer, fmt: []const u8, qt: QualType) !usize { const i = Diagnostics.templateIndex(w, fmt, "{qt}"); try w.writeByte('\''); try qt.print(p.comp, w); @@ -501,7 +502,7 @@ fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) return i; } -fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize { +fn formatResult(p: *Parser, w: *Io.Writer, fmt: []const u8, res: Result) !usize { const i = Diagnostics.templateIndex(w, fmt, "{value}"); switch (res.val.opt_ref) { .none => try w.writeAll("(none)"), @@ -524,7 +525,7 @@ const Normalized = struct { return .{ .str = str }; } - pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt: []const u8) !usize { + pub fn format(ctx: Normalized, w: *Io.Writer, fmt: []const u8) !usize { const i = Diagnostics.templateIndex(w, fmt, "{normalized}"); var it: std.unicode.Utf8Iterator = .{ .bytes = ctx.str, @@ -558,7 +559,7 @@ const Codepoint = struct { return .{ .codepoint = codepoint }; } - pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt: []const u8) !usize { + pub fn format(ctx: Codepoint, w: *Io.Writer, fmt: []const u8) !usize { const i = Diagnostics.templateIndex(w, fmt, "{codepoint}"); try w.print("{X:0>4}", .{ctx.codepoint}); return i; @@ -572,7 +573,7 @@ const Escaped = struct { return .{ .str = str }; } - pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt: []const u8) !usize { + pub fn format(ctx: Escaped, w: *Io.Writer, fmt: []const u8) !usize { const i = Diagnostics.templateIndex(w, fmt, "{s}"); try std.zig.stringEscape(ctx.str, w); return i; @@ -1453,7 +1454,7 @@ fn decl(p: *Parser) Error!bool { return true; } -fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result, allocating: *std.Io.Writer.Allocating) !?[]const u8 { +fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result, allocating: *Io.Writer.Allocating) !?[]const u8 { const w = &allocating.writer; const cond = cond_node.get(&p.tree); @@ -1526,7 +1527,7 @@ fn staticAssert(p: *Parser) Error!bool { } else { if (!res.val.toBool(p.comp)) { var sf = std.heap.stackFallback(1024, gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); if (p.staticAssertMessage(res_node, str, &allocating) catch return error.OutOfMemory) |message| { @@ -9719,7 +9720,7 @@ fn primaryExpr(p: *Parser) Error!?Result { qt = some.qt; } else if (p.func.qt) |func_qt| { var sf = std.heap.stackFallback(1024, gpa); - var allocating: std.Io.Writer.Allocating = .init(sf.get()); + var allocating: Io.Writer.Allocating = .init(sf.get()); defer allocating.deinit(); func_qt.printNamed(p.tokSlice(p.func.name), p.comp, &allocating.writer) catch return error.OutOfMemory; @@ -10608,7 +10609,7 @@ test "Node locations" { const arena = arena_state.allocator(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); const file = try comp.addSourceFromBuffer("file.c", diff --git a/lib/compiler/aro/aro/Preprocessor.zig b/lib/compiler/aro/aro/Preprocessor.zig index d47727cbf0..e8343dc83a 100644 --- a/lib/compiler/aro/aro/Preprocessor.zig +++ b/lib/compiler/aro/aro/Preprocessor.zig @@ -3900,7 +3900,7 @@ test "Preserve pragma tokens sometimes" { defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); try comp.addDefaultPragmaHandlers(); @@ -3967,7 +3967,7 @@ test "destringify" { var arena: std.heap.ArenaAllocator = .init(gpa); defer arena.deinit(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(gpa, arena.allocator(), std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var pp = Preprocessor.init(&comp, .default); defer pp.deinit(); @@ -4030,7 +4030,7 @@ test "Include guards" { const arena = arena_state.allocator(); var diagnostics: Diagnostics = .{ .output = .ignore }; - var comp = Compilation.init(gpa, arena, std.testing.io, &diagnostics, std.fs.cwd()); + var comp = Compilation.init(gpa, arena, std.testing.io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var pp = Preprocessor.init(&comp, .default); defer pp.deinit(); diff --git a/lib/compiler/aro/aro/Tokenizer.zig b/lib/compiler/aro/aro/Tokenizer.zig index c497c5ce82..198d49364a 100644 --- a/lib/compiler/aro/aro/Tokenizer.zig +++ b/lib/compiler/aro/aro/Tokenizer.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const Compilation = @import("Compilation.zig"); @@ -2326,7 +2327,7 @@ test "Tokenizer fuzz test" { fn testOne(_: @This(), input_bytes: []const u8) anyerror!void { var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); defer arena.deinit(); - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); const source = try comp.addSourceFromBuffer("fuzz.c", input_bytes); @@ -2351,7 +2352,7 @@ test "Tokenizer fuzz test" { fn expectTokensExtra(contents: []const u8, expected_tokens: []const Token.Id, langopts: ?LangOpts) !void { var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); defer arena.deinit(); - var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena.allocator(), std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); if (langopts) |provided| { comp.langopts = provided; diff --git a/lib/compiler/aro/aro/Value.zig b/lib/compiler/aro/aro/Value.zig index 25a2d1824f..14949ce03b 100644 --- a/lib/compiler/aro/aro/Value.zig +++ b/lib/compiler/aro/aro/Value.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; @@ -80,7 +81,7 @@ test "minUnsignedBits" { defer arena_state.deinit(); const arena = arena_state.allocator(); - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); const target_query = try std.Target.Query.parse(.{ .arch_os_abi = "x86_64-linux-gnu" }); comp.target = .fromZigTarget(try std.zig.system.resolveTargetQuery(std.testing.io, target_query)); @@ -119,7 +120,7 @@ test "minSignedBits" { defer arena_state.deinit(); const arena = arena_state.allocator(); - var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, std.fs.cwd()); + var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, undefined, Io.Dir.cwd()); defer comp.deinit(); const target_query = try std.Target.Query.parse(.{ .arch_os_abi = "x86_64-linux-gnu" }); comp.target = .fromZigTarget(try std.zig.system.resolveTargetQuery(std.testing.io, target_query)); @@ -1080,7 +1081,7 @@ const NestedPrint = union(enum) { }, }; -pub fn printPointer(offset: Value, base: []const u8, comp: *const Compilation, w: *std.Io.Writer) std.Io.Writer.Error!void { +pub fn printPointer(offset: Value, base: []const u8, comp: *const Compilation, w: *Io.Writer) Io.Writer.Error!void { try w.writeByte('&'); try w.writeAll(base); if (!offset.isZero(comp)) { @@ -1089,7 +1090,7 @@ pub fn printPointer(offset: Value, base: []const u8, comp: *const Compilation, w } } -pub fn print(v: Value, qt: QualType, comp: *const Compilation, w: *std.Io.Writer) std.Io.Writer.Error!?NestedPrint { +pub fn print(v: Value, qt: QualType, comp: *const Compilation, w: *Io.Writer) Io.Writer.Error!?NestedPrint { if (qt.is(comp, .bool)) { try w.writeAll(if (v.isZero(comp)) "false" else "true"); return null; @@ -1116,7 +1117,7 @@ pub fn print(v: Value, qt: QualType, comp: *const Compilation, w: *std.Io.Writer return null; } -pub fn printString(bytes: []const u8, qt: QualType, comp: *const Compilation, w: *std.Io.Writer) std.Io.Writer.Error!void { +pub fn printString(bytes: []const u8, qt: QualType, comp: *const Compilation, w: *Io.Writer) Io.Writer.Error!void { const size: Compilation.CharUnitSize = @enumFromInt(qt.childType(comp).sizeof(comp)); const without_null = bytes[0 .. bytes.len - @intFromEnum(size)]; try w.writeByte('"'); diff --git a/lib/compiler/aro/main.zig b/lib/compiler/aro/main.zig index 66c8add4a3..d1be1dbb21 100644 --- a/lib/compiler/aro/main.zig +++ b/lib/compiler/aro/main.zig @@ -59,7 +59,7 @@ pub fn main() u8 { } }, }; - var comp = Compilation.initDefault(gpa, arena, io, &diagnostics, std.fs.cwd()) catch |er| switch (er) { + var comp = Compilation.initDefault(gpa, arena, io, &diagnostics, Io.Dir.cwd()) catch |er| switch (er) { error.OutOfMemory => { std.debug.print("out of memory\n", .{}); if (fast_exit) process.exit(1); diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index 485e644daa..e48f76a6a6 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -152,7 +152,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void defer threaded.deinit(); const io = threaded.io(); - const input_file = fs.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); + const input_file = Io.Dir.cwd().openFile(input, .{}) catch |err| fatal("failed to open {s}: {t}", .{ input, err }); defer input_file.close(io); const stat = input_file.stat() catch |err| fatal("failed to stat {s}: {t}", .{ input, err }); @@ -180,7 +180,7 @@ fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void const mode = if (out_fmt != .elf or only_keep_debug) Io.File.default_mode else stat.mode; - var output_file = try fs.cwd().createFile(output, .{ .mode = mode }); + var output_file = try Io.Dir.cwd().createFile(io, output, .{ .mode = mode }); defer output_file.close(io); var out = output_file.writer(&output_buffer); diff --git a/lib/compiler/reduce.zig b/lib/compiler/reduce.zig index bbd3d172b4..d3f33ad81a 100644 --- a/lib/compiler/reduce.zig +++ b/lib/compiler/reduce.zig @@ -233,7 +233,7 @@ pub fn main() !void { } } - try std.fs.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); + try Io.Dir.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); // std.debug.print("trying this code:\n{s}\n", .{rendered.items}); const interestingness = try runCheck(arena, interestingness_argv.items); @@ -274,7 +274,7 @@ pub fn main() !void { fixups.clearRetainingCapacity(); rendered.clearRetainingCapacity(); try tree.render(gpa, &rendered.writer, fixups); - try std.fs.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); + try Io.Dir.cwd().writeFile(.{ .sub_path = root_source_file_path, .data = rendered.written() }); return std.process.cleanExit(); } @@ -398,7 +398,7 @@ fn transformationsToFixups( } fn parse(gpa: Allocator, file_path: []const u8) !Ast { - const source_code = std.fs.cwd().readFileAllocOptions( + const source_code = Io.Dir.cwd().readFileAllocOptions( file_path, gpa, .limited(std.math.maxInt(u32)), diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index bb54289e3e..ae4ece2968 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -2003,7 +2003,7 @@ test "maybeAppendRC" { // Create the file so that it's found. In this scenario, .rc should not get // appended. - var file = try tmp.dir.createFile("foo", .{}); + var file = try tmp.dir.createFile(io, "foo", .{}); file.close(io); try options.maybeAppendRC(tmp.dir); try std.testing.expectEqualStrings("foo", options.input_source.filename); diff --git a/lib/compiler/resinator/compile.zig b/lib/compiler/resinator/compile.zig index 7dc77e5ee1..3e046a10c1 100644 --- a/lib/compiler/resinator/compile.zig +++ b/lib/compiler/resinator/compile.zig @@ -111,7 +111,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io try search_dirs.append(allocator, .{ .dir = root_dir, .path = try allocator.dupe(u8, root_dir_path) }); } } - // Re-open the passed in cwd since we want to be able to close it (std.fs.cwd() shouldn't be closed) + // Re-open the passed in cwd since we want to be able to close it (Io.Dir.cwd() shouldn't be closed) const cwd_dir = options.cwd.openDir(".", .{}) catch |err| { try options.diagnostics.append(.{ .err = .failed_to_open_cwd, @@ -406,7 +406,7 @@ pub const Compiler = struct { // `/test.bin` relative to include paths and instead only treats it as // an absolute path. if (std.fs.path.isAbsolute(path)) { - const file = try utils.openFileNotDir(std.fs.cwd(), path, .{}); + const file = try utils.openFileNotDir(Io.Dir.cwd(), path, .{}); errdefer file.close(io); if (self.dependencies) |dependencies| { diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index c726a06cf4..416abc2ab7 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -67,7 +67,7 @@ pub fn main() !void { }, else => |e| return e, }; - try options.maybeAppendRC(std.fs.cwd()); + try options.maybeAppendRC(Io.Dir.cwd()); if (!zig_integration) { // print any warnings/notes @@ -141,7 +141,7 @@ pub fn main() !void { if (!zig_integration) std.debug.unlockStderrWriter(); } - var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd()); + var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd()); defer comp.deinit(); var argv: std.ArrayList([]const u8) = .empty; @@ -196,7 +196,7 @@ pub fn main() !void { }; }, .filename => |input_filename| { - break :full_input std.fs.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| { + break :full_input Io.Dir.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| { try error_handler.emitMessage(gpa, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) }); std.process.exit(1); }; @@ -212,7 +212,7 @@ pub fn main() !void { try output_file.writeAll(full_input); }, .filename => |output_filename| { - try std.fs.cwd().writeFile(.{ .sub_path = output_filename, .data = full_input }); + try Io.Dir.cwd().writeFile(.{ .sub_path = output_filename, .data = full_input }); }, } return; @@ -277,7 +277,7 @@ pub fn main() !void { const output_buffered_stream = res_stream_writer.interface(); compile(gpa, io, final_input, output_buffered_stream, .{ - .cwd = std.fs.cwd(), + .cwd = Io.Dir.cwd(), .diagnostics = &diagnostics, .source_mappings = &mapping_results.mappings, .dependencies = maybe_dependencies, @@ -294,7 +294,7 @@ pub fn main() !void { .warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page, }) catch |err| switch (err) { error.ParseError, error.CompileError => { - try error_handler.emitDiagnostics(gpa, std.fs.cwd(), final_input, &diagnostics, mapping_results.mappings); + try error_handler.emitDiagnostics(gpa, Io.Dir.cwd(), final_input, &diagnostics, mapping_results.mappings); // Delete the output file on error res_stream.cleanupAfterError(io); std.process.exit(1); @@ -306,12 +306,12 @@ pub fn main() !void { // print any warnings/notes if (!zig_integration) { - diagnostics.renderToStdErr(std.fs.cwd(), final_input, mapping_results.mappings); + diagnostics.renderToStdErr(Io.Dir.cwd(), final_input, mapping_results.mappings); } // write the depfile if (options.depfile_path) |depfile_path| { - var depfile = std.fs.cwd().createFile(depfile_path, .{}) catch |err| { + var depfile = Io.Dir.cwd().createFile(io, depfile_path, .{}) catch |err| { try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); std.process.exit(1); }; @@ -440,7 +440,7 @@ const IoStream = struct { // Delete the output file on error file.close(io); // Failing to delete is not really a big deal, so swallow any errors - std.fs.cwd().deleteFile(self.name) catch {}; + Io.Dir.cwd().deleteFile(self.name) catch {}; }, .stdio, .memory, .closed => return, } @@ -457,8 +457,8 @@ const IoStream = struct { switch (source) { .filename => |filename| return .{ .file = switch (io) { - .input => try openFileNotDir(std.fs.cwd(), filename, .{}), - .output => try std.fs.cwd().createFile(filename, .{}), + .input => try openFileNotDir(Io.Dir.cwd(), filename, .{}), + .output => try Io.Dir.cwd().createFile(io, filename, .{}), }, }, .stdio => |file| return .{ .stdio = file }, diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index e4efac28cd..87c4da9faa 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -40,7 +40,7 @@ pub fn main() !void { const zig_exe_path = argv.next().?; const global_cache_path = argv.next().?; - var lib_dir = try std.fs.cwd().openDir(zig_lib_directory, .{}); + var lib_dir = try Io.Dir.cwd().openDir(zig_lib_directory, .{}); defer lib_dir.close(io); var listen_port: u16 = 0; diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index 830c70e424..d0a873fd78 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -47,7 +47,7 @@ pub fn main() u8 { }; defer diagnostics.deinit(); - var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, std.fs.cwd()) catch |err| switch (err) { + var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, Io.Dir.cwd()) catch |err| switch (err) { error.OutOfMemory => { std.debug.print("ran out of memory initializing C compilation\n", .{}); if (fast_exit) process.exit(1); @@ -226,7 +226,7 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration const dep_file_name = try d.getDepFileName(source, out_buf[0..std.fs.max_name_bytes]); const file = if (dep_file_name) |path| - d.comp.cwd.createFile(path, .{}) catch |er| + d.comp.cwd.createFile(io, path, .{}) catch |er| return d.fatal("unable to create dependency file '{s}': {s}", .{ path, aro.Driver.errorDescription(er) }) else Io.File.stdout(); @@ -253,10 +253,10 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration if (d.output_name) |path| blk: { if (std.mem.eql(u8, path, "-")) break :blk; if (std.fs.path.dirname(path)) |dirname| { - std.fs.cwd().makePath(dirname) catch |err| + Io.Dir.cwd().makePath(dirname) catch |err| return d.fatal("failed to create path to '{s}': {s}", .{ path, aro.Driver.errorDescription(err) }); } - out_file = std.fs.cwd().createFile(path, .{}) catch |err| { + out_file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| { return d.fatal("failed to create output file '{s}': {s}", .{ path, aro.Driver.errorDescription(err) }); }; close_out_file = true; diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 7bfdbb6449..cc2f70fd2f 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1702,13 +1702,13 @@ pub fn addCheckFile( pub fn truncateFile(b: *Build, dest_path: []const u8) (Io.Dir.MakeError || Io.Dir.StatFileError)!void { const io = b.graph.io; if (b.verbose) log.info("truncate {s}", .{dest_path}); - const cwd = fs.cwd(); - var src_file = cwd.createFile(dest_path, .{}) catch |err| switch (err) { + const cwd = Io.Dir.cwd(); + var src_file = cwd.createFile(io, dest_path, .{}) catch |err| switch (err) { error.FileNotFound => blk: { if (fs.path.dirname(dest_path)) |dirname| { try cwd.makePath(dirname); } - break :blk try cwd.createFile(dest_path, .{}); + break :blk try cwd.createFile(io, dest_path, .{}); }, else => |e| return e, }; @@ -1846,7 +1846,7 @@ pub fn runAllowFail( }; errdefer b.allocator.free(stdout); - const term = try child.wait(); + const term = try child.wait(io); switch (term) { .Exited => |code| { if (code != 0) { @@ -2193,7 +2193,7 @@ fn dependencyInner( const build_root: std.Build.Cache.Directory = .{ .path = build_root_string, - .handle = fs.cwd().openDir(build_root_string, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(build_root_string, .{}) catch |err| { std.debug.print("unable to open '{s}': {s}\n", .{ build_root_string, @errorName(err), }); diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 42459c033d..fdcb2ab714 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -508,7 +508,7 @@ pub const Manifest = struct { // and `want_shared_lock` is set, a shared lock might be sufficient, so we'll // open with a shared lock instead. while (true) { - if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ + if (self.cache.manifest_dir.createFile(io, &manifest_file_path, .{ .read = true, .truncate = false, .lock = .exclusive, @@ -543,7 +543,7 @@ pub const Manifest = struct { return error.CacheCheckFailed; } - if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ + if (self.cache.manifest_dir.createFile(io, &manifest_file_path, .{ .read = true, .truncate = false, .lock = .exclusive, @@ -873,7 +873,7 @@ pub const Manifest = struct { if (man.want_refresh_timestamp) { man.want_refresh_timestamp = false; - var file = man.cache.manifest_dir.createFile("timestamp", .{ + var file = man.cache.manifest_dir.createFile(io, "timestamp", .{ .read = true, .truncate = true, }) catch |err| switch (err) { @@ -1324,7 +1324,7 @@ fn hashFile(file: Io.File, bin_digest: *[Hasher.mac_length]u8) Io.File.PReadErro fn testGetCurrentFileTimestamp(io: Io, dir: Io.Dir) !Io.Timestamp { const test_out_file = "test-filetimestamp.tmp"; - var file = try dir.createFile(test_out_file, .{ + var file = try dir.createFile(io, test_out_file, .{ .read = true, .truncate = true, }); diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 56ef32e8d8..2ec1c0ef31 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -401,6 +401,9 @@ pub fn evalZigProcess( web_server: ?*Build.WebServer, gpa: Allocator, ) !?Path { + const b = s.owner; + const io = b.graph.io; + // If an error occurs, it's happened in this command: assert(s.result_failed_command == null); s.result_failed_command = try allocPrintCmd(gpa, null, argv); @@ -411,7 +414,7 @@ pub fn evalZigProcess( const result = zigProcessUpdate(s, zp, watch, web_server, gpa) catch |err| switch (err) { error.BrokenPipe => { // Process restart required. - const term = zp.child.wait() catch |e| { + const term = zp.child.wait(io) catch |e| { return s.fail("unable to wait for {s}: {t}", .{ argv[0], e }); }; _ = term; @@ -427,7 +430,7 @@ pub fn evalZigProcess( if (s.result_error_msgs.items.len > 0 and result == null) { // Crash detected. - const term = zp.child.wait() catch |e| { + const term = zp.child.wait(io) catch |e| { return s.fail("unable to wait for {s}: {t}", .{ argv[0], e }); }; s.result_peak_rss = zp.child.resource_usage_statistics.getMaxRss() orelse 0; @@ -439,9 +442,7 @@ pub fn evalZigProcess( return result; } assert(argv.len != 0); - const b = s.owner; const arena = b.allocator; - const io = b.graph.io; try handleChildProcUnsupported(s); try handleVerbose(s.owner, null, argv); @@ -478,7 +479,7 @@ pub fn evalZigProcess( zp.child.stdin.?.close(io); zp.child.stdin = null; - const term = zp.child.wait() catch |err| { + const term = zp.child.wait(io) catch |err| { return s.fail("unable to wait for {s}: {t}", .{ argv[0], err }); }; s.result_peak_rss = zp.child.resource_usage_statistics.getMaxRss() orelse 0; @@ -519,7 +520,7 @@ pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u pub fn installDir(s: *Step, dest_path: []const u8) !Io.Dir.MakePathStatus { const b = s.owner; try handleVerbose(b, null, &.{ "install", "-d", dest_path }); - return std.fs.cwd().makePathStatus(dest_path) catch |err| + return Io.Dir.cwd().makePathStatus(dest_path) catch |err| return s.fail("unable to create dir '{s}': {t}", .{ dest_path, err }); } @@ -895,7 +896,7 @@ pub fn addWatchInput(step: *Step, lazy_file: Build.LazyPath) Allocator.Error!voi try addWatchInputFromPath(step, .{ .root_dir = .{ .path = null, - .handle = std.fs.cwd(), + .handle = Io.Dir.cwd(), }, .sub_path = std.fs.path.dirname(path_string) orelse "", }, std.fs.path.basename(path_string)); @@ -920,7 +921,7 @@ pub fn addDirectoryWatchInput(step: *Step, lazy_directory: Build.LazyPath) Alloc try addDirectoryWatchInputFromPath(step, .{ .root_dir = .{ .path = null, - .handle = std.fs.cwd(), + .handle = Io.Dir.cwd(), }, .sub_path = path_string, }); diff --git a/lib/std/Build/Step/CheckFile.zig b/lib/std/Build/Step/CheckFile.zig index efeedc8b80..560b6ad050 100644 --- a/lib/std/Build/Step/CheckFile.zig +++ b/lib/std/Build/Step/CheckFile.zig @@ -3,7 +3,9 @@ //! TODO: generalize the code in std.testing.expectEqualStrings and make this //! CheckFile step produce those helpful diagnostics when there is not a match. const CheckFile = @This(); + const std = @import("std"); +const Io = std.Io; const Step = std.Build.Step; const fs = std.fs; const mem = std.mem; @@ -53,7 +55,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { try step.singleUnchangingWatchInput(check_file.source); const src_path = check_file.source.getPath2(b, step); - const contents = fs.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err), }); diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index df2419764d..ea7d9d99ff 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -1,5 +1,7 @@ -const std = @import("std"); const ConfigHeader = @This(); + +const std = @import("std"); +const Io = std.Io; const Step = std.Build.Step; const Allocator = std.mem.Allocator; const Writer = std.Io.Writer; @@ -205,7 +207,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .autoconf_undef, .autoconf_at => |file_source| { try bw.writeAll(c_generated_line); const src_path = file_source.getPath2(b, step); - const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { return step.fail("unable to read autoconf input file '{s}': {s}", .{ src_path, @errorName(err), }); @@ -219,7 +221,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { .cmake => |file_source| { try bw.writeAll(c_generated_line); const src_path = file_source.getPath2(b, step); - const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { + const contents = Io.Dir.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { return step.fail("unable to read cmake input file '{s}': {s}", .{ src_path, @errorName(err), }); diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 9f5665e93a..1416e0e916 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -1,12 +1,13 @@ -const std = @import("std"); +const Options = @This(); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const fs = std.fs; const Step = std.Build.Step; const GeneratedFile = std.Build.GeneratedFile; const LazyPath = std.Build.LazyPath; -const Options = @This(); - pub const base_id: Step.Id = .options; step: Step, @@ -542,11 +543,11 @@ test Options { .cache = .{ .io = io, .gpa = arena.allocator(), - .manifest_dir = std.fs.cwd(), + .manifest_dir = Io.Dir.cwd(), }, .zig_exe = "test", .env_map = std.process.EnvMap.init(arena.allocator()), - .global_cache_root = .{ .path = "test", .handle = std.fs.cwd() }, + .global_cache_root = .{ .path = "test", .handle = Io.Dir.cwd() }, .host = .{ .query = .{}, .result = try std.zig.system.resolveTargetQuery(io, .{}), @@ -557,8 +558,8 @@ test Options { var builder = try std.Build.create( &graph, - .{ .path = "test", .handle = std.fs.cwd() }, - .{ .path = "test", .handle = std.fs.cwd() }, + .{ .path = "test", .handle = Io.Dir.cwd() }, + .{ .path = "test", .handle = Io.Dir.cwd() }, &.{}, ); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 7c54c8048e..af6bc20438 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1023,7 +1023,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, options, null); - const dep_file_dir = std.fs.cwd(); + const dep_file_dir = Io.Dir.cwd(); const dep_file_basename = dep_output_file.generated_file.getPath2(b, step); if (has_side_effects) try man.addDepFile(dep_file_dir, dep_file_basename) diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig index ff06ad3ff3..f7ac47961e 100644 --- a/lib/std/Build/Watch.zig +++ b/lib/std/Build/Watch.zig @@ -122,7 +122,7 @@ const Os = switch (builtin.os.tag) { }) catch return error.NameTooLong; const stack_ptr: *std.os.linux.file_handle = @ptrCast(&file_handle_buffer); stack_ptr.handle_bytes = file_handle_buffer.len - @sizeOf(std.os.linux.file_handle); - try posix.name_to_handle_at(path.root_dir.handle.fd, adjusted_path, stack_ptr, mount_id, std.os.linux.AT.HANDLE_FID); + try posix.name_to_handle_at(path.root_dir.handle.handle, adjusted_path, stack_ptr, mount_id, std.os.linux.AT.HANDLE_FID); const stack_lfh: FileHandle = .{ .handle = stack_ptr }; return stack_lfh.clone(gpa); } @@ -222,7 +222,7 @@ const Os = switch (builtin.os.tag) { posix.fanotify_mark(fan_fd, .{ .ADD = true, .ONLYDIR = true, - }, fan_mask, path.root_dir.handle.fd, path.subPathOrDot()) catch |err| { + }, fan_mask, path.root_dir.handle.handle, path.subPathOrDot()) catch |err| { fatal("unable to watch {f}: {s}", .{ path, @errorName(err) }); }; } @@ -275,7 +275,7 @@ const Os = switch (builtin.os.tag) { posix.fanotify_mark(fan_fd, .{ .REMOVE = true, .ONLYDIR = true, - }, fan_mask, path.root_dir.handle.fd, path.subPathOrDot()) catch |err| switch (err) { + }, fan_mask, path.root_dir.handle.handle, path.subPathOrDot()) catch |err| switch (err) { error.FileNotFound => {}, // Expected, harmless. else => |e| std.log.warn("unable to unwatch '{f}': {s}", .{ path, @errorName(e) }), }; @@ -353,7 +353,7 @@ const Os = switch (builtin.os.tag) { // The following code is a drawn out NtCreateFile call. (mostly adapted from Io.Dir.makeOpenDirAccessMaskW) // It's necessary in order to get the specific flags that are required when calling ReadDirectoryChangesW. var dir_handle: windows.HANDLE = undefined; - const root_fd = path.root_dir.handle.fd; + const root_fd = path.root_dir.handle.handle; const sub_path = path.subPathOrDot(); const sub_path_w = try windows.sliceToPrefixedFileW(root_fd, sub_path); const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong; @@ -681,9 +681,9 @@ const Os = switch (builtin.os.tag) { if (!gop.found_existing) { const skip_open_dir = path.sub_path.len == 0; const dir_fd = if (skip_open_dir) - path.root_dir.handle.fd + path.root_dir.handle.handle else - posix.openat(path.root_dir.handle.fd, path.sub_path, dir_open_flags, 0) catch |err| { + posix.openat(path.root_dir.handle.handle, path.sub_path, dir_open_flags, 0) catch |err| { fatal("failed to open directory {f}: {s}", .{ path, @errorName(err) }); }; // Empirically the dir has to stay open or else no events are triggered. @@ -750,7 +750,7 @@ const Os = switch (builtin.os.tag) { // to access that data via the dir_fd field. const path = w.dir_table.keys()[i]; const dir_fd = if (path.sub_path.len == 0) - path.root_dir.handle.fd + path.root_dir.handle.handle else handles.items(.dir_fd)[i]; assert(dir_fd != -1); @@ -761,7 +761,7 @@ const Os = switch (builtin.os.tag) { const last_dir_fd = fd: { const last_path = w.dir_table.keys()[handles.len - 1]; const last_dir_fd = if (last_path.sub_path.len == 0) - last_path.root_dir.handle.fd + last_path.root_dir.handle.handle else handles.items(.dir_fd)[handles.len - 1]; assert(last_dir_fd != -1); diff --git a/lib/std/Io/File.zig b/lib/std/Io/File.zig index 8e71f648e2..a9b4775772 100644 --- a/lib/std/Io/File.zig +++ b/lib/std/Io/File.zig @@ -527,6 +527,14 @@ pub fn writerStreaming(file: File, io: Io, buffer: []u8) Writer { return .initStreaming(file, io, buffer); } +/// Equivalent to creating a streaming writer, writing `bytes`, and then flushing. +pub fn writeStreamingAll(file: File, io: Io, bytes: []const u8) Writer.Error!void { + var index: usize = 0; + while (index < bytes.len) { + index += try io.vtable.fileWriteStreaming(io.userdata, file, &.{}, &.{bytes[index..]}, 1); + } +} + pub const LockError = error{ SystemResources, FileLocksUnsupported, diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index fb76002201..124f886515 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -2361,7 +2361,7 @@ fn dirCreateFilePosix( .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, // Linux when accessing procfs. .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -2670,7 +2670,7 @@ fn dirOpenFilePosix( .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, // Linux when opening procfs files. .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -3287,7 +3287,7 @@ fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_b .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + .SRCH => return error.FileNotFound, // Linux when accessing procfs. .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -5548,7 +5548,6 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: [][]u8) File. switch (e) { .INVAL => |err| return errnoBug(err), .FAULT => |err| return errnoBug(err), - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => |err| { if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory. @@ -5672,7 +5671,6 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: [][]u8, offs switch (e) { .INVAL => |err| return errnoBug(err), .FAULT => |err| return errnoBug(err), - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => |err| { if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory. @@ -6312,7 +6310,6 @@ fn fileWriteStreaming( switch (e) { .INVAL => return error.InvalidArgument, .FAULT => |err| return errnoBug(err), - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => return error.NotOpenForWriting, // Can be a race condition. .DESTADDRREQ => |err| return errnoBug(err), // `connect` was never called. diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 3f25bc6a26..63ae6d93a0 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -2835,7 +2835,7 @@ test "discarding sendFile" { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [256]u8 = undefined; var file_writer: File.Writer = .init(file, &r_buffer); @@ -2857,7 +2857,7 @@ test "allocating sendFile" { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; var file_writer: File.Writer = .init(file, &r_buffer); @@ -2881,7 +2881,7 @@ test sendFileReading { var tmp_dir = testing.tmpDir(.{}); defer tmp_dir.cleanup(); - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); var r_buffer: [2]u8 = undefined; var file_writer: File.Writer = .init(file, &r_buffer); diff --git a/lib/std/Io/net/test.zig b/lib/std/Io/net/test.zig index 5818f6c3f7..c9ed0d3284 100644 --- a/lib/std/Io/net/test.zig +++ b/lib/std/Io/net/test.zig @@ -278,7 +278,7 @@ test "listen on a unix socket, send bytes, receive bytes" { defer testing.allocator.free(socket_path); const socket_addr = try net.UnixAddress.init(socket_path); - defer std.fs.cwd().deleteFile(socket_path) catch {}; + defer Io.Dir.cwd().deleteFile(socket_path) catch {}; var server = try socket_addr.listen(io, .{}); defer server.socket.close(io); diff --git a/lib/std/Io/test.zig b/lib/std/Io/test.zig index 9f21fe50e7..e731dc18d7 100644 --- a/lib/std/Io/test.zig +++ b/lib/std/Io/test.zig @@ -27,7 +27,7 @@ test "write a file, read it, then delete it" { random.bytes(data[0..]); const tmp_file_name = "temp_test_file.txt"; { - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); var file_writer = file.writer(&.{}); @@ -40,7 +40,7 @@ test "write a file, read it, then delete it" { { // Make sure the exclusive flag is honored. - try expectError(File.OpenError.PathAlreadyExists, tmp.dir.createFile(tmp_file_name, .{ .exclusive = true })); + try expectError(File.OpenError.PathAlreadyExists, tmp.dir.createFile(io, tmp_file_name, .{ .exclusive = true })); } { @@ -70,7 +70,7 @@ test "File seek ops" { const io = testing.io; const tmp_file_name = "temp_test_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); try file.writeAll(&([_]u8{0x55} ** 8192)); @@ -96,7 +96,7 @@ test "setEndPos" { defer tmp.cleanup(); const tmp_file_name = "temp_test_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); // Verify that the file size changes and the file offset is not moved @@ -121,7 +121,7 @@ test "updateTimes" { defer tmp.cleanup(); const tmp_file_name = "just_a_temporary_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{ .read = true }); + var file = try tmp.dir.createFile(io, tmp_file_name, .{ .read = true }); defer file.close(io); const stat_old = try file.stat(); diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 102bb59415..8453bc4c81 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -208,7 +208,7 @@ pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { var buf: [32]u8 = undefined; const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()}); - const file = try std.fs.cwd().openFile(io, path, .{ .mode = .write_only }); + const file = try Io.Dir.cwd().openFile(io, path, .{ .mode = .write_only }); defer file.close(io); try file.writeAll(name); @@ -325,7 +325,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co var threaded: std.Io.Threaded = .init_single_threaded; const io = threaded.ioBasic(); - const file = try std.fs.cwd().openFile(io, path, .{}); + const file = try Io.Dir.cwd().openFile(io, path, .{}); defer file.close(io); var file_reader = file.readerStreaming(io, &.{}); diff --git a/lib/std/crypto/Certificate/Bundle/macos.zig b/lib/std/crypto/Certificate/Bundle/macos.zig index 473505ac51..444d8da675 100644 --- a/lib/std/crypto/Certificate/Bundle/macos.zig +++ b/lib/std/crypto/Certificate/Bundle/macos.zig @@ -19,7 +19,7 @@ pub fn rescanMac(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanM _ = io; // TODO migrate file system to use std.Io for (keychain_paths) |keychain_path| { - const bytes = std.fs.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { + const bytes = Io.Dir.cwd().readFileAlloc(keychain_path, gpa, .limited(std.math.maxInt(u32))) catch |err| switch (err) { error.StreamTooLong => return error.FileTooBig, else => |e| return e, }; diff --git a/lib/std/crypto/codecs/asn1/test.zig b/lib/std/crypto/codecs/asn1/test.zig index ff854fcbde..3dbedb9f80 100644 --- a/lib/std/crypto/codecs/asn1/test.zig +++ b/lib/std/crypto/codecs/asn1/test.zig @@ -73,8 +73,8 @@ test AllTypes { try std.testing.expectEqualSlices(u8, encoded, buf); // Use this to update test file. - // const dir = try std.fs.cwd().openDir("lib/std/crypto/asn1", .{}); - // var file = try dir.createFile(path, .{}); + // const dir = try Io.Dir.cwd().openDir("lib/std/crypto/asn1", .{}); + // var file = try dir.createFile(io, path, .{}); // defer file.close(io); // try file.writeAll(buf); } diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 97741ecb40..5df0eef2d5 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -60,7 +60,7 @@ pub const cpu_context = @import("debug/cpu_context.zig"); /// }; /// /// Only required if `can_unwind == true`. Unwinds a single stack frame, returning the frame's /// /// return address, or 0 if the end of the stack has been reached. -/// pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) SelfInfoError!usize; +/// pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, io: Io, context: *UnwindContext) SelfInfoError!usize; /// ``` pub const SelfInfo = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "SelfInfo")) root.debug.SelfInfo @@ -558,9 +558,9 @@ pub fn defaultPanic( stderr.print("{s}\n", .{msg}) catch break :trace; if (@errorReturnTrace()) |t| if (t.index > 0) { - stderr.writeAll("error return context:\n") catch break :trace; + stderr.writeStreamingAll("error return context:\n") catch break :trace; writeStackTrace(t, stderr, tty_config) catch break :trace; - stderr.writeAll("\nstack trace:\n") catch break :trace; + stderr.writeStreamingAll("\nstack trace:\n") catch break :trace; }; writeCurrentStackTrace(.{ .first_address = first_trace_addr orelse @returnAddress(), @@ -575,7 +575,7 @@ pub fn defaultPanic( // A panic happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - File.stderr().writeAll("aborting due to recursive panic\n") catch {}; + File.stderr().writeStreamingAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. } @@ -960,7 +960,7 @@ const StackIterator = union(enum) { }, }; - fn next(it: *StackIterator) Result { + fn next(it: *StackIterator, io: Io) Result { switch (it.*) { .ctx_first => |context_ptr| { // After the first frame, start actually unwinding. @@ -976,7 +976,7 @@ const StackIterator = union(enum) { .di => |*unwind_context| { const di = getSelfDebugInfo() catch unreachable; const di_gpa = getDebugInfoAllocator(); - const ret_addr = di.unwindFrame(di_gpa, unwind_context) catch |err| { + const ret_addr = di.unwindFrame(di_gpa, io, unwind_context) catch |err| { const pc = unwind_context.pc; const fp = unwind_context.getFp(); it.* = .{ .fp = fp }; @@ -1297,7 +1297,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("line_overlaps_page_boundary.zig", .{}); + const file = try test_dir.dir.createFile(io, "line_overlaps_page_boundary.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "line_overlaps_page_boundary.zig" }); defer gpa.free(path); @@ -1316,7 +1316,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("file_ends_on_page_boundary.zig", .{}); + const file = try test_dir.dir.createFile(io, "file_ends_on_page_boundary.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "file_ends_on_page_boundary.zig" }); defer gpa.free(path); @@ -1330,7 +1330,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("very_long_first_line_spanning_multiple_pages.zig", .{}); + const file = try test_dir.dir.createFile(io, "very_long_first_line_spanning_multiple_pages.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "very_long_first_line_spanning_multiple_pages.zig" }); defer gpa.free(path); @@ -1356,7 +1356,7 @@ test printLineFromFile { aw.clearRetainingCapacity(); } { - const file = try test_dir.dir.createFile("file_of_newlines.zig", .{}); + const file = try test_dir.dir.createFile(io, "file_of_newlines.zig", .{}); defer file.close(io); const path = try fs.path.join(gpa, &.{ test_dir_path, "file_of_newlines.zig" }); defer gpa.free(path); diff --git a/lib/std/debug/ElfFile.zig b/lib/std/debug/ElfFile.zig index a0f1188ade..203ee8effb 100644 --- a/lib/std/debug/ElfFile.zig +++ b/lib/std/debug/ElfFile.zig @@ -375,7 +375,7 @@ fn loadSeparateDebugFile( args: anytype, ) Allocator.Error!?[]align(std.heap.page_size_min) const u8 { const path = try std.fmt.allocPrint(arena, fmt, args); - const elf_file = std.fs.cwd().openFile(io, path, .{}) catch return null; + const elf_file = Io.Dir.cwd().openFile(io, path, .{}) catch return null; defer elf_file.close(io); const result = loadInner(arena, elf_file, opt_crc) catch |err| switch (err) { diff --git a/lib/std/debug/MachOFile.zig b/lib/std/debug/MachOFile.zig index ae904c0aec..18126a1c29 100644 --- a/lib/std/debug/MachOFile.zig +++ b/lib/std/debug/MachOFile.zig @@ -512,7 +512,7 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { /// Uses `mmap` to map the file at `path` into memory. fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { - const file = std.fs.cwd().openFile(io, path, .{}) catch |err| switch (err) { + const file = Io.Dir.cwd().openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return error.ReadFailed, }; diff --git a/lib/std/debug/SelfInfo/Elf.zig b/lib/std/debug/SelfInfo/Elf.zig index 213389bf04..6ed18bcb80 100644 --- a/lib/std/debug/SelfInfo/Elf.zig +++ b/lib/std/debug/SelfInfo/Elf.zig @@ -29,13 +29,12 @@ pub fn deinit(si: *SelfInfo, gpa: Allocator) void { } pub fn getSymbol(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!std.debug.Symbol { - _ = io; const module = try si.findModule(gpa, address, .exclusive); defer si.rwlock.unlock(); const vaddr = address - module.load_offset; - const loaded_elf = try module.getLoadedElf(gpa); + const loaded_elf = try module.getLoadedElf(gpa, io); if (loaded_elf.file.dwarf) |*dwarf| { if (!loaded_elf.scanned_dwarf) { dwarf.open(gpa, native_endian) catch |err| switch (err) { @@ -180,7 +179,7 @@ comptime { } } pub const UnwindContext = Dwarf.SelfUnwinder; -pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error!usize { +pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, io: Io, context: *UnwindContext) Error!usize { comptime assert(can_unwind); { @@ -201,7 +200,7 @@ pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error @memset(si.unwind_cache.?, .empty); } - const unwind_sections = try module.getUnwindSections(gpa); + const unwind_sections = try module.getUnwindSections(gpa, io); for (unwind_sections) |*unwind| { if (context.computeRules(gpa, unwind, module.load_offset, null)) |entry| { entry.populate(si.unwind_cache.?); @@ -261,12 +260,12 @@ const Module = struct { }; /// Assumes we already hold an exclusive lock. - fn getUnwindSections(mod: *Module, gpa: Allocator) Error![]Dwarf.Unwind { - if (mod.unwind == null) mod.unwind = loadUnwindSections(mod, gpa); + fn getUnwindSections(mod: *Module, gpa: Allocator, io: Io) Error![]Dwarf.Unwind { + if (mod.unwind == null) mod.unwind = loadUnwindSections(mod, gpa, io); const us = &(mod.unwind.? catch |err| return err); return us.buf[0..us.len]; } - fn loadUnwindSections(mod: *Module, gpa: Allocator) Error!UnwindSections { + fn loadUnwindSections(mod: *Module, gpa: Allocator, io: Io) Error!UnwindSections { var us: UnwindSections = .{ .buf = undefined, .len = 0, @@ -284,7 +283,7 @@ const Module = struct { } else { // There is no `.eh_frame_hdr` section. There may still be an `.eh_frame` or `.debug_frame` // section, but we'll have to load the binary to get at it. - const loaded = try mod.getLoadedElf(gpa); + const loaded = try mod.getLoadedElf(gpa, io); // If both are present, we can't just pick one -- the info could be split between them. // `.debug_frame` is likely to be the more complete section, so we'll prioritize that one. if (loaded.file.debug_frame) |*debug_frame| { @@ -325,7 +324,7 @@ const Module = struct { } fn loadElf(mod: *Module, gpa: Allocator, io: Io) Error!LoadedElf { const load_result = if (mod.name.len > 0) res: { - var file = std.fs.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; + var file = Io.Dir.cwd().openFile(io, mod.name, .{}) catch return error.MissingDebugInfo; defer file.close(io); break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(mod.name)); } else res: { @@ -334,7 +333,7 @@ const Module = struct { else => return error.ReadFailed, }; defer gpa.free(path); - var file = std.fs.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; + var file = Io.Dir.cwd().openFile(io, path, .{}) catch return error.MissingDebugInfo; defer file.close(io); break :res std.debug.ElfFile.load(gpa, file, mod.build_id, &.native(path)); }; diff --git a/lib/std/debug/SelfInfo/MachO.zig b/lib/std/debug/SelfInfo/MachO.zig index 15da616f3b..db8e5334e6 100644 --- a/lib/std/debug/SelfInfo/MachO.zig +++ b/lib/std/debug/SelfInfo/MachO.zig @@ -616,7 +616,7 @@ test { /// Uses `mmap` to map the file at `path` into memory. fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) const u8 { - const file = std.fs.cwd().openFile(io, path, .{}) catch |err| switch (err) { + const file = Io.Dir.cwd().openFile(io, path, .{}) catch |err| switch (err) { error.FileNotFound => return error.MissingDebugInfo, else => return error.ReadFailed, }; diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig index f0ac30cca2..9874efd497 100644 --- a/lib/std/debug/SelfInfo/Windows.zig +++ b/lib/std/debug/SelfInfo/Windows.zig @@ -432,7 +432,7 @@ const Module = struct { break :pdb null; }; const pdb_file_open_result = if (fs.path.isAbsolute(path)) res: { - break :res std.fs.cwd().openFile(io, path, .{}); + break :res Io.Dir.cwd().openFile(io, path, .{}); } else res: { const self_dir = std.process.executableDirPathAlloc(io, gpa) catch |err| switch (err) { error.OutOfMemory, error.Unexpected => |e| return e, @@ -441,7 +441,7 @@ const Module = struct { defer gpa.free(self_dir); const abs_path = try fs.path.join(gpa, &.{ self_dir, path }); defer gpa.free(abs_path); - break :res std.fs.cwd().openFile(io, abs_path, .{}); + break :res Io.Dir.cwd().openFile(io, abs_path, .{}); }; const pdb_file = pdb_file_open_result catch |err| switch (err) { error.FileNotFound, error.IsDir => break :pdb null, diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 7db177ad70..a1801d00d0 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -160,7 +160,7 @@ pub const ElfDynLib = struct { fn openPath(path: []const u8, io: Io) !Io.Dir { if (path.len == 0) return error.NotDir; var parts = std.mem.tokenizeScalar(u8, path, '/'); - var parent = if (path[0] == '/') try std.fs.cwd().openDir("/", .{}) else std.fs.cwd(); + var parent = if (path[0] == '/') try Io.Dir.cwd().openDir("/", .{}) else Io.Dir.cwd(); while (parts.next()) |part| { const child = try parent.openDir(part, .{}); parent.close(io); @@ -174,7 +174,7 @@ pub const ElfDynLib = struct { while (paths.next()) |p| { var dir = openPath(p) catch continue; defer dir.close(io); - const fd = posix.openat(dir.fd, file_name, .{ + const fd = posix.openat(dir.handle, file_name, .{ .ACCMODE = .RDONLY, .CLOEXEC = true, }, 0) catch continue; @@ -184,9 +184,9 @@ pub const ElfDynLib = struct { } fn resolveFromParent(io: Io, dir_path: []const u8, file_name: []const u8) ?posix.fd_t { - var dir = std.fs.cwd().openDir(dir_path, .{}) catch return null; + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch return null; defer dir.close(io); - return posix.openat(dir.fd, file_name, .{ + return posix.openat(dir.handle, file_name, .{ .ACCMODE = .RDONLY, .CLOEXEC = true, }, 0) catch null; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index f4bdecf89d..aab86d40a6 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -46,7 +46,7 @@ const PathType = enum { // The final path may not actually exist which would cause realpath to fail. // So instead, we get the path of the dir and join it with the relative path. var fd_path_buf: [fs.max_path_bytes]u8 = undefined; - const dir_path = try std.os.getFdPath(dir.fd, &fd_path_buf); + const dir_path = try std.os.getFdPath(dir.handle, &fd_path_buf); return fs.path.joinZ(allocator, &.{ dir_path, relative_path }); } }.transform, @@ -55,7 +55,7 @@ const PathType = enum { // Any drive absolute path (C:\foo) can be converted into a UNC path by // using '127.0.0.1' as the server name and '$' as the share name. var fd_path_buf: [fs.max_path_bytes]u8 = undefined; - const dir_path = try std.os.getFdPath(dir.fd, &fd_path_buf); + const dir_path = try std.os.getFdPath(dir.handle, &fd_path_buf); const windows_path_type = windows.getWin32PathType(u8, dir_path); switch (windows_path_type) { .unc_absolute => return fs.path.joinZ(allocator, &.{ dir_path, relative_path }), @@ -256,7 +256,7 @@ fn testReadLinkW(allocator: mem.Allocator, dir: Dir, target_path: []const u8, sy const target_path_w = try std.unicode.wtf8ToWtf16LeAlloc(allocator, target_path); defer allocator.free(target_path_w); // Calling the W functions directly requires the path to be NT-prefixed - const symlink_path_w = try std.os.windows.sliceToPrefixedFileW(dir.fd, symlink_path); + const symlink_path_w = try std.os.windows.sliceToPrefixedFileW(dir.handle, symlink_path); const wtf16_buffer = try allocator.alloc(u16, target_path_w.len); defer allocator.free(wtf16_buffer); const actual = try dir.readLinkW(symlink_path_w.span(), wtf16_buffer); @@ -288,9 +288,11 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { var symlink: Dir = switch (builtin.target.os.tag) { .windows => windows_symlink: { - const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink"); + const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.handle, "symlink"); - var handle: windows.HANDLE = undefined; + var result: Dir = .{ + .handle = undefined, + }; const path_len_bytes = @as(u16, @intCast(sub_path_w.span().len * 2)); var nt_name = windows.UNICODE_STRING{ @@ -300,26 +302,16 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { }; var attr: windows.OBJECT_ATTRIBUTES = .{ .Length = @sizeOf(windows.OBJECT_ATTRIBUTES), - .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.fd, - .Attributes = .{}, + .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.handle, + .Attributes = 0, .ObjectName = &nt_name, .SecurityDescriptor = null, .SecurityQualityOfService = null, }; var io_status_block: windows.IO_STATUS_BLOCK = undefined; const rc = windows.ntdll.NtCreateFile( - &handle, - .{ - .SPECIFIC = .{ .FILE_DIRECTORY = .{ - .READ_EA = true, - .TRAVERSE = true, - .READ_ATTRIBUTES = true, - } }, - .STANDARD = .{ - .RIGHTS = .READ, - .SYNCHRONIZE = true, - }, - }, + &result.handle, + windows.STANDARD_RIGHTS_READ | windows.FILE_READ_ATTRIBUTES | windows.FILE_READ_EA | windows.SYNCHRONIZE | windows.FILE_TRAVERSE, &attr, &io_status_block, null, @@ -337,7 +329,7 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { ); switch (rc) { - .SUCCESS => break :windows_symlink .{ .fd = handle }, + .SUCCESS => break :windows_symlink .{ .fd = result.handle }, else => return windows.unexpectedStatus(rc), } }, @@ -351,8 +343,8 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" { .ACCMODE = .RDONLY, .CLOEXEC = true, }; - const fd = try posix.openatZ(ctx.dir.fd, &sub_path_c, flags, 0); - break :linux_symlink Dir{ .fd = fd }; + const fd = try posix.openatZ(ctx.dir.handle, &sub_path_c, flags, 0); + break :linux_symlink .{ .handle = fd }; }, else => unreachable, }; @@ -456,7 +448,7 @@ test "openDirAbsolute" { test "openDir cwd parent '..'" { const io = testing.io; - var dir = fs.cwd().openDir("..", .{}) catch |err| { + var dir = Io.Dir.cwd().openDir("..", .{}) catch |err| { if (native_os == .wasi and err == error.PermissionDenied) { return; // This is okay. WASI disallows escaping from the fs sandbox } @@ -534,7 +526,7 @@ test "Dir.Iterator" { defer tmp_dir.cleanup(); // First, create a couple of entries to iterate over. - const file = try tmp_dir.dir.createFile("some_file", .{}); + const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); try tmp_dir.dir.makeDir("some_dir"); @@ -570,7 +562,7 @@ test "Dir.Iterator many entries" { var buf: [4]u8 = undefined; // Enough to store "1024". while (i < num) : (i += 1) { const name = try std.fmt.bufPrint(&buf, "{}", .{i}); - const file = try tmp_dir.dir.createFile(name, .{}); + const file = try tmp_dir.dir.createFile(io, name, .{}); file.close(io); } @@ -603,7 +595,7 @@ test "Dir.Iterator twice" { defer tmp_dir.cleanup(); // First, create a couple of entries to iterate over. - const file = try tmp_dir.dir.createFile("some_file", .{}); + const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); try tmp_dir.dir.makeDir("some_dir"); @@ -638,7 +630,7 @@ test "Dir.Iterator reset" { defer tmp_dir.cleanup(); // First, create a couple of entries to iterate over. - const file = try tmp_dir.dir.createFile("some_file", .{}); + const file = try tmp_dir.dir.createFile(io, "some_file", .{}); file.close(io); try tmp_dir.dir.makeDir("some_dir"); @@ -769,7 +761,7 @@ test "readFileAlloc" { var tmp_dir = tmpDir(.{}); defer tmp_dir.cleanup(); - var file = try tmp_dir.dir.createFile("test_file", .{ .read = true }); + var file = try tmp_dir.dir.createFile(io, "test_file", .{ .read = true }); defer file.close(io); const buf1 = try tmp_dir.dir.readFileAlloc("test_file", testing.allocator, .limited(1024)); @@ -843,7 +835,7 @@ test "directory operations on files" { const test_file_name = try ctx.transformPath("test_file"); - var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); + var file = try ctx.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try testing.expectError(error.PathAlreadyExists, ctx.dir.makeDir(test_file_name)); @@ -876,7 +868,7 @@ test "file operations on directories" { try ctx.dir.makeDir(test_dir_name); - try testing.expectError(error.IsDir, ctx.dir.createFile(test_dir_name, .{})); + try testing.expectError(error.IsDir, ctx.dir.createFile(io, test_dir_name, .{})); try testing.expectError(error.IsDir, ctx.dir.deleteFile(test_dir_name)); switch (native_os) { .dragonfly, .netbsd => { @@ -969,7 +961,7 @@ test "Dir.rename files" { // Renaming files const test_file_name = try ctx.transformPath("test_file"); const renamed_test_file_name = try ctx.transformPath("test_file_renamed"); - var file = try ctx.dir.createFile(test_file_name, .{ .read = true }); + var file = try ctx.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try ctx.dir.rename(test_file_name, renamed_test_file_name); @@ -983,7 +975,7 @@ test "Dir.rename files" { // Rename to existing file succeeds const existing_file_path = try ctx.transformPath("existing_file"); - var existing_file = try ctx.dir.createFile(existing_file_path, .{ .read = true }); + var existing_file = try ctx.dir.createFile(io, existing_file_path, .{ .read = true }); existing_file.close(io); try ctx.dir.rename(renamed_test_file_name, existing_file_path); @@ -1017,7 +1009,7 @@ test "Dir.rename directories" { var dir = try ctx.dir.openDir(test_dir_renamed_path, .{}); // Put a file in the directory - var file = try dir.createFile("test_file", .{ .read = true }); + var file = try dir.createFile(io, "test_file", .{ .read = true }); file.close(io); dir.close(io); @@ -1070,7 +1062,7 @@ test "Dir.rename directory onto non-empty dir" { try ctx.dir.makeDir(test_dir_path); var target_dir = try ctx.dir.makeOpenPath(target_dir_path, .{}); - var file = try target_dir.createFile("test_file", .{ .read = true }); + var file = try target_dir.createFile(io, "test_file", .{ .read = true }); file.close(io); target_dir.close(io); @@ -1094,7 +1086,7 @@ test "Dir.rename file <-> dir" { const test_file_path = try ctx.transformPath("test_file"); const test_dir_path = try ctx.transformPath("test_dir"); - var file = try ctx.dir.createFile(test_file_path, .{ .read = true }); + var file = try ctx.dir.createFile(io, test_file_path, .{ .read = true }); file.close(io); try ctx.dir.makeDir(test_dir_path); try testing.expectError(error.IsDir, ctx.dir.rename(test_file_path, test_dir_path)); @@ -1115,7 +1107,7 @@ test "rename" { // Renaming files const test_file_name = "test_file"; const renamed_test_file_name = "test_file_renamed"; - var file = try tmp_dir1.dir.createFile(test_file_name, .{ .read = true }); + var file = try tmp_dir1.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try fs.rename(tmp_dir1.dir, test_file_name, tmp_dir2.dir, renamed_test_file_name); @@ -1149,7 +1141,7 @@ test "renameAbsolute" { // Renaming files const test_file_name = "test_file"; const renamed_test_file_name = "test_file_renamed"; - var file = try tmp_dir.dir.createFile(test_file_name, .{ .read = true }); + var file = try tmp_dir.dir.createFile(io, test_file_name, .{ .read = true }); file.close(io); try fs.renameAbsolute( try fs.path.join(allocator, &.{ base_path, test_file_name }), @@ -1454,7 +1446,7 @@ test "writev, readv" { var write_vecs: [2][]const u8 = .{ line1, line2 }; var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; - var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); + var src_file = try tmp.dir.createFile(io, "test.txt", .{ .read = true }); defer src_file.close(io); var writer = src_file.writerStreaming(&.{}); @@ -1484,7 +1476,7 @@ test "pwritev, preadv" { var buf2: [line2.len]u8 = undefined; var read_vecs: [2][]u8 = .{ &buf2, &buf1 }; - var src_file = try tmp.dir.createFile("test.txt", .{ .read = true }); + var src_file = try tmp.dir.createFile(io, "test.txt", .{ .read = true }); defer src_file.close(io); var writer = src_file.writer(&.{}); @@ -1584,14 +1576,14 @@ test "sendfile" { const line2 = "second line\n"; var vecs = [_][]const u8{ line1, line2 }; - var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); + var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true }); defer src_file.close(io); { var fw = src_file.writer(&.{}); try fw.interface.writeVecAll(&vecs); } - var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); + var dest_file = try dir.createFile(io, "sendfile2.txt", .{ .read = true }); defer dest_file.close(io); const header1 = "header1\n"; @@ -1627,12 +1619,12 @@ test "sendfile with buffered data" { var dir = try tmp.dir.openDir("os_test_tmp", .{}); defer dir.close(io); - var src_file = try dir.createFile("sendfile1.txt", .{ .read = true }); + var src_file = try dir.createFile(io, "sendfile1.txt", .{ .read = true }); defer src_file.close(io); try src_file.writeAll("AAAABBBB"); - var dest_file = try dir.createFile("sendfile2.txt", .{ .read = true }); + var dest_file = try dir.createFile(io, "sendfile2.txt", .{ .read = true }); defer dest_file.close(io); var src_buffer: [32]u8 = undefined; @@ -1718,10 +1710,10 @@ test "open file with exclusive nonblocking lock twice" { const io = ctx.io; const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); - const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file1 = try ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); defer file1.close(io); - const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file2 = ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } }.impl); @@ -1735,10 +1727,10 @@ test "open file with shared and exclusive nonblocking lock" { const io = ctx.io; const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); - const file1 = try ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); + const file1 = try ctx.dir.createFile(io, filename, .{ .lock = .shared, .lock_nonblocking = true }); defer file1.close(io); - const file2 = ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file2 = ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } }.impl); @@ -1752,10 +1744,10 @@ test "open file with exclusive and shared nonblocking lock" { const io = ctx.io; const filename = try ctx.transformPath("file_nonblocking_lock_test.txt"); - const file1 = try ctx.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); + const file1 = try ctx.dir.createFile(io, filename, .{ .lock = .exclusive, .lock_nonblocking = true }); defer file1.close(io); - const file2 = ctx.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); + const file2 = ctx.dir.createFile(io, filename, .{ .lock = .shared, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } }.impl); @@ -1769,13 +1761,13 @@ test "open file with exclusive lock twice, make sure second lock waits" { const io = ctx.io; const filename = try ctx.transformPath("file_lock_test.txt"); - const file = try ctx.dir.createFile(filename, .{ .lock = .exclusive }); + const file = try ctx.dir.createFile(io, filename, .{ .lock = .exclusive }); errdefer file.close(io); const S = struct { fn checkFn(dir: *Io.Dir, path: []const u8, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { started.set(); - const file1 = try dir.createFile(path, .{ .lock = .exclusive }); + const file1 = try dir.createFile(io, path, .{ .lock = .exclusive }); locked.set(); file1.close(io); @@ -1847,13 +1839,13 @@ test "read from locked file" { const filename = try ctx.transformPath("read_lock_file_test.txt"); { - const f = try ctx.dir.createFile(filename, .{ .read = true }); + const f = try ctx.dir.createFile(io, filename, .{ .read = true }); defer f.close(io); var buffer: [1]u8 = undefined; _ = try f.read(&buffer); } { - const f = try ctx.dir.createFile(filename, .{ + const f = try ctx.dir.createFile(io, filename, .{ .read = true, .lock = .exclusive, }); @@ -2037,7 +2029,7 @@ test "'.' and '..' in Io.Dir functions" { var created_subdir = try ctx.dir.openDir(subdir_path, .{}); created_subdir.close(io); - const created_file = try ctx.dir.createFile(file_path, .{}); + const created_file = try ctx.dir.createFile(io, file_path, .{}); created_file.close(io); try ctx.dir.access(file_path, .{}); @@ -2103,7 +2095,7 @@ test "chmod" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file = try tmp.dir.createFile("test_file", .{ .mode = 0o600 }); + const file = try tmp.dir.createFile(io, "test_file", .{ .mode = 0o600 }); defer file.close(io); try testing.expectEqual(@as(File.Mode, 0o600), (try file.stat()).mode & 0o7777); @@ -2127,7 +2119,7 @@ test "chown" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file = try tmp.dir.createFile("test_file", .{}); + const file = try tmp.dir.createFile(io, "test_file", .{}); defer file.close(io); try file.chown(null, null); @@ -2228,7 +2220,7 @@ test "read file non vectored" { const contents = "hello, world!\n"; - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); { var file_writer: File.Writer = .init(file, &.{}); @@ -2260,7 +2252,7 @@ test "seek keeping partial buffer" { const contents = "0123456789"; - const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); + const file = try tmp_dir.dir.createFile(io, "input.txt", .{ .read = true }); defer file.close(io); { var file_writer: File.Writer = .init(file, &.{}); @@ -2321,7 +2313,7 @@ test "seekTo flushes buffered data" { const contents = "data"; - const file = try tmp.dir.createFile("seek.bin", .{ .read = true }); + const file = try tmp.dir.createFile(io, "seek.bin", .{ .read = true }); defer file.close(io); { var buf: [16]u8 = undefined; @@ -2350,7 +2342,7 @@ test "File.Writer sendfile with buffered contents" { try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" }); const in = try tmp_dir.dir.openFile(io, "a", .{}); defer in.close(io); - const out = try tmp_dir.dir.createFile("b", .{}); + const out = try tmp_dir.dir.createFile(io, "b", .{}); defer out.close(io); var in_buf: [2]u8 = undefined; @@ -2397,7 +2389,7 @@ test "readlinkat" { // create a symbolic link if (native_os == .windows) { std.os.windows.CreateSymbolicLink( - tmp.dir.fd, + tmp.dir.handle, &[_]u16{ 'l', 'i', 'n', 'k' }, &[_:0]u16{ 'f', 'i', 'l', 'e', '.', 't', 'x', 't' }, false, @@ -2407,7 +2399,7 @@ test "readlinkat" { else => return err, }; } else { - try posix.symlinkat("file.txt", tmp.dir.fd, "link"); + try posix.symlinkat("file.txt", tmp.dir.handle, "link"); } // read the link diff --git a/lib/std/os/linux/IoUring.zig b/lib/std/os/linux/IoUring.zig index c7d3f35d40..0972a302da 100644 --- a/lib/std/os/linux/IoUring.zig +++ b/lib/std/os/linux/IoUring.zig @@ -1991,7 +1991,7 @@ test "writev/fsync/readv" { defer tmp.cleanup(); const path = "test_io_uring_writev_fsync_readv"; - const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); + const file = try tmp.dir.createFile(io, path, .{ .read = true, .truncate = true }); defer file.close(io); const fd = file.handle; @@ -2062,7 +2062,7 @@ test "write/read" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); const path = "test_io_uring_write_read"; - const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); + const file = try tmp.dir.createFile(io, path, .{ .read = true, .truncate = true }); defer file.close(io); const fd = file.handle; @@ -2110,12 +2110,12 @@ test "splice/read" { var tmp = std.testing.tmpDir(.{}); const path_src = "test_io_uring_splice_src"; - const file_src = try tmp.dir.createFile(path_src, .{ .read = true, .truncate = true }); + const file_src = try tmp.dir.createFile(io, path_src, .{ .read = true, .truncate = true }); defer file_src.close(io); const fd_src = file_src.handle; const path_dst = "test_io_uring_splice_dst"; - const file_dst = try tmp.dir.createFile(path_dst, .{ .read = true, .truncate = true }); + const file_dst = try tmp.dir.createFile(io, path_dst, .{ .read = true, .truncate = true }); defer file_dst.close(io); const fd_dst = file_dst.handle; @@ -2185,7 +2185,7 @@ test "write_fixed/read_fixed" { defer tmp.cleanup(); const path = "test_io_uring_write_read_fixed"; - const file = try tmp.dir.createFile(path, .{ .read = true, .truncate = true }); + const file = try tmp.dir.createFile(io, path, .{ .read = true, .truncate = true }); defer file.close(io); const fd = file.handle; @@ -2306,7 +2306,7 @@ test "close" { defer tmp.cleanup(); const path = "test_io_uring_close"; - const file = try tmp.dir.createFile(path, .{}); + const file = try tmp.dir.createFile(io, path, .{}); errdefer file.close(io); const sqe_close = try ring.close(0x44444444, file.handle); @@ -2652,7 +2652,7 @@ test "fallocate" { defer tmp.cleanup(); const path = "test_io_uring_fallocate"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); try testing.expectEqual(@as(u64, 0), (try file.stat()).size); @@ -2699,7 +2699,7 @@ test "statx" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); const path = "test_io_uring_statx"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); try testing.expectEqual(@as(u64, 0), (try file.stat()).size); @@ -2969,7 +2969,7 @@ test "renameat" { // Write old file with data - const old_file = try tmp.dir.createFile(old_path, .{ .truncate = true, .mode = 0o666 }); + const old_file = try tmp.dir.createFile(io, old_path, .{ .truncate = true, .mode = 0o666 }); defer old_file.close(io); try old_file.writeAll("hello"); @@ -3028,7 +3028,7 @@ test "unlinkat" { // Write old file with data - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); // Submit unlinkat @@ -3125,7 +3125,7 @@ test "symlinkat" { const path = "test_io_uring_symlinkat"; const link_path = "test_io_uring_symlinkat_link"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); // Submit symlinkat @@ -3177,7 +3177,7 @@ test "linkat" { // Write file with data - const first_file = try tmp.dir.createFile(first_path, .{ .truncate = true, .mode = 0o666 }); + const first_file = try tmp.dir.createFile(io, first_path, .{ .truncate = true, .mode = 0o666 }); defer first_file.close(io); try first_file.writeAll("hello"); diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index 39606ddfac..d7cfb4e138 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -18,7 +18,7 @@ test "fallocate" { defer tmp.cleanup(); const path = "test_fallocate"; - const file = try tmp.dir.createFile(path, .{ .truncate = true, .mode = 0o666 }); + const file = try tmp.dir.createFile(io, path, .{ .truncate = true, .mode = 0o666 }); defer file.close(io); try expect((try file.stat()).size == 0); @@ -85,7 +85,7 @@ test "statx" { defer tmp.cleanup(); const tmp_file_name = "just_a_temporary_file.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); var buf: linux.Statx = undefined; @@ -121,7 +121,7 @@ test "fadvise" { defer tmp.cleanup(); const tmp_file_name = "temp_posix_fadvise.txt"; - var file = try tmp.dir.createFile(tmp_file_name, .{}); + var file = try tmp.dir.createFile(io, tmp_file_name, .{}); defer file.close(io); var buf: [2048]u8 = undefined; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 6b5b678b20..ba5282256f 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -4639,8 +4639,8 @@ pub fn wToPrefixedFileW(dir: ?HANDLE, path: [:0]const u16) Wtf16ToPrefixedFileWE break :path_to_get path; } // We can also skip GetFinalPathNameByHandle if the handle matches - // the handle returned by fs.cwd() - if (dir.? == std.fs.cwd().fd) { + // the handle returned by Io.Dir.cwd() + if (dir.? == Io.Dir.cwd().fd) { break :path_to_get path; } // At this point, we know we have a relative path that had too many diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 392987ec50..f4aa970413 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -15,15 +15,16 @@ //! deal with the exception. const builtin = @import("builtin"); -const root = @import("root"); +const native_os = builtin.os.tag; + const std = @import("std.zig"); +const Io = std.Io; const mem = std.mem; const fs = std.fs; -const max_path_bytes = fs.max_path_bytes; +const max_path_bytes = std.fs.max_path_bytes; const maxInt = std.math.maxInt; const cast = std.math.cast; const assert = std.debug.assert; -const native_os = builtin.os.tag; const page_size_min = std.heap.page_size_min; test { @@ -797,7 +798,6 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { .INTR => continue, .INVAL => unreachable, .FAULT => unreachable, - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .CANCELED => return error.Canceled, .BADF => return error.NotOpenForReading, // Can be a race condition. @@ -917,7 +917,6 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { .INTR => continue, .INVAL => return error.InvalidArgument, .FAULT => unreachable, - .SRCH => return error.ProcessNotFound, .AGAIN => return error.WouldBlock, .BADF => return error.NotOpenForWriting, // can be a race condition. .DESTADDRREQ => unreachable, // `connect` was never called. @@ -985,7 +984,8 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t { .NFILE => return error.SystemFdQuotaExceeded, .NODEV => return error.NoDevice, .NOENT => return error.FileNotFound, - .SRCH => return error.ProcessNotFound, + // Can happen on Linux when opening procfs files. + .SRCH => return error.FileNotFound, .NOMEM => return error.SystemResources, .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, @@ -1560,7 +1560,7 @@ pub fn mkdirZ(dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void { pub fn mkdirW(dir_path_w: []const u16, mode: mode_t) MakeDirError!void { _ = mode; const sub_dir_handle = windows.OpenFile(dir_path_w, .{ - .dir = fs.cwd().fd, + .dir = Io.Dir.cwd().handle, .access_mask = .{ .STANDARD = .{ .SYNCHRONIZE = true }, .GENERIC = .{ .READ = true }, diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index 0071a72a26..dc63be6e14 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -148,7 +148,7 @@ test "linkat with different directories" { try tmp.dir.writeFile(.{ .sub_path = target_name, .data = "example" }); // Test 1: link from file in subdir back up to target in parent directory - try posix.linkat(tmp.dir.fd, target_name, subdir.fd, link_name, 0); + try posix.linkat(tmp.dir.handle, target_name, subdir.handle, link_name, 0); const efd = try tmp.dir.openFile(io, target_name, .{}); defer efd.close(io); @@ -164,7 +164,7 @@ test "linkat with different directories" { } // Test 2: remove link - try posix.unlinkat(subdir.fd, link_name, 0); + try posix.unlinkat(subdir.handle, link_name, 0); _, const elink = try getLinkInfo(efd.handle); try testing.expectEqual(@as(posix.nlink_t, 1), elink); } @@ -373,7 +373,7 @@ test "mmap" { // Create a file used for testing mmap() calls with a file descriptor { - const file = try tmp.dir.createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); var stream = file.writer(&.{}); @@ -444,7 +444,7 @@ test "fcntl" { const test_out_file = "os_tmp_test"; - const file = try tmp.dir.createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); // Note: The test assumes createFile opens the file with CLOEXEC @@ -495,7 +495,7 @@ test "fsync" { defer tmp.cleanup(); const test_out_file = "os_tmp_test"; - const file = try tmp.dir.createFile(test_out_file, .{}); + const file = try tmp.dir.createFile(io, test_out_file, .{}); defer file.close(io); try posix.fsync(file.handle); @@ -617,7 +617,7 @@ test "dup & dup2" { defer tmp.cleanup(); { - var file = try tmp.dir.createFile("os_dup_test", .{}); + var file = try tmp.dir.createFile(io, "os_dup_test", .{}); defer file.close(io); var duped = Io.File{ .handle = try posix.dup(file.handle) }; @@ -659,7 +659,7 @@ test "writev longer than IOV_MAX" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("pwritev", .{}); + var file = try tmp.dir.createFile(io, "pwritev", .{}); defer file.close(io); const iovecs = [_]posix.iovec_const{.{ .base = "a", .len = 1 }} ** (posix.IOV_MAX + 1); @@ -684,7 +684,7 @@ test "POSIX file locking with fcntl" { defer tmp.cleanup(); // Create a temporary lock file - var file = try tmp.dir.createFile("lock", .{ .read = true }); + var file = try tmp.dir.createFile(io, "lock", .{ .read = true }); defer file.close(io); try file.setEndPos(2); const fd = file.handle; @@ -881,7 +881,7 @@ test "isatty" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("foo", .{}); + var file = try tmp.dir.createFile(io, "foo", .{}); defer file.close(io); try expectEqual(posix.isatty(file.handle), false); @@ -893,7 +893,7 @@ test "pread with empty buffer" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("pread_empty", .{ .read = true }); + var file = try tmp.dir.createFile(io, "pread_empty", .{ .read = true }); defer file.close(io); const bytes = try a.alloc(u8, 0); @@ -909,7 +909,7 @@ test "write with empty buffer" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("write_empty", .{}); + var file = try tmp.dir.createFile(io, "write_empty", .{}); defer file.close(io); const bytes = try a.alloc(u8, 0); @@ -925,7 +925,7 @@ test "pwrite with empty buffer" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - var file = try tmp.dir.createFile("pwrite_empty", .{}); + var file = try tmp.dir.createFile(io, "pwrite_empty", .{}); defer file.close(io); const bytes = try a.alloc(u8, 0); @@ -965,35 +965,35 @@ test "fchmodat smoke test" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - try expectError(error.FileNotFound, posix.fchmodat(tmp.dir.fd, "regfile", 0o666, 0)); + try expectError(error.FileNotFound, posix.fchmodat(tmp.dir.handle, "regfile", 0o666, 0)); const fd = try posix.openat( - tmp.dir.fd, + tmp.dir.handle, "regfile", .{ .ACCMODE = .WRONLY, .CREAT = true, .EXCL = true, .TRUNC = true }, 0o644, ); posix.close(fd); - try posix.symlinkat("regfile", tmp.dir.fd, "symlink"); - const sym_mode = try getFileMode(tmp.dir.fd, "symlink"); + try posix.symlinkat("regfile", tmp.dir.handle, "symlink"); + const sym_mode = try getFileMode(tmp.dir.handle, "symlink"); - try posix.fchmodat(tmp.dir.fd, "regfile", 0o640, 0); - try expectMode(tmp.dir.fd, "regfile", 0o640); - try posix.fchmodat(tmp.dir.fd, "regfile", 0o600, posix.AT.SYMLINK_NOFOLLOW); - try expectMode(tmp.dir.fd, "regfile", 0o600); + try posix.fchmodat(tmp.dir.handle, "regfile", 0o640, 0); + try expectMode(tmp.dir.handle, "regfile", 0o640); + try posix.fchmodat(tmp.dir.handle, "regfile", 0o600, posix.AT.SYMLINK_NOFOLLOW); + try expectMode(tmp.dir.handle, "regfile", 0o600); - try posix.fchmodat(tmp.dir.fd, "symlink", 0o640, 0); - try expectMode(tmp.dir.fd, "regfile", 0o640); - try expectMode(tmp.dir.fd, "symlink", sym_mode); + try posix.fchmodat(tmp.dir.handle, "symlink", 0o640, 0); + try expectMode(tmp.dir.handle, "regfile", 0o640); + try expectMode(tmp.dir.handle, "symlink", sym_mode); var test_link = true; - posix.fchmodat(tmp.dir.fd, "symlink", 0o600, posix.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) { + posix.fchmodat(tmp.dir.handle, "symlink", 0o600, posix.AT.SYMLINK_NOFOLLOW) catch |err| switch (err) { error.OperationNotSupported => test_link = false, else => |e| return e, }; if (test_link) - try expectMode(tmp.dir.fd, "symlink", 0o600); - try expectMode(tmp.dir.fd, "regfile", 0o640); + try expectMode(tmp.dir.handle, "symlink", 0o600); + try expectMode(tmp.dir.handle, "regfile", 0o640); } const CommonOpenFlags = packed struct { diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index b774303901..33faeef061 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -677,7 +677,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void { setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err); if (self.cwd_dir) |cwd| { - posix.fchdir(cwd.fd) catch |err| forkChildErrReport(err_pipe[1], err); + posix.fchdir(cwd.handle) catch |err| forkChildErrReport(err_pipe[1], err); } else if (self.cwd) |cwd| { posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err); } diff --git a/lib/std/std.zig b/lib/std/std.zig index 106811859b..1690c0575c 100644 --- a/lib/std/std.zig +++ b/lib/std/std.zig @@ -114,7 +114,7 @@ pub const options: Options = if (@hasDecl(root, "std_options")) root.std_options pub const Options = struct { enable_segfault_handler: bool = debug.default_enable_segfault_handler, - /// Function used to implement `std.fs.cwd` for WASI. + /// Function used to implement `std.Io.Dir.cwd` for WASI. wasiCwd: fn () os.wasi.fd_t = os.defaultWasiCwd, /// The current log level. diff --git a/lib/std/tar.zig b/lib/std/tar.zig index d861314fec..8a0bbb342f 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -610,7 +610,7 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp } }, .file => { - if (createDirAndFile(dir, file_name, fileMode(file.mode, options))) |fs_file| { + if (createDirAndFile(io, dir, file_name, fileMode(file.mode, options))) |fs_file| { defer fs_file.close(io); var file_writer = fs_file.writer(&file_contents_buffer); try it.streamRemaining(file, &file_writer.interface); @@ -638,12 +638,12 @@ pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOp } } -fn createDirAndFile(dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { - const fs_file = dir.createFile(file_name, .{ .exclusive = true, .mode = mode }) catch |err| { +fn createDirAndFile(io: Io, dir: Io.Dir, file_name: []const u8, mode: Io.File.Mode) !Io.File { + const fs_file = dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }) catch |err| { if (err == error.FileNotFound) { if (std.fs.path.dirname(file_name)) |dir_name| { try dir.makePath(dir_name); - return try dir.createFile(file_name, .{ .exclusive = true, .mode = mode }); + return try dir.createFile(io, file_name, .{ .exclusive = true, .mode = mode }); } } return err; @@ -880,9 +880,9 @@ test "create file and symlink" { var root = testing.tmpDir(.{}); defer root.cleanup(); - var file = try createDirAndFile(root.dir, "file1", default_mode); + var file = try createDirAndFile(io, root.dir, "file1", default_mode); file.close(io); - file = try createDirAndFile(root.dir, "a/b/c/file2", default_mode); + file = try createDirAndFile(io, root.dir, "a/b/c/file2", default_mode); file.close(io); createDirAndSymlink(root.dir, "a/b/c/file2", "symlink1") catch |err| { @@ -894,7 +894,7 @@ test "create file and symlink" { // Danglink symlnik, file created later try createDirAndSymlink(root.dir, "../../../g/h/i/file4", "j/k/l/symlink3"); - file = try createDirAndFile(root.dir, "g/h/i/file4", default_mode); + file = try createDirAndFile(io, root.dir, "g/h/i/file4", default_mode); file.close(io); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 19038543a6..99d67ec132 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -628,7 +628,7 @@ pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir { var sub_path: [TmpDir.sub_path_len]u8 = undefined; _ = std.fs.base64_encoder.encode(&sub_path, &random_bytes); - const cwd = std.fs.cwd(); + const cwd = Io.Dir.cwd(); var cache_dir = cwd.makeOpenPath(".zig-cache", .{}) catch @panic("unable to make tmp dir for testing: unable to make and open .zig-cache dir"); defer cache_dir.close(io); diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index c8bde2ab02..80317850df 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -57,7 +57,7 @@ pub fn parse( } } - const contents = try std.fs.cwd().readFileAlloc(libc_file, allocator, .limited(std.math.maxInt(usize))); + const contents = try Io.Dir.cwd().readFileAlloc(libc_file, allocator, .limited(std.math.maxInt(usize))); defer allocator.free(contents); var it = std.mem.tokenizeScalar(u8, contents, '\n'); @@ -337,7 +337,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F // search in reverse order const search_path_untrimmed = search_paths.items[search_paths.items.len - path_i - 1]; const search_path = std.mem.trimStart(u8, search_path_untrimmed, " "); - var search_dir = fs.cwd().openDir(search_path, .{}) catch |err| switch (err) { + var search_dir = Io.Dir.cwd().openDir(search_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -392,7 +392,7 @@ fn findNativeIncludeDirWindows( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); - var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -440,7 +440,7 @@ fn findNativeCrtDirWindows( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); - var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -508,7 +508,7 @@ fn findNativeKernel32LibDir( result_buf.shrinkAndFree(0); try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); - var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, @@ -544,7 +544,7 @@ fn findNativeMsvcIncludeDir( const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" }); errdefer allocator.free(dir_path); - var dir = fs.cwd().openDir(dir_path, .{}) catch |err| switch (err) { + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.NoDevice, diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig index 6b6e4fa9f7..dca474020a 100644 --- a/lib/std/zig/WindowsSdk.zig +++ b/lib/std/zig/WindowsSdk.zig @@ -828,7 +828,7 @@ const MsvcLibDir = struct { try lib_dir_buf.appendSlice("VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"); var default_tools_version_buf: [512]u8 = undefined; - const default_tools_version_contents = std.fs.cwd().readFile(lib_dir_buf.items, &default_tools_version_buf) catch { + const default_tools_version_contents = Io.Dir.cwd().readFile(lib_dir_buf.items, &default_tools_version_buf) catch { return error.PathNotFound; }; var tokenizer = std.mem.tokenizeAny(u8, default_tools_version_contents, " \r\n"); diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index d3bafc16f2..9fa0546c3b 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -1,11 +1,12 @@ const builtin = @import("builtin"); +const native_endian = builtin.cpu.arch.endian(); + const std = @import("../std.zig"); const mem = std.mem; const elf = std.elf; const fs = std.fs; const assert = std.debug.assert; const Target = std.Target; -const native_endian = builtin.cpu.arch.endian(); const posix = std.posix; const Io = std.Io; @@ -69,7 +70,7 @@ pub fn getExternalExecutor( if (os_match and cpu_ok) native: { if (options.link_libc) { if (candidate.dynamic_linker.get()) |candidate_dl| { - fs.cwd().access(candidate_dl, .{}) catch { + Io.Dir.cwd().access(candidate_dl, .{}) catch { bad_result = .{ .bad_dl = candidate_dl }; break :native; }; @@ -710,6 +711,7 @@ fn abiAndDynamicLinkerFromFile( error.SystemResources, error.FileSystem, error.SymLinkLoop, + error.Canceled, error.Unexpected, => |e| return e, }; diff --git a/lib/std/zig/system/darwin/macos.zig b/lib/std/zig/system/darwin/macos.zig index 9bb4e34e3b..4ff6846a09 100644 --- a/lib/std/zig/system/darwin/macos.zig +++ b/lib/std/zig/system/darwin/macos.zig @@ -1,9 +1,10 @@ -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const mem = std.mem; const testing = std.testing; - const Target = std.Target; /// Detect macOS version. @@ -54,7 +55,7 @@ pub fn detect(target_os: *Target.Os) !void { // approx. 4 times historical file size var buf: [2048]u8 = undefined; - if (std.fs.cwd().readFile(path, &buf)) |bytes| { + if (Io.Dir.cwd().readFile(path, &buf)) |bytes| { if (parseSystemVersion(bytes)) |ver| { // never return non-canonical `10.(16+)` if (!(ver.major == 10 and ver.minor >= 16)) { diff --git a/lib/std/zip.zig b/lib/std/zip.zig index 0ca77c98a1..9d08847092 100644 --- a/lib/std/zip.zig +++ b/lib/std/zip.zig @@ -564,9 +564,9 @@ pub const Iterator = struct { defer parent_dir.close(io); const basename = std.fs.path.basename(filename); - break :blk try parent_dir.createFile(basename, .{ .exclusive = true }); + break :blk try parent_dir.createFile(io, basename, .{ .exclusive = true }); } - break :blk try dest.createFile(filename, .{ .exclusive = true }); + break :blk try dest.createFile(io, filename, .{ .exclusive = true }); }; defer out_file.close(io); var out_file_buffer: [1024]u8 = undefined; diff --git a/src/Compilation.zig b/src/Compilation.zig index 24b994f608..5f15ef5f74 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -450,7 +450,7 @@ pub const Path = struct { const dir = switch (p.root) { .none => { const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); - return .{ fs.cwd(), cwd_sub_path }; + return .{ Io.Dir.cwd(), cwd_sub_path }; }, .zig_lib => dirs.zig_lib.handle, .global_cache => dirs.global_cache.handle, @@ -723,7 +723,7 @@ pub const Directories = struct { pub fn deinit(dirs: *Directories, io: Io) void { // The local and global caches could be the same. - const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; + const close_local = dirs.local_cache.handle.handle != dirs.global_cache.handle.handle; dirs.global_cache.handle.close(io); if (close_local) dirs.local_cache.handle.close(io); @@ -814,7 +814,7 @@ pub const Directories = struct { return .{ .path = if (std.mem.eql(u8, name, ".")) null else name, .handle = .{ - .fd = preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), + .handle = preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), }, }; } @@ -824,8 +824,8 @@ pub const Directories = struct { }; const nonempty_path = if (path.len == 0) "." else path; const handle_or_err = switch (thing) { - .@"zig lib" => fs.cwd().openDir(nonempty_path, .{}), - .@"global cache", .@"local cache" => fs.cwd().makeOpenPath(nonempty_path, .{}), + .@"zig lib" => Io.Dir.cwd().openDir(nonempty_path, .{}), + .@"global cache", .@"local cache" => Io.Dir.cwd().makeOpenPath(nonempty_path, .{}), }; return .{ .path = if (path.len == 0) null else path, @@ -1104,7 +1104,7 @@ pub const CObject = struct { const source_line = source_line: { if (diag.src_loc.offset == 0 or diag.src_loc.column == 0) break :source_line 0; - const file = fs.cwd().openFile(io, file_name, .{}) catch break :source_line 0; + const file = Io.Dir.cwd().openFile(io, file_name, .{}) catch break :source_line 0; defer file.close(io); var buffer: [1024]u8 = undefined; var file_reader = file.reader(io, &buffer); @@ -1179,7 +1179,7 @@ pub const CObject = struct { }; var buffer: [1024]u8 = undefined; - const file = try fs.cwd().openFile(io, path, .{}); + const file = try Io.Dir.cwd().openFile(io, path, .{}); defer file.close(io); var file_reader = file.reader(io, &buffer); var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); @@ -2109,7 +2109,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, }, }; // These correspond to std.zig.Server.Message.PathPrefix. - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(options.dirs.zig_lib); cache.addPrefix(options.dirs.local_cache); cache.addPrefix(options.dirs.global_cache); @@ -5220,7 +5220,7 @@ fn createDepFile( binfile: Cache.Path, ) anyerror!void { var buf: [4096]u8 = undefined; - var af = try std.fs.cwd().atomicFile(depfile, .{ .write_buffer = &buf }); + var af = try Io.Dir.cwd().atomicFile(depfile, .{ .write_buffer = &buf }); defer af.deinit(); comp.writeDepFile(binfile, &af.file_writer.interface) catch return af.file_writer.err.?; @@ -5284,7 +5284,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { }; } - var tar_file = out_dir.createFile("sources.tar", .{}) catch |err| { + var tar_file = out_dir.createFile(io, "sources.tar", .{}) catch |err| { return comp.lockAndSetMiscFailure( .docs_copy, "unable to create '{f}/sources.tar': {s}", diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 3bd05120ff..8a30529bc5 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -383,14 +383,14 @@ pub fn run(f: *Fetch) RunError!void { }, .remote => |remote| remote, .path_or_url => |path_or_url| { - if (fs.cwd().openDir(path_or_url, .{ .iterate = true })) |dir| { + if (Io.Dir.cwd().openDir(path_or_url, .{ .iterate = true })) |dir| { var resource: Resource = .{ .dir = dir }; return f.runResource(path_or_url, &resource, null); } else |dir_err| { var server_header_buffer: [init_resource_buffer_size]u8 = undefined; const file_err = if (dir_err == error.NotDir) e: { - if (fs.cwd().openFile(io, path_or_url, .{})) |file| { + if (Io.Dir.cwd().openFile(io, path_or_url, .{})) |file| { var resource: Resource = .{ .file = file.reader(io, &server_header_buffer) }; return f.runResource(path_or_url, &resource, null); } else |err| break :e err; @@ -1303,7 +1303,7 @@ fn unzip( const random_integer = std.crypto.random.int(u64); zip_path[prefix.len..][0..random_len].* = std.fmt.hex(random_integer); - break cache_root.handle.createFile(&zip_path, .{ + break cache_root.handle.createFile(io, &zip_path, .{ .exclusive = true, .read = true, }) catch |err| switch (err) { @@ -1365,7 +1365,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U { var pack_dir = try out_dir.makeOpenPath(".git", .{}); defer pack_dir.close(io); - var pack_file = try pack_dir.createFile("pkg.pack", .{ .read = true }); + var pack_file = try pack_dir.createFile(io, "pkg.pack", .{ .read = true }); defer pack_file.close(io); var pack_file_buffer: [4096]u8 = undefined; var pack_file_reader = b: { @@ -1376,7 +1376,7 @@ fn unpackGitPack(f: *Fetch, out_dir: Io.Dir, resource: *Resource.Git) anyerror!U break :b pack_file_writer.moveToReader(io); }; - var index_file = try pack_dir.createFile("pkg.idx", .{ .read = true }); + var index_file = try pack_dir.createFile(io, "pkg.idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [2000]u8 = undefined; var index_file_writer = index_file.writer(&index_file_buffer); @@ -2235,7 +2235,7 @@ test "set executable bit based on file content" { fn saveEmbedFile(io: Io, comptime tarball_name: []const u8, dir: Io.Dir) !void { //const tarball_name = "duplicate_paths_excluded.tar.gz"; const tarball_content = @embedFile("Fetch/testdata/" ++ tarball_name); - var tmp_file = try dir.createFile(tarball_name, .{}); + var tmp_file = try dir.createFile(io, tarball_name, .{}); defer tmp_file.close(io); try tmp_file.writeAll(tarball_content); } diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index ccae9440e2..7b08a89cae 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -264,7 +264,7 @@ pub const Repository = struct { try repository.odb.seekOid(entry.oid); const file_object = try repository.odb.readObject(); if (file_object.type != .blob) return error.InvalidFile; - var file = dir.createFile(entry.name, .{ .exclusive = true }) catch |e| { + var file = dir.createFile(io, entry.name, .{ .exclusive = true }) catch |e| { const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name }); errdefer diagnostics.allocator.free(file_name); try diagnostics.errors.append(diagnostics.allocator, .{ .unable_to_create_file = .{ @@ -1584,14 +1584,14 @@ fn runRepositoryTest(io: Io, comptime format: Oid.Format, head_commit: []const u var git_dir = testing.tmpDir(.{}); defer git_dir.cleanup(); - var pack_file = try git_dir.dir.createFile("testrepo.pack", .{ .read = true }); + var pack_file = try git_dir.dir.createFile(io, "testrepo.pack", .{ .read = true }); defer pack_file.close(io); try pack_file.writeAll(testrepo_pack); var pack_file_buffer: [2000]u8 = undefined; var pack_file_reader = pack_file.reader(io, &pack_file_buffer); - var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); + var index_file = try git_dir.dir.createFile(io, "testrepo.idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [2000]u8 = undefined; var index_file_writer = index_file.writer(&index_file_buffer); @@ -1714,20 +1714,20 @@ pub fn main() !void { const format = std.meta.stringToEnum(Oid.Format, args[1]) orelse return error.InvalidFormat; - var pack_file = try std.fs.cwd().openFile(io, args[2], .{}); + var pack_file = try Io.Dir.cwd().openFile(io, args[2], .{}); defer pack_file.close(io); var pack_file_buffer: [4096]u8 = undefined; var pack_file_reader = pack_file.reader(io, &pack_file_buffer); const commit = try Oid.parse(format, args[3]); - var worktree = try std.fs.cwd().makeOpenPath(args[4], .{}); + var worktree = try Io.Dir.cwd().makeOpenPath(args[4], .{}); defer worktree.close(io); var git_dir = try worktree.makeOpenPath(".git", .{}); defer git_dir.close(io); std.debug.print("Starting index...\n", .{}); - var index_file = try git_dir.createFile("idx", .{ .read = true }); + var index_file = try git_dir.createFile(io, "idx", .{ .read = true }); defer index_file.close(io); var index_file_buffer: [4096]u8 = undefined; var index_file_writer = index_file.writer(&index_file_buffer); diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 45b1302138..9a75b2096e 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -170,7 +170,7 @@ pub fn updateFile( // version. Likewise if we're working on AstGen and another process asks for // the cached file, they'll get it. const cache_file = while (true) { - break zir_dir.createFile(&hex_digest, .{ + break zir_dir.createFile(io, &hex_digest, .{ .read = true, .truncate = false, .lock = lock, @@ -196,7 +196,7 @@ pub fn updateFile( cache_directory, }); } - break zir_dir.createFile(&hex_digest, .{ + break zir_dir.createFile(io, &hex_digest, .{ .read = true, .truncate = false, .lock = lock, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index cb4fe0459f..4fc58c2c4b 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1,19 +1,22 @@ -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const Allocator = std.mem.Allocator; const log = std.log.scoped(.codegen); const math = std.math; const DW = std.dwarf; - const Builder = std.zig.llvm.Builder; + +const build_options = @import("build_options"); const llvm = if (build_options.have_llvm) @import("llvm/bindings.zig") else @compileError("LLVM unavailable"); + const link = @import("../link.zig"); const Compilation = @import("../Compilation.zig"); -const build_options = @import("build_options"); const Zcu = @import("../Zcu.zig"); const InternPool = @import("../InternPool.zig"); const Package = @import("../Package.zig"); @@ -964,7 +967,7 @@ pub const Object = struct { if (std.mem.eql(u8, path, "-")) { o.builder.dump(); } else { - o.builder.printToFilePath(std.fs.cwd(), path) catch |err| { + o.builder.printToFilePath(Io.Dir.cwd(), path) catch |err| { log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); }; } @@ -978,7 +981,7 @@ pub const Object = struct { o.builder.clearAndFree(); if (options.pre_bc_path) |path| { - var file = std.fs.cwd().createFile(path, .{}) catch |err| + var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); defer file.close(io); @@ -991,7 +994,7 @@ pub const Object = struct { options.post_ir_path == null and options.post_bc_path == null) return; if (options.post_bc_path) |path| { - var file = std.fs.cwd().createFile(path, .{}) catch |err| + var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); defer file.close(io); @@ -2711,7 +2714,7 @@ pub const Object = struct { } fn allocTypeName(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error![:0]const u8 { - var aw: std.Io.Writer.Allocating = .init(o.gpa); + var aw: Io.Writer.Allocating = .init(o.gpa); defer aw.deinit(); ty.print(&aw.writer, pt, null) catch |err| switch (err) { error.WriteFailed => return error.OutOfMemory, diff --git a/src/fmt.zig b/src/fmt.zig index ce8a31fa4c..36a3833986 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -182,11 +182,11 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! // Mark any excluded files/directories as already seen, // so that they are skipped later during actual processing for (excluded_files.items) |file_path| { - const stat = fs.cwd().statFile(file_path) catch |err| switch (err) { + const stat = Io.Dir.cwd().statFile(file_path) catch |err| switch (err) { error.FileNotFound => continue, // On Windows, statFile does not work for directories error.IsDir => dir: { - var dir = try fs.cwd().openDir(file_path, .{}); + var dir = try Io.Dir.cwd().openDir(file_path, .{}); defer dir.close(io); break :dir try dir.stat(); }, @@ -196,7 +196,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! } for (input_files.items) |file_path| { - try fmtPath(&fmt, file_path, check_flag, fs.cwd(), file_path); + try fmtPath(&fmt, file_path, check_flag, Io.Dir.cwd(), file_path); } try fmt.stdout_writer.interface.flush(); if (fmt.any_error) { diff --git a/src/introspect.zig b/src/introspect.zig index d2faa9a55c..04ddf47e8a 100644 --- a/src/introspect.zig +++ b/src/introspect.zig @@ -82,7 +82,7 @@ pub fn findZigLibDirFromSelfExe( cwd_path: []const u8, self_exe_path: []const u8, ) error{ OutOfMemory, FileNotFound }!Cache.Directory { - const cwd = fs.cwd(); + const cwd = Io.Dir.cwd(); var cur_path: []const u8 = self_exe_path; while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { var base_dir = cwd.openDir(dirname, .{}) catch continue; @@ -206,7 +206,7 @@ pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator var cur_dir = cwd; while (true) { const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); - if (fs.cwd().access(joined, .{})) |_| { + if (Io.Dir.cwd().access(joined, .{})) |_| { return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); } else |err| switch (err) { error.FileNotFound => { diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index 8c5e0afe4b..cfd8d5554c 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -1,9 +1,9 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; const log = std.log; -const fs = std.fs; -const path = fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const Version = std.SemanticVersion; const Path = std.Build.Cache.Path; @@ -446,7 +446,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -468,7 +468,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -986,7 +986,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -1014,7 +1014,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) std.Io.C const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.getSoVersion(&target.os), + so_files.dir_path.sub_path, path.sep, lib.name, lib.getSoVersion(&target.os), }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index bec20ff3d4..e3d8ce1f7f 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -1,9 +1,9 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; const log = std.log; -const fs = std.fs; -const path = fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const Version = std.SemanticVersion; const Path = std.Build.Cache.Path; @@ -681,7 +681,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -703,7 +703,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -775,7 +775,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye try stubs_asm.appendSlice(".text\n"); var sym_i: usize = 0; - var sym_name_buf: std.Io.Writer.Allocating = .init(arena); + var sym_name_buf: Io.Writer.Allocating = .init(arena); var opt_symbol_name: ?[]const u8 = null; var versions_buffer: [32]u8 = undefined; var versions_len: usize = undefined; @@ -796,7 +796,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye // twice, which causes a "duplicate symbol" assembler error. var versions_written = std.AutoArrayHashMap(Version, void).init(arena); - var inc_reader: std.Io.Reader = .fixed(metadata.inclusions); + var inc_reader: Io.Reader = .fixed(metadata.inclusions); const fn_inclusions_len = try inc_reader.takeInt(u16, .little); @@ -1130,7 +1130,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -1156,7 +1156,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) std.Io.C const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.sover, + so_files.dir_path.sub_path, path.sep, lib.name, lib.sover, }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 005696e1fc..b3ca51e833 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -1,7 +1,8 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; -const path = std.fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const log = std.log.scoped(.mingw); @@ -259,7 +260,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -304,7 +305,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { .output = .{ .to_list = .{ .arena = .init(gpa) } }, }; defer diagnostics.deinit(); - var aro_comp = aro.Compilation.init(gpa, arena, io, &diagnostics, std.fs.cwd()); + var aro_comp = aro.Compilation.init(gpa, arena, io, &diagnostics, Io.Dir.cwd()); defer aro_comp.deinit(); aro_comp.target = .fromZigTarget(target.*); @@ -343,7 +344,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { } const members = members: { - var aw: std.Io.Writer.Allocating = .init(gpa); + var aw: Io.Writer.Allocating = .init(gpa); errdefer aw.deinit(); try pp.prettyPrintTokens(&aw.writer, .result_only); @@ -376,7 +377,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { errdefer gpa.free(lib_final_path); { - const lib_final_file = try o_dir.createFile(final_lib_basename, .{ .truncate = true }); + const lib_final_file = try o_dir.createFile(io, final_lib_basename, .{ .truncate = true }); defer lib_final_file.close(io); var buffer: [1024]u8 = undefined; var file_writer = lib_final_file.writer(&buffer); @@ -442,7 +443,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{ lib_path, lib_name }); } - if (std.fs.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, @@ -459,7 +460,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{lib_name}); } - if (std.fs.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, @@ -476,7 +477,7 @@ fn findDef( } else { try override_path.print(fmt_path, .{lib_name}); } - if (std.fs.cwd().access(override_path.items, .{})) |_| { + if (Io.Dir.cwd().access(override_path.items, .{})) |_| { return override_path.toOwnedSlice(); } else |err| switch (err) { error.FileNotFound => {}, diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index 67e6a2f903..cb6a80d69d 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -1,9 +1,9 @@ const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const mem = std.mem; const log = std.log; -const fs = std.fs; -const path = fs.path; +const path = std.Io.Dir.path; const assert = std.debug.assert; const Version = std.SemanticVersion; const Path = std.Build.Cache.Path; @@ -387,7 +387,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .io = io, .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), }; - cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); + cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); cache.addPrefix(comp.dirs.zig_lib); cache.addPrefix(comp.dirs.global_cache); defer cache.manifest_dir.close(io); @@ -409,7 +409,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -640,7 +640,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye .lock = man.toOwnedLock(), .dir_path = .{ .root_dir = comp.dirs.global_cache, - .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), + .sub_path = try gpa.dupe(u8, "o" ++ path.sep_str ++ digest), }, }); } @@ -661,7 +661,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) std.Io.C const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.sover, + so_files.dir_path.sub_path, path.sep, lib.name, lib.sover, }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; diff --git a/src/link/C.zig b/src/link/C.zig index 04c92443e5..a001f8fdd9 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -136,7 +136,7 @@ pub fn createEmpty( assert(!use_lld); assert(!use_llvm); - const file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + const file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ // Truncation is done on `flush`. .truncate = false, }); @@ -792,7 +792,7 @@ pub fn flushEmitH(zcu: *Zcu) !void { } const directory = emit_h.loc.directory orelse zcu.comp.local_cache_directory; - const file = try directory.handle.createFile(emit_h.loc.basename, .{ + const file = try directory.handle.createFile(io, emit_h.loc.basename, .{ // We set the end position explicitly below; by not truncating the file, we possibly // make it easier on the file system by doing 1 reallocation instead of two. .truncate = false, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index e1d52fb7c4..009e59ed0d 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -631,12 +631,14 @@ fn create( else => return error.UnsupportedCOFFArchitecture, }; + const io = comp.io; + const coff = try arena.create(Coff); - const file = try path.root_dir.handle.createFile(comp.io, path.sub_path, .{ + const file = try path.root_dir.handle.createFile(io, path.sub_path, .{ .read = true, .mode = link.File.determineMode(comp.config.output_mode, comp.config.link_mode), }); - errdefer file.close(comp.io); + errdefer file.close(io); coff.* = .{ .base = .{ .tag = .coff2, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 584a50c7f2..53812a37ec 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -313,9 +313,11 @@ pub fn createEmpty( const is_obj = output_mode == .Obj; const is_obj_or_ar = is_obj or (output_mode == .Lib and link_mode == .static); + const io = comp.io; + // What path should this ELF linker code output to? const sub_path = emit.sub_path; - self.base.file = try emit.root_dir.handle.createFile(sub_path, .{ + self.base.file = try emit.root_dir.handle.createFile(io, sub_path, .{ .truncate = true, .read = true, .mode = link.File.determineMode(output_mode, link_mode), diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 49f6d3f7c7..b25b9da9d9 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1572,7 +1572,7 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { // report a nice error here with the file path if it fails instead of // just returning the error code. // chmod does not interact with umask, so we use a conservative -rwxr--r-- here. - std.posix.fchmodat(fs.cwd().fd, full_out_path, 0o744, 0) catch |err| switch (err) { + std.posix.fchmodat(Io.Dir.cwd().handle, full_out_path, 0o744, 0) catch |err| switch (err) { error.OperationNotSupported => unreachable, // Not a symlink. else => |e| return e, }; @@ -1624,7 +1624,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi const rand_int = std.crypto.random.int(u64); const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; - const rsp_file = try comp.dirs.local_cache.handle.createFile(rsp_path, .{}); + const rsp_file = try comp.dirs.local_cache.handle.createFile(io, rsp_path, .{}); defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err| log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); { diff --git a/src/link/MachO.zig b/src/link/MachO.zig index e837cc853a..0f6127e10e 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -219,7 +219,9 @@ pub fn createEmpty( }; errdefer self.base.destroy(); - self.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + const io = comp.io; + + self.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, .mode = link.File.determineMode(output_mode, link_mode), @@ -1082,7 +1084,7 @@ fn accessLibPath( test_path.clearRetainingCapacity(); try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext }); try checked_paths.append(try arena.dupe(u8, test_path.items)); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -1110,7 +1112,7 @@ fn accessFrameworkPath( ext, }); try checked_paths.append(try arena.dupe(u8, test_path.items)); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -1191,7 +1193,7 @@ fn parseDependentDylibs(self: *MachO) !void { try test_path.print("{s}{s}", .{ path, ext }); } try checked_paths.append(try arena.dupe(u8, test_path.items)); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, }; @@ -3289,7 +3291,7 @@ pub fn reopenDebugInfo(self: *MachO) !void { var d_sym_bundle = try self.base.emit.root_dir.handle.makeOpenPath(d_sym_path, .{}); defer d_sym_bundle.close(io); - self.d_sym.?.file = try d_sym_bundle.createFile(fs.path.basename(self.base.emit.sub_path), .{ + self.d_sym.?.file = try d_sym_bundle.createFile(io, fs.path.basename(self.base.emit.sub_path), .{ .truncate = false, .read = true, }); @@ -4370,7 +4372,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi // The file/property is also available with vendored libc. fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 { const sdk_path = try fs.path.join(arena, &.{ dir, "SDKSettings.json" }); - const contents = try fs.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16))); + const contents = try Io.Dir.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16))); const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{}); if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string; return error.SdkVersionFailure; diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index 5f9a9ecac9..814faf234a 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -247,7 +247,7 @@ pub fn deinit(self: *CodeSignature, allocator: Allocator) void { } pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const u8) !void { - const inner = try fs.cwd().readFileAlloc(path, allocator, .limited(std.math.maxInt(u32))); + const inner = try Io.Dir.cwd().readFileAlloc(path, allocator, .limited(std.math.maxInt(u32))); self.entitlements = .{ .inner = inner }; } diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index 7e28dc0a8b..d13caaa315 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -33,6 +33,7 @@ pub fn createEmpty( options: link.File.OpenOptions, ) !*Linker { const gpa = comp.gpa; + const io = comp.io; const target = &comp.root_mod.resolved_target.result; assert(!comp.config.use_lld); // Caught by Compilation.Config.resolve @@ -78,7 +79,7 @@ pub fn createEmpty( }; errdefer linker.deinit(); - linker.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + linker.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, }); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 7ab1e0eb4b..5f89625d56 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2997,7 +2997,9 @@ pub fn createEmpty( .named => |name| (try wasm.internString(name)).toOptional(), }; - wasm.base.file = try emit.root_dir.handle.createFile(emit.sub_path, .{ + const io = comp.io; + + wasm.base.file = try emit.root_dir.handle.createFile(io, emit.sub_path, .{ .truncate = true, .read = true, .mode = if (fs.has_executable_bit) diff --git a/src/main.zig b/src/main.zig index b040b6c8ef..67b7384b57 100644 --- a/src/main.zig +++ b/src/main.zig @@ -713,7 +713,7 @@ const Emit = union(enum) { } else e: { // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would. if (fs.path.dirname(path)) |dir_path| { - var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| { fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); }; dir.close(io); @@ -3304,7 +3304,7 @@ fn buildOutputType( } else emit: { // If there's a dirname, check that dir exists. This will give a more descriptive error than `Compilation` otherwise would. if (fs.path.dirname(path)) |dir_path| { - var dir = fs.cwd().openDir(dir_path, .{}) catch |err| { + var dir = Io.Dir.cwd().openDir(dir_path, .{}) catch |err| { fatal("unable to open output directory '{s}': {s}", .{ dir_path, @errorName(err) }); }; dir.close(io); @@ -3389,7 +3389,7 @@ fn buildOutputType( // file will not run and this temp file will be leaked. The filename // will be a hash of its contents — so multiple invocations of // `zig cc -` will result in the same temp file name. - var f = try dirs.local_cache.handle.createFile(dump_path, .{}); + var f = try dirs.local_cache.handle.createFile(io, dump_path, .{}); defer f.close(io); // Re-using the hasher from Cache, since the functional requirements @@ -4773,7 +4773,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! var ok_count: usize = 0; for (template_paths) |template_path| { - if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { + if (templates.write(arena, Io.Dir.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { std.log.info("created {s}", .{template_path}); ok_count += 1; } else |err| switch (err) { @@ -5227,7 +5227,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) if (system_pkg_dir_path) |p| { job_queue.global_cache = .{ .path = p, - .handle = fs.cwd().openDir(p, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(p, .{}) catch |err| { fatal("unable to open system package directory '{s}': {s}", .{ p, @errorName(err), }); @@ -5823,7 +5823,7 @@ const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, /// Initialize the arguments from a Response File. "*.rsp" fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile { const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit - const cmd_line = try fs.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes)); + const cmd_line = try Io.Dir.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes)); errdefer allocator.free(cmd_line); return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line); @@ -6187,7 +6187,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { const display_path = zig_source_path orelse ""; const source: [:0]const u8 = s: { var f = if (zig_source_path) |p| file: { - break :file fs.cwd().openFile(io, p, .{}) catch |err| { + break :file Io.Dir.cwd().openFile(io, p, .{}) catch |err| { fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); }; } else Io.File.stdin(); @@ -6494,7 +6494,7 @@ fn cmdDumpZir(arena: Allocator, io: Io, args: []const []const u8) !void { const cache_file = args[0]; - var f = fs.cwd().openFile(io, cache_file, .{}) catch |err| { + var f = Io.Dir.cwd().openFile(io, cache_file, .{}) catch |err| { fatal("unable to open zir cache file for dumping '{s}': {s}", .{ cache_file, @errorName(err) }); }; defer f.close(io); @@ -6541,7 +6541,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { const new_source_path = args[1]; const old_source = source: { - var f = fs.cwd().openFile(io, old_source_path, .{}) catch |err| + var f = Io.Dir.cwd().openFile(io, old_source_path, .{}) catch |err| fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); defer f.close(io); var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); @@ -6549,7 +6549,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); }; const new_source = source: { - var f = fs.cwd().openFile(io, new_source_path, .{}) catch |err| + var f = Io.Dir.cwd().openFile(io, new_source_path, .{}) catch |err| fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); defer f.close(io); var file_reader: Io.File.Reader = f.reader(io, &stdin_buffer); @@ -6845,7 +6845,7 @@ fn accessFrameworkPath( framework_dir_path, framework_name, framework_name, ext, }); try checked_paths.print("\n {s}", .{test_path.items}); - fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + Io.Dir.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| fatal("unable to search for {s} framework '{s}': {s}", .{ ext, test_path.items, @errorName(e), @@ -6957,7 +6957,7 @@ fn cmdFetch( var global_cache_directory: Directory = l: { const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); break :l .{ - .handle = try fs.cwd().makeOpenPath(p, .{}), + .handle = try Io.Dir.cwd().makeOpenPath(p, .{}), .path = p, }; }; @@ -7260,7 +7260,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { if (options.build_file) |bf| { if (fs.path.dirname(bf)) |dirname| { - const dir = fs.cwd().openDir(dirname, .{}) catch |err| { + const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| { fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) }); }; return .{ @@ -7272,7 +7272,7 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { return .{ .build_zig_basename = build_zig_basename, - .directory = .{ .path = null, .handle = fs.cwd() }, + .directory = .{ .path = null, .handle = Io.Dir.cwd() }, .cleanup_build_dir = null, }; } @@ -7280,8 +7280,8 @@ fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { var dirname: []const u8 = cwd_path; while (true) { const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); - if (fs.cwd().access(joined_path, .{})) |_| { - const dir = fs.cwd().openDir(dirname, .{}) catch |err| { + if (Io.Dir.cwd().access(joined_path, .{})) |_| { + const dir = Io.Dir.cwd().openDir(dirname, .{}) catch |err| { fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) }); }; return .{ @@ -7443,7 +7443,7 @@ const Templates = struct { } }; fn writeSimpleTemplateFile(io: Io, file_name: []const u8, comptime fmt: []const u8, args: anytype) !void { - const f = try fs.cwd().createFile(file_name, .{ .exclusive = true }); + const f = try Io.Dir.cwd().createFile(io, file_name, .{ .exclusive = true }); defer f.close(io); var buf: [4096]u8 = undefined; var fw = f.writer(&buf); @@ -7591,7 +7591,7 @@ fn addLibDirectoryWarn2( ignore_not_found: bool, ) void { lib_directories.appendAssumeCapacity(.{ - .handle = fs.cwd().openDir(path, .{}) catch |err| { + .handle = Io.Dir.cwd().openDir(path, .{}) catch |err| { if (err == error.FileNotFound and ignore_not_found) return; warn("unable to open library directory '{s}': {s}", .{ path, @errorName(err) }); return; -- cgit v1.2.3 From 1925e0319f1337b4856bd5a181bf4f6d3ac7d428 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 12 Dec 2025 19:04:35 -0800 Subject: update lockStderrWriter sites use the application's Io implementation where possible. This correctly makes writing to stderr cancelable, fallible, and participate in the application's event loop. It also removes one more hard-coded dependency on a secondary Io implementation. --- lib/compiler/build_runner.zig | 18 +++---- lib/compiler/resinator/cli.zig | 8 ++-- lib/compiler/resinator/errors.zig | 8 ++-- lib/compiler/resinator/main.zig | 98 ++++++++++++++++++++------------------- lib/compiler/std-docs.zig | 2 +- lib/compiler/test_runner.zig | 3 -- lib/std/Build.zig | 31 +++++++++---- lib/std/Build/Fuzz.zig | 21 +++++---- lib/std/Build/Step/Compile.zig | 17 ++++--- lib/std/Build/Step/Run.zig | 5 +- lib/std/Build/WebServer.zig | 2 +- lib/std/Progress.zig | 2 +- lib/std/json/dynamic.zig | 5 +- lib/std/process.zig | 2 +- lib/std/testing.zig | 16 +++++-- lib/std/zig.zig | 4 +- lib/std/zig/ErrorBundle.zig | 10 ++-- lib/std/zig/parser_test.zig | 30 +++++++----- src/Air/print.zig | 28 +++++++---- src/Compilation.zig | 53 ++++++++++++--------- src/InternPool.zig | 63 ++++++++++++------------- src/Sema.zig | 8 ++-- src/Zcu/PerThread.zig | 5 +- src/codegen/aarch64/Select.zig | 11 +++-- src/crash_report.zig | 9 ++-- src/fmt.zig | 8 ++-- src/libs/mingw.zig | 29 ++++++++---- src/libs/mingw/def.zig | 32 +++++++++---- src/link.zig | 2 +- src/link/Coff.zig | 15 ++++-- src/link/Elf2.zig | 14 ++++-- src/main.zig | 33 ++++++------- 32 files changed, 345 insertions(+), 247 deletions(-) (limited to 'src/codegen') diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index acba1a4621..d284d85747 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -522,7 +522,7 @@ pub fn main() !void { // Perhaps in the future there could be an Advanced Options flag // such as --debug-build-runner-leaks which would make this code // return instead of calling exit. - _ = std.debug.lockStderrWriter(&.{}); + _ = io.lockStderrWriter(&.{}) catch {}; process.exit(1); }, else => |e| return e, @@ -554,8 +554,8 @@ pub fn main() !void { } rebuild: while (true) : (if (run.error_style.clearOnUpdate()) { - const stderr = std.debug.lockStderrWriter(&stdio_buffer_allocation); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); + defer io.unlockStderrWriter(); try stderr.writeAllUnescaped("\x1B[2J\x1B[3J\x1B[H"); }) { if (run.web_server) |*ws| ws.startBuild(); @@ -856,8 +856,8 @@ fn runStepNames( .none => break :summary, } - const stderr = std.debug.lockStderrWriter(&stdio_buffer_allocation); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); + defer io.unlockStderrWriter(); const w = &stderr.interface; const fwm = stderr.mode; @@ -954,7 +954,7 @@ fn runStepNames( if (run.error_style.verboseContext()) break :code 1; // failure; print build command break :code 2; // failure; do not print build command }; - _ = std.debug.lockStderrWriter(&.{}); + _ = io.lockStderrWriter(&.{}) catch {}; process.exit(code); } @@ -1369,8 +1369,10 @@ fn workerMakeOneStep( const show_error_msgs = s.result_error_msgs.items.len > 0; const show_stderr = s.result_stderr.len > 0; if (show_error_msgs or show_compile_errors or show_stderr) { - const stderr = std.debug.lockStderrWriter(&stdio_buffer_allocation); - defer std.debug.unlockStderrWriter(); + const stderr = io.lockStderrWriter(&stdio_buffer_allocation) catch |err| switch (err) { + error.Canceled => return, + }; + defer io.unlockStderrWriter(); printErrorMessages(gpa, s, .{}, &stderr.interface, stderr.mode, run.error_style, run.multiline_errors) catch {}; } diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index d2dd71b1f6..08befbe1fa 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -125,10 +125,10 @@ pub const Diagnostics = struct { try self.errors.append(self.allocator, error_details); } - pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8) void { - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - self.renderToWriter(args, stderr, ttyconf) catch return; + pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) void { + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + self.renderToWriter(args, &stderr.interface, stderr.mode) catch return; } pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void { diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index 14ff28a697..031b5d3574 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -67,12 +67,12 @@ pub const Diagnostics = struct { return @intCast(index); } - pub fn renderToStdErr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { + pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { const io = self.io; - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); for (self.errors.items) |err_details| { - renderErrorMessage(io, stderr, ttyconf, cwd, err_details, source, self.strings.items, source_mappings) catch return; + renderErrorMessage(io, &stderr.interface, stderr.mode, cwd, err_details, source, self.strings.items, source_mappings) catch return; } } diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 6c12903f06..bd2fcc912e 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -24,6 +24,10 @@ pub fn main() !void { defer std.debug.assert(debug_allocator.deinit() == .ok); const gpa = debug_allocator.allocator(); + var threaded: std.Io.Threaded = .init(gpa); + defer threaded.deinit(); + const io = threaded.io(); + var arena_state = std.heap.ArenaAllocator.init(gpa); defer arena_state.deinit(); const arena = arena_state.allocator(); @@ -31,8 +35,8 @@ pub fn main() !void { const args = try std.process.argsAlloc(arena); if (args.len < 2) { - const w, const ttyconf = std.debug.lockStderrWriter(&.{}); - try renderErrorMessage(w, ttyconf, .err, "expected zig lib dir as first argument", .{}); + const stderr = io.lockStderrWriter(&.{}); + try renderErrorMessage(&stderr.interface, stderr.mode, .err, "expected zig lib dir as first argument", .{}); std.process.exit(1); } const zig_lib_dir = args[1]; @@ -45,7 +49,7 @@ pub fn main() !void { } var stdout_buffer: [1024]u8 = undefined; - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); const stdout = &stdout_writer.interface; var error_handler: ErrorHandler = switch (zig_integration) { true => .{ @@ -71,24 +75,20 @@ pub fn main() !void { if (!zig_integration) { // print any warnings/notes - cli_diagnostics.renderToStdErr(cli_args); + cli_diagnostics.renderToStderr(io, cli_args); // If there was something printed, then add an extra newline separator // so that there is a clear separation between the cli diagnostics and whatever // gets printed after if (cli_diagnostics.errors.items.len > 0) { - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try stderr.writeByte('\n'); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + try stderr.interface.writeByte('\n'); } } break :options options; }; defer options.deinit(); - var threaded: std.Io.Threaded = .init(gpa); - defer threaded.deinit(); - const io = threaded.io(); - if (options.print_help_and_exit) { try cli.writeUsage(stdout, "zig rc"); try stdout.flush(); @@ -130,10 +130,10 @@ pub fn main() !void { var stderr_buf: [512]u8 = undefined; var diagnostics: aro.Diagnostics = .{ .output = output: { if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } }; - const w, const ttyconf = std.debug.lockStderrWriter(&stderr_buf); + const stderr = io.lockStderrWriter(&stderr_buf); break :output .{ .to_writer = .{ - .writer = w, - .color = ttyconf, + .writer = &stderr.interface, + .color = stderr.mode, } }; } }; defer { @@ -175,11 +175,11 @@ pub fn main() !void { std.process.exit(1); }, error.FileTooBig => { - try error_handler.emitMessage(gpa, .err, "failed during preprocessing: maximum file size exceeded", .{}); + try error_handler.emitMessage(gpa, io, .err, "failed during preprocessing: maximum file size exceeded", .{}); std.process.exit(1); }, error.WriteFailed => { - try error_handler.emitMessage(gpa, .err, "failed during preprocessing: error writing the preprocessed output", .{}); + try error_handler.emitMessage(gpa, io, .err, "failed during preprocessing: error writing the preprocessed output", .{}); std.process.exit(1); }, error.OutOfMemory => |e| return e, @@ -191,13 +191,13 @@ pub fn main() !void { .stdio => |file| { var file_reader = file.reader(io, &.{}); break :full_input file_reader.interface.allocRemaining(gpa, .unlimited) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read input from stdin: {s}", .{@errorName(err)}); + try error_handler.emitMessage(gpa, io, .err, "unable to read input from stdin: {s}", .{@errorName(err)}); std.process.exit(1); }; }, .filename => |input_filename| { break :full_input Io.Dir.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) }); std.process.exit(1); }; }, @@ -228,12 +228,12 @@ pub fn main() !void { } else if (options.input_format == .res) IoStream.fromIoSource(options.input_source, .input) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read res file path '{s}': {s}", .{ options.input_source.filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to read res file path '{s}': {s}", .{ options.input_source.filename, @errorName(err) }); std.process.exit(1); } else IoStream.fromIoSource(options.output_source, .output) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); std.process.exit(1); }; defer res_stream.deinit(gpa); @@ -246,17 +246,17 @@ pub fn main() !void { var mapping_results = parseAndRemoveLineCommands(gpa, full_input, full_input, .{ .initial_filename = options.input_source.filename }) catch |err| switch (err) { error.InvalidLineCommand => { // TODO: Maybe output the invalid line command - try error_handler.emitMessage(gpa, .err, "invalid line command in the preprocessed source", .{}); + try error_handler.emitMessage(gpa, io, .err, "invalid line command in the preprocessed source", .{}); if (options.preprocess == .no) { - try error_handler.emitMessage(gpa, .note, "line commands must be of the format: #line \"\"", .{}); + try error_handler.emitMessage(gpa, io, .note, "line commands must be of the format: #line \"\"", .{}); } else { - try error_handler.emitMessage(gpa, .note, "this is likely to be a bug, please report it", .{}); + try error_handler.emitMessage(gpa, io, .note, "this is likely to be a bug, please report it", .{}); } std.process.exit(1); }, error.LineNumberOverflow => { // TODO: Better error message - try error_handler.emitMessage(gpa, .err, "line number count exceeded maximum of {}", .{std.math.maxInt(usize)}); + try error_handler.emitMessage(gpa, io, .err, "line number count exceeded maximum of {}", .{std.math.maxInt(usize)}); std.process.exit(1); }, error.OutOfMemory => |e| return e, @@ -306,13 +306,13 @@ pub fn main() !void { // print any warnings/notes if (!zig_integration) { - diagnostics.renderToStdErr(Io.Dir.cwd(), final_input, mapping_results.mappings); + diagnostics.renderToStderr(io, Io.Dir.cwd(), final_input, mapping_results.mappings); } // write the depfile if (options.depfile_path) |depfile_path| { var depfile = Io.Dir.cwd().createFile(io, depfile_path, .{}) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) }); std.process.exit(1); }; defer depfile.close(io); @@ -340,7 +340,7 @@ pub fn main() !void { if (options.output_format != .coff) return; break :res_data res_stream.source.readAll(gpa, io) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to read res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to read res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); std.process.exit(1); }; }; @@ -353,14 +353,14 @@ pub fn main() !void { var res_reader: std.Io.Reader = .fixed(res_data.bytes); break :resources cvtres.parseRes(gpa, &res_reader, .{ .max_size = res_data.bytes.len }) catch |err| { // TODO: Better errors - try error_handler.emitMessage(gpa, .err, "unable to parse res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to parse res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); std.process.exit(1); }; }; defer resources.deinit(); var coff_stream = IoStream.fromIoSource(options.output_source, .output) catch |err| { - try error_handler.emitMessage(gpa, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) }); std.process.exit(1); }; defer coff_stream.deinit(gpa); @@ -373,7 +373,7 @@ pub fn main() !void { switch (err) { error.DuplicateResource => { const duplicate_resource = resources.list.items[cvtres_diagnostics.duplicate_resource]; - try error_handler.emitMessage(gpa, .err, "duplicate resource [id: {f}, type: {f}, language: {f}]", .{ + try error_handler.emitMessage(gpa, io, .err, "duplicate resource [id: {f}, type: {f}, language: {f}]", .{ duplicate_resource.name_value, fmtResourceType(duplicate_resource.type_value), duplicate_resource.language, @@ -381,8 +381,8 @@ pub fn main() !void { }, error.ResourceDataTooLong => { const overflow_resource = resources.list.items[cvtres_diagnostics.duplicate_resource]; - try error_handler.emitMessage(gpa, .err, "resource has a data length that is too large to be written into a coff section", .{}); - try error_handler.emitMessage(gpa, .note, "the resource with the invalid size is [id: {f}, type: {f}, language: {f}]", .{ + try error_handler.emitMessage(gpa, io, .err, "resource has a data length that is too large to be written into a coff section", .{}); + try error_handler.emitMessage(gpa, io, .note, "the resource with the invalid size is [id: {f}, type: {f}, language: {f}]", .{ overflow_resource.name_value, fmtResourceType(overflow_resource.type_value), overflow_resource.language, @@ -390,15 +390,15 @@ pub fn main() !void { }, error.TotalResourceDataTooLong => { const overflow_resource = resources.list.items[cvtres_diagnostics.duplicate_resource]; - try error_handler.emitMessage(gpa, .err, "total resource data exceeds the maximum of the coff 'size of raw data' field", .{}); - try error_handler.emitMessage(gpa, .note, "size overflow occurred when attempting to write this resource: [id: {f}, type: {f}, language: {f}]", .{ + try error_handler.emitMessage(gpa, io, .err, "total resource data exceeds the maximum of the coff 'size of raw data' field", .{}); + try error_handler.emitMessage(gpa, io, .note, "size overflow occurred when attempting to write this resource: [id: {f}, type: {f}, language: {f}]", .{ overflow_resource.name_value, fmtResourceType(overflow_resource.type_value), overflow_resource.language, }); }, else => { - try error_handler.emitMessage(gpa, .err, "unable to write coff output file '{s}': {s}", .{ coff_stream.name, @errorName(err) }); + try error_handler.emitMessage(gpa, io, .err, "unable to write coff output file '{s}': {s}", .{ coff_stream.name, @errorName(err) }); }, } // Delete the output file on error @@ -550,16 +550,16 @@ const LazyIncludePaths = struct { else => |e| { switch (e) { error.UnsupportedAutoIncludesMachineType => { - try error_handler.emitMessage(self.arena, .err, "automatic include path detection is not supported for target '{s}'", .{@tagName(self.target_machine_type)}); + try error_handler.emitMessage(self.arena, io, .err, "automatic include path detection is not supported for target '{s}'", .{@tagName(self.target_machine_type)}); }, error.MsvcIncludesNotFound => { - try error_handler.emitMessage(self.arena, .err, "MSVC include paths could not be automatically detected", .{}); + try error_handler.emitMessage(self.arena, io, .err, "MSVC include paths could not be automatically detected", .{}); }, error.MingwIncludesNotFound => { - try error_handler.emitMessage(self.arena, .err, "MinGW include paths could not be automatically detected", .{}); + try error_handler.emitMessage(self.arena, io, .err, "MinGW include paths could not be automatically detected", .{}); }, } - try error_handler.emitMessage(self.arena, .note, "to disable auto includes, use the option /:auto-includes none", .{}); + try error_handler.emitMessage(self.arena, io, .note, "to disable auto includes, use the option /:auto-includes none", .{}); std.process.exit(1); }, }; @@ -664,6 +664,7 @@ const ErrorHandler = union(enum) { pub fn emitCliDiagnostics( self: *ErrorHandler, allocator: Allocator, + io: Io, args: []const []const u8, diagnostics: *cli.Diagnostics, ) !void { @@ -674,7 +675,7 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, - .stderr => diagnostics.renderToStdErr(args), + .stderr => diagnostics.renderToStderr(io, args), } } @@ -684,6 +685,7 @@ const ErrorHandler = union(enum) { fail_msg: []const u8, comp: *aro.Compilation, ) !void { + const io = comp.io; switch (self.*) { .server => |*server| { var error_bundle = try compiler_util.aroDiagnosticsToErrorBundle( @@ -697,9 +699,9 @@ const ErrorHandler = union(enum) { }, .stderr => { // aro errors have already been emitted - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try renderErrorMessage(stderr, ttyconf, .err, "{s}", .{fail_msg}); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + try renderErrorMessage(&stderr.interface, stderr.mode, .err, "{s}", .{fail_msg}); }, } } @@ -707,6 +709,7 @@ const ErrorHandler = union(enum) { pub fn emitDiagnostics( self: *ErrorHandler, allocator: Allocator, + io: Io, cwd: Io.Dir, source: []const u8, diagnostics: *Diagnostics, @@ -719,13 +722,14 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, - .stderr => diagnostics.renderToStdErr(cwd, source, mappings), + .stderr => diagnostics.renderToStderr(io, cwd, source, mappings), } } pub fn emitMessage( self: *ErrorHandler, allocator: Allocator, + io: Io, msg_type: @import("utils.zig").ErrorMessageType, comptime format: []const u8, args: anytype, @@ -741,9 +745,9 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, .stderr => { - const stderr, const ttyconf = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try renderErrorMessage(stderr, ttyconf, msg_type, format, args); + const stderr = io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + try renderErrorMessage(&stderr.interface, stderr.mode, msg_type, format, args); }, } } diff --git a/lib/compiler/std-docs.zig b/lib/compiler/std-docs.zig index 538558fe48..9ff199d07b 100644 --- a/lib/compiler/std-docs.zig +++ b/lib/compiler/std-docs.zig @@ -407,7 +407,7 @@ fn buildWasmBinary( } if (result_error_bundle.errorMessageCount() > 0) { - result_error_bundle.renderToStdErr(.{}, true); + result_error_bundle.renderToStderr(io, .{}, true); std.log.err("the following command failed with {d} compilation errors:\n{s}", .{ result_error_bundle.errorMessageCount(), try std.Build.Step.allocPrintCmd(arena, null, argv.items), diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index f7f59a5bf3..3a135ab8fd 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -411,16 +411,13 @@ pub fn fuzz( std.debug.writeStackTrace(trace, &stderr.interface, stderr.mode) catch break :p; } stderr.interface.print("failed with error.{t}\n", .{err}) catch break :p; - stderr.interface.flush() catch break :p; } - stderr.interface.flush() catch {}; std.process.exit(1); }, }; if (log_err_count != 0) { const stderr = std.debug.lockStderrWriter(&.{}); stderr.interface.print("error logs detected\n", .{}) catch {}; - stderr.interface.flush() catch {}; std.process.exit(1); } } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index b7300cb5df..de2985d2b5 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -2238,7 +2238,7 @@ pub const GeneratedFile = struct { /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards. path: ?[]const u8 = null, - /// Deprecated, see `getPath2`. + /// Deprecated, see `getPath3`. pub fn getPath(gen: GeneratedFile) []const u8 { return gen.step.owner.pathFromCwd(gen.path orelse std.debug.panic( "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?", @@ -2246,11 +2246,18 @@ pub const GeneratedFile = struct { )); } + /// Deprecated, see `getPath3`. pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 { + return getPath3(gen, src_builder, asking_step) catch |err| switch (err) { + error.Canceled => std.process.exit(1), + }; + } + + pub fn getPath3(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) Io.Cancelable![]const u8 { return gen.path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const io = gen.step.owner.graph.io; + const stderr = try io.lockStderrWriter(&.{}); dumpBadGetPathHelp(gen.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; - std.debug.unlockStderrWriter(); @panic("misconfigured build script"); }; } @@ -2425,22 +2432,29 @@ pub const LazyPath = union(enum) { } } - /// Deprecated, see `getPath3`. + /// Deprecated, see `getPath4`. pub fn getPath(lazy_path: LazyPath, src_builder: *Build) []const u8 { return getPath2(lazy_path, src_builder, null); } - /// Deprecated, see `getPath3`. + /// Deprecated, see `getPath4`. pub fn getPath2(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 { const p = getPath3(lazy_path, src_builder, asking_step); return src_builder.pathResolve(&.{ p.root_dir.path orelse ".", p.sub_path }); } + /// Deprecated, see `getPath4`. + pub fn getPath3(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Cache.Path { + return getPath4(lazy_path, src_builder, asking_step) catch |err| switch (err) { + error.Canceled => std.process.exit(1), + }; + } + /// Intended to be used during the make phase only. /// /// `asking_step` is only used for debugging purposes; it's the step being /// run that is asking for the path. - pub fn getPath3(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Cache.Path { + pub fn getPath4(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) Io.Cancelable!Cache.Path { switch (lazy_path) { .src_path => |sp| return .{ .root_dir = sp.owner.build_root, @@ -2457,9 +2471,10 @@ pub const LazyPath = union(enum) { var file_path: Cache.Path = .{ .root_dir = Cache.Directory.cwd(), .sub_path = gen.file.path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const io = src_builder.graph.io; + const stderr = try io.lockStderrWriter(&.{}); dumpBadGetPathHelp(gen.file.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); @panic("misconfigured build script"); }, }; diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index c2b7d1e9e9..4770e03a0c 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -158,6 +158,7 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, parent_prog_node: std.P } fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_node: std.Progress.Node) !void { + const io = run.step.owner.graph.io; const compile = run.producer.?; const prog_node = parent_prog_node.start(compile.step.name, 0); defer prog_node.end(); @@ -170,8 +171,8 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod if (show_error_msgs or show_compile_errors or show_stderr) { var buf: [256]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buf); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buf); + defer io.unlockStderrWriter(); build_runner.printErrorMessages(gpa, &compile.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; } @@ -182,12 +183,10 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod run.rebuilt_executable = try rebuilt_bin_path.join(gpa, compile.out_filename); } -fn fuzzWorkerRun( - fuzz: *Fuzz, - run: *Step.Run, - unit_test_index: u32, -) void { - const gpa = run.step.owner.allocator; +fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void { + const owner = run.step.owner; + const gpa = owner.allocator; + const io = owner.graph.io; const test_name = run.cached_test_metadata.?.testName(unit_test_index); const prog_node = fuzz.prog_node.start(test_name, 0); @@ -196,8 +195,10 @@ fn fuzzWorkerRun( run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) { error.MakeFailed => { var buf: [256]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buf); - defer std.debug.unlockStderrWriter(); + const stderr = io.lockStderrWriter(&buf) catch |e| switch (e) { + error.Canceled => return, + }; + defer io.unlockStderrWriter(); build_runner.printErrorMessages(gpa, &run.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; return; }, diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index d703e55b87..888775884d 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -922,20 +922,23 @@ const CliNamedModules = struct { } }; -fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 { +fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 { + const step = &compile.step; + const b = step.owner; + const io = b.graph.io; const maybe_path: ?*GeneratedFile = @field(compile, tag_name); const generated_file = maybe_path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = try io.lockStderrWriter(&.{}); std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); @panic("missing emit option for " ++ tag_name); }; const path = generated_file.path orelse { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = try io.lockStderrWriter(&.{}); std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); @panic(tag_name ++ " is null. Is there a missing step dependency?"); }; @@ -1149,9 +1152,9 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { // For everything else, we directly link // against the library file. const full_path_lib = if (other_produces_implib) - other.getGeneratedFilePath("generated_implib", &compile.step) + try other.getGeneratedFilePath("generated_implib", &compile.step) else - other.getGeneratedFilePath("generated_bin", &compile.step); + try other.getGeneratedFilePath("generated_bin", &compile.step); try zig_args.append(full_path_lib); total_linker_objects += 1; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index f1e5313905..67cf201374 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1559,6 +1559,7 @@ fn spawnChildAndCollect( ) !?EvalGenericResult { const b = run.step.owner; const arena = b.allocator; + const io = b.graph.io; if (fuzz_context != null) { assert(!has_side_effects); @@ -1625,10 +1626,10 @@ fn spawnChildAndCollect( child.progress_node = options.progress_node; } if (inherit) { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = try io.lockStderrWriter(&.{}); try setColorEnvironmentVariables(run, env_map, stderr.mode); } - defer if (inherit) std.debug.unlockStderrWriter(); + defer if (inherit) io.unlockStderrWriter(); var timer = try std.time.Timer.start(); const res = try evalGeneric(run, &child); run.step.result_duration_ns = timer.read(); diff --git a/lib/std/Build/WebServer.zig b/lib/std/Build/WebServer.zig index ccb7159192..a2b35e3522 100644 --- a/lib/std/Build/WebServer.zig +++ b/lib/std/Build/WebServer.zig @@ -655,7 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim } if (result_error_bundle.errorMessageCount() > 0) { - result_error_bundle.renderToStdErr(.{}, .auto); + try result_error_bundle.renderToStderr(io, .{}, .auto); log.err("the following command failed with {d} compilation errors:\n{s}", .{ result_error_bundle.errorMessageCount(), try Build.Step.allocPrintCmd(arena, null, argv.items), diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index 603f53091e..6edbf9e471 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -764,7 +764,7 @@ fn appendTreeSymbol(symbol: TreeSymbol, buf: []u8, start_i: usize) usize { } } -pub fn clearWrittenWithEscapeCodes(file_writer: *Io.File.Writer) anyerror!void { +pub fn clearWrittenWithEscapeCodes(file_writer: *Io.File.Writer) Io.Writer.Error!void { if (noop_impl or !global_progress.need_clear) return; try file_writer.writeAllUnescaped(clear ++ progress_remove); global_progress.need_clear = false; diff --git a/lib/std/json/dynamic.zig b/lib/std/json/dynamic.zig index c3cccd1a91..f85916670b 100644 --- a/lib/std/json/dynamic.zig +++ b/lib/std/json/dynamic.zig @@ -47,10 +47,9 @@ pub const Value = union(enum) { } pub fn dump(v: Value) void { - const w, _ = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); - - json.Stringify.value(v, .{}, w) catch return; + json.Stringify.value(v, .{}, &stderr.interface) catch return; } pub fn jsonStringify(value: @This(), jws: anytype) !void { diff --git a/lib/std/process.zig b/lib/std/process.zig index 216e793cbe..4b4c27fe20 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1849,7 +1849,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { /// and does not return. pub fn cleanExit(io: Io) void { if (builtin.mode == .Debug) return; - _ = io.lockStderrWriter(&.{}); + _ = io.lockStderrWriter(&.{}) catch {}; exit(0); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 092b65d71a..64ea3d1a4d 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -368,13 +368,21 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const break :diff_index if (expected.len == actual.len) return else shortest; }; if (!backend_can_print) return error.TestExpectedEqual; - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; + if (io.lockStderrWriter(&.{})) |stderr| { + defer io.unlockStderrWriter(); + failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; + } else |_| {} return error.TestExpectedEqual; } -fn failEqualSlices(comptime T: type, expected: []const T, actual: []const T, diff_index: usize, w: *Io.Writer, fwm: Io.File.Writer.Mode) !void { +fn failEqualSlices( + comptime T: type, + expected: []const T, + actual: []const T, + diff_index: usize, + w: *Io.Writer, + fwm: Io.File.Writer.Mode, +) !void { try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); // TODO: Should this be configurable by the caller? diff --git a/lib/std/zig.zig b/lib/std/zig.zig index b6203326f2..a094dee83f 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -639,7 +639,7 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, file_reader: *Io.File.Reader) ![ return buffer.toOwnedSliceSentinel(gpa, 0); } -pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color: Color) !void { +pub fn printAstErrorsToStderr(gpa: Allocator, io: Io, tree: Ast, path: []const u8, color: Color) !void { var wip_errors: std.zig.ErrorBundle.Wip = undefined; try wip_errors.init(gpa); defer wip_errors.deinit(); @@ -648,7 +648,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); } pub fn putAstErrorsIntoBundle( diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index cc6182c8aa..0342874cf9 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -162,11 +162,13 @@ pub const RenderOptions = struct { include_log_text: bool = true, }; -pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions, color: std.zig.Color) void { +pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Mode.SetColorError; + +pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: std.zig.Color) RenderToStderrError!void { var buffer: [256]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); - renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch return; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + try renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)); } pub fn renderToWriter( diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 9d9a6a48ce..5318eab2df 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -1,7 +1,6 @@ const std = @import("std"); -const mem = std.mem; -const print = std.debug.print; -const maxInt = std.math.maxInt; +const Io = std.Io; +const Allocator = std.mem.Allocator; test "zig fmt: remove extra whitespace at start and end of file with comment between" { try testTransform( @@ -6332,10 +6331,10 @@ test "ampersand" { var fixed_buffer_mem: [100 * 1024]u8 = undefined; -fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 { +fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 { var buffer: [64]u8 = undefined; - const stderr = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); var tree = try std.zig.Ast.parse(allocator, source, .zig); defer tree.deinit(allocator); @@ -6359,27 +6358,36 @@ fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: * } const formatted = try tree.renderAlloc(allocator); - anything_changed.* = !mem.eql(u8, formatted, source); + anything_changed.* = !std.mem.eql(u8, formatted, source); return formatted; } -fn testTransformImpl(allocator: mem.Allocator, fba: *std.heap.FixedBufferAllocator, source: [:0]const u8, expected_source: []const u8) !void { +fn testTransformImpl( + io: Io, + allocator: Allocator, + fba: *std.heap.FixedBufferAllocator, + source: [:0]const u8, + expected_source: []const u8, +) !void { // reset the fixed buffer allocator each run so that it can be re-used for each // iteration of the failing index fba.reset(); var anything_changed: bool = undefined; - const result_source = try testParse(source, allocator, &anything_changed); + const result_source = try testParse(io, source, allocator, &anything_changed); try std.testing.expectEqualStrings(expected_source, result_source); const changes_expected = source.ptr != expected_source.ptr; if (anything_changed != changes_expected) { - print("std.zig.render returned {} instead of {}\n", .{ anything_changed, changes_expected }); + std.debug.print("std.zig.render returned {} instead of {}\n", .{ anything_changed, changes_expected }); return error.TestFailed; } try std.testing.expect(anything_changed == changes_expected); allocator.free(result_source); } fn testTransform(source: [:0]const u8, expected_source: []const u8) !void { + const io = std.testing.io; var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); - return std.testing.checkAllAllocationFailures(fixed_allocator.allocator(), testTransformImpl, .{ &fixed_allocator, source, expected_source }); + return std.testing.checkAllAllocationFailures(fixed_allocator.allocator(), testTransformImpl, .{ + io, &fixed_allocator, source, expected_source, + }); } fn testCanonical(source: [:0]const u8) !void { return testTransform(source, source); diff --git a/src/Air/print.zig b/src/Air/print.zig index 95c8a1fcda..05614a0ed3 100644 --- a/src/Air/print.zig +++ b/src/Air/print.zig @@ -9,7 +9,7 @@ const Type = @import("../Type.zig"); const Air = @import("../Air.zig"); const InternPool = @import("../InternPool.zig"); -pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { +pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) !void { comptime assert(build_options.enable_debug_extensions); const instruction_bytes = air.instructions.len * // Here we don't use @sizeOf(Air.Inst.Data) because it would include @@ -24,7 +24,7 @@ pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air liveness_special_bytes + tomb_bytes; // zig fmt: off - stream.print( + try stream.print( \\# Total AIR+Liveness bytes: {Bi} \\# AIR Instructions: {d} ({Bi}) \\# AIR Extra Data: {d} ({Bi}) @@ -39,7 +39,7 @@ pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air tomb_bytes, if (liveness) |l| l.extra.len else 0, liveness_extra_bytes, if (liveness) |l| l.special.count() else 0, liveness_special_bytes, - }) catch return; + }); // zig fmt: on var writer: Writer = .{ @@ -50,7 +50,7 @@ pub fn write(air: Air, stream: *std.Io.Writer, pt: Zcu.PerThread, liveness: ?Air .indent = 2, .skip_body = false, }; - writer.writeBody(stream, air.getMainBody()) catch return; + try writer.writeBody(stream, air.getMainBody()); } pub fn writeInst( @@ -73,15 +73,23 @@ pub fn writeInst( } pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { - const stderr_bw, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - air.write(stderr_bw, pt, liveness); + const comp = pt.zcu.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + air.write(w, pt, liveness); } pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { - const stderr_bw, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - air.writeInst(stderr_bw, inst, pt, liveness); + const comp = pt.zcu.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + air.writeInst(w, inst, pt, liveness); } const Writer = struct { diff --git a/src/Compilation.zig b/src/Compilation.zig index 9e76b8feca..47098317b5 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2088,12 +2088,13 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, if (options.verbose_llvm_cpu_features) { if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { - const stderr_w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print; - stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; - stderr_w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; - stderr_w.print(" features: {s}\n", .{cf}) catch {}; + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + w.print("compilation: {s}\n", .{options.root_name}) catch break :print; + w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; + w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; + w.print(" features: {s}\n", .{cf}) catch {}; } } @@ -4257,12 +4258,13 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { // However, we haven't reported any such error. // This is a compiler bug. print_ctx: { - var stderr_w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; - stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; + w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; while (ref) |r| { - stderr_w.print("referenced by: {f}{s}\n", .{ + w.print("referenced by: {f}{s}\n", .{ zcu.fmtAnalUnit(r.referencer), if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "", }) catch break :print_ctx; @@ -5756,7 +5758,7 @@ pub fn translateC( try argv.appendSlice(comp.global_cc_argv); try argv.appendSlice(owner_mod.cc_argv); try argv.appendSlice(&.{ source_path, "-o", translated_path }); - if (comp.verbose_cimport) dump_argv(argv.items); + if (comp.verbose_cimport) dumpArgv(io, argv.items); } var stdout: []u8 = undefined; @@ -6264,7 +6266,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } if (comp.verbose_cc) { - dump_argv(argv.items); + dumpArgv(io, argv.items); } const err = std.process.execv(arena, argv.items); @@ -6310,7 +6312,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr } if (comp.verbose_cc) { - dump_argv(argv.items); + dumpArgv(io, argv.items); } // Just to save disk space, we delete the files that are never needed again. @@ -7773,17 +7775,22 @@ pub fn lockAndSetMiscFailure( return setMiscFailure(comp, tag, format, args); } -pub fn dump_argv(argv: []const []const u8) void { +pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { var buffer: [64]u8 = undefined; - const stderr, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); - nosuspend { - for (argv, 0..) |arg, i| { - if (i != 0) stderr.writeByte(' ') catch return; - stderr.writeAll(arg) catch return; - } - stderr.writeByte('\n') catch return; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + return dumpArgvWriter(w, argv) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; +} + +fn dumpArgvWriter(w: *Io.Writer, argv: []const []const u8) Io.Writer.Error!void { + for (argv, 0..) |arg, i| { + if (i != 0) try w.writeByte(' '); + try w.writeAll(arg); } + try w.writeByte('\n'); } pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend { diff --git a/src/InternPool.zig b/src/InternPool.zig index 5568c493d9..539cb441c5 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -1,8 +1,11 @@ //! All interned objects have both a value and a type. //! This data structure is self-contained. +const InternPool = @This(); const builtin = @import("builtin"); + const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; @@ -11,10 +14,9 @@ const Cache = std.Build.Cache; const Io = std.Io; const Limb = std.math.big.Limb; const Hash = std.hash.Wyhash; +const Zir = std.zig.Zir; -const InternPool = @This(); const Zcu = @import("Zcu.zig"); -const Zir = std.zig.Zir; /// One item per thread, indexed by `tid`, which is dense and unique per thread. locals: []Local, @@ -11165,12 +11167,16 @@ pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) v @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release); } -pub fn dump(ip: *const InternPool) void { - dumpStatsFallible(ip, std.heap.page_allocator) catch return; - dumpAllFallible(ip) catch return; +pub fn dump(ip: *const InternPool, io: Io) Io.Cancelable!void { + var buffer: [4096]u8 = undefined; + const stderr_writer = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr_writer.interface; + try dumpStatsFallible(ip, w, std.heap.page_allocator); + try dumpAllFallible(ip, w); } -fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { +fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) anyerror!void { var items_len: usize = 0; var extra_len: usize = 0; var limbs_len: usize = 0; @@ -11423,18 +11429,13 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { }; counts.sort(SortContext{ .map = &counts }); const len = @min(50, counts.count()); - std.debug.print(" top 50 tags:\n", .{}); + w.print(" top 50 tags:\n", .{}); for (counts.keys()[0..len], counts.values()[0..len]) |tag, stats| { - std.debug.print(" {s}: {d} occurrences, {d} total bytes\n", .{ - @tagName(tag), stats.count, stats.bytes, - }); + w.print(" {t}: {d} occurrences, {d} total bytes\n", .{ tag, stats.count, stats.bytes }); } } -fn dumpAllFallible(ip: *const InternPool) anyerror!void { - var buffer: [4096]u8 = undefined; - const stderr_bw, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); +fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { for (ip.locals, 0..) |*local, tid| { const items = local.shared.items.view(); for ( @@ -11443,12 +11444,12 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { 0.., ) |tag, data, index| { const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip); - try stderr_bw.print("${d} = {s}(", .{ i, @tagName(tag) }); + try w.print("${d} = {s}(", .{ i, @tagName(tag) }); switch (tag) { .removed => {}, - .simple_type => try stderr_bw.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}), - .simple_value => try stderr_bw.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}), + .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}), + .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}), .type_int_signed, .type_int_unsigned, @@ -11521,23 +11522,27 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { .func_coerced, .union_value, .memoized_call, - => try stderr_bw.print("{d}", .{data}), + => try w.print("{d}", .{data}), .opt_null, .type_slice, .only_possible_value, - => try stderr_bw.print("${d}", .{data}), + => try w.print("${d}", .{data}), } - try stderr_bw.writeAll(")\n"); + try w.writeAll(")\n"); } } } -pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void { - ip.dumpGenericInstancesFallible(allocator) catch return; +pub fn dumpGenericInstances(ip: *const InternPool, io: Io, allocator: Allocator) Io.Cancelable!void { + var buffer: [4096]u8 = undefined; + const stderr_writer = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr_writer.interface; + try ip.dumpGenericInstancesFallible(allocator, w); } -pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) anyerror!void { +pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator, w: *Io.Writer) !void { var arena_allocator = std.heap.ArenaAllocator.init(allocator); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); @@ -11564,10 +11569,6 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) } } - var buffer: [4096]u8 = undefined; - const stderr_bw, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); - const SortContext = struct { values: []std.ArrayList(Index), pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { @@ -11579,19 +11580,19 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) var it = instances.iterator(); while (it.next()) |entry| { const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav); - try stderr_bw.print("{f} ({d}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len }); + try w.print("{f} ({d}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len }); for (entry.value_ptr.items) |index| { const unwrapped_index = index.unwrap(ip); const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip)); const owner_nav = ip.getNav(func.owner_nav); - try stderr_bw.print(" {f}: (", .{owner_nav.name.fmt(ip)}); + try w.print(" {f}: (", .{owner_nav.name.fmt(ip)}); for (func.comptime_args.get(ip)) |arg| { if (arg != .none) { const key = ip.indexToKey(arg); - try stderr_bw.print(" {} ", .{key}); + try w.print(" {} ", .{key}); } } - try stderr_bw.writeAll(")\n"); + try w.writeAll(")\n"); } } } diff --git a/src/Sema.zig b/src/Sema.zig index fec6850c4c..1f6a577f60 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2668,16 +2668,18 @@ fn failWithTypeMismatch(sema: *Sema, block: *Block, src: LazySrcLoc, expected: T pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg) error{ AnalysisFail, OutOfMemory } { @branchHint(.cold); - const gpa = sema.gpa; const zcu = sema.pt.zcu; + const comp = zcu.comp; + const gpa = comp.gpa; + const io = comp.io; - if (build_options.enable_debug_extensions and zcu.comp.debug_compile_errors) { + if (build_options.enable_debug_extensions and comp.debug_compile_errors) { var wip_errors: std.zig.ErrorBundle.Wip = undefined; wip_errors.init(gpa) catch @panic("out of memory"); Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory"); std.debug.print("compile error during Sema:\n", .{}); var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory"); - error_bundle.renderToStdErr(.{}, .auto); + error_bundle.renderToStderr(io, .{}, .auto); std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{}); } diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 2333d7f286..408f16bd74 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -4556,8 +4556,9 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e defer if (liveness) |*l| l.deinit(gpa); if (build_options.enable_debug_extensions and comp.verbose_air) { - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); + const io = comp.io; + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {}; air.write(stderr, pt, liveness); stderr.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)}) catch {}; diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index f390d83f03..138c70fecf 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11273,15 +11273,18 @@ fn initValueAdvanced( return @enumFromInt(isel.values.items.len); } pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { - errdefer |err| @panic(@errorName(err)); - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - const zcu = isel.pt.zcu; + const io = zcu.comp.io; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const nav = ip.getNav(isel.nav_index); + errdefer |err| @panic(@errorName(err)); + + const stderr_writer = io.lockStderrWriter(&.{}) catch return; + defer io.unlockStderrWriter(); + const stderr = &stderr_writer.interface; + var reverse_live_values: std.AutoArrayHashMapUnmanaged(Value.Index, std.ArrayList(Air.Inst.Index)) = .empty; defer { for (reverse_live_values.values()) |*list| list.deinit(gpa); diff --git a/src/crash_report.zig b/src/crash_report.zig index 76503fdc53..f23806b758 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -97,17 +97,18 @@ fn dumpCrashContext() Io.Writer.Error!void { // and the actual panic printing, which would be quite confusing. const stderr = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); + const w = &stderr.interface; - try stderr.interface.writeAll("Compiler crash context:\n"); + try w.writeAll("Compiler crash context:\n"); if (CodegenFunc.current) |*cg| { const func_nav = cg.zcu.funcInfo(cg.func_index).owner_nav; const func_fqn = cg.zcu.intern_pool.getNav(func_nav).fqn; - try stderr.interface.print("Generating function '{f}'\n\n", .{func_fqn.fmt(&cg.zcu.intern_pool)}); + try w.print("Generating function '{f}'\n\n", .{func_fqn.fmt(&cg.zcu.intern_pool)}); } else if (AnalyzeBody.current) |anal| { - try dumpCrashContextSema(anal, &stderr.interface, &S.crash_heap); + try dumpCrashContextSema(anal, w, &S.crash_heap); } else { - try stderr.interface.writeAll("(no context)\n\n"); + try w.writeAll("(no context)\n\n"); } } fn dumpCrashContextSema(anal: *AnalyzeBody, stderr: *Io.Writer, crash_heap: []u8) Io.Writer.Error!void { diff --git a/src/fmt.zig b/src/fmt.zig index 55a68d1dc8..b9b1cc1363 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! try wip_errors.addZirErrorMessages(zir, tree, source_code, ""); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(2); } } else { @@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! try wip_errors.addZoirErrorMessages(zoir, tree, source_code, ""); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(2); } } @@ -319,7 +319,7 @@ fn fmtPathFile( try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, fmt.color); + error_bundle.renderToStderr(io, .{}, fmt.color); fmt.any_error = true; } }, @@ -334,7 +334,7 @@ fn fmtPathFile( try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path); var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, fmt.color); + error_bundle.renderToStderr(io, .{}, fmt.color); fmt.any_error = true; } }, diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 05a9de71e7..a76fec9237 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -312,11 +312,17 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" }); - if (comp.verbose_cc) print: { - var stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print; - nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print; + if (comp.verbose_cc) { + var buffer: [256]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + w.print("def file: {s}\n", .{def_file_path}) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; + w.print("include dir: {s}\n", .{include_dir}) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; } try aro_comp.search_path.append(gpa, .{ .path = include_dir, .kind = .normal }); @@ -333,11 +339,13 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) { var buffer: [64]u8 = undefined; - const w, const ttyconf = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); for (aro_comp.diagnostics.output.to_list.messages.items) |msg| { if (msg.kind == .@"fatal error" or msg.kind == .@"error") { - msg.write(w, ttyconf, true) catch {}; + msg.write(&stderr.interface, stderr.mode, true) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; return error.AroPreprocessorFailed; } } @@ -357,8 +365,9 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { error.OutOfMemory => |e| return e, error.ParseError => { var buffer: [64]u8 = undefined; - const w, _ = std.debug.lockStderrWriter(&buffer); - defer std.debug.unlockStderrWriter(); + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; try w.writeAll("error: "); try def_diagnostics.writeMsg(w, input); try w.writeByte('\n'); diff --git a/src/libs/mingw/def.zig b/src/libs/mingw/def.zig index 24dc95c13c..9a105b6182 100644 --- a/src/libs/mingw/def.zig +++ b/src/libs/mingw/def.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; pub const ModuleDefinitionType = enum { mingw, @@ -663,7 +664,9 @@ test parse { \\ ; - try testParse(.AMD64, source, "foo.dll", &[_]ModuleDefinition.Export{ + const io = std.testing.io; + + try testParse(io, .AMD64, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "foo", .mangled_symbol_name = null, @@ -743,7 +746,7 @@ test parse { }, }); - try testParse(.I386, source, "foo.dll", &[_]ModuleDefinition.Export{ + try testParse(io, .I386, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "_foo", .mangled_symbol_name = null, @@ -823,7 +826,7 @@ test parse { }, }); - try testParse(.ARMNT, source, "foo.dll", &[_]ModuleDefinition.Export{ + try testParse(io, .ARMNT, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "foo", .mangled_symbol_name = null, @@ -903,7 +906,7 @@ test parse { }, }); - try testParse(.ARM64, source, "foo.dll", &[_]ModuleDefinition.Export{ + try testParse(io, .ARM64, source, "foo.dll", &[_]ModuleDefinition.Export{ .{ .name = "foo", .mangled_symbol_name = null, @@ -997,7 +1000,9 @@ test "ntdll" { \\RtlActivateActivationContextUnsafeFast@0 ; - try testParse(.AMD64, source, "ntdll.dll", &[_]ModuleDefinition.Export{ + const io = std.testing.io; + + try testParse(io, .AMD64, source, "ntdll.dll", &[_]ModuleDefinition.Export{ .{ .name = "RtlDispatchAPC@12", .mangled_symbol_name = null, @@ -1023,15 +1028,22 @@ test "ntdll" { }); } -fn testParse(machine_type: std.coff.IMAGE.FILE.MACHINE, source: [:0]const u8, expected_module_name: []const u8, expected_exports: []const ModuleDefinition.Export) !void { +fn testParse( + io: Io, + machine_type: std.coff.IMAGE.FILE.MACHINE, + source: [:0]const u8, + expected_module_name: []const u8, + expected_exports: []const ModuleDefinition.Export, +) !void { var diagnostics: Diagnostics = undefined; const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) { error.OutOfMemory => |e| return e, error.ParseError => { - const stderr, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - try diagnostics.writeMsg(stderr, source); - try stderr.writeByte('\n'); + const stderr = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + try diagnostics.writeMsg(w, source); + try w.writeByte('\n'); return err; }, }; diff --git a/src/link.zig b/src/link.zig index e37ba98cd9..a4729f296c 100644 --- a/src/link.zig +++ b/src/link.zig @@ -2246,7 +2246,7 @@ fn resolvePathInputLib( var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); std.process.exit(1); } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 8954266e3f..d379669613 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -4,6 +4,7 @@ const builtin = @import("builtin"); const native_endian = builtin.cpu.arch.endian(); const std = @import("std"); +const Io = std.Io; const assert = std.debug.assert; const log = std.log.scoped(.link); @@ -2377,10 +2378,16 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe _ = name; } -pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void { - const w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - coff.printNode(tid, w, .root, 0) catch {}; +pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void { + const comp = coff.base.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + coff.printNode(tid, w, .root, 0) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; } pub fn printNode( diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index fc4794a7b0..3c511f1ee9 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -3729,10 +3729,16 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm _ = name; } -pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void { - const w, _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - elf.printNode(tid, w, .root, 0) catch {}; +pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { + const comp = elf.base.comp; + const io = comp.io; + var buffer: [512]u8 = undefined; + const stderr = try io.lockStderrWriter(&buffer); + defer io.unlockStderrWriter(); + const w = &stderr.interface; + elf.printNode(tid, w, .root, 0) catch |err| switch (err) { + error.WriteFailed => return stderr.err.?, + }; } pub fn printNode( diff --git a/src/main.zig b/src/main.zig index 115c1b5212..f735f671c6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4429,9 +4429,9 @@ fn runOrTest( // the error message and invocation below. if (process.can_execv and arg_mode == .run) { // execv releases the locks; no need to destroy the Compilation here. - _ = std.debug.lockStderrWriter(&.{}); + _ = try io.lockStderrWriter(&.{}); const err = process.execve(gpa, argv.items, &env_map); - std.debug.unlockStderrWriter(); + io.unlockStderrWriter(); try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd }); @@ -4448,8 +4448,8 @@ fn runOrTest( comp_destroyed.* = true; const term_result = t: { - _ = std.debug.lockStderrWriter(); - defer std.debug.unlockStderrWriter(); + _ = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); break :t child.spawnAndWait(io); }; const term = term_result catch |err| { @@ -4606,7 +4606,8 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node) defer errors.deinit(comp.gpa); if (errors.errorMessageCount() > 0) { - errors.renderToStdErr(.{}, color); + const io = comp.io; + errors.renderToStderr(io, .{}, color); return error.CompileErrorsReported; } } @@ -4659,7 +4660,7 @@ fn cmdTranslateC( return; } else { const color: Color = .auto; - result.errors.renderToStdErr(.{}, color); + result.errors.renderToStderr(io, .{}, color); process.exit(1); } } @@ -5280,7 +5281,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) if (fetch.error_bundle.root_list.items.len > 0) { var errors = try fetch.error_bundle.toOwnedBundle(""); - errors.renderToStdErr(.{}, color); + errors.renderToStderr(io, .{}, color); process.exit(1); } @@ -5412,8 +5413,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) child.stderr_behavior = .Inherit; const term = t: { - _ = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); + _ = try io.lockStderrWriter(&.{}); + defer io.unlockStderrWriter(); break :t child.spawnAndWait(io) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); }; @@ -6212,7 +6213,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZirErrorMessages(zir, tree, source, display_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); if (zir.loweringFailed()) { process.exit(1); } @@ -6283,7 +6284,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(1); } @@ -6557,7 +6558,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(1); } @@ -6569,7 +6570,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void { try wip_errors.init(arena); try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path); var error_bundle = try wip_errors.toOwnedBundle(""); - error_bundle.renderToStdErr(.{}, color); + error_bundle.renderToStderr(io, .{}, color); process.exit(1); } @@ -7005,7 +7006,7 @@ fn cmdFetch( if (fetch.error_bundle.root_list.items.len > 0) { var errors = try fetch.error_bundle.toOwnedBundle(""); - errors.renderToStdErr(.{}, color); + errors.renderToStderr(io, .{}, color); process.exit(1); } @@ -7345,7 +7346,7 @@ fn loadManifest( errdefer ast.deinit(gpa); if (ast.errors.len > 0) { - try std.zig.printAstErrorsToStderr(gpa, ast, Package.Manifest.basename, options.color); + try std.zig.printAstErrorsToStderr(gpa, io, ast, Package.Manifest.basename, options.color); process.exit(2); } @@ -7362,7 +7363,7 @@ fn loadManifest( var error_bundle = try wip_errors.toOwnedBundle(""); defer error_bundle.deinit(gpa); - error_bundle.renderToStdErr(.{}, options.color); + error_bundle.renderToStderr(io, .{}, options.color); process.exit(2); } -- cgit v1.2.3 From 608145c2f07d90c46cdaa8bc2013f31b965a5b8b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 17 Dec 2025 17:00:41 -0800 Subject: fix more fallout from locking stderr --- lib/compiler/aro/aro/Diagnostics.zig | 28 ++- lib/compiler/build_runner.zig | 338 +++++++++++++++++------------------ lib/compiler/resinator/cli.zig | 10 +- lib/compiler/resinator/errors.zig | 6 +- lib/compiler/resinator/main.zig | 31 ++-- lib/compiler/test_runner.zig | 8 +- lib/std/Build.zig | 73 ++++---- lib/std/Build/Fuzz.zig | 18 +- lib/std/Build/Step.zig | 9 +- lib/std/Build/Step/Compile.zig | 17 +- lib/std/Build/Step/Run.zig | 22 +-- lib/std/Io.zig | 2 +- lib/std/Io/File/Writer.zig | 2 +- lib/std/Io/Terminal.zig | 22 --- lib/std/Io/Threaded.zig | 6 +- lib/std/debug.zig | 24 +-- lib/std/debug/simple_panic.zig | 6 +- lib/std/json/dynamic.zig | 6 +- lib/std/log.zig | 2 +- lib/std/process.zig | 2 +- lib/std/testing.zig | 21 +-- lib/std/zig.zig | 21 +-- lib/std/zig/ErrorBundle.zig | 72 ++++---- lib/std/zig/parser_test.zig | 16 +- src/Air/print.zig | 12 +- src/Compilation.zig | 45 +++-- src/InternPool.zig | 10 +- src/Zcu/PerThread.zig | 8 +- src/codegen/aarch64/Select.zig | 7 +- src/crash_report.zig | 6 +- src/libs/mingw.zig | 24 +-- src/libs/mingw/def.zig | 6 +- src/link/Coff.zig | 6 +- src/link/Elf2.zig | 6 +- src/main.zig | 12 +- 35 files changed, 446 insertions(+), 458 deletions(-) (limited to 'src/codegen') diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index bebcf4e3d2..b33efa3f85 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -24,20 +24,21 @@ pub const Message = struct { @"fatal error", }; - pub fn write(msg: Message, w: *std.Io.Writer, config: std.Io.File.Writer.Mode, details: bool) std.Io.tty.Config.SetColorError!void { - try config.setColor(w, .bold); + pub fn write(msg: Message, t: std.Io.Terminal, details: bool) std.Io.Terminal.SetColorError!void { + const w = t.writer; + try t.setColor(.bold); if (msg.location) |loc| { try w.print("{s}:{d}:{d}: ", .{ loc.path, loc.line_no, loc.col }); } switch (msg.effective_kind) { - .@"fatal error", .@"error" => try config.setColor(w, .bright_red), - .note => try config.setColor(w, .bright_cyan), - .warning => try config.setColor(w, .bright_magenta), + .@"fatal error", .@"error" => try t.setColor(.bright_red), + .note => try t.setColor(.bright_cyan), + .warning => try t.setColor(.bright_magenta), .off => unreachable, } try w.print("{s}: ", .{@tagName(msg.effective_kind)}); - try config.setColor(w, .white); + try t.setColor(.white); try w.writeAll(msg.text); if (msg.opt) |some| { if (msg.effective_kind == .@"error" and msg.kind != .@"error") { @@ -55,17 +56,17 @@ pub const Message = struct { if (!details or msg.location == null) { try w.writeAll("\n"); - try config.setColor(w, .reset); + try t.setColor(.reset); } else { const loc = msg.location.?; const trailer = if (loc.end_with_splice) "\\ " else ""; - try config.setColor(w, .reset); + try t.setColor(.reset); try w.print("\n{s}{s}\n", .{ loc.line, trailer }); try w.splatByteAll(' ', loc.width); - try config.setColor(w, .bold); - try config.setColor(w, .bright_green); + try t.setColor(.bold); + try t.setColor(.bright_green); try w.writeAll("^\n"); - try config.setColor(w, .reset); + try t.setColor(.reset); } try w.flush(); } @@ -290,10 +291,7 @@ pub const State = struct { const Diagnostics = @This(); output: union(enum) { - to_writer: struct { - writer: *std.Io.Writer, - color: std.Io.File.Writer.Mode, - }, + to_writer: std.Io.Terminal, to_list: struct { messages: std.ArrayList(Message) = .empty, arena: std.heap.ArenaAllocator, diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index d284d85747..1c30ecaadc 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -286,8 +286,8 @@ pub fn main() !void { const next_arg = nextArg(args, &arg_idx) orelse fatalWithHint("expected u16 after '{s}'", .{arg}); debounce_interval_ms = std.fmt.parseUnsigned(u16, next_arg, 0) catch |err| { - fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {s}\n", .{ - next_arg, @errorName(err), + fatal("unable to parse debounce interval '{s}' as unsigned 16-bit integer: {t}\n", .{ + next_arg, err, }); }; } else if (mem.eql(u8, arg, "--webui")) { @@ -429,6 +429,12 @@ pub fn main() !void { } } + graph.stderr_mode = switch (color) { + .auto => try .detect(io, .stderr()), + .on => .escape_codes, + .off => .no_color, + }; + if (webui_listen != null) { if (watch) fatal("using '--webui' and '--watch' together is not yet supported; consider omitting '--watch' in favour of the web UI \"Rebuild\" button", .{}); if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{}); @@ -522,7 +528,7 @@ pub fn main() !void { // Perhaps in the future there could be an Advanced Options flag // such as --debug-build-runner-leaks which would make this code // return instead of calling exit. - _ = io.lockStderrWriter(&.{}) catch {}; + _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; process.exit(1); }, else => |e| return e, @@ -554,9 +560,9 @@ pub fn main() !void { } rebuild: while (true) : (if (run.error_style.clearOnUpdate()) { - const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); - defer io.unlockStderrWriter(); - try stderr.writeAllUnescaped("\x1B[2J\x1B[3J\x1B[H"); + const stderr = try io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode); + defer io.unlockStderr(); + try stderr.file_writer.interface.writeAll("\x1B[2J\x1B[3J\x1B[H"); }) { if (run.web_server) |*ws| ws.startBuild(); @@ -730,7 +736,8 @@ fn runStepNames( fuzz: ?std.Build.Fuzz.Mode, ) !void { const gpa = run.gpa; - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; const step_stack = &run.step_stack; { @@ -856,20 +863,19 @@ fn runStepNames( .none => break :summary, } - const stderr = try io.lockStderrWriter(&stdio_buffer_allocation); - defer io.unlockStderrWriter(); - - const w = &stderr.interface; - const fwm = stderr.mode; + const stderr = try io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode); + defer io.unlockStderr(); + const t = stderr.terminal(); + const w = &stderr.file_writer.interface; const total_count = success_count + failure_count + pending_count + skipped_count; - fwm.setColor(w, .cyan) catch {}; - fwm.setColor(w, .bold) catch {}; + t.setColor(.cyan) catch {}; + t.setColor(.bold) catch {}; w.writeAll("Build Summary: ") catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; w.print("{d}/{d} steps succeeded", .{ success_count, total_count }) catch {}; { - fwm.setColor(w, .dim) catch {}; + t.setColor(.dim) catch {}; var first = true; if (skipped_count > 0) { w.print("{s}{d} skipped", .{ if (first) " (" else ", ", skipped_count }) catch {}; @@ -880,12 +886,12 @@ fn runStepNames( first = false; } if (!first) w.writeByte(')') catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; } if (test_count > 0) { w.print("; {d}/{d} tests passed", .{ test_pass_count, test_count }) catch {}; - fwm.setColor(w, .dim) catch {}; + t.setColor(.dim) catch {}; var first = true; if (test_skip_count > 0) { w.print("{s}{d} skipped", .{ if (first) " (" else ", ", test_skip_count }) catch {}; @@ -904,7 +910,7 @@ fn runStepNames( first = false; } if (!first) w.writeByte(')') catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; } w.writeAll("\n") catch {}; @@ -918,7 +924,7 @@ fn runStepNames( var print_node: PrintNode = .{ .parent = null }; if (step_names.len == 0) { print_node.last = true; - printTreeStep(b, b.default_step, run, w, fwm, &print_node, &step_stack_copy) catch {}; + printTreeStep(b, b.default_step, run, t, &print_node, &step_stack_copy) catch {}; } else { const last_index = if (run.summary == .all) b.top_level_steps.count() else blk: { var i: usize = step_names.len; @@ -937,7 +943,7 @@ fn runStepNames( for (step_names, 0..) |step_name, i| { const tls = b.top_level_steps.get(step_name).?; print_node.last = i + 1 == last_index; - printTreeStep(b, &tls.step, run, w, fwm, &print_node, &step_stack_copy) catch {}; + printTreeStep(b, &tls.step, run, t, &print_node, &step_stack_copy) catch {}; } } w.writeByte('\n') catch {}; @@ -954,7 +960,7 @@ fn runStepNames( if (run.error_style.verboseContext()) break :code 1; // failure; print build command break :code 2; // failure; do not print build command }; - _ = io.lockStderrWriter(&.{}) catch {}; + _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; process.exit(code); } @@ -963,33 +969,30 @@ const PrintNode = struct { last: bool = false, }; -fn printPrefix(node: *PrintNode, w: *Writer, fwm: File.Writer.Mode) !void { +fn printPrefix(node: *PrintNode, stderr: Io.Terminal) !void { const parent = node.parent orelse return; + const writer = stderr.writer; if (parent.parent == null) return; - try printPrefix(parent, w, fwm); + try printPrefix(parent, stderr); if (parent.last) { - try w.writeAll(" "); + try writer.writeAll(" "); } else { - try w.writeAll(switch (fwm) { - .terminal_escaped => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │ + try writer.writeAll(switch (stderr.mode) { + .escape_codes => "\x1B\x28\x30\x78\x1B\x28\x42 ", // │ else => "| ", }); } } -fn printChildNodePrefix(w: *Writer, fwm: File.Writer.Mode) !void { - try w.writeAll(switch (fwm) { - .terminal_escaped => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─ +fn printChildNodePrefix(stderr: Io.Terminal) !void { + try stderr.writer.writeAll(switch (stderr.mode) { + .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─ else => "+- ", }); } -fn printStepStatus( - s: *Step, - stderr: *Writer, - fwm: File.Writer.Mode, - run: *const Run, -) !void { +fn printStepStatus(s: *Step, stderr: Io.Terminal, run: *const Run) !void { + const writer = stderr.writer; switch (s.state) { .precheck_unstarted => unreachable, .precheck_started => unreachable, @@ -997,139 +1000,135 @@ fn printStepStatus( .running => unreachable, .dependency_failure => { - try fwm.setColor(stderr, .dim); - try stderr.writeAll(" transitive failure\n"); - try fwm.setColor(stderr, .reset); + try stderr.setColor(.dim); + try writer.writeAll(" transitive failure\n"); + try stderr.setColor(.reset); }, .success => { - try fwm.setColor(stderr, .green); + try stderr.setColor(.green); if (s.result_cached) { - try stderr.writeAll(" cached"); + try writer.writeAll(" cached"); } else if (s.test_results.test_count > 0) { const pass_count = s.test_results.passCount(); assert(s.test_results.test_count == pass_count + s.test_results.skip_count); - try stderr.print(" {d} pass", .{pass_count}); + try writer.print(" {d} pass", .{pass_count}); if (s.test_results.skip_count > 0) { - try fwm.setColor(stderr, .reset); - try stderr.writeAll(", "); - try fwm.setColor(stderr, .yellow); - try stderr.print("{d} skip", .{s.test_results.skip_count}); + try stderr.setColor(.reset); + try writer.writeAll(", "); + try stderr.setColor(.yellow); + try writer.print("{d} skip", .{s.test_results.skip_count}); } - try fwm.setColor(stderr, .reset); - try stderr.print(" ({d} total)", .{s.test_results.test_count}); + try stderr.setColor(.reset); + try writer.print(" ({d} total)", .{s.test_results.test_count}); } else { - try stderr.writeAll(" success"); + try writer.writeAll(" success"); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); if (s.result_duration_ns) |ns| { - try fwm.setColor(stderr, .dim); + try stderr.setColor(.dim); if (ns >= std.time.ns_per_min) { - try stderr.print(" {d}m", .{ns / std.time.ns_per_min}); + try writer.print(" {d}m", .{ns / std.time.ns_per_min}); } else if (ns >= std.time.ns_per_s) { - try stderr.print(" {d}s", .{ns / std.time.ns_per_s}); + try writer.print(" {d}s", .{ns / std.time.ns_per_s}); } else if (ns >= std.time.ns_per_ms) { - try stderr.print(" {d}ms", .{ns / std.time.ns_per_ms}); + try writer.print(" {d}ms", .{ns / std.time.ns_per_ms}); } else if (ns >= std.time.ns_per_us) { - try stderr.print(" {d}us", .{ns / std.time.ns_per_us}); + try writer.print(" {d}us", .{ns / std.time.ns_per_us}); } else { - try stderr.print(" {d}ns", .{ns}); + try writer.print(" {d}ns", .{ns}); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } if (s.result_peak_rss != 0) { const rss = s.result_peak_rss; - try fwm.setColor(stderr, .dim); + try stderr.setColor(.dim); if (rss >= 1000_000_000) { - try stderr.print(" MaxRSS:{d}G", .{rss / 1000_000_000}); + try writer.print(" MaxRSS:{d}G", .{rss / 1000_000_000}); } else if (rss >= 1000_000) { - try stderr.print(" MaxRSS:{d}M", .{rss / 1000_000}); + try writer.print(" MaxRSS:{d}M", .{rss / 1000_000}); } else if (rss >= 1000) { - try stderr.print(" MaxRSS:{d}K", .{rss / 1000}); + try writer.print(" MaxRSS:{d}K", .{rss / 1000}); } else { - try stderr.print(" MaxRSS:{d}B", .{rss}); + try writer.print(" MaxRSS:{d}B", .{rss}); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } - try stderr.writeAll("\n"); + try writer.writeAll("\n"); }, .skipped, .skipped_oom => |skip| { - try fwm.setColor(stderr, .yellow); - try stderr.writeAll(" skipped"); + try stderr.setColor(.yellow); + try writer.writeAll(" skipped"); if (skip == .skipped_oom) { - try stderr.writeAll(" (not enough memory)"); - try fwm.setColor(stderr, .dim); - try stderr.print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss }); - try fwm.setColor(stderr, .yellow); + try writer.writeAll(" (not enough memory)"); + try stderr.setColor(.dim); + try writer.print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss }); + try stderr.setColor(.yellow); } - try stderr.writeAll("\n"); - try fwm.setColor(stderr, .reset); + try writer.writeAll("\n"); + try stderr.setColor(.reset); }, .failure => { - try printStepFailure(s, stderr, fwm, false); - try fwm.setColor(stderr, .reset); + try printStepFailure(s, stderr, false); + try stderr.setColor(.reset); }, } } -fn printStepFailure( - s: *Step, - stderr: *Writer, - fwm: File.Writer.Mode, - dim: bool, -) !void { +fn printStepFailure(s: *Step, stderr: Io.Terminal, dim: bool) !void { + const w = stderr.writer; if (s.result_error_bundle.errorMessageCount() > 0) { - try fwm.setColor(stderr, .red); - try stderr.print(" {d} errors\n", .{ + try stderr.setColor(.red); + try w.print(" {d} errors\n", .{ s.result_error_bundle.errorMessageCount(), }); } else if (!s.test_results.isSuccess()) { // These first values include all of the test "statuses". Every test is either passsed, // skipped, failed, crashed, or timed out. - try fwm.setColor(stderr, .green); - try stderr.print(" {d} pass", .{s.test_results.passCount()}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try stderr.setColor(.green); + try w.print(" {d} pass", .{s.test_results.passCount()}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); if (s.test_results.skip_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .yellow); - try stderr.print("{d} skip", .{s.test_results.skip_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.yellow); + try w.print("{d} skip", .{s.test_results.skip_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } if (s.test_results.fail_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} fail", .{s.test_results.fail_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.red); + try w.print("{d} fail", .{s.test_results.fail_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } if (s.test_results.crash_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} crash", .{s.test_results.crash_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.red); + try w.print("{d} crash", .{s.test_results.crash_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } if (s.test_results.timeout_count > 0) { - try stderr.writeAll(", "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} timeout", .{s.test_results.timeout_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll(", "); + try stderr.setColor(.red); + try w.print("{d} timeout", .{s.test_results.timeout_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } - try stderr.print(" ({d} total)", .{s.test_results.test_count}); + try w.print(" ({d} total)", .{s.test_results.test_count}); // Memory leaks are intentionally written after the total, because is isn't a test *status*, // but just a flag that any tests -- even passed ones -- can have. We also use a different // separator, so it looks like: // 2 pass, 1 skip, 2 fail (5 total); 2 leaks if (s.test_results.leak_count > 0) { - try stderr.writeAll("; "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} leaks", .{s.test_results.leak_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll("; "); + try stderr.setColor(.red); + try w.print("{d} leaks", .{s.test_results.leak_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } // It's usually not helpful to know how many error logs there were because they tend to @@ -1142,21 +1141,21 @@ fn printStepFailure( break :show alt_results.isSuccess(); }; if (show_err_logs) { - try stderr.writeAll("; "); - try fwm.setColor(stderr, .red); - try stderr.print("{d} error logs", .{s.test_results.log_err_count}); - try fwm.setColor(stderr, .reset); - if (dim) try fwm.setColor(stderr, .dim); + try w.writeAll("; "); + try stderr.setColor(.red); + try w.print("{d} error logs", .{s.test_results.log_err_count}); + try stderr.setColor(.reset); + if (dim) try stderr.setColor(.dim); } - try stderr.writeAll("\n"); + try w.writeAll("\n"); } else if (s.result_error_msgs.items.len > 0) { - try fwm.setColor(stderr, .red); - try stderr.writeAll(" failure\n"); + try stderr.setColor(.red); + try w.writeAll(" failure\n"); } else { assert(s.result_stderr.len > 0); - try fwm.setColor(stderr, .red); - try stderr.writeAll(" stderr\n"); + try stderr.setColor(.red); + try w.writeAll(" w\n"); } } @@ -1164,11 +1163,11 @@ fn printTreeStep( b: *std.Build, s: *Step, run: *const Run, - stderr: *Writer, - fwm: File.Writer.Mode, + stderr: Io.Terminal, parent_node: *PrintNode, step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), ) !void { + const writer = stderr.writer; const first = step_stack.swapRemove(s); const summary = run.summary; const skip = switch (summary) { @@ -1178,26 +1177,26 @@ fn printTreeStep( .failures => s.state == .success, }; if (skip) return; - try printPrefix(parent_node, stderr, fwm); + try printPrefix(parent_node, stderr); if (parent_node.parent != null) { if (parent_node.last) { - try printChildNodePrefix(stderr, fwm); + try printChildNodePrefix(stderr); } else { - try stderr.writeAll(switch (fwm) { - .terminal_escaped => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─ + try writer.writeAll(switch (stderr.mode) { + .escape_codes => "\x1B\x28\x30\x74\x71\x1B\x28\x42 ", // ├─ else => "+- ", }); } } - if (!first) try fwm.setColor(stderr, .dim); + if (!first) try stderr.setColor(.dim); // dep_prefix omitted here because it is redundant with the tree. - try stderr.writeAll(s.name); + try writer.writeAll(s.name); if (first) { - try printStepStatus(s, stderr, fwm, run); + try printStepStatus(s, stderr, run); const last_index = if (summary == .all) s.dependencies.items.len -| 1 else blk: { var i: usize = s.dependencies.items.len; @@ -1219,17 +1218,17 @@ fn printTreeStep( .parent = parent_node, .last = i == last_index, }; - try printTreeStep(b, dep, run, stderr, fwm, &print_node, step_stack); + try printTreeStep(b, dep, run, stderr, &print_node, step_stack); } } else { if (s.dependencies.items.len == 0) { - try stderr.writeAll(" (reused)\n"); + try writer.writeAll(" (reused)\n"); } else { - try stderr.print(" (+{d} more reused dependencies)\n", .{ + try writer.print(" (+{d} more reused dependencies)\n", .{ s.dependencies.items.len, }); } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } } @@ -1300,7 +1299,8 @@ fn workerMakeOneStep( prog_node: std.Progress.Node, run: *Run, ) void { - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; const gpa = run.gpa; // First, check the conditions for running this step. If they are not met, @@ -1369,11 +1369,11 @@ fn workerMakeOneStep( const show_error_msgs = s.result_error_msgs.items.len > 0; const show_stderr = s.result_stderr.len > 0; if (show_error_msgs or show_compile_errors or show_stderr) { - const stderr = io.lockStderrWriter(&stdio_buffer_allocation) catch |err| switch (err) { + const stderr = io.lockStderr(&stdio_buffer_allocation, graph.stderr_mode) catch |err| switch (err) { error.Canceled => return, }; - defer io.unlockStderrWriter(); - printErrorMessages(gpa, s, .{}, &stderr.interface, stderr.mode, run.error_style, run.multiline_errors) catch {}; + defer io.unlockStderr(); + printErrorMessages(gpa, s, .{}, stderr.terminal(), run.error_style, run.multiline_errors) catch {}; } handle_result: { @@ -1440,11 +1440,11 @@ pub fn printErrorMessages( gpa: Allocator, failing_step: *Step, options: std.zig.ErrorBundle.RenderOptions, - stderr: *Writer, - fwm: File.Writer.Mode, + stderr: Io.Terminal, error_style: ErrorStyle, multiline_errors: MultilineErrors, ) !void { + const writer = stderr.writer; if (error_style.verboseContext()) { // Provide context for where these error messages are coming from by // printing the corresponding Step subtree. @@ -1456,70 +1456,70 @@ pub fn printErrorMessages( } // Now, `step_stack` has the subtree that we want to print, in reverse order. - try fwm.setColor(stderr, .dim); + try stderr.setColor(.dim); var indent: usize = 0; while (step_stack.pop()) |s| : (indent += 1) { if (indent > 0) { - try stderr.splatByteAll(' ', (indent - 1) * 3); - try printChildNodePrefix(stderr, fwm); + try writer.splatByteAll(' ', (indent - 1) * 3); + try printChildNodePrefix(stderr); } - try stderr.writeAll(s.name); + try writer.writeAll(s.name); if (s == failing_step) { - try printStepFailure(s, stderr, fwm, true); + try printStepFailure(s, stderr, true); } else { - try stderr.writeAll("\n"); + try writer.writeAll("\n"); } } - try fwm.setColor(stderr, .reset); + try stderr.setColor(.reset); } else { // Just print the failing step itself. - try fwm.setColor(stderr, .dim); - try stderr.writeAll(failing_step.name); - try printStepFailure(failing_step, stderr, fwm, true); - try fwm.setColor(stderr, .reset); + try stderr.setColor(.dim); + try writer.writeAll(failing_step.name); + try printStepFailure(failing_step, stderr, true); + try stderr.setColor(.reset); } if (failing_step.result_stderr.len > 0) { - try stderr.writeAll(failing_step.result_stderr); + try writer.writeAll(failing_step.result_stderr); if (!mem.endsWith(u8, failing_step.result_stderr, "\n")) { - try stderr.writeAll("\n"); + try writer.writeAll("\n"); } } - try failing_step.result_error_bundle.renderToWriter(options, stderr, fwm); + try failing_step.result_error_bundle.renderToTerminal(options, stderr); for (failing_step.result_error_msgs.items) |msg| { - try fwm.setColor(stderr, .red); - try stderr.writeAll("error:"); - try fwm.setColor(stderr, .reset); + try stderr.setColor(.red); + try writer.writeAll("error:"); + try stderr.setColor(.reset); if (std.mem.indexOfScalar(u8, msg, '\n') == null) { - try stderr.print(" {s}\n", .{msg}); + try writer.print(" {s}\n", .{msg}); } else switch (multiline_errors) { .indent => { var it = std.mem.splitScalar(u8, msg, '\n'); - try stderr.print(" {s}\n", .{it.first()}); + try writer.print(" {s}\n", .{it.first()}); while (it.next()) |line| { - try stderr.print(" {s}\n", .{line}); + try writer.print(" {s}\n", .{line}); } }, - .newline => try stderr.print("\n{s}\n", .{msg}), - .none => try stderr.print(" {s}\n", .{msg}), + .newline => try writer.print("\n{s}\n", .{msg}), + .none => try writer.print(" {s}\n", .{msg}), } } if (error_style.verboseContext()) { if (failing_step.result_failed_command) |cmd_str| { - try fwm.setColor(stderr, .red); - try stderr.writeAll("failed command: "); - try fwm.setColor(stderr, .reset); - try stderr.writeAll(cmd_str); - try stderr.writeByte('\n'); + try stderr.setColor(.red); + try writer.writeAll("failed command: "); + try stderr.setColor(.reset); + try writer.writeAll(cmd_str); + try writer.writeByte('\n'); } } - try stderr.writeByte('\n'); + try writer.writeByte('\n'); } fn printSteps(builder: *std.Build, w: *Writer) !void { diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index 08befbe1fa..ddf3ca18b7 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -126,14 +126,14 @@ pub const Diagnostics = struct { } pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) void { - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - self.renderToWriter(args, &stderr.interface, stderr.mode) catch return; + const stderr = io.lockStderr(&.{}, null); + defer io.unlockStderr(); + self.renderToWriter(args, stderr.terminal()) catch return; } - pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void { + pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, t: Io.Terminal) !void { for (self.errors.items) |err_details| { - try renderErrorMessage(writer, config, err_details, args); + try renderErrorMessage(t, err_details, args); } } diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index 031b5d3574..6146f777cd 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -69,10 +69,10 @@ pub const Diagnostics = struct { pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) void { const io = self.io; - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + const stderr = io.lockStderr(&.{}, null); + defer io.unlockStderr(); for (self.errors.items) |err_details| { - renderErrorMessage(io, &stderr.interface, stderr.mode, cwd, err_details, source, self.strings.items, source_mappings) catch return; + renderErrorMessage(io, stderr.terminal(), cwd, err_details, source, self.strings.items, source_mappings) catch return; } } diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index bd2fcc912e..81a3a8689a 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -35,8 +35,8 @@ pub fn main() !void { const args = try std.process.argsAlloc(arena); if (args.len < 2) { - const stderr = io.lockStderrWriter(&.{}); - try renderErrorMessage(&stderr.interface, stderr.mode, .err, "expected zig lib dir as first argument", .{}); + const stderr = try io.lockStderr(&.{}, null); + try renderErrorMessage(stderr.terminal(), .err, "expected zig lib dir as first argument", .{}); std.process.exit(1); } const zig_lib_dir = args[1]; @@ -80,9 +80,9 @@ pub fn main() !void { // so that there is a clear separation between the cli diagnostics and whatever // gets printed after if (cli_diagnostics.errors.items.len > 0) { - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - try stderr.interface.writeByte('\n'); + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + try stderr.file_writer.interface.writeByte('\n'); } } break :options options; @@ -130,15 +130,12 @@ pub fn main() !void { var stderr_buf: [512]u8 = undefined; var diagnostics: aro.Diagnostics = .{ .output = output: { if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } }; - const stderr = io.lockStderrWriter(&stderr_buf); - break :output .{ .to_writer = .{ - .writer = &stderr.interface, - .color = stderr.mode, - } }; + const stderr = try io.lockStderr(&stderr_buf, null); + break :output .{ .to_writer = stderr.terminal() }; } }; defer { diagnostics.deinit(); - if (!zig_integration) std.debug.unlockStderrWriter(); + if (!zig_integration) std.debug.unlockStderr(); } var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd()); @@ -699,9 +696,9 @@ const ErrorHandler = union(enum) { }, .stderr => { // aro errors have already been emitted - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - try renderErrorMessage(&stderr.interface, stderr.mode, .err, "{s}", .{fail_msg}); + const stderr = io.lockStderr(&.{}, null); + defer io.unlockStderr(); + try renderErrorMessage(stderr.terminal(), .err, "{s}", .{fail_msg}); }, } } @@ -745,9 +742,9 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, .stderr => { - const stderr = io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - try renderErrorMessage(&stderr.interface, stderr.mode, msg_type, format, args); + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + try renderErrorMessage(stderr.terminal(), msg_type, format, args); }, } } diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 3a135ab8fd..3d97944a7f 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -405,18 +405,18 @@ pub fn fuzz( testOne(ctx, input.toSlice()) catch |err| switch (err) { error.SkipZigTest => return, else => { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderr(&.{}, null).terminal(); p: { if (@errorReturnTrace()) |trace| { - std.debug.writeStackTrace(trace, &stderr.interface, stderr.mode) catch break :p; + std.debug.writeStackTrace(trace, stderr) catch break :p; } - stderr.interface.print("failed with error.{t}\n", .{err}) catch break :p; + stderr.writer.print("failed with error.{t}\n", .{err}) catch break :p; } std.process.exit(1); }, }; if (log_err_count != 0) { - const stderr = std.debug.lockStderrWriter(&.{}); + const stderr = std.debug.lockStderr(&.{}, .no_color); stderr.interface.print("error logs detected\n", .{}) catch {}; std.process.exit(1); } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index de2985d2b5..cf0b9e5b0d 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -129,6 +129,9 @@ pub const Graph = struct { dependency_cache: InitializedDepMap = .empty, allow_so_scripts: ?bool = null, time_report: bool, + /// Similar to the `Io.Terminal.Mode` returned by `Io.lockStderr`, but also + /// respects the '--color' flag. + stderr_mode: ?Io.Terminal.Mode = null, }; const AvailableDeps = []const struct { []const u8, []const u8 }; @@ -2255,9 +2258,10 @@ pub const GeneratedFile = struct { pub fn getPath3(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) Io.Cancelable![]const u8 { return gen.path orelse { - const io = gen.step.owner.graph.io; - const stderr = try io.lockStderrWriter(&.{}); - dumpBadGetPathHelp(gen.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; + const graph = gen.step.owner.graph; + const io = graph.io; + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + dumpBadGetPathHelp(gen.step, stderr.terminal(), src_builder, asking_step) catch {}; @panic("misconfigured build script"); }; } @@ -2468,13 +2472,15 @@ pub const LazyPath = union(enum) { // TODO make gen.file.path not be absolute and use that as the // basis for not traversing up too many directories. + const graph = src_builder.graph; + var file_path: Cache.Path = .{ .root_dir = Cache.Directory.cwd(), .sub_path = gen.file.path orelse { - const io = src_builder.graph.io; - const stderr = try io.lockStderrWriter(&.{}); - dumpBadGetPathHelp(gen.file.step, &stderr.interface, stderr.mode, src_builder, asking_step) catch {}; - io.unlockStderrWriter(); + const io = graph.io; + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + dumpBadGetPathHelp(gen.file.step, stderr.terminal(), src_builder, asking_step) catch {}; + io.unlockStderr(); @panic("misconfigured build script"); }, }; @@ -2564,43 +2570,36 @@ fn dumpBadDirnameHelp( comptime msg: []const u8, args: anytype, ) anyerror!void { - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - - const w = &stderr.interface; - const fwm = stderr.mode; + const stderr = std.debug.lockStderr(&.{}).terminal(); + defer std.debug.unlockStderr(); + const w = stderr.writer; try w.print(msg, args); if (fail_step) |s| { - fwm.setColor(w, .red) catch {}; + stderr.setColor(.red) catch {}; try w.writeAll(" The step was created by this stack trace:\n"); - fwm.setColor(w, .reset) catch {}; + stderr.setColor(.reset) catch {}; - s.dump(w, fwm); + s.dump(stderr); } if (asking_step) |as| { - fwm.setColor(w, .red) catch {}; + stderr.setColor(.red) catch {}; try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name}); - fwm.setColor(w, .reset) catch {}; + stderr.setColor(.reset) catch {}; - as.dump(w, fwm); + as.dump(stderr); } - fwm.setColor(w, .red) catch {}; - try w.writeAll(" Hope that helps. Proceeding to panic.\n"); - fwm.setColor(w, .reset) catch {}; + stderr.setColor(.red) catch {}; + try w.writeAll(" Proceeding to panic.\n"); + stderr.setColor(.reset) catch {}; } /// In this function the stderr mutex has already been locked. -pub fn dumpBadGetPathHelp( - s: *Step, - w: *Io.Writer, - fwm: File.Writer.Mode, - src_builder: *Build, - asking_step: ?*Step, -) anyerror!void { +pub fn dumpBadGetPathHelp(s: *Step, t: Io.Terminal, src_builder: *Build, asking_step: ?*Step) anyerror!void { + const w = t.writer; try w.print( \\getPath() was called on a GeneratedFile that wasn't built yet. \\ source package path: {s} @@ -2611,21 +2610,21 @@ pub fn dumpBadGetPathHelp( s.name, }); - fwm.setColor(w, .red) catch {}; + t.setColor(.red) catch {}; try w.writeAll(" The step was created by this stack trace:\n"); - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; - s.dump(w, fwm); + s.dump(t); if (asking_step) |as| { - fwm.setColor(w, .red) catch {}; + t.setColor(.red) catch {}; try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name}); - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; - as.dump(w, fwm); + as.dump(t); } - fwm.setColor(w, .red) catch {}; - try w.writeAll(" Hope that helps. Proceeding to panic.\n"); - fwm.setColor(w, .reset) catch {}; + t.setColor(.red) catch {}; + try w.writeAll(" Proceeding to panic.\n"); + t.setColor(.reset) catch {}; } pub const InstallDir = union(enum) { diff --git a/lib/std/Build/Fuzz.zig b/lib/std/Build/Fuzz.zig index 4770e03a0c..d308efdf70 100644 --- a/lib/std/Build/Fuzz.zig +++ b/lib/std/Build/Fuzz.zig @@ -158,7 +158,8 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, parent_prog_node: std.P } fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_node: std.Progress.Node) !void { - const io = run.step.owner.graph.io; + const graph = run.step.owner.graph; + const io = graph.io; const compile = run.producer.?; const prog_node = parent_prog_node.start(compile.step.name, 0); defer prog_node.end(); @@ -171,9 +172,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod if (show_error_msgs or show_compile_errors or show_stderr) { var buf: [256]u8 = undefined; - const stderr = try io.lockStderrWriter(&buf); - defer io.unlockStderrWriter(); - build_runner.printErrorMessages(gpa, &compile.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; + const stderr = try io.lockStderr(&buf, graph.stderr_mode); + defer io.unlockStderr(); + build_runner.printErrorMessages(gpa, &compile.step, .{}, stderr.terminal(), .verbose, .indent) catch {}; } const rebuilt_bin_path = result catch |err| switch (err) { @@ -186,7 +187,8 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, parent_prog_nod fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void { const owner = run.step.owner; const gpa = owner.allocator; - const io = owner.graph.io; + const graph = owner.graph; + const io = graph.io; const test_name = run.cached_test_metadata.?.testName(unit_test_index); const prog_node = fuzz.prog_node.start(test_name, 0); @@ -195,11 +197,11 @@ fn fuzzWorkerRun(fuzz: *Fuzz, run: *Step.Run, unit_test_index: u32) void { run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) { error.MakeFailed => { var buf: [256]u8 = undefined; - const stderr = io.lockStderrWriter(&buf) catch |e| switch (e) { + const stderr = io.lockStderr(&buf, graph.stderr_mode) catch |e| switch (e) { error.Canceled => return, }; - defer io.unlockStderrWriter(); - build_runner.printErrorMessages(gpa, &run.step, .{}, &stderr.interface, stderr.mode, .verbose, .indent) catch {}; + defer io.unlockStderr(); + build_runner.printErrorMessages(gpa, &run.step, .{}, stderr.terminal(), .verbose, .indent) catch {}; return; }, else => { diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index 0df58b24b7..74b41634a7 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -328,16 +328,17 @@ pub fn cast(step: *Step, comptime T: type) ?*T { } /// For debugging purposes, prints identifying information about this Step. -pub fn dump(step: *Step, w: *Io.Writer, fwm: Io.File.Writer.Mode) void { +pub fn dump(step: *Step, t: Io.Terminal) void { + const w = t.writer; if (step.debug_stack_trace.instruction_addresses.len > 0) { w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {}; - std.debug.writeStackTrace(&step.debug_stack_trace, w, fwm) catch {}; + std.debug.writeStackTrace(&step.debug_stack_trace, t) catch {}; } else { const field = "debug_stack_frames_count"; comptime assert(@hasField(Build, field)); - fwm.setColor(w, .yellow) catch {}; + t.setColor(.yellow) catch {}; w.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {}; - fwm.setColor(w, .reset) catch {}; + t.setColor(.reset) catch {}; } } diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 888775884d..4752046089 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -925,20 +925,21 @@ const CliNamedModules = struct { fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) ![]const u8 { const step = &compile.step; const b = step.owner; - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; const maybe_path: ?*GeneratedFile = @field(compile, tag_name); const generated_file = maybe_path orelse { - const stderr = try io.lockStderrWriter(&.{}); - std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - io.unlockStderrWriter(); + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {}; + io.unlockStderr(); @panic("missing emit option for " ++ tag_name); }; const path = generated_file.path orelse { - const stderr = try io.lockStderrWriter(&.{}); - std.Build.dumpBadGetPathHelp(&compile.step, &stderr.interface, stderr.mode, compile.step.owner, asking_step) catch {}; - io.unlockStderrWriter(); + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + std.Build.dumpBadGetPathHelp(&compile.step, stderr.terminal(), compile.step.owner, asking_step) catch {}; + io.unlockStderr(); @panic(tag_name ++ " is null. Is there a missing step dependency?"); }; @@ -1907,7 +1908,7 @@ fn checkCompileErrors(compile: *Compile) !void { try actual_eb.renderToWriter(.{ .include_reference_trace = false, .include_source_line = false, - }, &aw.writer, .streaming); + }, &aw.writer); break :ae try aw.toOwnedSlice(); }; diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 67cf201374..157a0292e7 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1559,7 +1559,8 @@ fn spawnChildAndCollect( ) !?EvalGenericResult { const b = run.step.owner; const arena = b.allocator; - const io = b.graph.io; + const graph = b.graph; + const io = graph.io; if (fuzz_context != null) { assert(!has_side_effects); @@ -1625,11 +1626,12 @@ fn spawnChildAndCollect( if (!run.disable_zig_progress and !inherit) { child.progress_node = options.progress_node; } - if (inherit) { - const stderr = try io.lockStderrWriter(&.{}); - try setColorEnvironmentVariables(run, env_map, stderr.mode); - } - defer if (inherit) io.unlockStderrWriter(); + const terminal_mode: Io.Terminal.Mode = if (inherit) m: { + const stderr = try io.lockStderr(&.{}, graph.stderr_mode); + break :m stderr.terminal_mode; + } else .no_color; + defer if (inherit) io.unlockStderr(); + try setColorEnvironmentVariables(run, env_map, terminal_mode); var timer = try std.time.Timer.start(); const res = try evalGeneric(run, &child); run.step.result_duration_ns = timer.read(); @@ -1637,7 +1639,7 @@ fn spawnChildAndCollect( } } -fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, fwm: Io.File.Writer.Mode) !void { +fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, terminal_mode: Io.Terminal.Mode) !void { color: switch (run.color) { .manual => {}, .enable => { @@ -1648,9 +1650,9 @@ fn setColorEnvironmentVariables(run: *Run, env_map: *EnvMap, fwm: Io.File.Writer try env_map.put("NO_COLOR", "1"); env_map.remove("CLICOLOR_FORCE"); }, - .inherit => switch (fwm) { - .terminal_escaped => continue :color .enable, - else => continue :color .disable, + .inherit => switch (terminal_mode) { + .no_color, .windows_api => continue :color .disable, + .escape_codes => continue :color .enable, }, .auto => { const capture_stderr = run.captured_stderr != null or switch (run.stdio) { diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 6fa05b16d2..78049633a0 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -713,7 +713,7 @@ pub const VTable = struct { processExecutableOpen: *const fn (?*anyopaque, File.OpenFlags) std.process.OpenExecutableError!File, processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize, lockStderr: *const fn (?*anyopaque, buffer: []u8, ?Terminal.Mode) Cancelable!LockedStderr, - tryLockStderr: *const fn (?*anyopaque, buffer: []u8) Cancelable!?LockedStderr, + tryLockStderr: *const fn (?*anyopaque, buffer: []u8, ?Terminal.Mode) Cancelable!?LockedStderr, unlockStderr: *const fn (?*anyopaque) void, now: *const fn (?*anyopaque, Clock) Clock.Error!Timestamp, diff --git a/lib/std/Io/File/Writer.zig b/lib/std/Io/File/Writer.zig index 1d0494c674..56a1c09340 100644 --- a/lib/std/Io/File/Writer.zig +++ b/lib/std/Io/File/Writer.zig @@ -229,7 +229,7 @@ pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void { .positional, .positional_simple => { w.pos = offset; }, - .streaming, .streaming_simple, .terminal_escaped, .terminal_winapi => { + .streaming, .streaming_simple => { if (w.seek_err) |err| return err; io.vtable.fileSeekTo(io.userdata, w.file, offset) catch |err| { w.seek_err = err; diff --git a/lib/std/Io/Terminal.zig b/lib/std/Io/Terminal.zig index cd0ec56caa..a39f2175d2 100644 --- a/lib/std/Io/Terminal.zig +++ b/lib/std/Io/Terminal.zig @@ -130,25 +130,3 @@ pub fn setColor(t: Terminal, color: Color) Io.Writer.Error!void { }, } } - -pub fn disableEscape(t: *Terminal) Mode { - const prev = t.mode; - t.mode = t.mode.toUnescaped(); - return prev; -} - -pub fn restoreEscape(t: *Terminal, mode: Mode) void { - t.mode = mode; -} - -pub fn writeAllUnescaped(t: *Terminal, bytes: []const u8) Io.Writer.Error!void { - const prev_mode = t.disableEscape(); - defer t.restoreEscape(prev_mode); - return t.interface.writeAll(bytes); -} - -pub fn printUnescaped(t: *Terminal, comptime fmt: []const u8, args: anytype) Io.Writer.Error!void { - const prev_mode = t.disableEscape(); - defer t.restoreEscape(prev_mode); - return t.interface.print(fmt, args); -} diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 3e7b6950d4..b07a9bb9a8 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -7178,7 +7178,7 @@ fn fileWriteFileStreaming( break :o .{ &off, @min(@intFromEnum(limit), size - file_reader.pos, max_count) }; }, .streaming => .{ null, limit.minInt(max_count) }, - .streaming_reading, .positional_reading => break :sf, + .streaming_simple, .positional_simple => break :sf, .failure => return error.ReadFailed, }; const current_thread = Thread.getCurrent(t); @@ -7251,7 +7251,7 @@ fn fileWriteFileStreaming( } var off_in: i64 = undefined; const off_in_ptr: ?*i64 = switch (file_reader.mode) { - .positional_reading, .streaming_reading => return error.Unimplemented, + .positional_simple, .streaming_simple => return error.Unimplemented, .positional => p: { off_in = @intCast(file_reader.pos); break :p &off_in; @@ -7427,7 +7427,7 @@ fn fileWriteFilePositional( } var off_in: i64 = undefined; const off_in_ptr: ?*i64 = switch (file_reader.mode) { - .positional_reading, .streaming_reading => return error.Unimplemented, + .positional_simple, .streaming_simple => return error.Unimplemented, .positional => p: { off_in = @intCast(file_reader.pos); break :p &off_in; diff --git a/lib/std/debug.zig b/lib/std/debug.zig index fd3a456ff7..e33a2bd575 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -283,12 +283,12 @@ var static_single_threaded_io: Io.Threaded = .init_single_threaded; /// /// Alternatively, use the higher-level `Io.lockStderr` to integrate with the /// application's chosen `Io` implementation. -pub fn lockStderr(buffer: []u8) Io.Terminal { - return (static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) { +pub fn lockStderr(buffer: []u8) Io.LockedStderr { + return static_single_threaded_io.ioBasic().lockStderr(buffer, null) catch |err| switch (err) { // Impossible to cancel because no calls to cancel using // `static_single_threaded_io` exist. error.Canceled => unreachable, - }).terminal(); + }; } pub fn unlockStderr() void { @@ -311,7 +311,7 @@ pub fn print(comptime fmt: []const u8, args: anytype) void { var buffer: [64]u8 = undefined; const stderr = lockStderr(&buffer); defer unlockStderr(); - stderr.writer.print(fmt, args) catch return; + stderr.file_writer.interface.print(fmt, args) catch return; } } @@ -327,7 +327,7 @@ pub inline fn getSelfDebugInfo() !*SelfInfo { /// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned. /// Obtains the stderr mutex while dumping. pub fn dumpHex(bytes: []const u8) void { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); dumpHexFallible(stderr, bytes) catch {}; } @@ -551,7 +551,7 @@ pub fn defaultPanic( _ = panicking.fetchAdd(1, .seq_cst); trace: { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); const writer = stderr.writer; @@ -581,7 +581,7 @@ pub fn defaultPanic( // A panic happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); stderr.writer.writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. @@ -751,7 +751,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, t: Io.Termin } /// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors. pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); writeCurrentStackTrace(.{ .first_address = a: { @@ -814,7 +814,7 @@ pub fn writeStackTrace(st: *const StackTrace, t: Io.Terminal) Writer.Error!void } /// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors. pub fn dumpStackTrace(st: *const StackTrace) void { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); writeStackTrace(st, stderr) catch |err| switch (err) { error.WriteFailed => {}, @@ -1550,7 +1550,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex _ = panicking.fetchAdd(1, .seq_cst); trace: { - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); if (addr) |a| { @@ -1571,7 +1571,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex // A segfault happened while trying to print a previous panic message. // We're still holding the mutex but that's fine as we're going to // call abort(). - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); stderr.writer.writeAll("aborting due to recursive panic\n") catch {}; }, else => {}, // Panicked while printing the recursive panic message. @@ -1678,7 +1678,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize pub fn dump(t: @This()) void { if (!enabled) return; - const stderr = lockStderr(&.{}); + const stderr = lockStderr(&.{}).terminal(); defer unlockStderr(); const end = @min(t.index, size); for (t.addrs[0..end], 0..) |frames_array, i| { diff --git a/lib/std/debug/simple_panic.zig b/lib/std/debug/simple_panic.zig index 2d0e5abf4e..34e8f7b43c 100644 --- a/lib/std/debug/simple_panic.zig +++ b/lib/std/debug/simple_panic.zig @@ -14,9 +14,9 @@ const std = @import("../std.zig"); pub fn call(msg: []const u8, ra: ?usize) noreturn { @branchHint(.cold); _ = ra; - const stderr = std.debug.lockStderrWriter(&.{}); - stderr.interface.writeAll(msg) catch {}; - stderr.interface.flush(msg) catch {}; + const stderr_writer = std.debug.lockStderr(&.{}, null).terminal().writer; + stderr_writer.writeAll(msg) catch {}; + stderr_writer.flush(msg) catch {}; @trap(); } diff --git a/lib/std/json/dynamic.zig b/lib/std/json/dynamic.zig index f85916670b..e38ea9cb17 100644 --- a/lib/std/json/dynamic.zig +++ b/lib/std/json/dynamic.zig @@ -47,9 +47,9 @@ pub const Value = union(enum) { } pub fn dump(v: Value) void { - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - json.Stringify.value(v, .{}, &stderr.interface) catch return; + const stderr = std.debug.lockStderr(&.{}, null); + defer std.debug.unlockStderr(); + json.Stringify.value(v, .{}, &stderr.file_writer.interface) catch return; } pub fn jsonStringify(value: @This(), jws: anytype) !void { diff --git a/lib/std/log.zig b/lib/std/log.zig index 8579bb04e0..81bfc4ebb6 100644 --- a/lib/std/log.zig +++ b/lib/std/log.zig @@ -92,7 +92,7 @@ pub fn defaultLog( args: anytype, ) void { var buffer: [64]u8 = undefined; - const stderr = std.debug.lockStderr(&buffer); + const stderr = std.debug.lockStderr(&buffer).terminal(); defer std.debug.unlockStderr(); return defaultLogFileTerminal(level, scope, format, args, stderr) catch {}; } diff --git a/lib/std/process.zig b/lib/std/process.zig index 45cd575133..23a3d92e9b 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1856,7 +1856,7 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 { /// and does not return. pub fn cleanExit(io: Io) void { if (builtin.mode == .Debug) return; - _ = io.lockStderrWriter(&.{}) catch {}; + _ = io.lockStderr(&.{}, .no_color) catch {}; exit(0); } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index be6f316804..98fca2f2d5 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -368,8 +368,8 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const break :diff_index if (expected.len == actual.len) return else shortest; }; if (!backend_can_print) return error.TestExpectedEqual; - if (io.lockStderrWriter(&.{})) |stderr| { - defer io.unlockStderrWriter(); + if (io.lockStderr(&.{}, null)) |stderr| { + defer io.unlockStderr(); failEqualSlices(T, expected, actual, diff_index, &stderr.interface, stderr.mode) catch {}; } else |_| {} return error.TestExpectedEqual; @@ -381,7 +381,7 @@ fn failEqualSlices( actual: []const T, diff_index: usize, w: *Io.Writer, - fwm: Io.File.Writer.Mode, + terminal_mode: Io.Terminal.Mode, ) !void { try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); @@ -404,12 +404,12 @@ fn failEqualSlices( var differ = if (T == u8) BytesDiffer{ .expected = expected_window, .actual = actual_window, - .file_writer_mode = fwm, + .terminal_mode = terminal_mode, } else SliceDiffer(T){ .start_index = window_start, .expected = expected_window, .actual = actual_window, - .file_writer_mode = fwm, + .terminal_mode = terminal_mode, }; // Print indexes as hex for slices of u8 since it's more likely to be binary data where @@ -466,21 +466,22 @@ fn SliceDiffer(comptime T: type) type { start_index: usize, expected: []const T, actual: []const T, - file_writer_mode: Io.File.Writer.Mode, + terminal_mode: Io.Terminal.Mode, const Self = @This(); pub fn write(self: Self, writer: *Io.Writer) !void { + const t: Io.Terminal = .{ .writer = writer, .mode = self.terminal_mode }; for (self.expected, 0..) |value, i| { const full_index = self.start_index + i; const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; - if (diff) try self.file_writer_mode.setColor(writer, .red); + if (diff) try t.setColor(writer, .red); if (@typeInfo(T) == .pointer) { try writer.print("[{}]{*}: {any}\n", .{ full_index, value, value }); } else { try writer.print("[{}]: {any}\n", .{ full_index, value }); } - if (diff) try self.file_writer_mode.setColor(writer, .reset); + if (diff) try t.setColor(writer, .reset); } } }; @@ -489,7 +490,7 @@ fn SliceDiffer(comptime T: type) type { const BytesDiffer = struct { expected: []const u8, actual: []const u8, - file_writer_mode: Io.File.Writer.Mode, + terminal_mode: Io.Terminal.Mode, pub fn write(self: BytesDiffer, writer: *Io.Writer) !void { var expected_iterator = std.mem.window(u8, self.expected, 16, 16); @@ -516,7 +517,7 @@ const BytesDiffer = struct { try self.writeDiff(writer, "{c}", .{byte}, diff); } else { // TODO: remove this `if` when https://github.com/ziglang/zig/issues/7600 is fixed - if (self.file_writer_mode == .terminal_winapi) { + if (self.terminal_mode == .windows_api) { try self.writeDiff(writer, ".", .{}, diff); continue; } diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 6e89c75d91..6212264005 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -46,25 +46,18 @@ pub const SrcHasher = std.crypto.hash.Blake3; pub const SrcHash = [16]u8; pub const Color = enum { - /// Determine whether stderr is a terminal or not automatically. + /// Auto-detect whether stream supports terminal colors. auto, - /// Assume stderr is not a terminal. + /// Force-enable colors. off, - /// Assume stderr is a terminal. + /// Suppress colors. on, - pub fn getTtyConf(color: Color, detected: Io.File.Writer.Mode) Io.File.Writer.Mode { + pub fn terminalMode(color: Color) ?Io.Terminal.Mode { return switch (color) { - .auto => detected, - .on => .terminal_escaped, - .off => .streaming, - }; - } - pub fn detectTtyConf(color: Color, io: Io) Io.File.Writer.Mode { - return switch (color) { - .auto => .detect(io, .stderr()), - .on => .terminal_escaped, - .off => .streaming, + .auto => null, + .on => .escape_codes, + .off => .no_color, }; } }; diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index 556b1167a3..c5275729ae 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -166,51 +166,53 @@ pub const RenderToStderrError = Io.Cancelable || Io.File.Writer.Error; pub fn renderToStderr(eb: ErrorBundle, io: Io, options: RenderOptions, color: std.zig.Color) RenderToStderrError!void { var buffer: [256]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - renderToWriter(eb, options, &stderr.interface, color.getTtyConf(stderr.mode)) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + const stderr = try io.lockStderr(&buffer, color.terminalMode()); + defer io.unlockStderr(); + renderToTerminal(eb, options, stderr.terminal()) catch |err| switch (err) { + error.WriteFailed => return stderr.file_writer.err.?, else => |e| return e, }; } -pub fn renderToWriter( - eb: ErrorBundle, - options: RenderOptions, - w: *Writer, - fwm: Io.File.Writer.Mode, -) Io.File.Writer.Mode.SetColorError!void { +pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer) Writer.Error!void { + return renderToTerminal(eb, options, .{ .writer = w, .mode = .no_color }) catch |err| switch (err) { + error.WriteFailed => |e| return e, + else => unreachable, + }; +} + +pub fn renderToTerminal(eb: ErrorBundle, options: RenderOptions, t: Io.Terminal) Io.Terminal.SetColorError!void { if (eb.extra.len == 0) return; for (eb.getMessages()) |err_msg| { - try renderErrorMessageToWriter(eb, options, err_msg, w, fwm, "error", .red, 0); + try renderErrorMessage(eb, options, err_msg, t, "error", .red, 0); } if (options.include_log_text) { const log_text = eb.getCompileLogOutput(); if (log_text.len != 0) { - try w.writeAll("\nCompile Log Output:\n"); - try w.writeAll(log_text); + try t.writer.writeAll("\nCompile Log Output:\n"); + try t.writer.writeAll(log_text); } } } -fn renderErrorMessageToWriter( +fn renderErrorMessage( eb: ErrorBundle, options: RenderOptions, err_msg_index: MessageIndex, - w: *Writer, - fwm: Io.File.Writer.Mode, + t: Io.Terminal, kind: []const u8, - color: Io.File.Writer.Color, + color: Io.Terminal.Color, indent: usize, -) Io.File.Writer.Mode.SetColorError!void { +) Io.Terminal.SetColorError!void { + const w = t.writer; const err_msg = eb.getErrorMessage(err_msg_index); if (err_msg.src_loc != .none) { const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc)); var prefix: Writer.Discarding = .init(&.{}); try w.splatByteAll(' ', indent); prefix.count += indent; - try fwm.setColor(w, .bold); + try t.setColor(.bold); try w.print("{s}:{d}:{d}: ", .{ eb.nullTerminatedString(src.data.src_path), src.data.line + 1, @@ -221,7 +223,7 @@ fn renderErrorMessageToWriter( src.data.line + 1, src.data.column + 1, }); - try fwm.setColor(w, color); + try t.setColor(color); try w.writeAll(kind); prefix.count += kind.len; try w.writeAll(": "); @@ -229,17 +231,17 @@ fn renderErrorMessageToWriter( // This is the length of the part before the error message: // e.g. "file.zig:4:5: error: " const prefix_len: usize = @intCast(prefix.count); - try fwm.setColor(w, .reset); - try fwm.setColor(w, .bold); + try t.setColor(.reset); + try t.setColor(.bold); if (err_msg.count == 1) { try writeMsg(eb, err_msg, w, prefix_len); try w.writeByte('\n'); } else { try writeMsg(eb, err_msg, w, prefix_len); - try fwm.setColor(w, .dim); + try t.setColor(.dim); try w.print(" ({d} times)\n", .{err_msg.count}); } - try fwm.setColor(w, .reset); + try t.setColor(.reset); if (src.data.source_line != 0 and options.include_source_line) { const line = eb.nullTerminatedString(src.data.source_line); for (line) |b| switch (b) { @@ -252,19 +254,19 @@ fn renderErrorMessageToWriter( // -1 since span.main includes the caret const after_caret = src.data.span_end -| src.data.span_main -| 1; try w.splatByteAll(' ', src.data.column - before_caret); - try fwm.setColor(w, .green); + try t.setColor(.green); try w.splatByteAll('~', before_caret); try w.writeByte('^'); try w.splatByteAll('~', after_caret); try w.writeByte('\n'); - try fwm.setColor(w, .reset); + try t.setColor(.reset); } for (eb.getNotes(err_msg_index)) |note| { - try renderErrorMessageToWriter(eb, options, note, w, fwm, "note", .cyan, indent); + try renderErrorMessage(eb, options, note, t, "note", .cyan, indent); } if (src.data.reference_trace_len > 0 and options.include_reference_trace) { - try fwm.setColor(w, .reset); - try fwm.setColor(w, .dim); + try t.setColor(.reset); + try t.setColor(.dim); try w.print("referenced by:\n", .{}); var ref_index = src.end; for (0..src.data.reference_trace_len) |_| { @@ -291,25 +293,25 @@ fn renderErrorMessageToWriter( ); } } - try fwm.setColor(w, .reset); + try t.setColor(.reset); } } else { - try fwm.setColor(w, color); + try t.setColor(color); try w.splatByteAll(' ', indent); try w.writeAll(kind); try w.writeAll(": "); - try fwm.setColor(w, .reset); + try t.setColor(.reset); const msg = eb.nullTerminatedString(err_msg.msg); if (err_msg.count == 1) { try w.print("{s}\n", .{msg}); } else { try w.print("{s}", .{msg}); - try fwm.setColor(w, .dim); + try t.setColor(.dim); try w.print(" ({d} times)\n", .{err_msg.count}); } - try fwm.setColor(w, .reset); + try t.setColor(.reset); for (eb.getNotes(err_msg_index)) |note| { - try renderErrorMessageToWriter(eb, options, note, w, fwm, "note", .cyan, indent + 4); + try renderErrorMessage(eb, options, note, t, "note", .cyan, indent + 4); } } } diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 6c11c3021b..94d877b406 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -6333,25 +6333,25 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined; fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); var tree = try std.zig.Ast.parse(allocator, source, .zig); defer tree.deinit(allocator); for (tree.errors) |parse_error| { const loc = tree.tokenLocation(0, parse_error.token); - try stderr.printUnescaped("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 }); - try tree.renderError(parse_error, &stderr.interface); - try stderr.interface.print("\n{s}\n", .{source[loc.line_start..loc.line_end]}); + try stderr.writer.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 }); + try tree.renderError(parse_error, stderr.writer); + try stderr.writer.print("\n{s}\n", .{source[loc.line_start..loc.line_end]}); { var i: usize = 0; while (i < loc.column) : (i += 1) { - try stderr.writeAllUnescaped(" "); + try stderr.writer.writeAll(" "); } - try stderr.writeAllUnescaped("^"); + try stderr.writer.writeAll("^"); } - try stderr.writeAllUnescaped("\n"); + try stderr.writer.writeAll("\n"); } if (tree.errors.len != 0) { return error.ParseError; diff --git a/src/Air/print.zig b/src/Air/print.zig index 05614a0ed3..98b0a0b242 100644 --- a/src/Air/print.zig +++ b/src/Air/print.zig @@ -76,9 +76,9 @@ pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { const comp = pt.zcu.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; air.write(w, pt, liveness); } @@ -86,9 +86,9 @@ pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Ai const comp = pt.zcu.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; air.writeInst(w, inst, pt, liveness); } diff --git a/src/Compilation.zig b/src/Compilation.zig index 37e15ab171..f3fcef40a0 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2092,14 +2092,16 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, } if (options.verbose_llvm_cpu_features) { - if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - const w = &stderr.interface; - w.print("compilation: {s}\n", .{options.root_name}) catch break :print; - w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; - w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; - w.print(" features: {s}\n", .{cf}) catch {}; + if (options.root_mod.resolved_target.llvm_cpu_features) |cf| { + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; + printVerboseLlvmCpuFeatures(w, arena, options.root_name, target, cf) catch |err| switch (err) { + error.WriteFailed => switch (stderr.file_writer.err.?) { + error.Canceled => |e| return e, + else => {}, + }, + }; } } @@ -2700,6 +2702,19 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, return comp; } +fn printVerboseLlvmCpuFeatures( + w: *Writer, + arena: Allocator, + root_name: []const u8, + target: *const std.Target, + cf: [*:0]const u8, +) Writer.Error!void { + try w.print("compilation: {s}\n", .{root_name}); + try w.print(" target: {s}\n", .{try target.zigTriple(arena)}); + try w.print(" cpu: {s}\n", .{target.cpu.model.name}); + try w.print(" features: {s}\n", .{cf}); +} + pub fn destroy(comp: *Compilation) void { const gpa = comp.gpa; const io = comp.io; @@ -4259,9 +4274,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle { // However, we haven't reported any such error. // This is a compiler bug. print_ctx: { - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = std.debug.lockStderr(&.{}).terminal(); + defer std.debug.unlockStderr(); + const w = stderr.writer; w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx; w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx; while (ref) |r| { @@ -7772,11 +7787,11 @@ pub fn lockAndSetMiscFailure( pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; return dumpArgvWriter(w, argv) catch |err| switch (err) { - error.WriteFailed => switch (stderr.err.?) { + error.WriteFailed => switch (stderr.file_writer.err.?) { error.Canceled => return error.Canceled, else => return, }, diff --git a/src/InternPool.zig b/src/InternPool.zig index 539cb441c5..98bde244c5 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -11169,9 +11169,9 @@ pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) v pub fn dump(ip: *const InternPool, io: Io) Io.Cancelable!void { var buffer: [4096]u8 = undefined; - const stderr_writer = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr_writer.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; try dumpStatsFallible(ip, w, std.heap.page_allocator); try dumpAllFallible(ip, w); } @@ -11536,8 +11536,8 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { pub fn dumpGenericInstances(ip: *const InternPool, io: Io, allocator: Allocator) Io.Cancelable!void { var buffer: [4096]u8 = undefined; - const stderr_writer = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); + const stderr_writer = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); const w = &stderr_writer.interface; try ip.dumpGenericInstancesFallible(allocator, w); } diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 76ab3e229c..103cbaaaae 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -4560,10 +4560,10 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e if (build_options.enable_debug_extensions and comp.verbose_air) p: { const io = comp.io; - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - printVerboseAir(pt, liveness, fqn, air, &stderr.interface) catch |err| switch (err) { - error.WriteFailed => switch (stderr.err.?) { + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + printVerboseAir(pt, liveness, fqn, air, &stderr.file_writer.interface) catch |err| switch (err) { + error.WriteFailed => switch (stderr.file_writer.err.?) { error.Canceled => |e| return e, else => break :p, }, diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index 138c70fecf..93a6e0a768 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11274,16 +11274,15 @@ fn initValueAdvanced( } pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { const zcu = isel.pt.zcu; - const io = zcu.comp.io; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const nav = ip.getNav(isel.nav_index); errdefer |err| @panic(@errorName(err)); - const stderr_writer = io.lockStderrWriter(&.{}) catch return; - defer io.unlockStderrWriter(); - const stderr = &stderr_writer.interface; + const locked_stderr = std.debug.lockStderr(&.{}, null); + defer std.debug.unlockStderr(); + const stderr = &locked_stderr.file_writer.interface; var reverse_live_values: std.AutoArrayHashMapUnmanaged(Value.Index, std.ArrayList(Air.Inst.Index)) = .empty; defer { diff --git a/src/crash_report.zig b/src/crash_report.zig index f23806b758..e56bc7cec5 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -95,9 +95,9 @@ fn dumpCrashContext() Io.Writer.Error!void { // TODO: this does mean that a different thread could grab the stderr mutex between the context // and the actual panic printing, which would be quite confusing. - const stderr = std.debug.lockStderrWriter(&.{}); - defer std.debug.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = std.debug.lockStderr(&.{}); + defer std.debug.unlockStderr(); + const w = &stderr.file_writer.interface; try w.writeAll("Compiler crash context:\n"); diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index a76fec9237..8cf1dfa303 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -314,14 +314,14 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (comp.verbose_cc) { var buffer: [256]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; w.print("def file: {s}\n", .{def_file_path}) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + error.WriteFailed => return stderr.file_writer.err.?, }; w.print("include dir: {s}\n", .{include_dir}) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + error.WriteFailed => return stderr.file_writer.err.?, }; } @@ -339,12 +339,12 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); for (aro_comp.diagnostics.output.to_list.messages.items) |msg| { if (msg.kind == .@"fatal error" or msg.kind == .@"error") { - msg.write(&stderr.interface, stderr.mode, true) catch |err| switch (err) { - error.WriteFailed => return stderr.err.?, + msg.write(stderr.terminal(), true) catch |err| switch (err) { + error.WriteFailed => return stderr.file_writer.err.?, }; return error.AroPreprocessorFailed; } @@ -365,9 +365,9 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { error.OutOfMemory => |e| return e, error.ParseError => { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; try w.writeAll("error: "); try def_diagnostics.writeMsg(w, input); try w.writeByte('\n'); diff --git a/src/libs/mingw/def.zig b/src/libs/mingw/def.zig index 9a105b6182..f1c112d16e 100644 --- a/src/libs/mingw/def.zig +++ b/src/libs/mingw/def.zig @@ -1039,9 +1039,9 @@ fn testParse( const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) { error.OutOfMemory => |e| return e, error.ParseError => { - const stderr = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&.{}, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; try diagnostics.writeMsg(w, source); try w.writeByte('\n'); return err; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index d379669613..03b757f5b4 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -2382,9 +2382,9 @@ pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void { const comp = coff.base.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.unlockStderr(); + const w = &stderr.file_writer.interface; coff.printNode(tid, w, .root, 0) catch |err| switch (err) { error.WriteFailed => return stderr.err.?, }; diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 3c511f1ee9..bbdb439385 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -3733,9 +3733,9 @@ pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { const comp = elf.base.comp; const io = comp.io; var buffer: [512]u8 = undefined; - const stderr = try io.lockStderrWriter(&buffer); - defer io.unlockStderrWriter(); - const w = &stderr.interface; + const stderr = try io.lockStderr(&buffer, null); + defer io.lockStderr(); + const w = &stderr.file_writer.interface; elf.printNode(tid, w, .root, 0) catch |err| switch (err) { error.WriteFailed => return stderr.err.?, }; diff --git a/src/main.zig b/src/main.zig index c5ed278921..8e30febb81 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4429,9 +4429,9 @@ fn runOrTest( // the error message and invocation below. if (process.can_execv and arg_mode == .run) { // execv releases the locks; no need to destroy the Compilation here. - _ = try io.lockStderrWriter(&.{}); + _ = try io.lockStderr(&.{}, .no_color); const err = process.execve(gpa, argv.items, &env_map); - io.unlockStderrWriter(); + io.unlockStderr(); try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc); const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd }); @@ -4448,8 +4448,8 @@ fn runOrTest( comp_destroyed.* = true; const term_result = t: { - _ = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + _ = try io.lockStderr(&.{}, .no_color); + defer io.unlockStderr(); break :t child.spawnAndWait(io); }; const term = term_result catch |err| { @@ -5418,8 +5418,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) child.stderr_behavior = .Inherit; const term = t: { - _ = try io.lockStderrWriter(&.{}); - defer io.unlockStderrWriter(); + _ = try io.lockStderr(&.{}, .no_color); + defer io.unlockStderr(); break :t child.spawnAndWait(io) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err }); }; -- cgit v1.2.3 From a5b719e9eb0a196a43a88af8f62c897d1ecfa04f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 17 Dec 2025 23:12:11 -0800 Subject: compiler: fix build failures from std.Io-fs --- lib/compiler/aro/aro/Diagnostics.zig | 10 +++++----- lib/std/Io/Dir.zig | 2 +- lib/std/Io/Threaded.zig | 2 +- lib/std/zig/llvm/Builder.zig | 4 ++-- src/Compilation.zig | 32 +++++++++++++------------------- src/InternPool.zig | 26 +++++++++++++------------- src/Package/Fetch.zig | 15 ++++++--------- src/codegen/aarch64/Select.zig | 2 +- src/codegen/llvm.zig | 18 +++++++++--------- src/libs/mingw.zig | 1 + src/link.zig | 3 +-- src/link/Elf.zig | 5 +++-- src/link/Lld.zig | 2 +- src/link/MachO.zig | 8 +++++--- src/link/MappedFile.zig | 4 ++-- src/link/Queue.zig | 1 + src/link/Wasm.zig | 3 ++- 17 files changed, 67 insertions(+), 71 deletions(-) (limited to 'src/codegen') diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index b33efa3f85..993b5d93af 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -541,11 +541,11 @@ fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void { switch (d.output) { .ignore => {}, - .to_writer => |writer| { - var config = writer.color; - if (d.color == false) config = .no_color; - if (d.color == true and config == .no_color) config = .escape_codes; - msg.write(writer.writer, config, d.details) catch { + .to_writer => |t| { + var new_mode = t.mode; + if (d.color == false) new_mode = .no_color; + if (d.color == true and new_mode == .no_color) new_mode = .escape_codes; + msg.write(.{ .writer = t.writer, .mode = new_mode }, d.details) catch { return error.FatalError; }; }, diff --git a/lib/std/Io/Dir.zig b/lib/std/Io/Dir.zig index f482f72afd..12fcea6576 100644 --- a/lib/std/Io/Dir.zig +++ b/lib/std/Io/Dir.zig @@ -1739,7 +1739,7 @@ pub fn setFilePermissions( new_permissions: File.Permissions, options: SetFilePermissionsOptions, ) SetFilePermissionsError!void { - return io.vtable.dirSetFilePermissions(io.userdata, sub_path, dir, new_permissions, options); + return io.vtable.dirSetFilePermissions(io.userdata, dir, sub_path, new_permissions, options); } pub const SetOwnerError = File.SetOwnerError; diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index b07a9bb9a8..ca10272b33 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -10139,7 +10139,7 @@ fn initLockedStderr( t.stderr_writer.interface.buffer = buffer; return .{ .file_writer = &t.stderr_writer, - .terminal_mode = t.stderr_mode, + .terminal_mode = terminal_mode orelse t.stderr_mode, }; } diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index 251c87defc..66d20df348 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -9576,10 +9576,10 @@ pub fn asmValue( return (try self.asmConst(ty, info, assembly, constraints)).toValue(); } -pub fn dump(b: *Builder) void { +pub fn dump(b: *Builder, io: Io) void { var buffer: [4000]u8 = undefined; const stderr: Io.File = .stderr(); - b.printToFile(stderr, &buffer) catch {}; + b.printToFile(io, stderr, &buffer) catch {}; } pub fn printToFilePath(b: *Builder, io: Io, dir: Io.Dir, path: []const u8) !void { diff --git a/src/Compilation.zig b/src/Compilation.zig index f3fcef40a0..a78bf19e66 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2101,6 +2101,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, error.Canceled => |e| return e, else => {}, }, + error.OutOfMemory => |e| return e, }; } } @@ -2708,7 +2709,7 @@ fn printVerboseLlvmCpuFeatures( root_name: []const u8, target: *const std.Target, cf: [*:0]const u8, -) Writer.Error!void { +) (Writer.Error || Allocator.Error)!void { try w.print("compilation: {s}\n", .{root_name}); try w.print(" target: {s}\n", .{try target.zigTriple(arena)}); try w.print(" cpu: {s}\n", .{target.cpu.model.name}); @@ -3113,7 +3114,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE if (build_options.enable_debug_extensions and comp.verbose_intern_pool) { std.debug.print("intern pool stats for '{s}':\n", .{comp.root_name}); - zcu.intern_pool.dump(io); + zcu.intern_pool.dump(); } if (build_options.enable_debug_extensions and comp.verbose_generic_instances) { @@ -3320,11 +3321,8 @@ pub fn resolveEmitPathFlush( }, } } -fn flush( - comp: *Compilation, - arena: Allocator, - tid: Zcu.PerThread.Id, -) Allocator.Error!void { + +fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancelable || Allocator.Error)!void { const io = comp.io; if (comp.zcu) |zcu| { if (zcu.llvm_object) |llvm_object| { @@ -3390,7 +3388,7 @@ fn flush( // This is needed before reading the error flags. lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) { error.LinkFailure => {}, // Already reported. - error.OutOfMemory => return error.OutOfMemory, + error.OutOfMemory, error.Canceled => |e| return e, }; } if (comp.zcu) |zcu| { @@ -3614,6 +3612,7 @@ fn emitFromCObject( new_ext: []const u8, unresolved_emit_path: []const u8, ) Allocator.Error!void { + const io = comp.io; // The dirname and stem (i.e. everything but the extension), of the sub path of the C object. // We'll append `new_ext` to it to get the path to the right thing (asm, LLVM IR, etc). const c_obj_dir_and_stem: []const u8 = p: { @@ -3623,23 +3622,18 @@ fn emitFromCObject( }; const src_path: Cache.Path = .{ .root_dir = c_obj_path.root_dir, - .sub_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ - c_obj_dir_and_stem, - new_ext, - }), + .sub_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ c_obj_dir_and_stem, new_ext }), }; const emit_path = comp.resolveEmitPath(unresolved_emit_path); - src_path.root_dir.handle.copyFile( + Io.Dir.copyFile( + src_path.root_dir.handle, src_path.sub_path, emit_path.root_dir.handle, emit_path.sub_path, + io, .{}, - ) catch |err| log.err("unable to copy '{f}' to '{f}': {s}", .{ - src_path, - emit_path, - @errorName(err), - }); + ) catch |err| log.err("unable to copy '{f}' to '{f}': {t}", .{ src_path, emit_path, err }); } /// Having the file open for writing is problematic as far as executing the @@ -7787,7 +7781,7 @@ pub fn lockAndSetMiscFailure( pub fn dumpArgv(io: Io, argv: []const []const u8) Io.Cancelable!void { var buffer: [64]u8 = undefined; - const stderr = try io.lockStderr(&buffer); + const stderr = try io.lockStderr(&buffer, null); defer io.unlockStderr(); const w = &stderr.file_writer.interface; return dumpArgvWriter(w, argv) catch |err| switch (err) { diff --git a/src/InternPool.zig b/src/InternPool.zig index 98bde244c5..3076aa2cf3 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -11167,16 +11167,16 @@ pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) v @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release); } -pub fn dump(ip: *const InternPool, io: Io) Io.Cancelable!void { +pub fn dump(ip: *const InternPool) void { var buffer: [4096]u8 = undefined; - const stderr = try io.lockStderr(&buffer, null); - defer io.unlockStderr(); + const stderr = std.debug.lockStderr(&buffer); + defer std.debug.unlockStderr(); const w = &stderr.file_writer.interface; - try dumpStatsFallible(ip, w, std.heap.page_allocator); - try dumpAllFallible(ip, w); + dumpStatsFallible(ip, w, std.heap.page_allocator) catch return; + dumpAllFallible(ip, w) catch return; } -fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) anyerror!void { +fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !void { var items_len: usize = 0; var extra_len: usize = 0; var limbs_len: usize = 0; @@ -11429,9 +11429,9 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) any }; counts.sort(SortContext{ .map = &counts }); const len = @min(50, counts.count()); - w.print(" top 50 tags:\n", .{}); + try w.print(" top 50 tags:\n", .{}); for (counts.keys()[0..len], counts.values()[0..len]) |tag, stats| { - w.print(" {t}: {d} occurrences, {d} total bytes\n", .{ tag, stats.count, stats.bytes }); + try w.print(" {t}: {d} occurrences, {d} total bytes\n", .{ tag, stats.count, stats.bytes }); } } @@ -11534,12 +11534,12 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { } } -pub fn dumpGenericInstances(ip: *const InternPool, io: Io, allocator: Allocator) Io.Cancelable!void { +pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void { var buffer: [4096]u8 = undefined; - const stderr_writer = try io.lockStderr(&buffer, null); - defer io.unlockStderr(); - const w = &stderr_writer.interface; - try ip.dumpGenericInstancesFallible(allocator, w); + const stderr = std.debug.lockStderr(&buffer); + defer std.debug.unlockStderr(); + const w = &stderr.file_writer.interface; + ip.dumpGenericInstancesFallible(allocator, w) catch return; } pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator, w: *Io.Writer) !void { diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 823015574b..b17b39cd83 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -1682,18 +1682,18 @@ fn hashFileFallible(io: Io, dir: Io.Dir, hashed_file: *HashedFile) HashedFile.Er hasher.update(&.{ 0, 0 }); var file_header: FileHeader = .{}; while (true) { - const bytes_read = try file.read(&buf); + const bytes_read = try file.readPositional(io, &.{&buf}, file_size); if (bytes_read == 0) break; file_size += bytes_read; hasher.update(buf[0..bytes_read]); file_header.update(buf[0..bytes_read]); } if (file_header.isExecutable()) { - try setExecutable(file); + try setExecutable(io, file); } }, .link => { - const link_name = try dir.readLink(io, hashed_file.fs_path, &buf); + const link_name = buf[0..try dir.readLink(io, hashed_file.fs_path, &buf)]; if (fs.path.sep != canonical_sep) { // Package hashes are intended to be consistent across // platforms which means we must normalize path separators @@ -1711,12 +1711,9 @@ fn deleteFileFallible(io: Io, dir: Io.Dir, deleted_file: *DeletedFile) DeletedFi try dir.deleteFile(io, deleted_file.fs_path); } -fn setExecutable(file: Io.File) !void { +fn setExecutable(io: Io, file: Io.File) !void { if (!Io.File.Permissions.has_executable_bit) return; - - const S = std.posix.S; - const mode = Io.File.default_mode | S.IXUSR | S.IXGRP | S.IXOTH; - try file.chmod(mode); + try file.setPermissions(io, .executable_file); } const DeletedFile = struct { @@ -1738,7 +1735,7 @@ const HashedFile = struct { const Error = Io.File.OpenError || - Io.File.Reader.Error || + Io.File.ReadPositionalError || Io.File.StatError || Io.File.SetPermissionsError || Io.Dir.ReadLinkError; diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index 93a6e0a768..49de055b47 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -11280,7 +11280,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void { errdefer |err| @panic(@errorName(err)); - const locked_stderr = std.debug.lockStderr(&.{}, null); + const locked_stderr = std.debug.lockStderr(&.{}); defer std.debug.unlockStderr(); const stderr = &locked_stderr.file_writer.interface; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4fc58c2c4b..fca89ea4fc 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -965,10 +965,10 @@ pub const Object = struct { const context, const module = emit: { if (options.pre_ir_path) |path| { if (std.mem.eql(u8, path, "-")) { - o.builder.dump(); + o.builder.dump(io); } else { - o.builder.printToFilePath(Io.Dir.cwd(), path) catch |err| { - log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); + o.builder.printToFilePath(io, Io.Dir.cwd(), path) catch |err| { + log.err("failed printing LLVM module to \"{s}\": {t}", .{ path, err }); }; } } @@ -982,12 +982,12 @@ pub const Object = struct { if (options.pre_bc_path) |path| { var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| - return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); + return diags.fail("failed to create '{s}': {t}", .{ path, err }); defer file.close(io); const ptr: [*]const u8 = @ptrCast(bitcode.ptr); - file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| - return diags.fail("failed to write to '{s}': {s}", .{ path, @errorName(err) }); + file.writeStreamingAll(io, ptr[0..(bitcode.len * 4)]) catch |err| + return diags.fail("failed to write to '{s}': {t}", .{ path, err }); } if (options.asm_path == null and options.bin_path == null and @@ -995,12 +995,12 @@ pub const Object = struct { if (options.post_bc_path) |path| { var file = Io.Dir.cwd().createFile(io, path, .{}) catch |err| - return diags.fail("failed to create '{s}': {s}", .{ path, @errorName(err) }); + return diags.fail("failed to create '{s}': {t}", .{ path, err }); defer file.close(io); const ptr: [*]const u8 = @ptrCast(bitcode.ptr); - file.writeAll(ptr[0..(bitcode.len * 4)]) catch |err| - return diags.fail("failed to write to '{s}': {s}", .{ path, @errorName(err) }); + file.writeStreamingAll(io, ptr[0..(bitcode.len * 4)]) catch |err| + return diags.fail("failed to write to '{s}': {t}", .{ path, err }); } if (!build_options.have_llvm or !comp.config.use_lib_llvm) { diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig index 8cf1dfa303..c4b002f983 100644 --- a/src/libs/mingw.zig +++ b/src/libs/mingw.zig @@ -345,6 +345,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { if (msg.kind == .@"fatal error" or msg.kind == .@"error") { msg.write(stderr.terminal(), true) catch |err| switch (err) { error.WriteFailed => return stderr.file_writer.err.?, + error.Unexpected => |e| return e, }; return error.AroPreprocessorFailed; } diff --git a/src/link.zig b/src/link.zig index 3b822b2e69..13306b90a4 100644 --- a/src/link.zig +++ b/src/link.zig @@ -900,10 +900,9 @@ pub const File = struct { } } - pub const FlushError = error{ + pub const FlushError = Io.Cancelable || Allocator.Error || error{ /// Indicates an error will be present in `Compilation.link_diags`. LinkFailure, - OutOfMemory, }; /// Commit pending changes and write headers. Takes into account final output mode. diff --git a/src/link/Elf.zig b/src/link/Elf.zig index a312138c04..85f37f88ce 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -748,9 +748,10 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std defer tracy.end(); const comp = self.base.comp; + const io = comp.io; const diags = &comp.link_diags; - if (comp.verbose_link) Compilation.dump_argv(self.dump_argv_list.items); + if (comp.verbose_link) try Compilation.dumpArgv(io, self.dump_argv_list.items); const sub_prog_node = prog_node.start("ELF Flush", 0); defer sub_prog_node.end(); @@ -758,7 +759,7 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std return flushInner(self, arena, tid) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.LinkFailure => return error.LinkFailure, - else => |e| return diags.fail("ELF flush failed: {s}", .{@errorName(e)}), + else => |e| return diags.fail("ELF flush failed: {t}", .{e}), }; } diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 8ba91905a8..b2a0f6e396 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1588,7 +1588,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi if (comp.verbose_link) { // Skip over our own name so that the LLD linker name is the first argv item. - Compilation.dump_argv(argv[1..]); + try Compilation.dumpArgv(io, argv[1..]); } // If possible, we run LLD as a child process because it does not always diff --git a/src/link/MachO.zig b/src/link/MachO.zig index cd9674a390..b3c62db2df 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -618,14 +618,16 @@ pub fn flush( }; const emit = self.base.emit; invalidateKernelCache(emit.root_dir.handle, emit.sub_path) catch |err| switch (err) { - else => |e| return diags.fail("failed to invalidate kernel cache: {s}", .{@errorName(e)}), + else => |e| return diags.fail("failed to invalidate kernel cache: {t}", .{e}), }; } } /// --verbose-link output fn dumpArgv(self: *MachO, comp: *Compilation) !void { - const gpa = self.base.comp.gpa; + const gpa = comp.gpa; + const io = comp.io; + var arena_allocator = std.heap.ArenaAllocator.init(gpa); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); @@ -820,7 +822,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { if (comp.ubsan_rt_obj) |obj| try argv.append(try obj.full_object_path.toString(arena)); } - Compilation.dump_argv(argv.items); + try Compilation.dumpArgv(io, argv.items); } /// TODO delete this, libsystem must be resolved when setting up the compilation pipeline diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index dca3dca503..2986e27e24 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -476,8 +476,8 @@ pub const Node = extern struct { return n; }, .streaming, - .streaming_reading, - .positional_reading, + .streaming_simple, + .positional_simple, .failure, => { const dest = limit.slice(interface.unusedCapacitySlice()); diff --git a/src/link/Queue.zig b/src/link/Queue.zig index e8e7700695..caa2cc1898 100644 --- a/src/link/Queue.zig +++ b/src/link/Queue.zig @@ -175,6 +175,7 @@ fn runLinkTasks(q: *Queue, comp: *Compilation) void { lf.post_prelink = true; } else |err| switch (err) { error.OutOfMemory => comp.link_diags.setAllocFailure(), + error.Canceled => @panic("TODO"), error.LinkFailure => {}, } } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index a8140327e5..216a641db3 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3828,8 +3828,9 @@ pub fn flush( const comp = wasm.base.comp; const diags = &comp.link_diags; const gpa = comp.gpa; + const io = comp.io; - if (comp.verbose_link) Compilation.dump_argv(wasm.dump_argv_list.items); + if (comp.verbose_link) try Compilation.dumpArgv(io, wasm.dump_argv_list.items); if (wasm.base.zcu_object_basename) |raw| { const zcu_obj_path: Path = try comp.resolveEmitPathFlush(arena, .temp, raw); -- cgit v1.2.3