authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-10-28 12:42:05+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-10-30 09:31:28+00:00
log74931fe25cdd94e1cd08b5ece9dcce19959bc079
tree75449b1d594d55a872aeb03f2dd3be16ac396274
parent74c23a237ef5245b63eb06b832a511aabeb715c0
signaturelock-open Commit is signed but in an unrecognized format.

std.debug.lockStderrWriter: also return ttyconf

`std.Io.tty.Config.detect` may be an expensive check (e.g. involving syscalls), and doing it every time we need to print isn't really necessary; under normal usage, we can compute the value once and cache it for the whole program's execution. Since anyone outputting to stderr may reasonably want this information (in fact they are very likely to), it makes sense to cache it and return it from `lockStderrWriter`. Call sites who do not need it will experience no significant overhead, and can just ignore the TTY config with a `const w, _` destructure.

37 files changed, 169 insertions(+), 193 deletions(-)

lib/compiler/build_runner.zig+16-25
......@@ -442,8 +442,7 @@ pub fn main() !void {
442442 if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});
443443 }
444444
445 const stderr: std.fs.File = .stderr();
446 const ttyconf = get_tty_conf(color, stderr);
445 const ttyconf = color.detectTtyConf();
447446 switch (ttyconf) {
448447 .no_color => try graph.env_map.put("NO_COLOR", "1"),
449448 .escape_codes => try graph.env_map.put("CLICOLOR_FORCE", "1"),
......@@ -522,9 +521,9 @@ pub fn main() !void {
522521 .error_style = error_style,
523522 .multiline_errors = multiline_errors,
524523 .summary = summary orelse if (watch or webui_listen != null) .line else .failures,
525 .ttyconf = ttyconf,
526 .stderr = stderr,
527524 .thread_pool = undefined,
525
526 .ttyconf = ttyconf,
528527 };
529528 defer {
530529 run.memory_blocked_steps.deinit(gpa);
......@@ -563,9 +562,9 @@ pub fn main() !void {
563562 break :ws .init(.{
564563 .gpa = gpa,
565564 .thread_pool = &run.thread_pool,
565 .ttyconf = ttyconf,
566566 .graph = &graph,
567567 .all_steps = run.step_stack.keys(),
568 .ttyconf = run.ttyconf,
569568 .root_prog_node = main_progress_node,
570569 .watch = watch,
571570 .listen_address = listen_address,
......@@ -578,7 +577,7 @@ pub fn main() !void {
578577 }
579578
580579 rebuild: while (true) : (if (run.error_style.clearOnUpdate()) {
581 const bw = std.debug.lockStderrWriter(&stdio_buffer_allocation);
580 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
582581 defer std.debug.unlockStderrWriter();
583582 try bw.writeAll("\x1B[2J\x1B[3J\x1B[H");
584583 }) {
......@@ -682,13 +681,14 @@ const Run = struct {
682681 /// Allocated into `gpa`.
683682 step_stack: std.AutoArrayHashMapUnmanaged(*Step, void),
684683 thread_pool: std.Thread.Pool,
684 /// Similar to the `tty.Config` returned by `std.debug.lockStderrWriter`,
685 /// but also respects the '--color' flag.
686 ttyconf: tty.Config,
685687
686688 claimed_rss: usize,
687689 error_style: ErrorStyle,
688690 multiline_errors: MultilineErrors,
689691 summary: Summary,
690 ttyconf: tty.Config,
691 stderr: File,
692692};
693693
694694fn prepare(
......@@ -834,8 +834,6 @@ fn runStepNames(
834834 }
835835 }
836836
837 const ttyconf = run.ttyconf;
838
839837 if (fuzz) |mode| blk: {
840838 switch (builtin.os.tag) {
841839 // Current implementation depends on two things that need to be ported to Windows:
......@@ -863,9 +861,9 @@ fn runStepNames(
863861 gpa,
864862 io,
865863 thread_pool,
864 run.ttyconf,
866865 step_stack.keys(),
867866 parent_prog_node,
868 ttyconf,
869867 mode,
870868 ) catch |err| fatal("failed to start fuzzer: {s}", .{@errorName(err)});
871869 defer f.deinit();
......@@ -890,8 +888,9 @@ fn runStepNames(
890888 .none => break :summary,
891889 }
892890
893 const w = std.debug.lockStderrWriter(&stdio_buffer_allocation);
891 const w, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
894892 defer std.debug.unlockStderrWriter();
893 const ttyconf = run.ttyconf;
895894
896895 const total_count = success_count + failure_count + pending_count + skipped_count;
897896 ttyconf.setColor(w, .cyan) catch {};
......@@ -1399,9 +1398,10 @@ fn workerMakeOneStep(
13991398 const show_error_msgs = s.result_error_msgs.items.len > 0;
14001399 const show_stderr = s.result_stderr.len > 0;
14011400 if (show_error_msgs or show_compile_errors or show_stderr) {
1402 const bw = std.debug.lockStderrWriter(&stdio_buffer_allocation);
1401 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
14031402 defer std.debug.unlockStderrWriter();
1404 printErrorMessages(run.gpa, s, .{ .ttyconf = run.ttyconf }, bw, run.error_style, run.multiline_errors) catch {};
1403 const ttyconf = run.ttyconf;
1404 printErrorMessages(run.gpa, s, .{}, bw, ttyconf, run.error_style, run.multiline_errors) catch {};
14051405 }
14061406
14071407 handle_result: {
......@@ -1465,11 +1465,10 @@ pub fn printErrorMessages(
14651465 failing_step: *Step,
14661466 options: std.zig.ErrorBundle.RenderOptions,
14671467 stderr: *Writer,
1468 ttyconf: tty.Config,
14681469 error_style: ErrorStyle,
14691470 multiline_errors: MultilineErrors,
14701471) !void {
1471 const ttyconf = options.ttyconf;
1472
14731472 if (error_style.verboseContext()) {
14741473 // Provide context for where these error messages are coming from by
14751474 // printing the corresponding Step subtree.
......@@ -1513,7 +1512,7 @@ pub fn printErrorMessages(
15131512 }
15141513 }
15151514
1516 try failing_step.result_error_bundle.renderToWriter(options, stderr);
1515 try failing_step.result_error_bundle.renderToWriter(options, stderr, ttyconf);
15171516
15181517 for (failing_step.result_error_msgs.items) |msg| {
15191518 try ttyconf.setColor(stderr, .red);
......@@ -1759,14 +1758,6 @@ const ErrorStyle = enum {
17591758const MultilineErrors = enum { indent, newline, none };
17601759const Summary = enum { all, new, failures, line, none };
17611760
1762fn get_tty_conf(color: Color, stderr: File) tty.Config {
1763 return switch (color) {
1764 .auto => tty.detectConfig(stderr),
1765 .on => .escape_codes,
1766 .off => .no_color,
1767 };
1768}
1769
17701761fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {
17711762 std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args);
17721763 process.exit(1);
lib/compiler/resinator/cli.zig+3-3
......@@ -124,10 +124,10 @@ pub const Diagnostics = struct {
124124 try self.errors.append(self.allocator, error_details);
125125 }
126126
127 pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8, config: std.Io.tty.Config) void {
128 const stderr = std.debug.lockStderrWriter(&.{});
127 pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8) void {
128 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
129129 defer std.debug.unlockStderrWriter();
130 self.renderToWriter(args, stderr, config) catch return;
130 self.renderToWriter(args, stderr, ttyconf) catch return;
131131 }
132132
133133 pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void {
lib/compiler/resinator/errors.zig+3-8
......@@ -67,20 +67,15 @@ pub const Diagnostics = struct {
6767 return @intCast(index);
6868 }
6969
70 pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, tty_config: std.Io.tty.Config, source_mappings: ?SourceMappings) void {
70 pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
7171 const io = self.io;
72 const stderr = std.debug.lockStderrWriter(&.{});
72 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
7373 defer std.debug.unlockStderrWriter();
7474 for (self.errors.items) |err_details| {
75 renderErrorMessage(io, stderr, tty_config, cwd, err_details, source, self.strings.items, source_mappings) catch return;
75 renderErrorMessage(io, stderr, ttyconf, cwd, err_details, source, self.strings.items, source_mappings) catch return;
7676 }
7777 }
7878
79 pub fn renderToStdErrDetectTTY(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
80 const tty_config = std.Io.tty.detectConfig(std.fs.File.stderr());
81 return self.renderToStdErr(cwd, source, tty_config, source_mappings);
82 }
83
8479 pub fn contains(self: *const Diagnostics, err: ErrorDetails.Error) bool {
8580 for (self.errors.items) |details| {
8681 if (details.err == err) return true;
lib/compiler/resinator/main.zig+29-34
......@@ -28,13 +28,11 @@ pub fn main() !void {
2828 defer arena_state.deinit();
2929 const arena = arena_state.allocator();
3030
31 const stderr = std.fs.File.stderr();
32 const stderr_config = std.Io.tty.detectConfig(stderr);
33
3431 const args = try std.process.argsAlloc(arena);
3532
3633 if (args.len < 2) {
37 try renderErrorMessage(std.debug.lockStderrWriter(&.{}), stderr_config, .err, "expected zig lib dir as first argument", .{});
34 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
35 try renderErrorMessage(w, ttyconf, .err, "expected zig lib dir as first argument", .{});
3836 std.process.exit(1);
3937 }
4038 const zig_lib_dir = args[1];
......@@ -56,9 +54,7 @@ pub fn main() !void {
5654 .in = undefined, // won't be receiving messages
5755 },
5856 },
59 false => .{
60 .tty = stderr_config,
61 },
57 false => .stderr,
6258 };
6359
6460 var options = options: {
......@@ -75,12 +71,14 @@ pub fn main() !void {
7571
7672 if (!zig_integration) {
7773 // print any warnings/notes
78 cli_diagnostics.renderToStdErr(cli_args, stderr_config);
74 cli_diagnostics.renderToStdErr(cli_args);
7975 // If there was something printed, then add an extra newline separator
8076 // so that there is a clear separation between the cli diagnostics and whatever
8177 // gets printed after
8278 if (cli_diagnostics.errors.items.len > 0) {
83 try stderr.writeAll("\n");
79 const stderr, _ = std.debug.lockStderrWriter(&.{});
80 defer std.debug.unlockStderrWriter();
81 try stderr.writeByte('\n');
8482 }
8583 }
8684 break :options options;
......@@ -130,17 +128,18 @@ pub fn main() !void {
130128 const aro_arena = aro_arena_state.allocator();
131129
132130 var stderr_buf: [512]u8 = undefined;
133 var stderr_writer = stderr.writer(&stderr_buf);
134 var diagnostics: aro.Diagnostics = switch (zig_integration) {
135 false => .{ .output = .{ .to_writer = .{
136 .writer = &stderr_writer.interface,
137 .color = stderr_config,
138 } } },
139 true => .{ .output = .{ .to_list = .{
140 .arena = .init(gpa),
141 } } },
142 };
143 defer diagnostics.deinit();
131 var diagnostics: aro.Diagnostics = .{ .output = output: {
132 if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } };
133 const w, const ttyconf = std.debug.lockStderrWriter(&stderr_buf);
134 break :output .{ .to_writer = .{
135 .writer = w,
136 .color = ttyconf,
137 } };
138 } };
139 defer {
140 diagnostics.deinit();
141 if (!zig_integration) std.debug.unlockStderrWriter();
142 }
144143
145144 var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd());
146145 defer comp.deinit();
......@@ -307,7 +306,7 @@ pub fn main() !void {
307306
308307 // print any warnings/notes
309308 if (!zig_integration) {
310 diagnostics.renderToStdErr(std.fs.cwd(), final_input, stderr_config, mapping_results.mappings);
309 diagnostics.renderToStdErr(std.fs.cwd(), final_input, mapping_results.mappings);
311310 }
312311
313312 // write the depfile
......@@ -660,7 +659,7 @@ const SourceMappings = @import("source_mapping.zig").SourceMappings;
660659
661660const ErrorHandler = union(enum) {
662661 server: std.zig.Server,
663 tty: std.Io.tty.Config,
662 stderr,
664663
665664 pub fn emitCliDiagnostics(
666665 self: *ErrorHandler,
......@@ -675,9 +674,7 @@ const ErrorHandler = union(enum) {
675674
676675 try server.serveErrorBundle(error_bundle);
677676 },
678 .tty => {
679 diagnostics.renderToStdErr(args, self.tty);
680 },
677 .stderr => diagnostics.renderToStdErr(args),
681678 }
682679 }
683680
......@@ -698,11 +695,11 @@ const ErrorHandler = union(enum) {
698695
699696 try server.serveErrorBundle(error_bundle);
700697 },
701 .tty => {
698 .stderr => {
702699 // aro errors have already been emitted
703 const stderr = std.debug.lockStderrWriter(&.{});
700 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
704701 defer std.debug.unlockStderrWriter();
705 try renderErrorMessage(stderr, self.tty, .err, "{s}", .{fail_msg});
702 try renderErrorMessage(stderr, ttyconf, .err, "{s}", .{fail_msg});
706703 },
707704 }
708705 }
......@@ -722,9 +719,7 @@ const ErrorHandler = union(enum) {
722719
723720 try server.serveErrorBundle(error_bundle);
724721 },
725 .tty => {
726 diagnostics.renderToStdErr(cwd, source, self.tty, mappings);
727 },
722 .stderr => diagnostics.renderToStdErr(cwd, source, mappings),
728723 }
729724 }
730725
......@@ -745,10 +740,10 @@ const ErrorHandler = union(enum) {
745740
746741 try server.serveErrorBundle(error_bundle);
747742 },
748 .tty => {
749 const stderr = std.debug.lockStderrWriter(&.{});
743 .stderr => {
744 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
750745 defer std.debug.unlockStderrWriter();
751 try renderErrorMessage(stderr, self.tty, msg_type, format, args);
746 try renderErrorMessage(stderr, ttyconf, msg_type, format, args);
752747 },
753748 }
754749 }
lib/compiler/std-docs.zig+1-2
......@@ -394,8 +394,7 @@ fn buildWasmBinary(
394394 }
395395
396396 if (result_error_bundle.errorMessageCount() > 0) {
397 const color = std.zig.Color.auto;
398 result_error_bundle.renderToStdErr(color.renderOptions());
397 result_error_bundle.renderToStdErr(.{}, true);
399398 std.log.err("the following command failed with {d} compilation errors:\n{s}", .{
400399 result_error_bundle.errorMessageCount(),
401400 try std.Build.Step.allocPrintCmd(arena, null, argv.items),
lib/std/Build.zig+5-7
......@@ -2257,8 +2257,8 @@ pub const GeneratedFile = struct {
22572257
22582258 pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 {
22592259 return gen.path orelse {
2260 const w = debug.lockStderrWriter(&.{});
2261 dumpBadGetPathHelp(gen.step, w, .detect(.stderr()), src_builder, asking_step) catch {};
2260 const w, const ttyconf = debug.lockStderrWriter(&.{});
2261 dumpBadGetPathHelp(gen.step, w, ttyconf, src_builder, asking_step) catch {};
22622262 debug.unlockStderrWriter();
22632263 @panic("misconfigured build script");
22642264 };
......@@ -2466,8 +2466,8 @@ pub const LazyPath = union(enum) {
24662466 var file_path: Cache.Path = .{
24672467 .root_dir = Cache.Directory.cwd(),
24682468 .sub_path = gen.file.path orelse {
2469 const w = debug.lockStderrWriter(&.{});
2470 dumpBadGetPathHelp(gen.file.step, w, .detect(.stderr()), src_builder, asking_step) catch {};
2469 const w, const ttyconf = debug.lockStderrWriter(&.{});
2470 dumpBadGetPathHelp(gen.file.step, w, ttyconf, src_builder, asking_step) catch {};
24712471 debug.unlockStderrWriter();
24722472 @panic("misconfigured build script");
24732473 },
......@@ -2558,13 +2558,11 @@ fn dumpBadDirnameHelp(
25582558 comptime msg: []const u8,
25592559 args: anytype,
25602560) anyerror!void {
2561 const w = debug.lockStderrWriter(&.{});
2561 const w, const tty_config = debug.lockStderrWriter(&.{});
25622562 defer debug.unlockStderrWriter();
25632563
25642564 try w.print(msg, args);
25652565
2566 const tty_config = std.Io.tty.detectConfig(.stderr());
2567
25682566 if (fail_step) |s| {
25692567 tty_config.setColor(w, .red) catch {};
25702568 try w.writeAll(" The step was created by this stack trace:\n");
lib/std/Build/Fuzz.zig+9-9
......@@ -16,6 +16,7 @@ const build_runner = @import("root");
1616
1717gpa: Allocator,
1818io: Io,
19ttyconf: tty.Config,
1920mode: Mode,
2021
2122/// Allocated into `gpa`.
......@@ -25,7 +26,6 @@ wait_group: std.Thread.WaitGroup,
2526root_prog_node: std.Progress.Node,
2627prog_node: std.Progress.Node,
2728thread_pool: *std.Thread.Pool,
28ttyconf: tty.Config,
2929
3030/// Protects `coverage_files`.
3131coverage_mutex: std.Thread.Mutex,
......@@ -79,9 +79,9 @@ pub fn init(
7979 gpa: Allocator,
8080 io: Io,
8181 thread_pool: *std.Thread.Pool,
82 ttyconf: tty.Config,
8283 all_steps: []const *Build.Step,
8384 root_prog_node: std.Progress.Node,
84 ttyconf: tty.Config,
8585 mode: Mode,
8686) Allocator.Error!Fuzz {
8787 const run_steps: []const *Step.Run = steps: {
......@@ -115,11 +115,11 @@ pub fn init(
115115 return .{
116116 .gpa = gpa,
117117 .io = io,
118 .ttyconf = ttyconf,
118119 .mode = mode,
119120 .run_steps = run_steps,
120121 .wait_group = .{},
121122 .thread_pool = thread_pool,
122 .ttyconf = ttyconf,
123123 .root_prog_node = root_prog_node,
124124 .prog_node = .none,
125125 .coverage_files = .empty,
......@@ -158,7 +158,7 @@ pub fn deinit(fuzz: *Fuzz) void {
158158 fuzz.gpa.free(fuzz.run_steps);
159159}
160160
161fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Config, parent_prog_node: std.Progress.Node) void {
161fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: tty.Config, parent_prog_node: std.Progress.Node) void {
162162 rebuildTestsWorkerRunFallible(run, gpa, ttyconf, parent_prog_node) catch |err| {
163163 const compile = run.producer.?;
164164 log.err("step '{s}': failed to rebuild in fuzz mode: {s}", .{
......@@ -167,7 +167,7 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Con
167167 };
168168}
169169
170fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Config, parent_prog_node: std.Progress.Node) !void {
170fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: tty.Config, parent_prog_node: std.Progress.Node) !void {
171171 const compile = run.producer.?;
172172 const prog_node = parent_prog_node.start(compile.step.name, 0);
173173 defer prog_node.end();
......@@ -180,9 +180,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io
180180
181181 if (show_error_msgs or show_compile_errors or show_stderr) {
182182 var buf: [256]u8 = undefined;
183 const w = std.debug.lockStderrWriter(&buf);
183 const w, _ = std.debug.lockStderrWriter(&buf);
184184 defer std.debug.unlockStderrWriter();
185 build_runner.printErrorMessages(gpa, &compile.step, .{ .ttyconf = ttyconf }, w, .verbose, .indent) catch {};
185 build_runner.printErrorMessages(gpa, &compile.step, .{}, w, ttyconf, .verbose, .indent) catch {};
186186 }
187187
188188 const rebuilt_bin_path = result catch |err| switch (err) {
......@@ -206,9 +206,9 @@ fn fuzzWorkerRun(
206206 run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
207207 error.MakeFailed => {
208208 var buf: [256]u8 = undefined;
209 const w = std.debug.lockStderrWriter(&buf);
209 const w, _ = std.debug.lockStderrWriter(&buf);
210210 defer std.debug.unlockStderrWriter();
211 build_runner.printErrorMessages(gpa, &run.step, .{ .ttyconf = fuzz.ttyconf }, w, .verbose, .indent) catch {};
211 build_runner.printErrorMessages(gpa, &run.step, .{}, w, fuzz.ttyconf, .verbose, .indent) catch {};
212212 return;
213213 },
214214 else => {
lib/std/Build/Step/Compile.zig+5-6
......@@ -1056,15 +1056,15 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking
10561056 const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
10571057
10581058 const generated_file = maybe_path orelse {
1059 const w = std.debug.lockStderrWriter(&.{});
1060 std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};
1059 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
1060 std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
10611061 std.debug.unlockStderrWriter();
10621062 @panic("missing emit option for " ++ tag_name);
10631063 };
10641064
10651065 const path = generated_file.path orelse {
1066 const w = std.debug.lockStderrWriter(&.{});
1067 std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};
1066 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
1067 std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
10681068 std.debug.unlockStderrWriter();
10691069 @panic(tag_name ++ " is null. Is there a missing step dependency?");
10701070 };
......@@ -2027,10 +2027,9 @@ fn checkCompileErrors(compile: *Compile) !void {
20272027 var aw: std.Io.Writer.Allocating = .init(arena);
20282028 defer aw.deinit();
20292029 try actual_eb.renderToWriter(.{
2030 .ttyconf = .no_color,
20312030 .include_reference_trace = false,
20322031 .include_source_line = false,
2033 }, &aw.writer);
2032 }, &aw.writer, .no_color);
20342033 break :ae try aw.toOwnedSlice();
20352034 };
20362035
lib/std/Build/WebServer.zig+4-5
......@@ -54,9 +54,9 @@ pub fn notifyUpdate(ws: *WebServer) void {
5454pub const Options = struct {
5555 gpa: Allocator,
5656 thread_pool: *std.Thread.Pool,
57 ttyconf: Io.tty.Config,
5758 graph: *const std.Build.Graph,
5859 all_steps: []const *Build.Step,
59 ttyconf: Io.tty.Config,
6060 root_prog_node: std.Progress.Node,
6161 watch: bool,
6262 listen_address: net.IpAddress,
......@@ -101,10 +101,10 @@ pub fn init(opts: Options) WebServer {
101101 return .{
102102 .gpa = opts.gpa,
103103 .thread_pool = opts.thread_pool,
104 .ttyconf = opts.ttyconf,
104105 .graph = opts.graph,
105106 .all_steps = all_steps,
106107 .listen_address = opts.listen_address,
107 .ttyconf = opts.ttyconf,
108108 .root_prog_node = opts.root_prog_node,
109109 .watch = opts.watch,
110110
......@@ -236,9 +236,9 @@ pub fn finishBuild(ws: *WebServer, opts: struct {
236236 ws.gpa,
237237 ws.graph.io,
238238 ws.thread_pool,
239 ws.ttyconf,
239240 ws.all_steps,
240241 ws.root_prog_node,
241 ws.ttyconf,
242242 .{ .forever = .{ .ws = ws } },
243243 ) catch |err| std.process.fatal("failed to start fuzzer: {s}", .{@errorName(err)});
244244 ws.fuzz.?.start();
......@@ -655,8 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim
655655 }
656656
657657 if (result_error_bundle.errorMessageCount() > 0) {
658 const color = std.zig.Color.auto;
659 result_error_bundle.renderToStdErr(color.renderOptions());
658 result_error_bundle.renderToStdErr(.{}, .auto);
660659 log.err("the following command failed with {d} compilation errors:\n{s}", .{
661660 result_error_bundle.errorMessageCount(),
662661 try Build.Step.allocPrintCmd(arena, null, argv.items),
lib/std/debug.zig+19-19
......@@ -272,7 +272,7 @@ pub fn unlockStdErr() void {
272272 std.Progress.unlockStdErr();
273273}
274274
275/// Allows the caller to freely write to stderr until `unlockStdErr` is called.
275/// Allows the caller to freely write to stderr until `unlockStderrWriter` is called.
276276///
277277/// During the lock, any `std.Progress` information is cleared from the terminal.
278278///
......@@ -282,8 +282,16 @@ pub fn unlockStdErr() void {
282282///
283283/// The returned `Writer` does not need to be manually flushed: flushing is performed automatically
284284/// when the matching `unlockStderrWriter` call occurs.
285pub fn lockStderrWriter(buffer: []u8) *Writer {
286 return std.Progress.lockStderrWriter(buffer);
285pub fn lockStderrWriter(buffer: []u8) struct { *Writer, tty.Config } {
286 const global = struct {
287 var conf: ?tty.Config = null;
288 };
289 const w = std.Progress.lockStderrWriter(buffer);
290 // The stderr lock also locks access to `global.conf`.
291 if (global.conf == null) {
292 global.conf = .detect(.stderr());
293 }
294 return .{ w, global.conf.? };
287295}
288296
289297pub fn unlockStderrWriter() void {
......@@ -297,7 +305,7 @@ pub fn unlockStderrWriter() void {
297305/// function returns.
298306pub fn print(comptime fmt: []const u8, args: anytype) void {
299307 var buffer: [64]u8 = undefined;
300 const bw = lockStderrWriter(&buffer);
308 const bw, _ = lockStderrWriter(&buffer);
301309 defer unlockStderrWriter();
302310 nosuspend bw.print(fmt, args) catch return;
303311}
......@@ -314,9 +322,8 @@ pub inline fn getSelfDebugInfo() !*SelfInfo {
314322/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
315323/// Obtains the stderr mutex while dumping.
316324pub fn dumpHex(bytes: []const u8) void {
317 const bw = lockStderrWriter(&.{});
325 const bw, const ttyconf = lockStderrWriter(&.{});
318326 defer unlockStderrWriter();
319 const ttyconf = tty.detectConfig(.stderr());
320327 dumpHexFallible(bw, ttyconf, bytes) catch {};
321328}
322329
......@@ -538,9 +545,7 @@ pub fn defaultPanic(
538545 _ = panicking.fetchAdd(1, .seq_cst);
539546
540547 trace: {
541 const tty_config = tty.detectConfig(.stderr());
542
543 const stderr = lockStderrWriter(&.{});
548 const stderr, const tty_config = lockStderrWriter(&.{});
544549 defer unlockStderrWriter();
545550
546551 if (builtin.single_threaded) {
......@@ -743,8 +748,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri
743748}
744749/// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors.
745750pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {
746 const tty_config = tty.detectConfig(.stderr());
747 const stderr = lockStderrWriter(&.{});
751 const stderr, const tty_config = lockStderrWriter(&.{});
748752 defer unlockStderrWriter();
749753 writeCurrentStackTrace(.{
750754 .first_address = a: {
......@@ -809,8 +813,7 @@ pub fn writeStackTrace(st: *const StackTrace, writer: *Writer, tty_config: tty.C
809813}
810814/// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors.
811815pub fn dumpStackTrace(st: *const StackTrace) void {
812 const tty_config = tty.detectConfig(.stderr());
813 const stderr = lockStderrWriter(&.{});
816 const stderr, const tty_config = lockStderrWriter(&.{});
814817 defer unlockStderrWriter();
815818 writeStackTrace(st, stderr, tty_config) catch |err| switch (err) {
816819 error.WriteFailed => {},
......@@ -1552,9 +1555,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex
15521555 _ = panicking.fetchAdd(1, .seq_cst);
15531556
15541557 trace: {
1555 const tty_config = tty.detectConfig(.stderr());
1556
1557 const stderr = lockStderrWriter(&.{});
1558 const stderr, const tty_config = lockStderrWriter(&.{});
15581559 defer unlockStderrWriter();
15591560
15601561 if (addr) |a| {
......@@ -1612,7 +1613,7 @@ test "manage resources correctly" {
16121613 &di,
16131614 &discarding.writer,
16141615 S.showMyTrace(),
1615 tty.detectConfig(.stderr()),
1616 .no_color,
16161617 );
16171618}
16181619
......@@ -1674,8 +1675,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
16741675 pub fn dump(t: @This()) void {
16751676 if (!enabled) return;
16761677
1677 const tty_config = tty.detectConfig(.stderr());
1678 const stderr = lockStderrWriter(&.{});
1678 const stderr, const tty_config = lockStderrWriter(&.{});
16791679 defer unlockStderrWriter();
16801680 const end = @min(t.index, size);
16811681 for (t.addrs[0..end], 0..) |frames_array, i| {
lib/std/json/dynamic.zig+1-1
......@@ -47,7 +47,7 @@ pub const Value = union(enum) {
4747 }
4848
4949 pub fn dump(v: Value) void {
50 const w = std.debug.lockStderrWriter(&.{});
50 const w, _ = std.debug.lockStderrWriter(&.{});
5151 defer std.debug.unlockStderrWriter();
5252
5353 json.Stringify.value(v, .{}, w) catch return;
lib/std/log.zig+1-1
......@@ -151,7 +151,7 @@ pub fn defaultLog(
151151 const level_txt = comptime message_level.asText();
152152 const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
153153 var buffer: [64]u8 = undefined;
154 const stderr = std.debug.lockStderrWriter(&buffer);
154 const stderr, _ = std.debug.lockStderrWriter(&buffer);
155155 defer std.debug.unlockStderrWriter();
156156 nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;
157157}
lib/std/testing.zig+4-4
......@@ -355,7 +355,7 @@ test expectApproxEqRel {
355355/// This function is intended to be used only in tests. When the two slices are not
356356/// equal, prints diagnostics to stderr to show exactly how they are not equal (with
357357/// the differences highlighted in red), then returns a test failure error.
358/// The colorized output is optional and controlled by the return of `std.Io.tty.detectConfig()`.
358/// The colorized output is optional and controlled by the return of `std.Io.tty.Config.detect`.
359359/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
360360pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
361361 const diff_index: usize = diff_index: {
......@@ -367,9 +367,9 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
367367 break :diff_index if (expected.len == actual.len) return else shortest;
368368 };
369369 if (!backend_can_print) return error.TestExpectedEqual;
370 const stderr_w = std.debug.lockStderrWriter(&.{});
370 const stderr_w, const ttyconf = std.debug.lockStderrWriter(&.{});
371371 defer std.debug.unlockStderrWriter();
372 failEqualSlices(T, expected, actual, diff_index, stderr_w) catch {};
372 failEqualSlices(T, expected, actual, diff_index, stderr_w, ttyconf) catch {};
373373 return error.TestExpectedEqual;
374374}
375375
......@@ -379,6 +379,7 @@ fn failEqualSlices(
379379 actual: []const T,
380380 diff_index: usize,
381381 w: *std.Io.Writer,
382 ttyconf: std.Io.tty.Config,
382383) !void {
383384 try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });
384385
......@@ -398,7 +399,6 @@ fn failEqualSlices(
398399 const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
399400 const actual_truncated = window_start + actual_window.len < actual.len;
400401
401 const ttyconf = std.Io.tty.detectConfig(.stderr());
402402 var differ = if (T == u8) BytesDiffer{
403403 .expected = expected_window,
404404 .actual = actual_window,
lib/std/zig.zig+8-7
......@@ -53,17 +53,18 @@ pub const Color = enum {
5353 /// Assume stderr is a terminal.
5454 on,
5555
56 pub fn get_tty_conf(color: Color) Io.tty.Config {
56 pub fn getTtyConf(color: Color, detected: Io.tty.Config) Io.tty.Config {
5757 return switch (color) {
58 .auto => Io.tty.detectConfig(std.fs.File.stderr()),
58 .auto => detected,
5959 .on => .escape_codes,
6060 .off => .no_color,
6161 };
6262 }
63
64 pub fn renderOptions(color: Color) std.zig.ErrorBundle.RenderOptions {
65 return .{
66 .ttyconf = get_tty_conf(color),
63 pub fn detectTtyConf(color: Color) Io.tty.Config {
64 return switch (color) {
65 .auto => .detect(.stderr()),
66 .on => .escape_codes,
67 .off => .no_color,
6768 };
6869 }
6970};
......@@ -606,7 +607,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color
606607
607608 var error_bundle = try wip_errors.toOwnedBundle("");
608609 defer error_bundle.deinit(gpa);
609 error_bundle.renderToStdErr(color.renderOptions());
610 error_bundle.renderToStdErr(.{}, color);
610611}
611612
612613pub fn putAstErrorsIntoBundle(
lib/std/zig/ErrorBundle.zig+8-9
......@@ -157,23 +157,22 @@ pub fn nullTerminatedString(eb: ErrorBundle, index: String) [:0]const u8 {
157157}
158158
159159pub const RenderOptions = struct {
160 ttyconf: Io.tty.Config,
161160 include_reference_trace: bool = true,
162161 include_source_line: bool = true,
163162 include_log_text: bool = true,
164163};
165164
166pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {
165pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions, color: std.zig.Color) void {
167166 var buffer: [256]u8 = undefined;
168 const w = std.debug.lockStderrWriter(&buffer);
167 const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
169168 defer std.debug.unlockStderrWriter();
170 renderToWriter(eb, options, w) catch return;
169 renderToWriter(eb, options, w, color.getTtyConf(ttyconf)) catch return;
171170}
172171
173pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer) (Writer.Error || std.posix.UnexpectedError)!void {
172pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer, ttyconf: Io.tty.Config) (Writer.Error || std.posix.UnexpectedError)!void {
174173 if (eb.extra.len == 0) return;
175174 for (eb.getMessages()) |err_msg| {
176 try renderErrorMessageToWriter(eb, options, err_msg, w, "error", .red, 0);
175 try renderErrorMessageToWriter(eb, options, err_msg, w, ttyconf, "error", .red, 0);
177176 }
178177
179178 if (options.include_log_text) {
......@@ -190,11 +189,11 @@ fn renderErrorMessageToWriter(
190189 options: RenderOptions,
191190 err_msg_index: MessageIndex,
192191 w: *Writer,
192 ttyconf: Io.tty.Config,
193193 kind: []const u8,
194194 color: Io.tty.Color,
195195 indent: usize,
196196) (Writer.Error || std.posix.UnexpectedError)!void {
197 const ttyconf = options.ttyconf;
198197 const err_msg = eb.getErrorMessage(err_msg_index);
199198 if (err_msg.src_loc != .none) {
200199 const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
......@@ -251,7 +250,7 @@ fn renderErrorMessageToWriter(
251250 try ttyconf.setColor(w, .reset);
252251 }
253252 for (eb.getNotes(err_msg_index)) |note| {
254 try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent);
253 try renderErrorMessageToWriter(eb, options, note, w, ttyconf, "note", .cyan, indent);
255254 }
256255 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
257256 try ttyconf.setColor(w, .reset);
......@@ -300,7 +299,7 @@ fn renderErrorMessageToWriter(
300299 }
301300 try ttyconf.setColor(w, .reset);
302301 for (eb.getNotes(err_msg_index)) |note| {
303 try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent + 4);
302 try renderErrorMessageToWriter(eb, options, note, w, ttyconf, "note", .cyan, indent + 4);
304303 }
305304 }
306305}
lib/std/zig/parser_test.zig+1-1
......@@ -6386,7 +6386,7 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;
63866386
63876387fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {
63886388 var buffer: [64]u8 = undefined;
6389 const stderr = std.debug.lockStderrWriter(&buffer);
6389 const stderr, _ = std.debug.lockStderrWriter(&buffer);
63906390 defer std.debug.unlockStderrWriter();
63916391
63926392 var tree = try std.zig.Ast.parse(allocator, source, .zig);
src/Air/print.zig+2-2
......@@ -73,13 +73,13 @@ pub fn writeInst(
7373}
7474
7575pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
76 const stderr_bw = std.debug.lockStderrWriter(&.{});
76 const stderr_bw, _ = std.debug.lockStderrWriter(&.{});
7777 defer std.debug.unlockStderrWriter();
7878 air.write(stderr_bw, pt, liveness);
7979}
8080
8181pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
82 const stderr_bw = std.debug.lockStderrWriter(&.{});
82 const stderr_bw, _ = std.debug.lockStderrWriter(&.{});
8383 defer std.debug.unlockStderrWriter();
8484 air.writeInst(stderr_bw, inst, pt, liveness);
8585}
src/Compilation.zig+3-3
......@@ -2093,7 +2093,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
20932093
20942094 if (options.verbose_llvm_cpu_features) {
20952095 if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {
2096 const stderr_w = std.debug.lockStderrWriter(&.{});
2096 const stderr_w, _ = std.debug.lockStderrWriter(&.{});
20972097 defer std.debug.unlockStderrWriter();
20982098 stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print;
20992099 stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;
......@@ -4270,7 +4270,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42704270 // However, we haven't reported any such error.
42714271 // This is a compiler bug.
42724272 print_ctx: {
4273 var stderr_w = std.debug.lockStderrWriter(&.{});
4273 var stderr_w, _ = std.debug.lockStderrWriter(&.{});
42744274 defer std.debug.unlockStderrWriter();
42754275 stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx;
42764276 stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx;
......@@ -7752,7 +7752,7 @@ pub fn lockAndSetMiscFailure(
77527752
77537753pub fn dump_argv(argv: []const []const u8) void {
77547754 var buffer: [64]u8 = undefined;
7755 const stderr = std.debug.lockStderrWriter(&buffer);
7755 const stderr, _ = std.debug.lockStderrWriter(&buffer);
77567756 defer std.debug.unlockStderrWriter();
77577757 nosuspend {
77587758 for (argv, 0..) |arg, i| {
src/InternPool.zig+2-2
......@@ -11330,7 +11330,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1133011330
1133111331fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1133211332 var buffer: [4096]u8 = undefined;
11333 const stderr_bw = std.debug.lockStderrWriter(&buffer);
11333 const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
1133411334 defer std.debug.unlockStderrWriter();
1133511335 for (ip.locals, 0..) |*local, tid| {
1133611336 const items = local.shared.items.view();
......@@ -11462,7 +11462,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1146211462 }
1146311463
1146411464 var buffer: [4096]u8 = undefined;
11465 const stderr_bw = std.debug.lockStderrWriter(&buffer);
11465 const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
1146611466 defer std.debug.unlockStderrWriter();
1146711467
1146811468 const SortContext = struct {
src/Package/Fetch.zig+2-2
......@@ -2043,7 +2043,7 @@ const UnpackResult = struct {
20432043 defer errors.deinit(gpa);
20442044 var aw: Io.Writer.Allocating = .init(gpa);
20452045 defer aw.deinit();
2046 try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);
2046 try errors.renderToWriter(.{}, &aw.writer, .no_color);
20472047 try std.testing.expectEqualStrings(
20482048 \\error: unable to unpack
20492049 \\ note: unable to create symlink from 'dir2/file2' to 'filename': SymlinkError
......@@ -2360,7 +2360,7 @@ const TestFetchBuilder = struct {
23602360 }
23612361 var aw: Io.Writer.Allocating = .init(std.testing.allocator);
23622362 defer aw.deinit();
2363 try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);
2363 try errors.renderToWriter(.{}, &aw.writer, .no_color);
23642364 try std.testing.expectEqualStrings(msg, aw.written());
23652365 }
23662366};
src/Sema.zig+1-1
......@@ -2631,7 +2631,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
26312631 Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");
26322632 std.debug.print("compile error during Sema:\n", .{});
26332633 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
2634 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
2634 error_bundle.renderToStdErr(.{}, .auto);
26352635 std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{});
26362636 }
26372637
src/Zcu/PerThread.zig+1-1
......@@ -4473,7 +4473,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
44734473 defer if (liveness) |*l| l.deinit(gpa);
44744474
44754475 if (build_options.enable_debug_extensions and comp.verbose_air) {
4476 const stderr = std.debug.lockStderrWriter(&.{});
4476 const stderr, _ = std.debug.lockStderrWriter(&.{});
44774477 defer std.debug.unlockStderrWriter();
44784478 stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};
44794479 air.write(stderr, pt, liveness);
src/codegen/aarch64/Select.zig+1-1
......@@ -11188,7 +11188,7 @@ fn initValueAdvanced(
1118811188}
1118911189pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
1119011190 errdefer |err| @panic(@errorName(err));
11191 const stderr = std.debug.lockStderrWriter(&.{});
11191 const stderr, _ = std.debug.lockStderrWriter(&.{});
1119211192 defer std.debug.unlockStderrWriter();
1119311193
1119411194 const zcu = isel.pt.zcu;
src/crash_report.zig+1-1
......@@ -95,7 +95,7 @@ fn dumpCrashContext() Io.Writer.Error!void {
9595
9696 // TODO: this does mean that a different thread could grab the stderr mutex between the context
9797 // and the actual panic printing, which would be quite confusing.
98 const stderr = std.debug.lockStderrWriter(&.{});
98 const stderr, _ = std.debug.lockStderrWriter(&.{});
9999 defer std.debug.unlockStderrWriter();
100100
101101 try stderr.writeAll("Compiler crash context:\n");
src/fmt.zig+4-4
......@@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
124124 try wip_errors.addZirErrorMessages(zir, tree, source_code, "<stdin>");
125125 var error_bundle = try wip_errors.toOwnedBundle("");
126126 defer error_bundle.deinit(gpa);
127 error_bundle.renderToStdErr(color.renderOptions());
127 error_bundle.renderToStdErr(.{}, color);
128128 process.exit(2);
129129 }
130130 } else {
......@@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
138138 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, "<stdin>");
139139 var error_bundle = try wip_errors.toOwnedBundle("");
140140 defer error_bundle.deinit(gpa);
141 error_bundle.renderToStdErr(color.renderOptions());
141 error_bundle.renderToStdErr(.{}, color);
142142 process.exit(2);
143143 }
144144 }
......@@ -317,7 +317,7 @@ fn fmtPathFile(
317317 try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path);
318318 var error_bundle = try wip_errors.toOwnedBundle("");
319319 defer error_bundle.deinit(gpa);
320 error_bundle.renderToStdErr(fmt.color.renderOptions());
320 error_bundle.renderToStdErr(.{}, fmt.color);
321321 fmt.any_error = true;
322322 }
323323 },
......@@ -332,7 +332,7 @@ fn fmtPathFile(
332332 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path);
333333 var error_bundle = try wip_errors.toOwnedBundle("");
334334 defer error_bundle.deinit(gpa);
335 error_bundle.renderToStdErr(fmt.color.renderOptions());
335 error_bundle.renderToStdErr(.{}, fmt.color);
336336 fmt.any_error = true;
337337 }
338338 },
src/libs/mingw.zig+4-4
......@@ -312,7 +312,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
312312 const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });
313313
314314 if (comp.verbose_cc) print: {
315 var stderr = std.debug.lockStderrWriter(&.{});
315 var stderr, _ = std.debug.lockStderrWriter(&.{});
316316 defer std.debug.unlockStderrWriter();
317317 nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
318318 nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;
......@@ -332,11 +332,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
332332
333333 if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) {
334334 var buffer: [64]u8 = undefined;
335 const w = std.debug.lockStderrWriter(&buffer);
335 const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
336336 defer std.debug.unlockStderrWriter();
337337 for (aro_comp.diagnostics.output.to_list.messages.items) |msg| {
338338 if (msg.kind == .@"fatal error" or msg.kind == .@"error") {
339 msg.write(w, .detect(std.fs.File.stderr()), true) catch {};
339 msg.write(w, ttyconf, true) catch {};
340340 return error.AroPreprocessorFailed;
341341 }
342342 }
......@@ -356,7 +356,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
356356 error.OutOfMemory => |e| return e,
357357 error.ParseError => {
358358 var buffer: [64]u8 = undefined;
359 const w = std.debug.lockStderrWriter(&buffer);
359 const w, _ = std.debug.lockStderrWriter(&buffer);
360360 defer std.debug.unlockStderrWriter();
361361 try w.writeAll("error: ");
362362 try def_diagnostics.writeMsg(w, input);
src/libs/mingw/def.zig+1-1
......@@ -1028,7 +1028,7 @@ fn testParse(machine_type: std.coff.IMAGE.FILE.MACHINE, source: [:0]const u8, ex
10281028 const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) {
10291029 error.OutOfMemory => |e| return e,
10301030 error.ParseError => {
1031 const stderr = std.debug.lockStderrWriter(&.{});
1031 const stderr, _ = std.debug.lockStderrWriter(&.{});
10321032 defer std.debug.unlockStderrWriter();
10331033 try diagnostics.writeMsg(stderr, source);
10341034 try stderr.writeByte('\n');
src/link.zig+1-1
......@@ -2215,7 +2215,7 @@ fn resolvePathInputLib(
22152215 var error_bundle = try wip_errors.toOwnedBundle("");
22162216 defer error_bundle.deinit(gpa);
22172217
2218 error_bundle.renderToStdErr(color.renderOptions());
2218 error_bundle.renderToStdErr(.{}, color);
22192219
22202220 std.process.exit(1);
22212221 }
src/link/Coff.zig+1-1
......@@ -2335,7 +2335,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe
23352335}
23362336
23372337pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void {
2338 const w = std.debug.lockStderrWriter(&.{});
2338 const w, _ = std.debug.lockStderrWriter(&.{});
23392339 defer std.debug.unlockStderrWriter();
23402340 coff.printNode(tid, w, .root, 0) catch {};
23412341}
src/link/Elf2.zig+1-1
......@@ -1965,7 +1965,7 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm
19651965}
19661966
19671967pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void {
1968 const w = std.debug.lockStderrWriter(&.{});
1968 const w, _ = std.debug.lockStderrWriter(&.{});
19691969 defer std.debug.unlockStderrWriter();
19701970 elf.printNode(tid, w, .root, 0) catch {};
19711971}
src/main.zig+9-9
......@@ -4520,7 +4520,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
45204520 defer errors.deinit(comp.gpa);
45214521
45224522 if (errors.errorMessageCount() > 0) {
4523 errors.renderToStdErr(color.renderOptions());
4523 errors.renderToStdErr(.{}, color);
45244524 return error.CompileErrorsReported;
45254525 }
45264526}
......@@ -4573,7 +4573,7 @@ fn cmdTranslateC(
45734573 return;
45744574 } else {
45754575 const color: Color = .auto;
4576 result.errors.renderToStdErr(color.renderOptions());
4576 result.errors.renderToStdErr(.{}, color);
45774577 process.exit(1);
45784578 }
45794579 }
......@@ -5199,7 +5199,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
51995199
52005200 if (fetch.error_bundle.root_list.items.len > 0) {
52015201 var errors = try fetch.error_bundle.toOwnedBundle("");
5202 errors.renderToStdErr(color.renderOptions());
5202 errors.renderToStdErr(.{}, color);
52035203 process.exit(1);
52045204 }
52055205
......@@ -6135,7 +6135,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
61356135 try wip_errors.init(arena);
61366136 try wip_errors.addZirErrorMessages(zir, tree, source, display_path);
61376137 var error_bundle = try wip_errors.toOwnedBundle("");
6138 error_bundle.renderToStdErr(color.renderOptions());
6138 error_bundle.renderToStdErr(.{}, color);
61396139 if (zir.loweringFailed()) {
61406140 process.exit(1);
61416141 }
......@@ -6206,7 +6206,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
62066206 try wip_errors.init(arena);
62076207 try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);
62086208 var error_bundle = try wip_errors.toOwnedBundle("");
6209 error_bundle.renderToStdErr(color.renderOptions());
6209 error_bundle.renderToStdErr(.{}, color);
62106210 process.exit(1);
62116211 }
62126212
......@@ -6479,7 +6479,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
64796479 try wip_errors.init(arena);
64806480 try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);
64816481 var error_bundle = try wip_errors.toOwnedBundle("");
6482 error_bundle.renderToStdErr(color.renderOptions());
6482 error_bundle.renderToStdErr(.{}, color);
64836483 process.exit(1);
64846484 }
64856485
......@@ -6491,7 +6491,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
64916491 try wip_errors.init(arena);
64926492 try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);
64936493 var error_bundle = try wip_errors.toOwnedBundle("");
6494 error_bundle.renderToStdErr(color.renderOptions());
6494 error_bundle.renderToStdErr(.{}, color);
64956495 process.exit(1);
64966496 }
64976497
......@@ -6948,7 +6948,7 @@ fn cmdFetch(
69486948
69496949 if (fetch.error_bundle.root_list.items.len > 0) {
69506950 var errors = try fetch.error_bundle.toOwnedBundle("");
6951 errors.renderToStdErr(color.renderOptions());
6951 errors.renderToStdErr(.{}, color);
69526952 process.exit(1);
69536953 }
69546954
......@@ -7304,7 +7304,7 @@ fn loadManifest(
73047304
73057305 var error_bundle = try wip_errors.toOwnedBundle("");
73067306 defer error_bundle.deinit(gpa);
7307 error_bundle.renderToStdErr(options.color.renderOptions());
7307 error_bundle.renderToStdErr(.{}, options.color);
73087308
73097309 process.exit(2);
73107310 }
tools/gen_spirv_spec.zig+3-4
......@@ -89,10 +89,9 @@ pub fn main() !void {
8989 const output = allocating.written()[0 .. allocating.written().len - 1 :0];
9090
9191 var tree = try std.zig.Ast.parse(allocator, output, .zig);
92 var color: std.zig.Color = .on;
9392
9493 if (tree.errors.len != 0) {
95 try std.zig.printAstErrorsToStderr(allocator, tree, "", color);
94 try std.zig.printAstErrorsToStderr(allocator, tree, "", .auto);
9695 return;
9796 }
9897
......@@ -104,7 +103,7 @@ pub fn main() !void {
104103 try wip_errors.addZirErrorMessages(zir, tree, output, "");
105104 var error_bundle = try wip_errors.toOwnedBundle("");
106105 defer error_bundle.deinit(allocator);
107 error_bundle.renderToStdErr(color.renderOptions());
106 error_bundle.renderToStdErr(.{}, .auto);
108107 }
109108
110109 const formatted_output = try tree.renderAlloc(allocator);
......@@ -931,7 +930,7 @@ fn parseHexInt(text: []const u8) !u31 {
931930}
932931
933932fn usageAndExit(arg0: []const u8, code: u8) noreturn {
934 const stderr = std.debug.lockStderrWriter(&.{});
933 const stderr, _ = std.debug.lockStderrWriter(&.{});
935934 stderr.print(
936935 \\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json>
937936 \\
tools/generate_linux_syscalls.zig+3-1
......@@ -177,7 +177,9 @@ pub fn main() !void {
177177
178178 const args = try std.process.argsAlloc(gpa);
179179 if (args.len < 2 or mem.eql(u8, args[1], "--help")) {
180 usage(std.debug.lockStderrWriter(&.{}), args[0]) catch std.process.exit(2);
180 const w, _ = std.debug.lockStderrWriter(&.{});
181 defer std.debug.unlockStderrWriter();
182 usage(w, args[0]) catch std.process.exit(2);
181183 std.process.exit(1);
182184 }
183185 const linux_path = args[1];
tools/incr-check.zig+5-10
......@@ -340,8 +340,7 @@ const Eval = struct {
340340 .unknown => return,
341341 .compile_errors => |ce| ce,
342342 .stdout, .exit_code => {
343 const color: std.zig.Color = .auto;
344 error_bundle.renderToStdErr(color.renderOptions());
343 error_bundle.renderToStdErr(.{}, .auto);
345344 eval.fatal("update '{s}': unexpected compile errors", .{update.name});
346345 },
347346 };
......@@ -350,8 +349,7 @@ const Eval = struct {
350349
351350 for (error_bundle.getMessages()) |err_idx| {
352351 if (expected_idx == expected.errors.len) {
353 const color: std.zig.Color = .auto;
354 error_bundle.renderToStdErr(color.renderOptions());
352 error_bundle.renderToStdErr(.{}, .auto);
355353 eval.fatal("update '{s}': more errors than expected", .{update.name});
356354 }
357355 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);
......@@ -359,8 +357,7 @@ const Eval = struct {
359357
360358 for (error_bundle.getNotes(err_idx)) |note_idx| {
361359 if (expected_idx == expected.errors.len) {
362 const color: std.zig.Color = .auto;
363 error_bundle.renderToStdErr(color.renderOptions());
360 error_bundle.renderToStdErr(.{}, .auto);
364361 eval.fatal("update '{s}': more error notes than expected", .{update.name});
365362 }
366363 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);
......@@ -369,8 +366,7 @@ const Eval = struct {
369366 }
370367
371368 if (!std.mem.eql(u8, error_bundle.getCompileLogOutput(), expected.compile_log_output)) {
372 const color: std.zig.Color = .auto;
373 error_bundle.renderToStdErr(color.renderOptions());
369 error_bundle.renderToStdErr(.{}, .auto);
374370 eval.fatal("update '{s}': unexpected compile log output", .{update.name});
375371 }
376372 }
......@@ -404,8 +400,7 @@ const Eval = struct {
404400 expected.column != src.column + 1 or
405401 !std.mem.eql(u8, expected.msg, msg))
406402 {
407 const color: std.zig.Color = .auto;
408 eb.renderToStdErr(color.renderOptions());
403 eb.renderToStdErr(.{}, .auto);
409404 eval.fatal("update '{s}': compile error did not match expected error", .{update.name});
410405 }
411406 }
tools/update_clang_options.zig+3-1
......@@ -961,7 +961,9 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
961961}
962962
963963fn printUsageAndExit(arg0: []const u8) noreturn {
964 printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2);
964 const w, _ = std.debug.lockStderrWriter(&.{});
965 defer std.debug.unlockStderrWriter();
966 printUsage(w, arg0) catch std.process.exit(2);
965967 std.process.exit(1);
966968}
967969
tools/update_cpu_features.zig+1-1
......@@ -2167,7 +2167,7 @@ fn processOneTarget(job: Job) void {
21672167}
21682168
21692169fn usageAndExit(arg0: []const u8, code: u8) noreturn {
2170 const stderr = std.debug.lockStderrWriter(&.{});
2170 const stderr, _ = std.debug.lockStderrWriter(&.{});
21712171 stderr.print(
21722172 \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter]
21732173 \\
tools/update_crc_catalog.zig+3-1
......@@ -190,7 +190,9 @@ pub fn main() anyerror!void {
190190}
191191
192192fn printUsageAndExit(arg0: []const u8) noreturn {
193 printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2);
193 const w, _ = std.debug.lockStderrWriter(&.{});
194 defer std.debug.unlockStderrWriter();
195 printUsage(w, arg0) catch std.process.exit(2);
194196 std.process.exit(1);
195197}
196198