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,11 +14,10 @@ const Cache = std.Build.Cache; const Io = std.Io; const Limb = std.math.big.Limb; const Hash = std.hash.Wyhash; - -const InternPool = @This(); -const Zcu = @import("Zcu.zig"); const Zir = std.zig.Zir; +const Zcu = @import("Zcu.zig"); + /// One item per thread, indexed by `tid`, which is dense and unique per thread. locals: []Local, /// Length must be a power of two and represents the number of simultaneous @@ -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); }