authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-06 15:51:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:53-07:00
log7e2a26c0c441a902968726442114e3590820433b
tree90035e47e0208afa7d1bcd3484e30d22d2a24f4e
parent5378fdb153bc76990105e3640e7725e434e8cdee

std.io.Writer.printValue: rework logic

Alignment and fill options only apply to numbers. Rework the implementation to mainly branch on the format string rather than the type information. This is more straightforward to maintain and more straightforward for comptime evaluation. Enums support being printed as decimal, hexadecimal, octal, and binary. `formatInteger` is another possible format method that is unconditionally called when the value type is struct and one of the integer-printing format specifiers are used.

29 files changed, 636 insertions(+), 452 deletions(-)

lib/compiler/aro/aro/Diagnostics.zig+2-2
......@@ -461,10 +461,10 @@ pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
461461 try writer.writeByte(@intCast(codepoint));
462462 } else if (codepoint < 0xFFFF) {
463463 try writer.writeAll("\\u");
464 try writer.printIntOptions(codepoint, 16, .upper, .{ .fill = '0', .width = 4 });
464 try writer.printInt(codepoint, 16, .upper, .{ .fill = '0', .width = 4 });
465465 } else {
466466 try writer.writeAll("\\U");
467 try writer.printIntOptions(codepoint, 16, .upper, .{ .fill = '0', .width = 8 });
467 try writer.printInt(codepoint, 16, .upper, .{ .fill = '0', .width = 8 });
468468 }
469469 }
470470 }
lib/compiler/aro/aro/Preprocessor.zig+1-1
......@@ -3262,7 +3262,7 @@ fn printLinemarker(
32623262 // containing the same bytes as the input regardless of encoding.
32633263 else => {
32643264 try w.writeAll("\\x");
3265 // TODO try w.printIntOptions(byte, 16, .lower, .{ .width = 2, .fill = '0' });
3265 // TODO try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' });
32663266 try w.print("{x:0>2}", .{byte});
32673267 },
32683268 };
lib/compiler/aro/aro/Value.zig+1-2
......@@ -961,8 +961,7 @@ pub fn print(v: Value, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w
961961 switch (key) {
962962 .null => return w.writeAll("nullptr_t"),
963963 .int => |repr| switch (repr) {
964 inline .u64, .i64 => |x| return w.print("{d}", .{x}),
965 .big_int => |x| return w.print("{fd}", .{x}),
964 inline .u64, .i64, .big_int => |x| return w.print("{d}", .{x}),
966965 },
967966 .float => |repr| switch (repr) {
968967 .f16 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000) / 1000}),
lib/std/Build/Step/CheckObject.zig+4-7
......@@ -230,12 +230,7 @@ const ComputeCompareExpected = struct {
230230 literal: u64,
231231 },
232232
233 pub fn format(
234 value: ComputeCompareExpected,
235 bw: *Writer,
236 comptime fmt: []const u8,
237 ) !void {
238 if (fmt.len != 0) std.fmt.invalidFmtError(fmt, value);
233 pub fn format(value: ComputeCompareExpected, bw: *Writer) Writer.Error!void {
239234 try bw.print("{s} ", .{@tagName(value.op)});
240235 switch (value.value) {
241236 .variable => |name| try bw.writeAll(name),
......@@ -571,7 +566,9 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
571566 null,
572567 .of(u64),
573568 null,
574 ) catch |err| return step.fail("unable to read '{f'}': {s}", .{ src_path, @errorName(err) });
569 ) catch |err| return step.fail("unable to read '{f}': {s}", .{
570 std.fmt.alt(src_path, .formatEscapeChar), @errorName(err),
571 });
575572
576573 var vars: std.StringHashMap(u64) = .init(gpa);
577574 for (check_object.checks.items) |chk| {
lib/std/Target.zig+7-18
......@@ -301,24 +301,13 @@ pub const Os = struct {
301301
302302 /// This function is defined to serialize a Zig source code representation of this
303303 /// type, that, when parsed, will deserialize into the same data.
304 pub fn format(ver: WindowsVersion, w: *std.io.Writer, comptime f: []const u8) std.io.Writer.Error!void {
305 const maybe_name = std.enums.tagName(WindowsVersion, ver);
306 if (comptime std.mem.eql(u8, f, "s")) {
307 if (maybe_name) |name|
308 try w.print(".{s}", .{name})
309 else
310 try w.print(".{d}", .{@intFromEnum(ver)});
311 } else if (comptime std.mem.eql(u8, f, "c")) {
312 if (maybe_name) |name|
313 try w.print(".{s}", .{name})
314 else
315 try w.print("@enumFromInt(0x{X:0>8})", .{@intFromEnum(ver)});
316 } else if (f.len == 0) {
317 if (maybe_name) |name|
318 try w.print("WindowsVersion.{s}", .{name})
319 else
320 try w.print("WindowsVersion(0x{X:0>8})", .{@intFromEnum(ver)});
321 } else std.fmt.invalidFmtError(f, ver);
304 pub fn format(wv: WindowsVersion, w: *std.io.Writer) std.io.Writer.Error!void {
305 if (std.enums.tagName(WindowsVersion, wv)) |name| {
306 var vecs: [2][]const u8 = .{ ".", name };
307 return w.writeVecAll(&vecs);
308 } else {
309 return w.print("@enumFromInt(0x{X:0>8})", .{wv});
310 }
322311 }
323312 };
324313
lib/std/Uri.zig+14
......@@ -240,6 +240,10 @@ pub fn parseAfterScheme(scheme: []const u8, text: []const u8) ParseError!Uri {
240240 return uri;
241241}
242242
243pub fn format(uri: *const Uri, writer: *std.io.Writer) std.io.Writer.Error!void {
244 return writeToStream(uri, writer, .all);
245}
246
243247pub fn writeToStream(uri: *const Uri, writer: *std.io.Writer, flags: Format.Flags) std.io.Writer.Error!void {
244248 if (flags.scheme) {
245249 try writer.print("{s}:", .{uri.scheme});
......@@ -302,6 +306,16 @@ pub const Format = struct {
302306 fragment: bool = false,
303307 /// When true, include the port part of the URI. Ignored when `port` is null.
304308 port: bool = true,
309
310 pub const all: Flags = .{
311 .scheme = true,
312 .authentication = true,
313 .authority = true,
314 .path = true,
315 .query = true,
316 .fragment = true,
317 .port = true,
318 };
305319 };
306320
307321 pub fn default(f: Format, writer: *std.io.Writer) std.io.Writer.Error!void {
lib/std/fmt.zig+40-62
......@@ -53,16 +53,20 @@ pub const Options = struct {
5353/// - when using a field name, you are required to enclose the field name (an identifier) in square
5454/// brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...}
5555/// - *specifier* is a type-dependent formatting option that determines how a type should formatted (see below)
56/// - *fill* is a single byte which is used to pad the formatted text
57/// - *alignment* is one of the three bytes '<', '^', or '>' to make the text left-, center-, or right-aligned, respectively
58/// - *width* is the total width of the field in bytes. This is generally only
59/// useful for ASCII text, such as numbers.
60/// - *precision* specifies how many decimals a formatted number should have
56/// - *fill* is a single byte which is used to pad formatted numbers.
57/// - *alignment* is one of the three bytes '<', '^', or '>' to make numbers
58/// left, center, or right-aligned, respectively.
59/// - *width* is the total width of the field in bytes. This only applies to number formatting.
60/// - *precision* specifies how many decimals a formatted number should have.
6161///
62/// Note that most of the parameters are optional and may be omitted. Also you can leave out separators like `:` and `.` when
63/// all parameters after the separator are omitted.
64/// Only exception is the *fill* parameter. If a non-zero *fill* character is required at the same time as *width* is specified,
65/// one has to specify *alignment* as well, as otherwise the digit following `:` is interpreted as *width*, not *fill*.
62/// Note that most of the parameters are optional and may be omitted. Also you
63/// can leave out separators like `:` and `.` when all parameters after the
64/// separator are omitted.
65///
66/// Only exception is the *fill* parameter. If a non-zero *fill* character is
67/// required at the same time as *width* is specified, one has to specify
68/// *alignment* as well, as otherwise the digit following `:` is interpreted as
69/// *width*, not *fill*.
6670///
6771/// The *specifier* has several options for types:
6872/// - `x` and `X`: output numeric value in hexadecimal notation, or string in hexadecimal bytes
......@@ -405,9 +409,9 @@ pub const ArgState = struct {
405409/// Asserts the rendered integer value fits in `buffer`.
406410/// Returns the end index within `buffer`.
407411pub fn printInt(buffer: []u8, value: anytype, base: u8, case: Case, options: Options) usize {
408 var bw: Writer = .fixed(buffer);
409 bw.printIntOptions(value, base, case, options) catch unreachable;
410 return bw.end;
412 var w: Writer = .fixed(buffer);
413 w.printInt(value, base, case, options) catch unreachable;
414 return w.end;
411415}
412416
413417/// Converts values in the range [0, 100) to a base 10 string.
......@@ -956,35 +960,23 @@ fn expectArrayFmt(expected: []const u8, comptime template: []const u8, comptime
956960}
957961
958962test "array" {
959 {
960 const value: [3]u8 = "abc".*;
961 try expectArrayFmt("array: abc\n", "array: {s}\n", value);
962 try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {d}\n", value);
963 try expectArrayFmt("array: 616263\n", "array: {x}\n", value);
964 try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {any}\n", value);
965
966 var buf: [100]u8 = undefined;
967 try expectFmt(
968 try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@intFromPtr(&value)}),
969 "array: {*}\n",
970 .{&value},
971 );
972 }
963 const value: [3]u8 = "abc".*;
964 try expectArrayFmt("array: abc\n", "array: {s}\n", value);
965 try expectArrayFmt("array: 616263\n", "array: {x}\n", value);
966 try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {any}\n", value);
973967
974 {
975 const value = [2][3]u8{ "abc".*, "def".* };
976
977 try expectArrayFmt("array: { abc, def }\n", "array: {s}\n", value);
978 try expectArrayFmt("array: { { 97, 98, 99 }, { 100, 101, 102 } }\n", "array: {d}\n", value);
979 try expectArrayFmt("array: { 616263, 646566 }\n", "array: {x}\n", value);
980 }
968 var buf: [100]u8 = undefined;
969 try expectFmt(
970 try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@intFromPtr(&value)}),
971 "array: {*}\n",
972 .{&value},
973 );
981974}
982975
983976test "slice" {
984977 {
985978 const value: []const u8 = "abc";
986979 try expectFmt("slice: abc\n", "slice: {s}\n", .{value});
987 try expectFmt("slice: { 97, 98, 99 }\n", "slice: {d}\n", .{value});
988980 try expectFmt("slice: 616263\n", "slice: {x}\n", .{value});
989981 try expectFmt("slice: { 97, 98, 99 }\n", "slice: {any}\n", .{value});
990982 }
......@@ -999,17 +991,12 @@ test "slice" {
999991 try expectFmt("buf: \x00hello\x00\n", "buf: {s}\n", .{null_term_slice});
1000992 }
1001993
1002 try expectFmt("buf: Test\n", "buf: {s:5}\n", .{"Test"});
1003994 try expectFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
1004995
1005996 {
1006997 var int_slice = [_]u32{ 1, 4096, 391891, 1111111111 };
1007 var runtime_zero: usize = 0;
1008 _ = &runtime_zero;
1009 try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {any}", .{int_slice[runtime_zero..]});
1010 try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {d}", .{int_slice[runtime_zero..]});
1011 try expectFmt("int: { 1, 1000, 5fad3, 423a35c7 }", "int: {x}", .{int_slice[runtime_zero..]});
1012 try expectFmt("int: { 00001, 01000, 5fad3, 423a35c7 }", "int: {x:0>5}", .{int_slice[runtime_zero..]});
998 const input: []const u32 = &int_slice;
999 try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {any}", .{input});
10131000 }
10141001 {
10151002 const S1 = struct {
......@@ -1054,11 +1041,6 @@ test "cstr" {
10541041 "cstr: {s}\n",
10551042 .{@as([*c]const u8, @ptrCast("Test C"))},
10561043 );
1057 try expectFmt(
1058 "cstr: Test C\n",
1059 "cstr: {s:10}\n",
1060 .{@as([*c]const u8, @ptrCast("Test C"))},
1061 );
10621044}
10631045
10641046test "struct" {
......@@ -1428,16 +1410,12 @@ test "enum-literal" {
14281410
14291411test "padding" {
14301412 try expectFmt("Simple", "{s}", .{"Simple"});
1431 try expectFmt(" true", "{:10}", .{true});
1432 try expectFmt(" true", "{:>10}", .{true});
1433 try expectFmt("======true", "{:=>10}", .{true});
1434 try expectFmt("true======", "{:=<10}", .{true});
1435 try expectFmt(" true ", "{:^10}", .{true});
1436 try expectFmt("===true===", "{:=^10}", .{true});
1437 try expectFmt(" Minimum width", "{s:18} width", .{"Minimum"});
1438 try expectFmt("==================Filled", "{s:=>24}", .{"Filled"});
1439 try expectFmt(" Centered ", "{s:^24}", .{"Centered"});
1440 try expectFmt("-", "{s:-^1}", .{""});
1413 try expectFmt(" 1234", "{:10}", .{1234});
1414 try expectFmt(" 1234", "{:>10}", .{1234});
1415 try expectFmt("======1234", "{:=>10}", .{1234});
1416 try expectFmt("1234======", "{:=<10}", .{1234});
1417 try expectFmt(" 1234 ", "{:^10}", .{1234});
1418 try expectFmt("===1234===", "{:=^10}", .{1234});
14411419 try expectFmt("====a", "{c:=>5}", .{'a'});
14421420 try expectFmt("==a==", "{c:=^5}", .{'a'});
14431421 try expectFmt("a====", "{c:=<5}", .{'a'});
......@@ -1485,17 +1463,17 @@ test "named arguments" {
14851463
14861464test "runtime width specifier" {
14871465 const width: usize = 9;
1488 try expectFmt("~~hello~~", "{s:~^[1]}", .{ "hello", width });
1489 try expectFmt("~~hello~~", "{s:~^[width]}", .{ .string = "hello", .width = width });
1490 try expectFmt(" hello", "{s:[1]}", .{ "hello", width });
1491 try expectFmt("42 hello", "{d} {s:[2]}", .{ 42, "hello", width });
1466 try expectFmt("~~12345~~", "{d:~^[1]}", .{ 12345, width });
1467 try expectFmt("~~12345~~", "{d:~^[width]}", .{ .string = 12345, .width = width });
1468 try expectFmt(" 12345", "{d:[1]}", .{ 12345, width });
1469 try expectFmt("42 12345", "{d} {d:[2]}", .{ 42, 12345, width });
14921470}
14931471
14941472test "runtime precision specifier" {
14951473 const number: f32 = 3.1415;
14961474 const precision: usize = 2;
1497 try expectFmt("3.14e0", "{:1.[1]}", .{ number, precision });
1498 try expectFmt("3.14e0", "{:1.[precision]}", .{ .number = number, .precision = precision });
1475 try expectFmt("3.14e0", "{e:1.[1]}", .{ number, precision });
1476 try expectFmt("3.14e0", "{e:1.[precision]}", .{ .number = number, .precision = precision });
14991477}
15001478
15011479test "recursive format function" {
lib/std/io/Writer.zig+284-207
......@@ -777,15 +777,15 @@ pub fn printAddress(w: *Writer, value: anytype) Error!void {
777777 .pointer => |info| {
778778 try w.writeAll(@typeName(info.child) ++ "@");
779779 if (info.size == .slice)
780 try w.printIntOptions(@intFromPtr(value.ptr), 16, .lower, .{})
780 try w.printInt(@intFromPtr(value.ptr), 16, .lower, .{})
781781 else
782 try w.printIntOptions(@intFromPtr(value), 16, .lower, .{});
782 try w.printInt(@intFromPtr(value), 16, .lower, .{});
783783 return;
784784 },
785785 .optional => |info| {
786786 if (@typeInfo(info.child) == .pointer) {
787787 try w.writeAll(@typeName(info.child) ++ "@");
788 try w.printIntOptions(@intFromPtr(value), 16, .lower, .{});
788 try w.printInt(@intFromPtr(value), 16, .lower, .{});
789789 return;
790790 }
791791 },
......@@ -804,11 +804,147 @@ pub fn printValue(
804804) Error!void {
805805 const T = @TypeOf(value);
806806
807 if (fmt.len == 1) switch (fmt[0]) {
808 '*' => return w.printAddress(value),
809 'f' => return value.format(w),
807 switch (fmt.len) {
808 1 => switch (fmt[0]) {
809 '*' => return w.printAddress(value),
810 'f' => return value.format(w),
811 'd' => switch (@typeInfo(T)) {
812 .float, .comptime_float => return printFloat(w, value, .decimal, options),
813 .int, .comptime_int => return printInt(w, value, 10, .lower, options),
814 .@"struct" => return value.formatInteger(w, 10, .lower),
815 .@"enum" => return printInt(w, @intFromEnum(value), 10, .lower, options),
816 .vector => return printVector(w, fmt, options, value, max_depth),
817 else => invalidFmtError(fmt, value),
818 },
819 'c' => return w.printAsciiChar(value, options),
820 'u' => return w.printUnicodeCodepoint(value),
821 'b' => switch (@typeInfo(T)) {
822 .int, .comptime_int => return printInt(w, value, 2, .lower, options),
823 .@"enum" => return printInt(w, @intFromEnum(value), 2, .lower, options),
824 .@"struct" => return value.formatInteger(w, 2, .lower),
825 .vector => return printVector(w, fmt, options, value, max_depth),
826 else => invalidFmtError(fmt, value),
827 },
828 'o' => switch (@typeInfo(T)) {
829 .int, .comptime_int => return printInt(w, value, 8, .lower, options),
830 .@"enum" => return printInt(w, @intFromEnum(value), 8, .lower, options),
831 .@"struct" => return value.formatInteger(w, 8, .lower),
832 .vector => return printVector(w, fmt, options, value, max_depth),
833 else => invalidFmtError(fmt, value),
834 },
835 'x' => switch (@typeInfo(T)) {
836 .float, .comptime_float => return printFloatHexOptions(w, value, .lower, options),
837 .int, .comptime_int => return printInt(w, value, 16, .lower, options),
838 .@"enum" => return printInt(w, @intFromEnum(value), 16, .lower, options),
839 .@"struct" => return value.formatInteger(w, 16, .lower),
840 .pointer => |info| switch (info.size) {
841 .one, .slice => {
842 const slice: []const u8 = value;
843 return printHex(w, slice, .lower);
844 },
845 .many, .c => {
846 const slice: [:0]const u8 = std.mem.span(value);
847 return printHex(w, slice, .lower);
848 },
849 },
850 .array => {
851 const slice: []const u8 = &value;
852 return printHex(w, slice, .lower);
853 },
854 .vector => return printVector(w, fmt, options, value, max_depth),
855 else => invalidFmtError(fmt, value),
856 },
857 'X' => switch (@typeInfo(T)) {
858 .float, .comptime_float => return printFloatHexOptions(w, value, .lower, options),
859 .int, .comptime_int => return printInt(w, value, 16, .upper, options),
860 .@"enum" => return printInt(w, @intFromEnum(value), 16, .upper, options),
861 .@"struct" => return value.formatInteger(w, 16, .upper),
862 .pointer => |info| switch (info.size) {
863 .one, .slice => {
864 const slice: []const u8 = value;
865 return printHex(w, slice, .upper);
866 },
867 .many, .c => {
868 const slice: [:0]const u8 = std.mem.span(value);
869 return printHex(w, slice, .upper);
870 },
871 },
872 .array => {
873 const slice: []const u8 = &value;
874 return printHex(w, slice, .upper);
875 },
876 .vector => return printVector(w, fmt, options, value, max_depth),
877 else => invalidFmtError(fmt, value),
878 },
879 's' => switch (@typeInfo(T)) {
880 .pointer => |info| switch (info.size) {
881 .one, .slice => {
882 const slice: []const u8 = value;
883 return w.writeAll(slice);
884 },
885 .many, .c => {
886 const slice: [:0]const u8 = std.mem.span(value);
887 return w.writeAll(slice);
888 },
889 },
890 .array => {
891 const slice: []const u8 = &value;
892 return w.writeAll(slice);
893 },
894 else => invalidFmtError(fmt, value),
895 },
896 'B' => switch (@typeInfo(T)) {
897 .int, .comptime_int => return w.printByteSize(value, .decimal, options),
898 .@"struct" => return value.formatByteSize(w, .decimal),
899 else => invalidFmtError(fmt, value),
900 },
901 'D' => switch (@typeInfo(T)) {
902 .int, .comptime_int => return w.printDuration(value, options),
903 .@"struct" => return value.formatDuration(w),
904 else => invalidFmtError(fmt, value),
905 },
906 'e' => switch (@typeInfo(T)) {
907 .float, .comptime_float => return printFloat(w, value, .scientific, options),
908 .@"struct" => return value.formatFloat(w, .scientific),
909 else => invalidFmtError(fmt, value),
910 },
911 't' => switch (@typeInfo(T)) {
912 .error_set => return w.writeAll(@errorName(value)),
913 .@"enum", .@"union" => return w.writeAll(@tagName(value)),
914 else => invalidFmtError(fmt, value),
915 },
916 else => {},
917 },
918 2 => switch (fmt[0]) {
919 'B' => switch (fmt[1]) {
920 'i' => switch (@typeInfo(T)) {
921 .int, .comptime_int => return w.printByteSize(value, .binary, options),
922 .@"struct" => return value.formatByteSize(w, .binary),
923 else => invalidFmtError(fmt, value),
924 },
925 else => {},
926 },
927 else => {},
928 },
929 3 => if (fmt[0] == 'b' and fmt[1] == '6' and fmt[2] == '4') switch (@typeInfo(T)) {
930 .pointer => |info| switch (info.size) {
931 .one, .slice => {
932 const slice: []const u8 = value;
933 return w.printBase64(slice);
934 },
935 .many, .c => {
936 const slice: [:0]const u8 = std.mem.span(value);
937 return w.printBase64(slice);
938 },
939 },
940 .array => {
941 const slice: []const u8 = &value;
942 return w.printBase64(slice);
943 },
944 else => invalidFmtError(fmt, value),
945 },
810946 else => {},
811 };
947 }
812948
813949 const is_any = comptime std.mem.eql(u8, fmt, ANY);
814950 if (!is_any and std.meta.hasMethod(T, "format") and fmt.len == 0) {
......@@ -817,15 +953,21 @@ pub fn printValue(
817953 }
818954
819955 switch (@typeInfo(T)) {
820 .float, .comptime_float => return w.printFloat(if (is_any) "d" else fmt, options, value),
821 .int, .comptime_int => return w.printInt(if (is_any) "d" else fmt, options, value),
956 .float, .comptime_float => {
957 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
958 return printFloat(w, value, .decimal, options);
959 },
960 .int, .comptime_int => {
961 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
962 return printInt(w, value, 10, .lower, options);
963 },
822964 .bool => {
823965 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
824 return w.alignBufferOptions(if (value) "true" else "false", options);
966 return w.writeAll(if (value) "true" else "false");
825967 },
826968 .void => {
827969 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
828 return w.alignBufferOptions("void", options);
970 return w.writeAll("void");
829971 },
830972 .optional => {
831973 const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '?')
......@@ -854,40 +996,18 @@ pub fn printValue(
854996 }
855997 },
856998 .error_set => {
857 if (fmt.len == 1 and fmt[0] == 't') return w.writeAll(@errorName(value));
858999 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
859 try printErrorSet(w, value);
1000 return printErrorSet(w, value);
8601001 },
861 .@"enum" => {
862 if (fmt.len == 1 and fmt[0] == 't') {
863 try w.writeAll(@tagName(value));
864 return;
865 }
866 if (!is_any) {
867 if (fmt.len != 0) return printValue(w, fmt, options, @intFromEnum(value), max_depth);
868 return printValue(w, ANY, options, value, max_depth);
869 }
870 const enum_info = @typeInfo(T).@"enum";
871 if (enum_info.is_exhaustive) {
872 var vecs: [2][]const u8 = .{ ".", @tagName(value) };
873 try w.writeVecAll(&vecs);
874 return;
875 }
876 if (std.enums.tagName(T, value)) |tag_name| {
877 var vecs: [2][]const u8 = .{ ".", tag_name };
878 try w.writeVecAll(&vecs);
879 return;
1002 .@"enum" => |info| {
1003 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1004 if (info.is_exhaustive) {
1005 return printEnumExhaustive(w, value);
1006 } else {
1007 return printEnumNonexhaustive(w, value);
8801008 }
881 try w.writeAll("@enumFromInt(");
882 try w.printValue(ANY, options, @intFromEnum(value), max_depth);
883 try w.writeByte(')');
884 return;
8851009 },
8861010 .@"union" => |info| {
887 if (fmt.len == 1 and fmt[0] == 't') {
888 try w.writeAll(@tagName(value));
889 return;
890 }
8911011 if (!is_any) {
8921012 if (fmt.len != 0) invalidFmtError(fmt, value);
8931013 return printValue(w, ANY, options, value, max_depth);
......@@ -971,38 +1091,18 @@ pub fn printValue(
9711091 else => {
9721092 var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" };
9731093 try w.writeVecAll(&buffers);
974 try w.printIntOptions(@intFromPtr(value), 16, .lower, options);
1094 try w.printInt(@intFromPtr(value), 16, .lower, options);
9751095 return;
9761096 },
9771097 },
9781098 .many, .c => {
979 if (ptr_info.sentinel() != null)
980 return w.printValue(fmt, options, std.mem.span(value), max_depth);
981 if (fmt.len == 1 and fmt[0] == 's' and ptr_info.child == u8)
982 return w.alignBufferOptions(std.mem.span(value), options);
983 if (!is_any and fmt.len == 0)
984 @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");
985 if (!is_any and fmt.len != 0)
986 invalidFmtError(fmt, value);
1099 if (!is_any) @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");
9871100 try w.printAddress(value);
9881101 },
9891102 .slice => {
990 if (!is_any and fmt.len == 0)
1103 if (!is_any)
9911104 @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})");
992 if (max_depth == 0)
993 return w.writeAll("{ ... }");
994 if (ptr_info.child == u8) switch (fmt.len) {
995 1 => switch (fmt[0]) {
996 's' => return w.alignBufferOptions(value, options),
997 'x' => return w.printHex(value, .lower),
998 'X' => return w.printHex(value, .upper),
999 else => {},
1000 },
1001 3 => if (fmt[0] == 'b' and fmt[1] == '6' and fmt[2] == '4') {
1002 return w.printBase64(value);
1003 },
1004 else => {},
1005 };
1105 if (max_depth == 0) return w.writeAll("{ ... }");
10061106 try w.writeAll("{ ");
10071107 for (value, 0..) |elem, i| {
10081108 try w.printValue(fmt, options, elem, max_depth - 1);
......@@ -1013,21 +1113,9 @@ pub fn printValue(
10131113 try w.writeAll(" }");
10141114 },
10151115 },
1016 .array => |info| {
1017 if (fmt.len == 0)
1018 @compileError("cannot format array without a specifier (i.e. {s} or {any})");
1019 if (max_depth == 0) {
1020 return w.writeAll("{ ... }");
1021 }
1022 if (info.child == u8) {
1023 if (fmt[0] == 's') {
1024 return w.alignBufferOptions(&value, options);
1025 } else if (fmt[0] == 'x') {
1026 return w.printHex(&value, .lower);
1027 } else if (fmt[0] == 'X') {
1028 return w.printHex(&value, .upper);
1029 }
1030 }
1116 .array => {
1117 if (!is_any) @compileError("cannot format array without a specifier (i.e. {s} or {any})");
1118 if (max_depth == 0) return w.writeAll("{ ... }");
10311119 try w.writeAll("{ ");
10321120 for (value, 0..) |elem, i| {
10331121 try w.printValue(fmt, options, elem, max_depth - 1);
......@@ -1037,33 +1125,23 @@ pub fn printValue(
10371125 }
10381126 try w.writeAll(" }");
10391127 },
1040 .vector => |info| {
1041 if (max_depth == 0) {
1042 return w.writeAll("{ ... }");
1043 }
1044 try w.writeAll("{ ");
1045 var i: usize = 0;
1046 while (i < info.len) : (i += 1) {
1047 try w.printValue(fmt, options, value[i], max_depth - 1);
1048 if (i < info.len - 1) {
1049 try w.writeAll(", ");
1050 }
1051 }
1052 try w.writeAll(" }");
1128 .vector => {
1129 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1130 return printVector(w, fmt, options, value, max_depth);
10531131 },
10541132 .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),
10551133 .type => {
10561134 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1057 return w.alignBufferOptions(@typeName(value), options);
1135 return w.writeAll(@typeName(value));
10581136 },
10591137 .enum_literal => {
10601138 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1061 const buffer = [_]u8{'.'} ++ @tagName(value);
1062 return w.alignBufferOptions(buffer, options);
1139 var vecs: [2][]const u8 = .{ ".", @tagName(value) };
1140 return w.writeVecAll(&vecs);
10631141 },
10641142 .null => {
10651143 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1066 return w.alignBufferOptions("null", options);
1144 return w.writeAll("null");
10671145 },
10681146 else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"),
10691147 }
......@@ -1074,75 +1152,68 @@ fn printErrorSet(w: *Writer, error_set: anyerror) Error!void {
10741152 try w.writeVecAll(&vecs);
10751153}
10761154
1077pub fn printInt(
1155fn printEnumExhaustive(w: *Writer, value: anytype) Error!void {
1156 var vecs: [2][]const u8 = .{ ".", @tagName(value) };
1157 try w.writeVecAll(&vecs);
1158}
1159
1160fn printEnumNonexhaustive(w: *Writer, value: anytype) Error!void {
1161 if (std.enums.tagName(@TypeOf(value), value)) |tag_name| {
1162 var vecs: [2][]const u8 = .{ ".", tag_name };
1163 try w.writeVecAll(&vecs);
1164 return;
1165 }
1166 try w.writeAll("@enumFromInt(");
1167 try w.printInt(@intFromEnum(value), 10, .lower, .{});
1168 try w.writeByte(')');
1169}
1170
1171pub fn printVector(
10781172 w: *Writer,
10791173 comptime fmt: []const u8,
10801174 options: std.fmt.Options,
10811175 value: anytype,
1176 max_depth: usize,
10821177) Error!void {
1083 const int_value = if (@TypeOf(value) == comptime_int) blk: {
1084 const Int = std.math.IntFittingRange(value, value);
1085 break :blk @as(Int, value);
1086 } else value;
1087
1088 switch (fmt.len) {
1089 0 => return w.printIntOptions(int_value, 10, .lower, options),
1090 1 => switch (fmt[0]) {
1091 'd' => return w.printIntOptions(int_value, 10, .lower, options),
1092 'c' => {
1093 if (@typeInfo(@TypeOf(int_value)).int.bits <= 8) {
1094 return w.printAsciiChar(@as(u8, int_value), options);
1095 } else {
1096 @compileError("cannot print integer that is larger than 8 bits as an ASCII character");
1097 }
1098 },
1099 'u' => {
1100 if (@typeInfo(@TypeOf(int_value)).int.bits <= 21) {
1101 return w.printUnicodeCodepoint(@as(u21, int_value), options);
1102 } else {
1103 @compileError("cannot print integer that is larger than 21 bits as an UTF-8 sequence");
1104 }
1105 },
1106 'b' => return w.printIntOptions(int_value, 2, .lower, options),
1107 'x' => return w.printIntOptions(int_value, 16, .lower, options),
1108 'X' => return w.printIntOptions(int_value, 16, .upper, options),
1109 'o' => return w.printIntOptions(int_value, 8, .lower, options),
1110 'B' => return w.printByteSize(int_value, .decimal, options),
1111 'D' => return w.printDuration(int_value, options),
1112 else => invalidFmtError(fmt, value),
1113 },
1114 2 => {
1115 if (fmt[0] == 'B' and fmt[1] == 'i') {
1116 return w.printByteSize(int_value, .binary, options);
1117 } else {
1118 invalidFmtError(fmt, value);
1119 }
1120 },
1121 else => invalidFmtError(fmt, value),
1178 const len = @typeInfo(@TypeOf(value)).vector.len;
1179 if (max_depth == 0) return w.writeAll("{ ... }");
1180 try w.writeAll("{ ");
1181 inline for (0..len) |i| {
1182 try w.printValue(fmt, options, value[i], max_depth - 1);
1183 if (i < len - 1) try w.writeAll(", ");
11221184 }
1123 comptime unreachable;
1124}
1125
1126pub fn printAsciiChar(w: *Writer, c: u8, options: std.fmt.Options) Error!void {
1127 return w.alignBufferOptions(@as(*const [1]u8, &c), options);
1185 try w.writeAll(" }");
11281186}
11291187
1130pub fn printAscii(w: *Writer, bytes: []const u8, options: std.fmt.Options) Error!void {
1131 return w.alignBufferOptions(bytes, options);
1132}
1133
1134pub fn printUnicodeCodepoint(w: *Writer, c: u21, options: std.fmt.Options) Error!void {
1135 var buf: [4]u8 = undefined;
1136 const len = std.unicode.utf8Encode(c, &buf) catch |err| switch (err) {
1137 error.Utf8CannotEncodeSurrogateHalf, error.CodepointTooLarge => l: {
1138 buf[0..3].* = std.unicode.replacement_character_utf8;
1139 break :l 3;
1188// A wrapper around `printIntAny` to avoid the generic explosion of this
1189// function by funneling smaller integer types through `isize` and `usize`.
1190pub inline fn printInt(
1191 w: *Writer,
1192 value: anytype,
1193 base: u8,
1194 case: std.fmt.Case,
1195 options: std.fmt.Options,
1196) Error!void {
1197 switch (@TypeOf(value)) {
1198 isize, usize => {},
1199 comptime_int => {
1200 if (comptime std.math.cast(usize, value)) |x| return printIntAny(w, x, base, case, options);
1201 if (comptime std.math.cast(isize, value)) |x| return printIntAny(w, x, base, case, options);
1202 const Int = std.math.IntFittingRange(value, value);
1203 return printIntAny(w, @as(Int, value), base, case, options);
11401204 },
1141 };
1142 return w.alignBufferOptions(buf[0..len], options);
1205 else => switch (@typeInfo(@TypeOf(value)).int.signedness) {
1206 .signed => if (std.math.cast(isize, value)) |x| return printIntAny(w, x, base, case, options),
1207 .unsigned => if (std.math.cast(usize, value)) |x| return printIntAny(w, x, base, case, options),
1208 },
1209 }
1210 return printIntAny(w, value, base, case, options);
11431211}
11441212
1145pub fn printIntOptions(
1213/// In general, prefer `printInt` to avoid generic explosion. However this
1214/// function may be used when optimal codegen for a particular integer type is
1215/// desired.
1216pub fn printIntAny(
11461217 w: *Writer,
11471218 value: anytype,
11481219 base: u8,
......@@ -1150,20 +1221,14 @@ pub fn printIntOptions(
11501221 options: std.fmt.Options,
11511222) Error!void {
11521223 assert(base >= 2);
1153
1154 const int_value = if (@TypeOf(value) == comptime_int) blk: {
1155 const Int = std.math.IntFittingRange(value, value);
1156 break :blk @as(Int, value);
1157 } else value;
1158
1159 const value_info = @typeInfo(@TypeOf(int_value)).int;
1224 const value_info = @typeInfo(@TypeOf(value)).int;
11601225
11611226 // The type must have the same size as `base` or be wider in order for the
11621227 // division to work
11631228 const min_int_bits = comptime @max(value_info.bits, 8);
11641229 const MinInt = std.meta.Int(.unsigned, min_int_bits);
11651230
1166 const abs_value = @abs(int_value);
1231 const abs_value = @abs(value);
11671232 // The worst case in terms of space needed is base 2, plus 1 for the sign
11681233 var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined;
11691234
......@@ -1210,38 +1275,49 @@ pub fn printIntOptions(
12101275 return w.alignBufferOptions(buf[index..], options);
12111276}
12121277
1278pub fn printAsciiChar(w: *Writer, c: u8, options: std.fmt.Options) Error!void {
1279 return w.alignBufferOptions(@as(*const [1]u8, &c), options);
1280}
1281
1282pub fn printAscii(w: *Writer, bytes: []const u8, options: std.fmt.Options) Error!void {
1283 return w.alignBufferOptions(bytes, options);
1284}
1285
1286pub fn printUnicodeCodepoint(w: *Writer, c: u21) Error!void {
1287 var buf: [4]u8 = undefined;
1288 const len = std.unicode.utf8Encode(c, &buf) catch |err| switch (err) {
1289 error.Utf8CannotEncodeSurrogateHalf, error.CodepointTooLarge => l: {
1290 buf[0..3].* = std.unicode.replacement_character_utf8;
1291 break :l 3;
1292 },
1293 };
1294 return w.writeAll(buf[0..len]);
1295}
1296
12131297pub fn printFloat(
12141298 w: *Writer,
1215 comptime fmt: []const u8,
1216 options: std.fmt.Options,
12171299 value: anytype,
1300 mode: std.fmt.float.Mode,
1301 options: std.fmt.Options,
12181302) Error!void {
12191303 var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined;
1304 const s = std.fmt.float.render(&buf, value, .{
1305 .mode = mode,
1306 .precision = options.precision,
1307 }) catch |err| switch (err) {
1308 error.BufferTooSmall => "(float)",
1309 };
1310 return w.alignBufferOptions(s, options);
1311}
12201312
1221 if (fmt.len > 1) invalidFmtError(fmt, value);
1222 switch (if (fmt.len == 0) 'e' else fmt[0]) {
1223 'e' => {
1224 const s = std.fmt.float.render(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) {
1225 error.BufferTooSmall => "(float)",
1226 };
1227 return w.alignBufferOptions(s, options);
1228 },
1229 'd' => {
1230 const s = std.fmt.float.render(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) {
1231 error.BufferTooSmall => "(float)",
1232 };
1233 return w.alignBufferOptions(s, options);
1234 },
1235 'x' => {
1236 var sub_bw: Writer = .fixed(&buf);
1237 sub_bw.printFloatHexadecimal(value, options.precision) catch unreachable;
1238 return w.alignBufferOptions(sub_bw.buffered(), options);
1239 },
1240 else => invalidFmtError(fmt, value),
1241 }
1313pub fn printFloatHexOptions(w: *Writer, value: anytype, case: std.fmt.Case, options: std.fmt.Options) Error!void {
1314 var buf: [50]u8 = undefined; // for aligning
1315 var sub_writer: Writer = .fixed(&buf);
1316 printFloatHex(&sub_writer, value, case, options.precision) catch unreachable; // buf is large enough
1317 return w.alignBufferOptions(sub_writer.buffered(), options);
12421318}
12431319
1244pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize) Error!void {
1320pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precision: ?usize) Error!void {
12451321 if (std.math.signbit(value)) try w.writeByte('-');
12461322 if (std.math.isNan(value)) return w.writeAll("nan");
12471323 if (std.math.isInf(value)) return w.writeAll("inf");
......@@ -1320,7 +1396,7 @@ pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize)
13201396
13211397 // +1 for the decimal part.
13221398 var buf: [1 + mantissa_digits]u8 = undefined;
1323 assert(std.fmt.printInt(&buf, mantissa, 16, .lower, .{ .fill = '0', .width = 1 + mantissa_digits }) == buf.len);
1399 assert(std.fmt.printInt(&buf, mantissa, 16, case, .{ .fill = '0', .width = 1 + mantissa_digits }) == buf.len);
13241400
13251401 try w.writeAll("0x");
13261402 try w.writeByte(buf[0]);
......@@ -1337,7 +1413,7 @@ pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize)
13371413 try w.splatByteAll('0', precision - trimmed.len);
13381414 };
13391415 try w.writeAll("p");
1340 try w.printIntOptions(exponent - exponent_bias, 10, .lower, .{});
1416 try w.printInt(exponent - exponent_bias, 10, case, .{});
13411417}
13421418
13431419pub const ByteSizeUnits = enum {
......@@ -1433,7 +1509,7 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
14331509 }) |unit| {
14341510 if (ns_remaining >= unit.ns) {
14351511 const units = ns_remaining / unit.ns;
1436 try w.printIntOptions(units, 10, .lower, .{});
1512 try w.printInt(units, 10, .lower, .{});
14371513 try w.writeByte(unit.sep);
14381514 ns_remaining -= units * unit.ns;
14391515 if (ns_remaining == 0) return;
......@@ -1447,13 +1523,13 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
14471523 }) |unit| {
14481524 const kunits = ns_remaining * 1000 / unit.ns;
14491525 if (kunits >= 1000) {
1450 try w.printIntOptions(kunits / 1000, 10, .lower, .{});
1526 try w.printInt(kunits / 1000, 10, .lower, .{});
14511527 const frac = kunits % 1000;
14521528 if (frac > 0) {
14531529 // Write up to 3 decimal places
14541530 var decimal_buf = [_]u8{ '.', 0, 0, 0 };
14551531 var inner: Writer = .fixed(decimal_buf[1..]);
1456 inner.printIntOptions(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable;
1532 inner.printInt(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable;
14571533 var end: usize = 4;
14581534 while (end > 1) : (end -= 1) {
14591535 if (decimal_buf[end - 1] != '0') break;
......@@ -1464,7 +1540,7 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
14641540 }
14651541 }
14661542
1467 try w.printIntOptions(ns_remaining, 10, .lower, .{});
1543 try w.printInt(ns_remaining, 10, .lower, .{});
14681544 try w.writeAll("ns");
14691545}
14701546
......@@ -1474,12 +1550,18 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
14741550pub fn printDuration(w: *Writer, nanoseconds: anytype, options: std.fmt.Options) Error!void {
14751551 // worst case: "-XXXyXXwXXdXXhXXmXX.XXXs".len = 24
14761552 var buf: [24]u8 = undefined;
1477 var sub_bw: Writer = .fixed(&buf);
1478 switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) {
1479 .signed => sub_bw.printDurationSigned(nanoseconds) catch unreachable,
1480 .unsigned => sub_bw.printDurationUnsigned(nanoseconds) catch unreachable,
1553 var sub_writer: Writer = .fixed(&buf);
1554 if (@TypeOf(nanoseconds) == comptime_int) {
1555 if (nanoseconds >= 0) {
1556 sub_writer.printDurationUnsigned(nanoseconds) catch unreachable;
1557 } else {
1558 sub_writer.printDurationSigned(nanoseconds) catch unreachable;
1559 }
1560 } else switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) {
1561 .signed => sub_writer.printDurationSigned(nanoseconds) catch unreachable,
1562 .unsigned => sub_writer.printDurationUnsigned(nanoseconds) catch unreachable,
14811563 }
1482 return w.alignBufferOptions(sub_bw.buffered(), options);
1564 return w.alignBufferOptions(sub_writer.buffered(), options);
14831565}
14841566
14851567pub fn printHex(w: *Writer, bytes: []const u8, case: std.fmt.Case) Error!void {
......@@ -1749,7 +1831,7 @@ fn testDurationCaseSigned(expected: []const u8, input: i64) !void {
17491831 try testing.expectEqualStrings(expected, w.buffered());
17501832}
17511833
1752test printIntOptions {
1834test printInt {
17531835 try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{});
17541836
17551837 try testPrintIntCase("-101111000110000101001110", @as(i32, -12345678), 2, .lower, .{});
......@@ -1765,27 +1847,22 @@ test printIntOptions {
17651847
17661848 try testPrintIntCase("+42", @as(i32, 42), 10, .lower, .{ .width = 3 });
17671849 try testPrintIntCase("-42", @as(i32, -42), 10, .lower, .{ .width = 3 });
1768}
17691850
1770test "printInt with comptime_int" {
1771 var buf: [20]u8 = undefined;
1772 var w: Writer = .fixed(&buf);
1773 try w.printInt("", .{}, @as(comptime_int, 123456789123456789));
1774 try std.testing.expectEqualStrings("123456789123456789", w.buffered());
1851 try testPrintIntCase("123456789123456789", @as(comptime_int, 123456789123456789), 10, .lower, .{});
17751852}
17761853
17771854test "printFloat with comptime_float" {
17781855 var buf: [20]u8 = undefined;
17791856 var w: Writer = .fixed(&buf);
1780 try w.printFloat("", .{}, @as(comptime_float, 1.0));
1857 try w.printFloat(@as(comptime_float, 1.0), .scientific, .{});
17811858 try std.testing.expectEqualStrings(w.buffered(), "1e0");
1782 try std.testing.expectFmt("1e0", "{}", .{1.0});
1859 try std.testing.expectFmt("1", "{}", .{1.0});
17831860}
17841861
17851862fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void {
17861863 var buffer: [100]u8 = undefined;
17871864 var w: Writer = .fixed(&buffer);
1788 try w.printIntOptions(value, base, case, options);
1865 try w.printInt(value, base, case, options);
17891866 try testing.expectEqualStrings(expected, w.buffered());
17901867}
17911868
lib/std/json/dynamic_test.zig+2-2
......@@ -254,7 +254,7 @@ test "Value.jsonStringify" {
254254 \\ true,
255255 \\ 42,
256256 \\ 43,
257 \\ 4.2e1,
257 \\ 42,
258258 \\ "weeee",
259259 \\ [
260260 \\ 1,
......@@ -266,7 +266,7 @@ test "Value.jsonStringify" {
266266 \\ }
267267 \\]
268268 ;
269 try testing.expectEqualSlices(u8, expected, fbs.getWritten());
269 try testing.expectEqualStrings(expected, fbs.getWritten());
270270}
271271
272272test "parseFromValue(std.json.Value,...)" {
lib/std/json/stringify.zig-1
......@@ -469,7 +469,6 @@ pub fn WriteStream(
469469 /// * When option `emit_nonportable_numbers_as_strings` is true, if the value is outside the range `+-1<<53` (the precise integer range of f64), it is rendered as a JSON string in base 10. Otherwise, it is rendered as JSON number.
470470 /// * Zig floats -> JSON number or string.
471471 /// * If the value cannot be precisely represented by an f64, it is rendered as a JSON string. Otherwise, it is rendered as JSON number.
472 /// * TODO: Float rendering will likely change in the future, e.g. to remove the unnecessary "e+00".
473472 /// * Zig `[]const u8`, `[]u8`, `*[N]u8`, `@Vector(N, u8)`, and similar -> JSON string.
474473 /// * See `StringifyOptions.emit_strings_as_arrays`.
475474 /// * If the content is not valid UTF-8, rendered as an array of numbers instead.
lib/std/json/stringify_test.zig+6-6
......@@ -74,16 +74,16 @@ fn testBasicWriteStream(w: anytype, slice_stream: anytype) !void {
7474 \\{
7575 \\ "object": {
7676 \\ "one": 1,
77 \\ "two": 2e0
77 \\ "two": 2
7878 \\ },
7979 \\ "string": "This is a string",
8080 \\ "array": [
8181 \\ "Another string",
8282 \\ 1,
83 \\ 3.5e0
83 \\ 3.5
8484 \\ ],
8585 \\ "int": 10,
86 \\ "float": 3.5e0
86 \\ "float": 3.5
8787 \\}
8888 ;
8989 try std.testing.expectEqualStrings(expected, result);
......@@ -123,12 +123,12 @@ test "stringify basic types" {
123123 try testStringify("null", @as(?u8, null), .{});
124124 try testStringify("null", @as(?*u32, null), .{});
125125 try testStringify("42", 42, .{});
126 try testStringify("4.2e1", 42.0, .{});
126 try testStringify("42", 42.0, .{});
127127 try testStringify("42", @as(u8, 42), .{});
128128 try testStringify("42", @as(u128, 42), .{});
129129 try testStringify("9999999999999999", 9999999999999999, .{});
130 try testStringify("4.2e1", @as(f32, 42), .{});
131 try testStringify("4.2e1", @as(f64, 42), .{});
130 try testStringify("42", @as(f32, 42), .{});
131 try testStringify("42", @as(f64, 42), .{});
132132 try testStringify("\"ItBroke\"", @as(anyerror, error.ItBroke), .{});
133133 try testStringify("\"ItBroke\"", error.ItBroke, .{});
134134}
lib/std/math/big/int.zig+13-19
......@@ -2028,6 +2028,14 @@ pub const Mutable = struct {
20282028 pub fn normalize(r: *Mutable, length: usize) void {
20292029 r.len = llnormalize(r.limbs[0..length]);
20302030 }
2031
2032 pub fn format(self: Mutable, w: *std.io.Writer) std.io.Writer.Error!void {
2033 return formatInteger(self, w, 10, .lower);
2034 }
2035
2036 pub fn formatInteger(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
2037 return self.toConst().formatInteger(w, base, case);
2038 }
20312039};
20322040
20332041/// A arbitrary-precision big integer, with a fixed set of immutable limbs.
......@@ -2321,7 +2329,7 @@ pub const Const = struct {
23212329 /// this function will fail to print the string, printing "(BigInt)" instead of a number.
23222330 /// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
23232331 /// See `toString` and `toStringAlloc` for a way to print big integers without failure.
2324 pub fn print(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
2332 pub fn formatInteger(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
23252333 const available_len = 64;
23262334 if (self.limbs.len > available_len)
23272335 return w.writeAll("(BigInt)");
......@@ -2337,20 +2345,6 @@ pub const Const = struct {
23372345 return w.writeAll(buf[0..len]);
23382346 }
23392347
2340 const Format = struct {
2341 int: Const,
2342 base: u8,
2343 case: std.fmt.Case,
2344
2345 pub fn default(f: Format, w: *std.io.Writer) std.io.Writer.Error!void {
2346 return print(f.int, w, f.base, f.case);
2347 }
2348 };
2349
2350 pub fn fmt(self: Const, base: u8, case: std.fmt.Case) std.fmt.Formatter(Format, Format.default) {
2351 return .{ .data = .{ .int = self, .base = base, .case = case } };
2352 }
2353
23542348 /// Converts self to a string in the requested base.
23552349 /// Caller owns returned memory.
23562350 /// Asserts that `base` is in the range [2, 36].
......@@ -2918,16 +2912,16 @@ pub const Managed = struct {
29182912 }
29192913
29202914 /// To allow `std.fmt.format` to work with `Managed`.
2921 pub fn format(self: Managed, w: *std.io.Writer, comptime f: []const u8) std.io.Writer.Error!void {
2922 return self.toConst().format(w, f);
2915 pub fn format(self: Managed, w: *std.io.Writer) std.io.Writer.Error!void {
2916 return formatInteger(self, w, 10, .lower);
29232917 }
29242918
29252919 /// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
29262920 /// this function will fail to print the string, printing "(BigInt)" instead of a number.
29272921 /// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
29282922 /// See `toString` and `toStringAlloc` for a way to print big integers without failure.
2929 pub fn fmt(self: Managed, base: u8, case: std.fmt.Case) std.fmt.Formatter(Const.Format, Const.Format.default) {
2930 return .{ .data = .{ .int = self.toConst(), .base = base, .case = case } };
2923 pub fn formatInteger(self: Managed, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
2924 return self.toConst().formatInteger(w, base, case);
29312925 }
29322926
29332927 /// Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| ==
lib/std/math/big/int_test.zig+4-4
......@@ -3813,8 +3813,8 @@ test "(BigInt) positive" {
38133813 try a.pow(&a, 64 * @sizeOf(Limb) * 8);
38143814 try b.sub(&a, &c);
38153815
3816 try testing.expectFmt("(BigInt)", "{f}", .{a.fmt(10, .lower)});
3817 try testing.expectFmt("1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190335", "{f}", .{b.fmt(10, .lower)});
3816 try testing.expectFmt("(BigInt)", "{d}", .{a});
3817 try testing.expectFmt("1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190335", "{d}", .{b});
38183818}
38193819
38203820test "(BigInt) negative" {
......@@ -3832,10 +3832,10 @@ test "(BigInt) negative" {
38323832 a.negate();
38333833 try b.add(&a, &c);
38343834
3835 const a_fmt = try std.fmt.allocPrint(testing.allocator, "{f}", .{a.fmt(10, .lower)});
3835 const a_fmt = try std.fmt.allocPrint(testing.allocator, "{d}", .{a});
38363836 defer testing.allocator.free(a_fmt);
38373837
3838 const b_fmt = try std.fmt.allocPrint(testing.allocator, "{f}", .{b.fmt(10, .lower)});
3838 const b_fmt = try std.fmt.allocPrint(testing.allocator, "{d}", .{b});
38393839 defer testing.allocator.free(b_fmt);
38403840
38413841 try testing.expect(mem.eql(u8, a_fmt, "(BigInt)"));
lib/std/zig.zig+2-2
......@@ -475,7 +475,7 @@ pub fn stringEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!vo
475475 ' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte),
476476 else => {
477477 try w.writeAll("\\x");
478 try w.printIntOptions(byte, 16, .lower, .{ .width = 2, .fill = '0' });
478 try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' });
479479 },
480480 };
481481}
......@@ -492,7 +492,7 @@ pub fn charEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!void
492492 ' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte),
493493 else => {
494494 try w.writeAll("\\x");
495 try w.printIntOptions(byte, 16, .lower, .{ .width = 2, .fill = '0' });
495 try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' });
496496 },
497497 };
498498}
lib/std/zig/llvm/Builder.zig+166-64
......@@ -246,7 +246,7 @@ pub const Type = enum(u32) {
246246 _,
247247
248248 pub const ptr_amdgpu_constant =
249 @field(Type, std.fmt.comptimePrint("ptr{f }", .{AddrSpace.amdgpu.constant}));
249 @field(Type, std.fmt.comptimePrint("ptr{f}", .{AddrSpace.amdgpu.constant.fmt(" ")}));
250250
251251 pub const Tag = enum(u4) {
252252 simple,
......@@ -779,7 +779,7 @@ pub const Type = enum(u32) {
779779 }
780780 },
781781 .integer => try w.print("i{d}", .{item.data}),
782 .pointer => try w.print("ptr{f }", .{@as(AddrSpace, @enumFromInt(item.data))}),
782 .pointer => try w.print("ptr{f}", .{@as(AddrSpace, @enumFromInt(item.data)).fmt(" ")}),
783783 .target => {
784784 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
785785 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
......@@ -1242,7 +1242,7 @@ pub const Attribute = union(Kind) {
12421242 .sret,
12431243 .elementtype,
12441244 => |ty| try w.print(" {s}({f})", .{ @tagName(attribute), ty.fmt(data.builder, .percent) }),
1245 .@"align" => |alignment| try w.print("{f }", .{alignment}),
1245 .@"align" => |alignment| try w.print("{f}", .{alignment.fmt(" ")}),
12461246 .dereferenceable,
12471247 .dereferenceable_or_null,
12481248 => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),
......@@ -1853,10 +1853,31 @@ pub const ThreadLocal = enum(u3) {
18531853 initialexec = 3,
18541854 localexec = 4,
18551855
1856 pub fn format(self: ThreadLocal, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
1857 if (self == .default) return;
1858 try w.print("{s}thread_local", .{prefix});
1859 if (self != .generaldynamic) try w.print("({s})", .{@tagName(self)});
1856 pub fn format(tl: ThreadLocal, w: *Writer) Writer.Error!void {
1857 return Prefixed.format(.{ .thread_local = tl, .prefix = "" }, w);
1858 }
1859
1860 pub const Prefixed = struct {
1861 thread_local: ThreadLocal,
1862 prefix: []const u8,
1863
1864 pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
1865 switch (p.thread_local) {
1866 .default => return,
1867 .generaldynamic => {
1868 var vecs: [2][]const u8 = .{ p.prefix, "thread_local" };
1869 return w.writeVecAll(&vecs);
1870 },
1871 else => {
1872 var vecs: [4][]const u8 = .{ p.prefix, "thread_local(", @tagName(p.thread_local), ")" };
1873 return w.writeVecAll(&vecs);
1874 },
1875 }
1876 }
1877 };
1878
1879 pub fn fmt(tl: ThreadLocal, prefix: []const u8) Prefixed {
1880 return .{ .thread_local = tl, .prefix = prefix };
18601881 }
18611882};
18621883
......@@ -1961,8 +1982,24 @@ pub const AddrSpace = enum(u24) {
19611982 pub const funcref: AddrSpace = @enumFromInt(20);
19621983 };
19631984
1964 pub fn format(self: AddrSpace, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
1965 if (self != .default) try w.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) });
1985 pub fn format(addr_space: AddrSpace, w: *Writer) Writer.Error!void {
1986 return Prefixed.format(.{ .addr_space = addr_space, .prefix = "" }, w);
1987 }
1988
1989 pub const Prefixed = struct {
1990 addr_space: AddrSpace,
1991 prefix: []const u8,
1992
1993 pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
1994 switch (p.addr_space) {
1995 .default => return,
1996 else => return w.print("{s}addrspace({d})", .{ p.prefix, p.addr_space }),
1997 }
1998 }
1999 };
2000
2001 pub fn fmt(addr_space: AddrSpace, prefix: []const u8) Prefixed {
2002 return .{ .addr_space = addr_space, .prefix = prefix };
19662003 }
19672004};
19682005
......@@ -1994,8 +2031,18 @@ pub const Alignment = enum(u6) {
19942031 return if (self == .default) 0 else (@intFromEnum(self) + 1);
19952032 }
19962033
1997 pub fn format(self: Alignment, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
1998 try w.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return });
2034 pub const Prefixed = struct {
2035 alignment: Alignment,
2036 prefix: []const u8,
2037
2038 pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
2039 const byte_units = p.alignment.toByteUnits() orelse return;
2040 return w.print("{s}align ({d})", .{ p.prefix, byte_units });
2041 }
2042 };
2043
2044 pub fn fmt(alignment: Alignment, prefix: []const u8) Prefixed {
2045 return .{ .alignment = alignment, .prefix = prefix };
19992046 }
20002047};
20012048
......@@ -6978,8 +7025,27 @@ pub const MemoryAccessKind = enum(u1) {
69787025 normal,
69797026 @"volatile",
69807027
6981 pub fn format(self: MemoryAccessKind, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
6982 if (self != .normal) try w.print("{s}{s}", .{ prefix, @tagName(self) });
7028 pub fn format(memory_access_kind: MemoryAccessKind, w: *Writer) Writer.Error!void {
7029 return Prefixed.format(.{ .memory_access_kind = memory_access_kind, .prefix = "" }, w);
7030 }
7031
7032 pub const Prefixed = struct {
7033 memory_access_kind: MemoryAccessKind,
7034 prefix: []const u8,
7035
7036 pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
7037 switch (p.memory_access_kind) {
7038 .normal => return,
7039 .@"volatile" => {
7040 var vecs: [2][]const u8 = .{ p.prefix, "volatile" };
7041 return w.writeVecAll(&vecs);
7042 },
7043 }
7044 }
7045 };
7046
7047 pub fn fmt(memory_access_kind: MemoryAccessKind, prefix: []const u8) Prefixed {
7048 return .{ .memory_access_kind = memory_access_kind, .prefix = prefix };
69837049 }
69847050};
69857051
......@@ -6987,10 +7053,27 @@ pub const SyncScope = enum(u1) {
69877053 singlethread,
69887054 system,
69897055
6990 pub fn format(self: SyncScope, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
6991 if (self != .system) try w.print(
6992 \\{s}syncscope("{s}")
6993 , .{ prefix, @tagName(self) });
7056 pub fn format(sync_scope: SyncScope, w: *Writer) Writer.Error!void {
7057 return Prefixed.format(.{ .sync_scope = sync_scope, .prefix = "" }, w);
7058 }
7059
7060 pub const Prefixed = struct {
7061 sync_scope: SyncScope,
7062 prefix: []const u8,
7063
7064 pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
7065 switch (p.sync_scope) {
7066 .system => return,
7067 .singlethread => {
7068 var vecs: [2][]const u8 = .{ p.prefix, "syncscope(\"singlethread\")" };
7069 return w.writeVecAll(&vecs);
7070 },
7071 }
7072 }
7073 };
7074
7075 pub fn fmt(sync_scope: SyncScope, prefix: []const u8) Prefixed {
7076 return .{ .sync_scope = sync_scope, .prefix = prefix };
69947077 }
69957078};
69967079
......@@ -7003,8 +7086,27 @@ pub const AtomicOrdering = enum(u3) {
70037086 acq_rel = 5,
70047087 seq_cst = 6,
70057088
7006 pub fn format(self: AtomicOrdering, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
7007 if (self != .none) try w.print("{s}{s}", .{ prefix, @tagName(self) });
7089 pub fn format(atomic_ordering: AtomicOrdering, w: *Writer) Writer.Error!void {
7090 return Prefixed.format(.{ .atomic_ordering = atomic_ordering, .prefix = "" }, w);
7091 }
7092
7093 pub const Prefixed = struct {
7094 atomic_ordering: AtomicOrdering,
7095 prefix: []const u8,
7096
7097 pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
7098 switch (p.atomic_ordering) {
7099 .none => return,
7100 else => {
7101 var vecs: [2][]const u8 = .{ p.prefix, @tagName(p.atomic_ordering) };
7102 return w.writeVecAll(&vecs);
7103 },
7104 }
7105 }
7106 };
7107
7108 pub fn fmt(atomic_ordering: AtomicOrdering, prefix: []const u8) Prefixed {
7109 return .{ .atomic_ordering = atomic_ordering, .prefix = prefix };
70087110 }
70097111};
70107112
......@@ -8550,7 +8652,7 @@ pub fn init(options: Options) Allocator.Error!Builder {
85508652 inline for (.{ 0, 4 }) |addr_space_index| {
85518653 const addr_space: AddrSpace = @enumFromInt(addr_space_index);
85528654 assert(self.ptrTypeAssumeCapacity(addr_space) ==
8553 @field(Type, std.fmt.comptimePrint("ptr{f }", .{addr_space})));
8655 @field(Type, std.fmt.comptimePrint("ptr{f}", .{addr_space.fmt(" ")})));
85548656 }
85558657 }
85568658
......@@ -9469,7 +9571,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
94699571 metadata_formatter.need_comma = true;
94709572 defer metadata_formatter.need_comma = undefined;
94719573 try w.print(
9472 \\{f} ={f}{f}{f}{f}{f }{f}{f }{f} {s} {f}{f}{f, }{f}
9574 \\{f} ={f}{f}{f}{f}{f}{f}{f}{f} {s} {f}{f}{f}{f}
94739575 \\
94749576 , .{
94759577 variable.global.fmt(self),
......@@ -9479,14 +9581,14 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
94799581 global.preemption,
94809582 global.visibility,
94819583 global.dll_storage_class,
9482 variable.thread_local,
9584 variable.thread_local.fmt(" "),
94839585 global.unnamed_addr,
9484 global.addr_space,
9586 global.addr_space.fmt(" "),
94859587 global.externally_initialized,
94869588 @tagName(variable.mutability),
94879589 global.type.fmt(self, .percent),
94889590 variable.init.fmt(self, .{ .space = true }),
9489 variable.alignment,
9591 variable.alignment.fmt(", "),
94909592 try metadata_formatter.fmt("!dbg ", global.dbg, null),
94919593 });
94929594 }
......@@ -9500,7 +9602,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
95009602 metadata_formatter.need_comma = true;
95019603 defer metadata_formatter.need_comma = undefined;
95029604 try w.print(
9503 \\{f} ={f}{f}{f}{f}{f }{f} alias {f}, {f}{f}
9605 \\{f} ={f}{f}{f}{f}{f}{f} alias {f}, {f}{f}
95049606 \\
95059607 , .{
95069608 alias.global.fmt(self),
......@@ -9508,7 +9610,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
95089610 global.preemption,
95099611 global.visibility,
95109612 global.dll_storage_class,
9511 alias.thread_local,
9613 alias.thread_local.fmt(" "),
95129614 global.unnamed_addr,
95139615 global.type.fmt(self, .percent),
95149616 alias.aliasee.fmt(self, .{ .percent = true }),
......@@ -9564,15 +9666,15 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
95649666 try w.writeAll("...");
95659667 },
95669668 }
9567 try w.print("){f}{f }", .{ global.unnamed_addr, global.addr_space });
9669 try w.print("){f}{f}", .{ global.unnamed_addr, global.addr_space.fmt(" ") });
95689670 if (function_attributes != .none) try w.print(" #{d}", .{
95699671 (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
95709672 });
95719673 {
95729674 metadata_formatter.need_comma = false;
95739675 defer metadata_formatter.need_comma = undefined;
9574 try w.print("{f }{f}", .{
9575 function.alignment,
9676 try w.print("{f}{f}", .{
9677 function.alignment.fmt(" "),
95769678 try metadata_formatter.fmt(" !dbg ", global.dbg, null),
95779679 });
95789680 }
......@@ -9709,7 +9811,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
97099811 .@"alloca inalloca",
97109812 => |tag| {
97119813 const extra = function.extraData(Function.Instruction.Alloca, instruction.data);
9712 try w.print(" %{f} = {s} {f}{f}{f, }{f, }", .{
9814 try w.print(" %{f} = {s} {f}{f}{f}{f}", .{
97139815 instruction_index.name(&function).fmt(self),
97149816 @tagName(tag),
97159817 extra.type.fmt(self, .percent),
......@@ -9720,24 +9822,24 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
97209822 .comma = true,
97219823 .percent = true,
97229824 }),
9723 extra.info.alignment,
9724 extra.info.addr_space,
9825 extra.info.alignment.fmt(", "),
9826 extra.info.addr_space.fmt(", "),
97259827 });
97269828 },
97279829 .arg => unreachable,
97289830 .atomicrmw => |tag| {
97299831 const extra =
97309832 function.extraData(Function.Instruction.AtomicRmw, instruction.data);
9731 try w.print(" %{f} = {s}{f } {s} {f}, {f}{f }{f }{f, }", .{
9833 try w.print(" %{f} = {t}{f} {t} {f}, {f}{f}{f}{f}", .{
97329834 instruction_index.name(&function).fmt(self),
9733 @tagName(tag),
9734 extra.info.access_kind,
9735 @tagName(extra.info.atomic_rmw_operation),
9835 tag,
9836 extra.info.access_kind.fmt(" "),
9837 extra.info.atomic_rmw_operation,
97369838 extra.ptr.fmt(function_index, self, .{ .percent = true }),
97379839 extra.val.fmt(function_index, self, .{ .percent = true }),
9738 extra.info.sync_scope,
9739 extra.info.success_ordering,
9740 extra.info.alignment,
9840 extra.info.sync_scope.fmt(" "),
9841 extra.info.success_ordering.fmt(" "),
9842 extra.info.alignment.fmt(", "),
97419843 });
97429844 },
97439845 .block => {
......@@ -9792,8 +9894,8 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
97929894 }),
97939895 .none => unreachable,
97949896 }
9795 try w.print("{s}{f}{f}{f} {f} {f}(", .{
9796 @tagName(tag),
9897 try w.print("{t}{f}{f}{f} {f} {f}(", .{
9898 tag,
97979899 extra.data.info.call_conv,
97989900 extra.data.attributes.ret(self).fmt(self, .{}),
97999901 extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self),
......@@ -9831,17 +9933,17 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
98319933 => |tag| {
98329934 const extra =
98339935 function.extraData(Function.Instruction.CmpXchg, instruction.data);
9834 try w.print(" %{f} = {s}{f } {f}, {f}, {f}{f }{f }{f }{f, }", .{
9936 try w.print(" %{f} = {t}{f} {f}, {f}, {f}{f}{f}{f}{f}", .{
98359937 instruction_index.name(&function).fmt(self),
9836 @tagName(tag),
9837 extra.info.access_kind,
9938 tag,
9939 extra.info.access_kind.fmt(" "),
98389940 extra.ptr.fmt(function_index, self, .{ .percent = true }),
98399941 extra.cmp.fmt(function_index, self, .{ .percent = true }),
98409942 extra.new.fmt(function_index, self, .{ .percent = true }),
9841 extra.info.sync_scope,
9842 extra.info.success_ordering,
9843 extra.info.failure_ordering,
9844 extra.info.alignment,
9943 extra.info.sync_scope.fmt(" "),
9944 extra.info.success_ordering.fmt(" "),
9945 extra.info.failure_ordering.fmt(" "),
9946 extra.info.alignment.fmt(", "),
98459947 });
98469948 },
98479949 .extractelement => |tag| {
......@@ -9869,10 +9971,10 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
98699971 },
98709972 .fence => |tag| {
98719973 const info: MemoryAccessInfo = @bitCast(instruction.data);
9872 try w.print(" {s}{f }{f }", .{
9873 @tagName(tag),
9874 info.sync_scope,
9875 info.success_ordering,
9974 try w.print(" {t}{f}{f}", .{
9975 tag,
9976 info.sync_scope.fmt(" "),
9977 info.success_ordering.fmt(" "),
98769978 });
98779979 },
98789980 .fneg,
......@@ -9947,15 +10049,15 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
994710049 .@"load atomic",
994810050 => |tag| {
994910051 const extra = function.extraData(Function.Instruction.Load, instruction.data);
9950 try w.print(" %{f} = {s}{f } {f}, {f}{f }{f }{f, }", .{
10052 try w.print(" %{f} = {t}{f} {f}, {f}{f}{f}{f}", .{
995110053 instruction_index.name(&function).fmt(self),
9952 @tagName(tag),
9953 extra.info.access_kind,
10054 tag,
10055 extra.info.access_kind.fmt(" "),
995410056 extra.type.fmt(self, .percent),
995510057 extra.ptr.fmt(function_index, self, .{ .percent = true }),
9956 extra.info.sync_scope,
9957 extra.info.success_ordering,
9958 extra.info.alignment,
10058 extra.info.sync_scope.fmt(" "),
10059 extra.info.success_ordering.fmt(" "),
10060 extra.info.alignment.fmt(", "),
995910061 });
996010062 },
996110063 .phi,
......@@ -10015,14 +10117,14 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
1001510117 .@"store atomic",
1001610118 => |tag| {
1001710119 const extra = function.extraData(Function.Instruction.Store, instruction.data);
10018 try w.print(" {s}{f } {f}, {f}{f }{f }{f, }", .{
10019 @tagName(tag),
10020 extra.info.access_kind,
10120 try w.print(" {t}{f} {f}, {f}{f}{f}{f}", .{
10121 tag,
10122 extra.info.access_kind.fmt(" "),
1002110123 extra.val.fmt(function_index, self, .{ .percent = true }),
1002210124 extra.ptr.fmt(function_index, self, .{ .percent = true }),
10023 extra.info.sync_scope,
10024 extra.info.success_ordering,
10025 extra.info.alignment,
10125 extra.info.sync_scope.fmt(" "),
10126 extra.info.success_ordering.fmt(" "),
10127 extra.info.alignment.fmt(", "),
1002610128 });
1002710129 },
1002810130 .@"switch" => |tag| {
lib/std/zon/stringify.zig+1-1
......@@ -615,7 +615,7 @@ pub fn Serializer(Writer: type) type {
615615
616616 /// Serialize an integer.
617617 pub fn int(self: *Self, val: anytype) Writer.Error!void {
618 //try self.writer.printIntOptions(val, 10, .lower, .{});
618 //try self.writer.printInt(val, 10, .lower, .{});
619619 try std.fmt.deprecatedFormat(self.writer, "{d}", .{val});
620620 }
621621
src/Builtin.zig+2-2
......@@ -200,8 +200,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
200200 }),
201201 .windows => |windows| try buffer.print(
202202 \\ .windows = .{{
203 \\ .min = {fc},
204 \\ .max = {fc},
203 \\ .min = {f},
204 \\ .max = {f},
205205 \\ }}}},
206206 \\
207207 , .{ windows.min, windows.max }),
src/Package/Fetch.zig+6-3
......@@ -227,9 +227,9 @@ pub const JobQueue = struct {
227227 }
228228
229229 try buf.writer().print(
230 \\ pub const build_root = "{fq}";
230 \\ pub const build_root = "{f}";
231231 \\
232 , .{fetch.package_root});
232 , .{std.fmt.alt(fetch.package_root, .formatEscapeString)});
233233
234234 if (fetch.has_build_zig) {
235235 try buf.writer().print(
......@@ -1079,7 +1079,10 @@ fn initResource(f: *Fetch, uri: std.Uri, server_header_buffer: []u8) RunError!Re
10791079 });
10801080 const notes_start = try eb.reserveNotes(notes_len);
10811081 eb.extra.items[notes_start] = @intFromEnum(try eb.addErrorMessage(.{
1082 .msg = try eb.printString("try .url = \"{f;+/}#{f}\",", .{ uri, want_oid }),
1082 .msg = try eb.printString("try .url = \"{f}#{f}\",", .{
1083 uri.fmt(.{ .scheme = true, .authority = true, .path = true }),
1084 want_oid,
1085 }),
10831086 }));
10841087 return error.FetchFailed;
10851088 }
src/Package/Fetch/git.zig+24-8
......@@ -662,13 +662,21 @@ pub const Session = struct {
662662 fn init(allocator: Allocator, uri: std.Uri) !Location {
663663 const scheme = try allocator.dupe(u8, uri.scheme);
664664 errdefer allocator.free(scheme);
665 const user = if (uri.user) |user| try std.fmt.allocPrint(allocator, "{fuser}", .{user}) else null;
665 const user = if (uri.user) |user| try std.fmt.allocPrint(allocator, "{f}", .{
666 std.fmt.alt(user, .formatUser),
667 }) else null;
666668 errdefer if (user) |s| allocator.free(s);
667 const password = if (uri.password) |password| try std.fmt.allocPrint(allocator, "{fpassword}", .{password}) else null;
669 const password = if (uri.password) |password| try std.fmt.allocPrint(allocator, "{f}", .{
670 std.fmt.alt(password, .formatPassword),
671 }) else null;
668672 errdefer if (password) |s| allocator.free(s);
669 const host = if (uri.host) |host| try std.fmt.allocPrint(allocator, "{fhost}", .{host}) else null;
673 const host = if (uri.host) |host| try std.fmt.allocPrint(allocator, "{f}", .{
674 std.fmt.alt(host, .formatHost),
675 }) else null;
670676 errdefer if (host) |s| allocator.free(s);
671 const path = try std.fmt.allocPrint(allocator, "{fpath}", .{uri.path});
677 const path = try std.fmt.allocPrint(allocator, "{f}", .{
678 std.fmt.alt(uri.path, .formatPath),
679 });
672680 errdefer allocator.free(path);
673681 // The query and fragment are not used as part of the base server URI.
674682 return .{
......@@ -699,7 +707,9 @@ pub const Session = struct {
699707 fn getCapabilities(session: *Session, http_headers_buffer: []u8) !CapabilityIterator {
700708 var info_refs_uri = session.location.uri;
701709 {
702 const session_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{session.location.uri.path});
710 const session_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
711 std.fmt.alt(session.location.uri.path, .formatPath),
712 });
703713 defer session.allocator.free(session_uri_path);
704714 info_refs_uri.path = .{ .percent_encoded = try std.fs.path.resolvePosix(session.allocator, &.{ "/", session_uri_path, "info/refs" }) };
705715 }
......@@ -723,7 +733,9 @@ pub const Session = struct {
723733 if (request.response.status != .ok) return error.ProtocolError;
724734 const any_redirects_occurred = request.redirect_behavior.remaining() < max_redirects;
725735 if (any_redirects_occurred) {
726 const request_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{request.uri.path});
736 const request_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
737 std.fmt.alt(request.uri.path, .formatPath),
738 });
727739 defer session.allocator.free(request_uri_path);
728740 if (!mem.endsWith(u8, request_uri_path, "/info/refs")) return error.UnparseableRedirect;
729741 var new_uri = request.uri;
......@@ -810,7 +822,9 @@ pub const Session = struct {
810822 pub fn listRefs(session: Session, options: ListRefsOptions) !RefIterator {
811823 var upload_pack_uri = session.location.uri;
812824 {
813 const session_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{session.location.uri.path});
825 const session_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
826 std.fmt.alt(session.location.uri.path, .formatPath),
827 });
814828 defer session.allocator.free(session_uri_path);
815829 upload_pack_uri.path = .{ .percent_encoded = try std.fs.path.resolvePosix(session.allocator, &.{ "/", session_uri_path, "git-upload-pack" }) };
816830 }
......@@ -925,7 +939,9 @@ pub const Session = struct {
925939 ) !FetchStream {
926940 var upload_pack_uri = session.location.uri;
927941 {
928 const session_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{session.location.uri.path});
942 const session_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
943 std.fmt.alt(session.location.uri.path, .formatPath),
944 });
929945 defer session.allocator.free(session_uri_path);
930946 upload_pack_uri.path = .{ .percent_encoded = try std.fs.path.resolvePosix(session.allocator, &.{ "/", session_uri_path, "git-upload-pack" }) };
931947 }
src/Sema/LowerZon.zig+1-1
......@@ -492,7 +492,7 @@ fn lowerInt(
492492 if (!val.fitsInTwosComp(int_info.signedness, int_info.bits)) {
493493 return self.fail(
494494 node,
495 "type '{f}' cannot represent integer value '{f}'",
495 "type '{f}' cannot represent integer value '{d}'",
496496 .{ res_ty.fmt(self.sema.pt), val },
497497 );
498498 }
src/arch/riscv64/CodeGen.zig+2-2
......@@ -1151,7 +1151,7 @@ fn gen(func: *Func) !void {
11511151 func.ret_mcv.long.address().offset(-func.ret_mcv.short.indirect.off),
11521152 );
11531153 func.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
1154 tracking_log.debug("spill {} to {f}", .{ func.ret_mcv.long, frame_index });
1154 tracking_log.debug("spill {} to {}", .{ func.ret_mcv.long, frame_index });
11551155 },
11561156 else => unreachable,
11571157 }
......@@ -1987,7 +1987,7 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex {
19871987 }
19881988 const frame_index: FrameIndex = @enumFromInt(func.frame_allocs.len);
19891989 try func.frame_allocs.append(func.gpa, alloc);
1990 log.debug("allocated frame {f}", .{frame_index});
1990 log.debug("allocated frame {}", .{frame_index});
19911991 return frame_index;
19921992}
19931993
src/arch/riscv64/bits.zig+6
......@@ -249,6 +249,12 @@ pub const FrameIndex = enum(u32) {
249249 spill_frame,
250250 /// Other indices are used for local variable stack slots
251251 _,
252
253 pub const named_count = @typeInfo(FrameIndex).@"enum".fields.len;
254
255 pub fn isNamed(fi: FrameIndex) bool {
256 return @intFromEnum(fi) < named_count;
257 }
252258};
253259
254260/// A linker symbol not yet allocated in VM.
src/arch/x86_64/CodeGen.zig+27-27
......@@ -525,47 +525,47 @@ pub const MCValue = union(enum) {
525525 };
526526 }
527527
528 pub fn format(mcv: MCValue, bw: *Writer) Writer.Error!void {
528 pub fn format(mcv: MCValue, w: *Writer) Writer.Error!void {
529529 switch (mcv) {
530 .none, .unreach, .dead, .undef => try bw.print("({s})", .{@tagName(mcv)}),
531 .immediate => |pl| try bw.print("0x{x}", .{pl}),
532 .memory => |pl| try bw.print("[ds:0x{x}]", .{pl}),
533 inline .eflags, .register => |pl| try bw.print("{s}", .{@tagName(pl)}),
534 .register_pair => |pl| try bw.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
535 .register_triple => |pl| try bw.print("{s}:{s}:{s}", .{
530 .none, .unreach, .dead, .undef => try w.print("({s})", .{@tagName(mcv)}),
531 .immediate => |pl| try w.print("0x{x}", .{pl}),
532 .memory => |pl| try w.print("[ds:0x{x}]", .{pl}),
533 inline .eflags, .register => |pl| try w.print("{s}", .{@tagName(pl)}),
534 .register_pair => |pl| try w.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
535 .register_triple => |pl| try w.print("{s}:{s}:{s}", .{
536536 @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
537537 }),
538 .register_quadruple => |pl| try bw.print("{s}:{s}:{s}:{s}", .{
538 .register_quadruple => |pl| try w.print("{s}:{s}:{s}:{s}", .{
539539 @tagName(pl[3]), @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
540540 }),
541 .register_offset => |pl| try bw.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
542 .register_overflow => |pl| try bw.print("{s}:{s}", .{
541 .register_offset => |pl| try w.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
542 .register_overflow => |pl| try w.print("{s}:{s}", .{
543543 @tagName(pl.eflags),
544544 @tagName(pl.reg),
545545 }),
546 .register_mask => |pl| try bw.print("mask({s},{f}):{c}{s}", .{
546 .register_mask => |pl| try w.print("mask({s},{f}):{c}{s}", .{
547547 @tagName(pl.info.kind),
548548 pl.info.scalar,
549549 @as(u8, if (pl.info.inverted) '!' else ' '),
550550 @tagName(pl.reg),
551551 }),
552 .indirect => |pl| try bw.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
553 .indirect_load_frame => |pl| try bw.print("[[{f} + 0x{x}]]", .{ pl.index, pl.off }),
554 .load_frame => |pl| try bw.print("[{f} + 0x{x}]", .{ pl.index, pl.off }),
555 .lea_frame => |pl| try bw.print("{f} + 0x{x}", .{ pl.index, pl.off }),
556 .load_nav => |pl| try bw.print("[nav:{d}]", .{@intFromEnum(pl)}),
557 .lea_nav => |pl| try bw.print("nav:{d}", .{@intFromEnum(pl)}),
558 .load_uav => |pl| try bw.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
559 .lea_uav => |pl| try bw.print("uav:{d}", .{@intFromEnum(pl.val)}),
560 .load_lazy_sym => |pl| try bw.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
561 .lea_lazy_sym => |pl| try bw.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
562 .load_extern_func => |pl| try bw.print("[extern:{d}]", .{@intFromEnum(pl)}),
563 .lea_extern_func => |pl| try bw.print("extern:{d}", .{@intFromEnum(pl)}),
564 .elementwise_args => |pl| try bw.print("elementwise:{d}:[{f} + 0x{x}]", .{
552 .indirect => |pl| try w.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
553 .indirect_load_frame => |pl| try w.print("[[{} + 0x{x}]]", .{ pl.index, pl.off }),
554 .load_frame => |pl| try w.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
555 .lea_frame => |pl| try w.print("{} + 0x{x}", .{ pl.index, pl.off }),
556 .load_nav => |pl| try w.print("[nav:{d}]", .{@intFromEnum(pl)}),
557 .lea_nav => |pl| try w.print("nav:{d}", .{@intFromEnum(pl)}),
558 .load_uav => |pl| try w.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
559 .lea_uav => |pl| try w.print("uav:{d}", .{@intFromEnum(pl.val)}),
560 .load_lazy_sym => |pl| try w.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
561 .lea_lazy_sym => |pl| try w.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
562 .load_extern_func => |pl| try w.print("[extern:{d}]", .{@intFromEnum(pl)}),
563 .lea_extern_func => |pl| try w.print("extern:{d}", .{@intFromEnum(pl)}),
564 .elementwise_args => |pl| try w.print("elementwise:{d}:[{} + 0x{x}]", .{
565565 pl.regs, pl.frame_index, pl.frame_off,
566566 }),
567 .reserved_frame => |pl| try bw.print("(dead:{f})", .{pl}),
568 .air_ref => |pl| try bw.print("(air:0x{x})", .{@intFromEnum(pl)}),
567 .reserved_frame => |pl| try w.print("(dead:{})", .{pl}),
568 .air_ref => |pl| try w.print("(air:0x{x})", .{@intFromEnum(pl)}),
569569 }
570570 }
571571};
......@@ -2026,7 +2026,7 @@ fn gen(
20262026 .{},
20272027 );
20282028 self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
2029 tracking_log.debug("spill {f} to {f}", .{ self.ret_mcv.long, frame_index });
2029 tracking_log.debug("spill {f} to {}", .{ self.ret_mcv.long, frame_index });
20302030 },
20312031 else => unreachable,
20322032 }
src/arch/x86_64/bits.zig+6
......@@ -721,6 +721,12 @@ pub const FrameIndex = enum(u32) {
721721 call_frame,
722722 // Other indices are used for local variable stack slots
723723 _,
724
725 pub const named_count = @typeInfo(FrameIndex).@"enum".fields.len;
726
727 pub fn isNamed(fi: FrameIndex) bool {
728 return @intFromEnum(fi) < named_count;
729 }
724730};
725731
726732pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
src/arch/x86_64/encoder.zig+1-1
......@@ -259,7 +259,7 @@ pub const Instruction = struct {
259259 switch (sib.base) {
260260 .none => any = false,
261261 .reg => |reg| try w.print("{s}", .{@tagName(reg)}),
262 .frame => |frame_index| try w.print("{f}", .{frame_index}),
262 .frame => |frame_index| try w.print("{}", .{frame_index}),
263263 .table => try w.print("Table", .{}),
264264 .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),
265265 .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}),
src/link.zig+8-6
......@@ -838,8 +838,10 @@ pub const File = struct {
838838 const cached_pp_file_path = the_key.status.success.object_path;
839839 cached_pp_file_path.root_dir.handle.copyFile(cached_pp_file_path.sub_path, emit.root_dir.handle, emit.sub_path, .{}) catch |err| {
840840 const diags = &base.comp.link_diags;
841 return diags.fail("failed to copy '{f'}' to '{f'}': {s}", .{
842 @as(Path, cached_pp_file_path), @as(Path, emit), @errorName(err),
841 return diags.fail("failed to copy '{f}' to '{f}': {s}", .{
842 std.fmt.alt(@as(Path, cached_pp_file_path), .formatEscapeChar),
843 std.fmt.alt(@as(Path, emit), .formatEscapeChar),
844 @errorName(err),
843845 });
844846 };
845847 return;
......@@ -2086,14 +2088,14 @@ fn resolvePathInputLib(
20862088 }) {
20872089 var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
20882090 error.FileNotFound => return .no_match,
2089 else => |e| fatal("unable to search for {s} library '{f'}': {s}", .{
2090 @tagName(link_mode), test_path, @errorName(e),
2091 else => |e| fatal("unable to search for {s} library '{f}': {s}", .{
2092 @tagName(link_mode), std.fmt.alt(test_path, .formatEscapeChar), @errorName(e),
20912093 }),
20922094 };
20932095 errdefer file.close();
20942096 try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len));
2095 const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f'}': {s}", .{
2096 test_path, @errorName(err),
2097 const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f}': {s}", .{
2098 std.fmt.alt(test_path, .formatEscapeChar), @errorName(err),
20972099 });
20982100 const buf = ld_script_bytes.items[0..n];
20992101 if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) {
src/link/C.zig+2-2
......@@ -503,8 +503,8 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P
503503 var fw = file.writer(&.{});
504504 var w = &fw.interface;
505505 w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {
506 error.WriteFailed => return diags.fail("failed to write to '{f'}': {s}", .{
507 self.base.emit, @errorName(fw.err.?),
506 error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{
507 std.fmt.alt(self.base.emit, .formatEscapeChar), @errorName(fw.err.?),
508508 }),
509509 };
510510}
src/main.zig+3-1
......@@ -6964,7 +6964,9 @@ fn cmdFetch(
69646964 std.log.info("resolved ref '{s}' to commit {s}", .{ target_ref, latest_commit_hex });
69656965
69666966 // include the original refspec in a query parameter, could be used to check for updates
6967 uri.query = .{ .percent_encoded = try std.fmt.allocPrint(arena, "ref={f%}", .{fragment}) };
6967 uri.query = .{ .percent_encoded = try std.fmt.allocPrint(arena, "ref={f}", .{
6968 std.fmt.alt(fragment, .formatEscaped),
6969 }) };
69686970 } else {
69696971 std.log.info("resolved to commit {s}", .{latest_commit_hex});
69706972 }
src/print_value.zig+1-1
......@@ -77,7 +77,7 @@ pub fn print(
7777 .func => |func| try writer.print("(function '{f}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}),
7878 .int => |int| switch (int.storage) {
7979 inline .u64, .i64 => |x| try writer.print("{d}", .{x}),
80 .big_int => |x| try writer.print("{fd}", .{x}),
80 .big_int => |x| try writer.print("{d}", .{x}),
8181 .lazy_align => |ty| if (opt_sema != null) {
8282 const a = try Type.fromInterned(ty).abiAlignmentSema(pt);
8383 try writer.print("{d}", .{a.toByteUnits() orelse 0});