Skip to content

Commit 1a99888

Browse files
authored
Merge pull request #24329 from ziglang/writergate
Deprecates all existing std.io readers and writers in favor of the newly provided std.io.Reader and std.io.Writer which are non-generic and have the buffer above the vtable - in other words the buffer is in the interface, not the implementation. This means that although Reader and Writer are no longer generic, they are still transparent to optimization; all of the interface functions have a concrete hot path operating on the buffer, and only make vtable calls when the buffer is full.
2 parents 5b4b033 + 10d6db5 commit 1a99888

File tree

356 files changed

+15235
-13432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

356 files changed

+15235
-13432
lines changed

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,6 @@ set(ZIG_STAGE2_SOURCES
436436
lib/std/elf.zig
437437
lib/std/fifo.zig
438438
lib/std/fmt.zig
439-
lib/std/fmt/format_float.zig
440439
lib/std/fmt/parse_float.zig
441440
lib/std/fs.zig
442441
lib/std/fs/AtomicFile.zig

build.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ pub fn build(b: *std.Build) !void {
279279

280280
const ancestor_ver = try std.SemanticVersion.parse(tagged_ancestor);
281281
if (zig_version.order(ancestor_ver) != .gt) {
282-
std.debug.print("Zig version '{}' must be greater than tagged ancestor '{}'\n", .{ zig_version, ancestor_ver });
282+
std.debug.print("Zig version '{f}' must be greater than tagged ancestor '{f}'\n", .{ zig_version, ancestor_ver });
283283
std.process.exit(1);
284284
}
285285

@@ -1449,7 +1449,7 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
14491449
}
14501450

14511451
var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
1452-
std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{
1452+
std.debug.panic("unable to open '{f}doc/langref' directory: {s}", .{
14531453
b.build_root, @errorName(err),
14541454
});
14551455
};
@@ -1470,7 +1470,7 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
14701470
// in a temporary directory
14711471
"--cache-root", b.cache_root.path orelse ".",
14721472
});
1473-
cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{}", .{b.graph.zig_lib_directory}) });
1473+
cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{f}", .{b.graph.zig_lib_directory}) });
14741474
cmd.addArgs(&.{"-i"});
14751475
cmd.addFileArg(b.path(b.fmt("doc/langref/{s}", .{entry.name})));
14761476

doc/langref.html.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@
374374
<p>
375375
Most of the time, it is more appropriate to write to stderr rather than stdout, and
376376
whether or not the message is successfully written to the stream is irrelevant.
377-
For this common case, there is a simpler API:
377+
Also, formatted printing often comes in handy. For this common case,
378+
there is a simpler API:
378379
</p>
379380
{#code|hello_again.zig#}
380381

doc/langref/bad_default_value.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn main() !void {
1717
.maximum = 0.20,
1818
};
1919
const category = threshold.categorize(0.90);
20-
try std.io.getStdOut().writeAll(@tagName(category));
20+
try std.fs.File.stdout().writeAll(@tagName(category));
2121
}
2222

2323
const std = @import("std");

doc/langref/hello.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
const std = @import("std");
22

33
pub fn main() !void {
4-
const stdout = std.io.getStdOut().writer();
5-
try stdout.print("Hello, {s}!\n", .{"world"});
4+
try std.fs.File.stdout().writeAll("Hello, World!\n");
65
}
76

87
// exe=succeed

doc/langref/hello_again.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const std = @import("std");
22

33
pub fn main() void {
4-
std.debug.print("Hello, world!\n", .{});
4+
std.debug.print("Hello, {s}!\n", .{"World"});
55
}
66

77
// exe=succeed

lib/compiler/aro/aro/Compilation.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,7 @@ fn getFileContents(comp: *Compilation, path: []const u8, limit: ?u32) ![]const u
14321432
defer buf.deinit();
14331433

