authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-02 07:55:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:52-07:00
logec3b5f0c7474b22dfbf2f19e0121a1f87a58efd0
tree24b0627edd26c90ca3135a9d0d792452d85caf6f
parent756a2dbf1a5f8af7fe153960e332eaad2ab3bcd8

compiler: upgrade various std.io API usage


5 files changed, 83 insertions(+), 64 deletions(-)

src/Zcu/PerThread.zig+55-48
......@@ -190,7 +190,7 @@ pub fn updateFile(
190190 // failure was a race, or ENOENT, indicating deletion of the
191191 // directory of our open handle.
192192 if (builtin.os.tag != .macos) {
193 std.process.fatal("cache directory '{}' unexpectedly removed during compiler execution", .{
193 std.process.fatal("cache directory '{f}' unexpectedly removed during compiler execution", .{
194194 cache_directory,
195195 });
196196 }
......@@ -202,7 +202,7 @@ pub fn updateFile(
202202 }) catch |excl_err| switch (excl_err) {
203203 error.PathAlreadyExists => continue,
204204 error.FileNotFound => {
205 std.process.fatal("cache directory '{}' unexpectedly removed during compiler execution", .{
205 std.process.fatal("cache directory '{f}' unexpectedly removed during compiler execution", .{
206206 cache_directory,
207207 });
208208 },
......@@ -249,11 +249,14 @@ pub fn updateFile(
249249 if (stat.size > std.math.maxInt(u32))
250250 return error.FileTooBig;
251251
252 const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);
252 const source = try gpa.allocSentinel(u8, @intCast(stat.size), 0);
253253 defer if (file.source == null) gpa.free(source);
254 const amt = try source_file.readAll(source);
255 if (amt != stat.size)
256 return error.UnexpectedEndOfFile;
254 var source_fr = source_file.reader(&.{});
255 source_fr.size = stat.size;
256 source_fr.interface.readSliceAll(source) catch |err| switch (err) {
257 error.ReadFailed => return source_fr.err.?,
258 error.EndOfStream => return error.UnexpectedEndOfFile,
259 };
257260
258261 file.source = source;
259262
......@@ -265,7 +268,7 @@ pub fn updateFile(
265268 file.zir = try AstGen.generate(gpa, file.tree.?);
266269 Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) {
267270 error.OutOfMemory => |e| return e,
268 else => log.warn("unable to write cached ZIR code for {} to {}{s}: {s}", .{
271 else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {s}", .{
269272 file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err),
270273 }),
271274 };
......@@ -273,7 +276,7 @@ pub fn updateFile(
273276 .zon => {
274277 file.zoir = try ZonGen.generate(gpa, file.tree.?, .{});
275278 Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| {
276 log.warn("unable to write cached ZOIR code for {} to {}{s}: {s}", .{
279 log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {s}", .{
277280 file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err),
278281 });
279282 };
......@@ -340,13 +343,19 @@ fn loadZirZoirCache(
340343 .zon => Zoir.Header,
341344 };
342345
346 var buffer: [@sizeOf(Header)]u8 = undefined;
347 var cache_fr = cache_file.reader(&buffer);
348 cache_fr.size = stat.size;
349 const cache_br = &cache_fr.interface;
350
343351 // First we read the header to determine the lengths of arrays.
344 const header = cache_file.deprecatedReader().readStruct(Header) catch |err| switch (err) {
352 const header = (cache_br.takeStruct(Header) catch |err| switch (err) {
353 error.ReadFailed => return cache_fr.err.?,
345354 // This can happen if Zig bails out of this function between creating
346355 // the cached file and writing it.
347356 error.EndOfStream => return .invalid,
348357 else => |e| return e,
349 };
358 }).*;
350359
351360 const unchanged_metadata =
352361 stat.size == header.stat_size and
......@@ -358,17 +367,15 @@ fn loadZirZoirCache(
358367 }
359368
360369 switch (mode) {
361 .zig => {
362 file.zir = Zcu.loadZirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
363 error.UnexpectedFileSize => return .truncated,
364 else => |e| return e,
365 };
370 .zig => file.zir = Zcu.loadZirCacheBody(gpa, header, cache_br) catch |err| switch (err) {
371 error.ReadFailed => return cache_fr.err.?,
372 error.EndOfStream => return .truncated,
373 else => |e| return e,
366374 },
367 .zon => {
368 file.zoir = Zcu.loadZoirCacheBody(gpa, header, cache_file) catch |err| switch (err) {
369 error.UnexpectedFileSize => return .truncated,
370 else => |e| return e,
371 };
375 .zon => file.zoir = Zcu.loadZoirCacheBody(gpa, header, cache_br) catch |err| switch (err) {
376 error.ReadFailed => return cache_fr.err.?,
377 error.EndOfStream => return .truncated,
378 else => |e| return e,
372379 },
373380 }
374381
......@@ -478,10 +485,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
478485 break :hash_changed;
479486 }
480487 log.debug("hash for (%{d} -> %{d}) changed: {x} -> {x}", .{
481 old_inst,
482 new_inst,
483 &old_hash,
484 &new_hash,
488 old_inst, new_inst, &old_hash, &new_hash,
485489 });
486490 }
487491 // The source hash associated with this instruction changed - invalidate relevant dependencies.
......@@ -649,7 +653,7 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
649653 // If this unit caused the error, it would have an entry in `failed_analysis`.
650654 // Since it does not, this must be a transitive failure.
651655 try zcu.transitive_failed_analysis.put(gpa, unit, {});
652 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(unit)});
656 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(unit)});
653657 }
654658 break :res .{ !prev_failed, true };
655659 },
......@@ -754,7 +758,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
754758
755759 const anal_unit: AnalUnit = .wrap(.{ .@"comptime" = cu_id });
756760
757 log.debug("ensureComptimeUnitUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
761 log.debug("ensureComptimeUnitUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
758762
759763 assert(!zcu.analysis_in_progress.contains(anal_unit));
760764
......@@ -805,7 +809,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
805809 // If this unit caused the error, it would have an entry in `failed_analysis`.
806810 // Since it does not, this must be a transitive failure.
807811 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
808 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
812 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
809813 }
810814 return error.AnalysisFail;
811815 },
......@@ -835,7 +839,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
835839 const anal_unit: AnalUnit = .wrap(.{ .@"comptime" = cu_id });
836840 const comptime_unit = ip.getComptimeUnit(cu_id);
837841
838 log.debug("analyzeComptimeUnit {}", .{zcu.fmtAnalUnit(anal_unit)});
842 log.debug("analyzeComptimeUnit {f}", .{zcu.fmtAnalUnit(anal_unit)});
839843
840844 const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
841845 const file = zcu.fileByIndex(inst_resolved.file);
......@@ -881,7 +885,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
881885 .r = .{ .simple = .comptime_keyword },
882886 } },
883887 .src_base_inst = comptime_unit.zir_index,
884 .type_name_ctx = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.comptime", .{
888 .type_name_ctx = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}.comptime", .{
885889 Type.fromInterned(zcu.namespacePtr(comptime_unit.namespace).owner_type).containerTypeName(ip).fmt(ip),
886890 }, .no_embedded_nulls),
887891 };
......@@ -933,7 +937,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
933937 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
934938 const nav = ip.getNav(nav_id);
935939
936 log.debug("ensureNavValUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
940 log.debug("ensureNavValUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
937941
938942 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
939943 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
......@@ -991,7 +995,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
991995 // If this unit caused the error, it would have an entry in `failed_analysis`.
992996 // Since it does not, this must be a transitive failure.
993997 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
994 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
998 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
995999 }
9961000 break :res .{ !prev_failed, true };
9971001 },
......@@ -1062,7 +1066,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
10621066 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
10631067 const old_nav = ip.getNav(nav_id);
10641068
1065 log.debug("analyzeNavVal {}", .{zcu.fmtAnalUnit(anal_unit)});
1069 log.debug("analyzeNavVal {f}", .{zcu.fmtAnalUnit(anal_unit)});
10661070
10671071 const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
10681072 const file = zcu.fileByIndex(inst_resolved.file);
......@@ -1321,7 +1325,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
13211325 const anal_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id });
13221326 const nav = ip.getNav(nav_id);
13231327
1324 log.debug("ensureNavTypeUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
1328 log.debug("ensureNavTypeUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
13251329
13261330 const type_resolved_by_value: bool = from_val: {
13271331 const analysis = nav.analysis orelse break :from_val false;
......@@ -1391,7 +1395,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
13911395 // If this unit caused the error, it would have an entry in `failed_analysis`.
13921396 // Since it does not, this must be a transitive failure.
13931397 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
1394 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
1398 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
13951399 }
13961400 break :res .{ !prev_failed, true };
13971401 },
......@@ -1433,7 +1437,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
14331437 const anal_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id });
14341438 const old_nav = ip.getNav(nav_id);
14351439
1436 log.debug("analyzeNavType {}", .{zcu.fmtAnalUnit(anal_unit)});
1440 log.debug("analyzeNavType {f}", .{zcu.fmtAnalUnit(anal_unit)});
14371441
14381442 const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
14391443 const file = zcu.fileByIndex(inst_resolved.file);
......@@ -1563,7 +1567,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
15631567 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
15641568 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });
15651569
1566 log.debug("ensureFuncBodyUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
1570 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
15671571
15681572 const func = zcu.funcInfo(maybe_coerced_func_index);
15691573
......@@ -1607,7 +1611,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
16071611 // If this function caused the error, it would have an entry in `failed_analysis`.
16081612 // Since it does not, this must be a transitive failure.
16091613 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
1610 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
1614 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
16111615 }
16121616 // We consider the IES to be outdated if the function previously succeeded analysis; in this case,
16131617 // we need to re-analyze dependants to ensure they hit a transitive error here, rather than reporting
......@@ -1677,7 +1681,7 @@ fn analyzeFuncBody(
16771681 else
16781682 .none;
16791683
1680 log.debug("analyze and generate fn body {}", .{zcu.fmtAnalUnit(anal_unit)});
1684 log.debug("analyze and generate fn body {f}", .{zcu.fmtAnalUnit(anal_unit)});
16811685
16821686 var air = try pt.analyzeFnBodyInner(func_index);
16831687 errdefer air.deinit(gpa);
......@@ -2414,8 +2418,12 @@ fn updateEmbedFileInner(
24142418 const old_len = strings.mutate.len;
24152419 errdefer strings.shrinkRetainingCapacity(old_len);
24162420 const bytes = (try strings.addManyAsSlice(size_plus_one))[0];
2417 const actual_read = try file.readAll(bytes[0..size]);
2418 if (actual_read != size) return error.UnexpectedEof;
2421 var fr = file.reader(&.{});
2422 fr.size = stat.size;
2423 fr.interface.readSliceAll(bytes[0..size]) catch |err| switch (err) {
2424 error.ReadFailed => return fr.err.?,
2425 error.EndOfStream => return error.UnexpectedEof,
2426 };
24192427 bytes[size] = 0;
24202428 break :str try ip.getOrPutTrailingString(gpa, tid, @intCast(bytes.len), .maybe_embedded_nulls);
24212429 };
......@@ -2584,7 +2592,7 @@ const ScanDeclIter = struct {
25842592 var gop = try iter.seen_decls.getOrPut(gpa, name);
25852593 var next_suffix: u32 = 0;
25862594 while (gop.found_existing) {
2587 name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
2595 name = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
25882596 gop = try iter.seen_decls.getOrPut(gpa, name);
25892597 next_suffix += 1;
25902598 }
......@@ -2716,7 +2724,7 @@ const ScanDeclIter = struct {
27162724
27172725 if (existing_unit == null and (want_analysis or decl.linkage == .@"export")) {
27182726 log.debug(
2719 "scanDecl queue analyze_comptime_unit file='{s}' unit={}",
2727 "scanDecl queue analyze_comptime_unit file='{s}' unit={f}",
27202728 .{ namespace.fileScope(zcu).sub_file_path, zcu.fmtAnalUnit(unit) },
27212729 );
27222730 try comp.queueJob(.{ .analyze_comptime_unit = unit });
......@@ -3134,7 +3142,7 @@ fn processExportsInner(
31343142 if (gop.found_existing) {
31353143 new_export.status = .failed_retryable;
31363144 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
3137 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{
3145 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {f}", .{
31383146 new_export.opts.name.fmt(ip),
31393147 });
31403148 errdefer msg.destroy(gpa);
......@@ -4376,12 +4384,11 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
43764384 defer liveness.deinit(gpa);
43774385
43784386 if (build_options.enable_debug_extensions and comp.verbose_air) {
4379 std.debug.lockStdErr();
4380 defer std.debug.unlockStdErr();
4381 const stderr = std.fs.File.stderr().deprecatedWriter();
4382 stderr.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)}) catch {};
4387 const stderr = std.debug.lockStderrWriter(&.{});
4388 defer std.debug.unlockStderrWriter();
4389 stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};
43834390 air.write(stderr, pt, liveness);
4384 stderr.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)}) catch {};
4391 stderr.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)}) catch {};
43854392 }
43864393
43874394 if (std.debug.runtime_safety) {
src/arch/x86_64/Emit.zig+8-1
......@@ -707,7 +707,14 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
707707 const comp = emit.bin_file.comp;
708708 const gpa = comp.gpa;
709709 const start_offset: u32 = @intCast(emit.code.items.len);
710 try lowered_inst.encode(emit.code.writer(gpa), .{});
710 {
711 var aw: std.io.Writer.Allocating = .fromArrayList(gpa, emit.code);
712 defer emit.code.* = aw.toArrayList();
713 lowered_inst.encode(&aw.writer, .{}) catch |err| switch (err) {
714 error.WriteFailed => return error.OutOfMemory,
715 else => |e| return e,
716 };
717 }
711718 const end_offset: u32 = @intCast(emit.code.items.len);
712719 for (reloc_info) |reloc| switch (reloc.target.type) {
713720 .inst => {
src/arch/x86_64/Encoding.zig+14-5
......@@ -1014,19 +1014,28 @@ pub const Feature = enum {
10141014};
10151015
10161016fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Operand) usize {
1017 var inst = Instruction{
1017 var inst: Instruction = .{
10181018 .prefix = prefix,
10191019 .encoding = encoding,
10201020 .ops = @splat(.none),
10211021 };
10221022 @memcpy(inst.ops[0..ops.len], ops);
10231023
1024 var cwriter = std.io.countingWriter(std.io.null_writer);
1025 inst.encode(cwriter.writer(), .{
1024 // By using a buffer with maximum length of encoded instruction, we can use
1025 // the `end` field of the Writer for the count.
1026 var buf: [16]u8 = undefined;
1027 var trash = std.io.Writer.discarding(&buf);
1028 inst.encode(&trash, .{
10261029 .allow_frame_locs = true,
10271030 .allow_symbols = true,
1028 }) catch unreachable; // Not allowed to fail here unless OOM.
1029 return @as(usize, @intCast(cwriter.bytes_written));
1031 }) catch {
1032 // Since the function signature for encode() does not mention under what
1033 // conditions it can fail, I have changed `unreachable` to `@panic` here.
1034 // This is a TODO item since it indicates this function
1035 // (`estimateInstructionLength`) has the wrong function signature.
1036 @panic("unexpected failure to encode");
1037 };
1038 return @intCast(trash.end);
10301039}
10311040
10321041const mnemonic_to_encodings_map = init: {
src/link/Elf/Atom.zig+4-6
......@@ -1390,7 +1390,8 @@ const x86_64 = struct {
13901390 // TODO: hack to force imm32s in the assembler
13911391 .{ .imm = .s(-129) },
13921392 }, t) catch return false;
1393 inst.encode(std.io.null_writer, .{}) catch return false;
1393 var trash = std.io.Writer.discarding(&.{});
1394 inst.encode(&trash, .{}) catch return false;
13941395 return true;
13951396 },
13961397 else => return false,
......@@ -1485,11 +1486,8 @@ const x86_64 = struct {
14851486 }
14861487
14871488 fn encode(insts: []const Instruction, code: []u8) !void {
1488 var stream = std.io.fixedBufferStream(code);
1489 const writer = stream.writer();
1490 for (insts) |inst| {
1491 try inst.encode(writer, .{});
1492 }
1489 var stream: std.io.Writer = .fixed(code);
1490 for (insts) |inst| try inst.encode(&stream, .{});
14931491 }
14941492
14951493 const bits = @import("../../arch/x86_64/bits.zig");
src/link/MachO/Atom.zig+2-4
......@@ -938,10 +938,8 @@ const x86_64 = struct {
938938 }
939939
940940 fn encode(insts: []const Instruction, code: []u8) !void {
941 var stream: std.io.Writer = .fixed(code);
942 for (insts) |inst| {
943 try inst.encode(&stream, .{});
944 }
941 var stream: Writer = .fixed(code);
942 for (insts) |inst| try inst.encode(&stream, .{});
945943 }
946944
947945 const bits = @import("../../arch/x86_64/bits.zig");