14341434
const max = limit orelse std.math.maxInt(u32);
1435-
file.reader().readAllArrayList(&buf, max) catch |e| switch (e) {
1435+
file.deprecatedReader().readAllArrayList(&buf, max) catch |e| switch (e) {
14361436
error.StreamTooLong => if (limit == null) return e,
14371437
else => return e,
14381438
};

lib/compiler/aro/aro/Diagnostics.zig

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std");
2+
const assert = std.debug.assert;
23
const Allocator = mem.Allocator;
34
const mem = std.mem;
45
const Source = @import("Source.zig");
@@ -323,12 +324,13 @@ pub fn addExtra(
323324

324325
pub fn render(comp: *Compilation, config: std.io.tty.Config) void {
325326
if (comp.diagnostics.list.items.len == 0) return;
326-
var m = defaultMsgWriter(config);
327+
var buffer: [1000]u8 = undefined;
328+
var m = defaultMsgWriter(config, &buffer);
327329
defer m.deinit();
328330
renderMessages(comp, &m);
329331
}
330-
pub fn defaultMsgWriter(config: std.io.tty.Config) MsgWriter {
331-
return MsgWriter.init(config);
332+
pub fn defaultMsgWriter(config: std.io.tty.Config, buffer: []u8) MsgWriter {
333+
return MsgWriter.init(config, buffer);
332334
}
333335

334336
pub fn renderMessages(comp: *Compilation, m: anytype) void {
@@ -443,18 +445,13 @@ pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
443445
printRt(m, prop.msg, .{"{s}"}, .{&str});
444446
} else {
445447
var buf: [3]u8 = undefined;
446-
const str = std.fmt.bufPrint(&buf, "x{x}", .{std.fmt.fmtSliceHexLower(&.{msg.extra.invalid_escape.char})}) catch unreachable;
448+
const str = std.fmt.bufPrint(&buf, "x{x}", .{msg.extra.invalid_escape.char}) catch unreachable;
447449
printRt(m, prop.msg, .{"{s}"}, .{str});
448450
}
449451
},
450452
.normalized => {
451453
const f = struct {
452-
pub fn f(
453-
bytes: []const u8,
454-
comptime _: []const u8,
455-
_: std.fmt.FormatOptions,
456-
writer: anytype,
457-
) !void {
454+
pub fn f(bytes: []const u8, writer: *std.io.Writer) std.io.Writer.Error!void {
458455
var it: std.unicode.Utf8Iterator = .{
459456
.bytes = bytes,
460457
.i = 0,
@@ -464,22 +461,16 @@ pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
464461
try writer.writeByte(@intCast(codepoint));
465462
} else if (codepoint < 0xFFFF) {
466463
try writer.writeAll("\\u");
467-
try std.fmt.formatInt(codepoint, 16, .upper, .{
468-
.fill = '0',
469-
.width = 4,
470-
}, writer);
464+
try writer.printInt(codepoint, 16, .upper, .{ .fill = '0', .width = 4 });
471465
} else {
472466
try writer.writeAll("\\U");
473-
try std.fmt.formatInt(codepoint, 16, .upper, .{
474-
.fill = '0',
475-
.width = 8,
476-
}, writer);
467+
try writer.printInt(codepoint, 16, .upper, .{ .fill = '0', .width = 8 });
477468
}
478469
}
479470
}
480471
}.f;
481-
printRt(m, prop.msg, .{"{s}"}, .{
482-
std.fmt.Formatter(f){ .data = msg.extra.normalized },
472+
printRt(m, prop.msg, .{"{f}"}, .{
473+
std.fmt.Formatter([]const u8, f){ .data = msg.extra.normalized },
483474
});
484475
},
485476
.none, .offset => m.write(prop.msg),
@@ -535,32 +526,31 @@ fn tagKind(d: *Diagnostics, tag: Tag, langopts: LangOpts) Kind {
535526
}
536527

537528
const MsgWriter = struct {
538-
w: std.io.BufferedWriter(4096, std.fs.File.Writer),
529+
writer: *std.io.Writer,
539530
config: std.io.tty.Config,
540531

541-
fn init(config: std.io.tty.Config) MsgWriter {
542-
std.debug.lockStdErr();
532+
fn init(config: std.io.tty.Config, buffer: []u8) MsgWriter {
543533
return .{
544-
.w = std.io.bufferedWriter(std.io.getStdErr().writer()),
534+
.writer = std.debug.lockStderrWriter(buffer),
545535
.config = config,
546536
};
547537
}
548538

549539
pub fn deinit(m: *MsgWriter) void {
550-
m.w.flush() catch {};
551-
std.debug.unlockStdErr();
540+
std.debug.unlockStderrWriter();
541+
m.* = undefined;
552542
}
553543

554544
pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void {
555-
m.w.writer().print(fmt, args) catch {};
545+
m.writer.print(fmt, args) catch {};
556546
}
557547

558548
fn write(m: *MsgWriter, msg: []const u8) void {
559-
m.w.writer().writeAll(msg) catch {};
549+
m.writer.writeAll(msg) catch {};
560550
}
561551

562552
fn setColor(m: *MsgWriter, color: std.io.tty.Color) void {
563-
m.config.setColor(m.w.writer(), color) catch {};
553+
m.config.setColor(m.writer, color) catch {};
564554
}
565555

566556
fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void {

lib/compiler/aro/aro/Driver.zig

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ fn option(arg: []const u8, name: []const u8) ?[]const u8 {
519519

520520
fn addSource(d: *Driver, path: []const u8) !Source {
521521
if (mem.eql(u8, "-", path)) {
522-
const stdin = std.io.getStdIn().reader();
522+
const stdin = std.fs.File.stdin().deprecatedReader();
523523
const input = try stdin.readAllAlloc(d.comp.gpa, std.math.maxInt(u32));
524524
defer d.comp.gpa.free(input);
525525
return d.comp.addSourceFromBuffer("<stdin>", input);
@@ -541,7 +541,7 @@ pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalEr
541541
}
542542

543543
pub fn renderErrors(d: *Driver) void {
544-
Diagnostics.render(d.comp, d.detectConfig(std.io.getStdErr()));
544+
Diagnostics.render(d.comp, d.detectConfig(std.fs.File.stderr()));
545545
}
546546

547547
pub fn detectConfig(d: *Driver, file: std.fs.File) std.io.tty.Config {
@@ -591,7 +591,7 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_
591591
var macro_buf = std.ArrayList(u8).init(d.comp.gpa);
592592
defer macro_buf.deinit();
593593

594-
const std_out = std.io.getStdOut().writer();
594+
const std_out = std.fs.File.stdout().deprecatedWriter();
595595
if (try parseArgs(d, std_out, macro_buf.writer(), args)) return;
596596

597597
const linking = !(d.only_preprocess or d.only_syntax or d.only_compile or d.only_preprocess_and_compile);
@@ -686,10 +686,10 @@ fn processSource(
686686
std.fs.cwd().createFile(some, .{}) catch |er|
687687
return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) })
688688
else
689-
std.io.getStdOut();
689+
std.fs.File.stdout();
690690
defer if (d.output_name != null) file.close();
691691

692-
var buf_w = std.io.bufferedWriter(file.writer());
692+
var buf_w = std.io.bufferedWriter(file.deprecatedWriter());
693693

694694
pp.prettyPrintTokens(buf_w.writer(), dump_mode) catch |er|
695695
return d.fatal("unable to write result: {s}", .{errorDescription(er)});
@@ -704,8 +704,8 @@ fn processSource(
704704
defer tree.deinit();
705705

706706
if (d.verbose_ast) {
707-
const stdout = std.io.getStdOut();
708-
var buf_writer = std.io.bufferedWriter(stdout.writer());
707+
const stdout = std.fs.File.stdout();
708+
var buf_writer = std.io.bufferedWriter(stdout.deprecatedWriter());
709709
tree.dump(d.detectConfig(stdout), buf_writer.writer()) catch {};
710710
buf_writer.flush() catch {};
711711
}
@@ -734,8 +734,8 @@ fn processSource(
734734
defer ir.deinit(d.comp.gpa);
735735

736736
if (d.verbose_ir) {
737-
const stdout = std.io.getStdOut();
738-
var buf_writer = std.io.bufferedWriter(stdout.writer());
737+
const stdout = std.fs.File.stdout();
738+
var buf_writer = std.io.bufferedWriter(stdout.deprecatedWriter());
739739
ir.dump(d.comp.gpa, d.detectConfig(stdout), buf_writer.writer()) catch {};
740740
buf_writer.flush() catch {};
741741
}
@@ -806,10 +806,10 @@ fn processSource(
806806
}
807807

808808
fn dumpLinkerArgs(items: []const []const u8) !void {
809-
const stdout = std.io.getStdOut().writer();
809+
const stdout = std.fs.File.stdout().deprecatedWriter();
810810
for (items, 0..) |item, i| {
811811
if (i > 0) try stdout.writeByte(' ');
812-
try stdout.print("\"{}\"", .{std.zig.fmtEscapes(item)});
812+
try stdout.print("\"{f}\"", .{std.zig.fmtString(item)});
813813
}
814814
try stdout.writeByte('\n');
815815
}

lib/compiler/aro/aro/Parser.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,8 @@ fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_
500500

501501
const w = p.strings.writer();
502502
const msg_str = p.comp.interner.get(@"error".msg.ref()).bytes;
503-
try w.print("call to '{s}' declared with attribute error: {}", .{
504-
p.tokSlice(@"error".__name_tok), std.zig.fmtEscapes(msg_str),
503+
try w.print("call to '{s}' declared with attribute error: {f}", .{
504+
p.tokSlice(@"error".__name_tok), std.zig.fmtString(msg_str),
505505
});
506506
const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
507507
try p.errStr(.error_attribute, usage_tok, str);
@@ -512,8 +512,8 @@ fn checkDeprecatedUnavailable(p: *Parser, ty: Type, usage_tok: TokenIndex, decl_
512512

513513
const w = p.strings.writer();
514514
const msg_str = p.comp.interner.get(warning.msg.ref()).bytes;
515-
try w.print("call to '{s}' declared with attribute warning: {}", .{
516-
p.tokSlice(warning.__name_tok), std.zig.fmtEscapes(msg_str),
515+
try w.print("call to '{s}' declared with attribute warning: {f}", .{
516+
p.tokSlice(warning.__name_tok), std.zig.fmtString(msg_str),
517517
});
518518
const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
519519
try p.errStr(.warning_attribute, usage_tok, str);
@@ -542,7 +542,7 @@ fn errDeprecated(p: *Parser, tag: Diagnostics.Tag, tok_i: TokenIndex, msg: ?Valu
542542
try w.writeAll(reason);
543543
if (msg) |m| {
544544
const str = p.comp.interner.get(m.ref()).bytes;
545-
try w.print(": {}", .{std.zig.fmtEscapes(str)});
545+
try w.print(": {f}", .{std.zig.fmtString(str)});
546546
}
547547
const str = try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
548548
return p.errStr(tag, tok_i, str);

0 commit comments

Comments
 (0)