Commit 1d763c8b29

Andrew Kelley <andrew@ziglang.org>
2025-06-30 19:15:22
std: formatted printing no longer prints type names
for structs, enums, and unions. auto untagged unions are no longer printed as pointers; instead they are printed as "{ ... }". extern and packed untagged unions have each field printed, similar to what gdb does. also fix bugs in delimiter based reading
1 parent 7eae26d
Changed files (4)
lib/std/io/Reader.zig
@@ -36,7 +36,10 @@ pub const VTable = struct {
     /// sizes combined with short reads (returning a value less than `limit`)
     /// in order to minimize complexity.
     ///
-    /// This function is always called when `buffer` is empty.
+    /// Although this function is usually called when `buffer` is empty, it is
+    /// also called when it needs to be filled more due to the API user
+    /// requesting contiguous memory. In either case, the existing buffer data
+    /// should be ignored; new data written to `w`.
     stream: *const fn (r: *Reader, w: *Writer, limit: Limit) StreamError!usize,
 
     /// Consumes bytes from the internally tracked stream position without
@@ -194,7 +197,7 @@ pub fn streamRemaining(r: *Reader, w: *Writer) StreamRemainingError!usize {
 /// Consumes the stream until the end, ignoring all the data, returning the
 /// number of bytes discarded.
 pub fn discardRemaining(r: *Reader) ShortError!usize {
-    var offset: usize = r.end;
+    var offset: usize = r.end - r.seek;
     r.seek = 0;
     r.end = 0;
     while (true) {
@@ -693,6 +696,17 @@ pub fn takeSentinel(r: *Reader, comptime sentinel: u8) DelimiterError![:sentinel
     return result;
 }
 
+/// Returns a slice of the next bytes of buffered data from the stream until
+/// `sentinel` is found, without advancing the seek position.
+///
+/// Returned slice has a sentinel; end of stream does not count as a delimiter.
+///
+/// Invalidates previously returned values from `peek`.
+///
+/// See also:
+/// * `takeSentinel`
+/// * `peekDelimiterExclusive`
+/// * `peekDelimiterInclusive`
 pub fn peekSentinel(r: *Reader, comptime sentinel: u8) DelimiterError![:sentinel]u8 {
     const result = try r.peekDelimiterInclusive(sentinel);
     return result[0 .. result.len - 1 :sentinel];
@@ -733,27 +747,37 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
         @branchHint(.likely);
         return buffer[seek .. end + 1];
     }
-    if (seek > 0) {
-        const remainder = buffer[seek..];
-        @memmove(buffer[0..remainder.len], remainder);
-        r.end = remainder.len;
-        r.seek = 0;
+    while (r.buffer.len - r.end != 0) {
+        const end_cap = r.buffer[r.end..];
+        var writer: Writer = .fixed(end_cap);
+        const n = r.vtable.stream(r, &writer, .limited(end_cap.len)) catch |err| switch (err) {
+            error.WriteFailed => unreachable,
+            else => |e| return e,
+        };
+        r.end += n;
+        if (std.mem.indexOfScalarPos(u8, end_cap[0..n], 0, delimiter)) |end| {
+            return r.buffer[seek .. r.end - n + end + 1];
+        }
     }
-    var writer: Writer = .{
-        .buffer = r.buffer,
-        .vtable = &.{ .drain = Writer.fixedDrain },
-    };
-    while (r.end < r.buffer.len) {
-        writer.end = r.end;
-        const n = r.vtable.stream(r, &writer, .limited(r.buffer.len - r.end)) catch |err| switch (err) {
+    var i: usize = 0;
+    while (seek - i != 0) {
+        const begin_cap = r.buffer[i..seek];
+        var writer: Writer = .fixed(begin_cap);
+        const n = r.vtable.stream(r, &writer, .limited(begin_cap.len)) catch |err| switch (err) {
             error.WriteFailed => unreachable,
             else => |e| return e,
         };
-        const prev_end = r.end;
-        r.end = prev_end + n;
-        if (std.mem.indexOfScalarPos(u8, r.buffer[0..r.end], prev_end, delimiter)) |end| {
-            return r.buffer[0 .. end + 1];
+        i += n;
+        if (std.mem.indexOfScalarPos(u8, r.buffer[0..seek], i, delimiter)) |end| {
+            std.mem.rotate(u8, r.buffer, seek);
+            r.seek = 0;
+            r.end += i;
+            return r.buffer[0 .. seek + end + 1];
         }
+    } else if (i != 0) {
+        std.mem.rotate(u8, r.buffer, seek);
+        r.seek = 0;
+        r.end += i;
     }
     return error.StreamTooLong;
 }
@@ -778,9 +802,10 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
 pub fn takeDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
     const result = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) {
         error.EndOfStream => {
-            if (r.end == 0) return error.EndOfStream;
-            r.toss(r.end);
-            return r.buffer[0..r.end];
+            const remaining = r.buffer[r.seek..r.end];
+            if (remaining.len == 0) return error.EndOfStream;
+            r.toss(remaining.len);
+            return remaining;
         },
         else => |e| return e,
     };
@@ -808,8 +833,10 @@ pub fn takeDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
 pub fn peekDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 {
     const result = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) {
         error.EndOfStream => {
-            if (r.end == 0) return error.EndOfStream;
-            return r.buffer[0..r.end];
+            const remaining = r.buffer[r.seek..r.end];
+            if (remaining.len == 0) return error.EndOfStream;
+            r.toss(remaining.len);
+            return remaining;
         },
         else => |e| return e,
     };
@@ -1219,27 +1246,38 @@ test fixed {
 }
 
 test peek {
-    return error.Unimplemented;
+    var r: Reader = .fixed("abc");
+    try testing.expectEqualStrings("ab", try r.peek(2));
+    try testing.expectEqualStrings("a", try r.peek(1));
 }
 
 test peekGreedy {
-    return error.Unimplemented;
+    var r: Reader = .fixed("abc");
+    try testing.expectEqualStrings("abc", try r.peekGreedy(1));
 }
 
 test toss {
-    return error.Unimplemented;
+    var r: Reader = .fixed("abc");
+    r.toss(1);
+    try testing.expectEqualStrings("bc", r.buffered());
 }
 
 test take {
-    return error.Unimplemented;
+    var r: Reader = .fixed("abc");
+    try testing.expectEqualStrings("ab", try r.take(2));
+    try testing.expectEqualStrings("c", try r.take(1));
 }
 
 test takeArray {
-    return error.Unimplemented;
+    var r: Reader = .fixed("abc");
+    try testing.expectEqualStrings("ab", try r.takeArray(2));
+    try testing.expectEqualStrings("c", try r.takeArray(1));
 }
 
 test peekArray {
-    return error.Unimplemented;
+    var r: Reader = .fixed("abc");
+    try testing.expectEqualStrings("ab", try r.peekArray(2));
+    try testing.expectEqualStrings("a", try r.peekArray(1));
 }
 
 test discardAll {
@@ -1251,35 +1289,63 @@ test discardAll {
 }
 
 test discardRemaining {
-    return error.Unimplemented;
+    var r: Reader = .fixed("foobar");
+    r.toss(1);
+    try testing.expectEqual(5, try r.discardRemaining());
+    try testing.expectEqual(0, try r.discardRemaining());
 }
 
 test stream {
-    return error.Unimplemented;
+    var out_buffer: [10]u8 = undefined;
+    var r: Reader = .fixed("foobar");
+    var w: Writer = .fixed(&out_buffer);
+    // Short streams are possible with this function but not with fixed.
+    try testing.expectEqual(2, try r.stream(&w, .limited(2)));
+    try testing.expectEqualStrings("fo", w.buffered());
+    try testing.expectEqual(4, try r.stream(&w, .unlimited));
+    try testing.expectEqualStrings("foobar", w.buffered());
 }
 
 test takeSentinel {
-    return error.Unimplemented;
+    var r: Reader = .fixed("ab\nc");
+    try testing.expectEqualStrings("ab", try r.takeSentinel('\n'));
+    try testing.expectError(error.EndOfStream, r.takeSentinel('\n'));
+    try testing.expectEqualStrings("c", try r.peek(1));
 }
 
 test peekSentinel {
-    return error.Unimplemented;
+    var r: Reader = .fixed("ab\nc");
+    try testing.expectEqualStrings("ab", try r.peekSentinel('\n'));
+    try testing.expectEqualStrings("ab", try r.peekSentinel('\n'));
 }
 
 test takeDelimiterInclusive {
-    return error.Unimplemented;
+    var r: Reader = .fixed("ab\nc");
+    try testing.expectEqualStrings("ab\n", try r.takeDelimiterInclusive('\n'));
+    try testing.expectError(error.EndOfStream, r.takeDelimiterInclusive('\n'));
 }
 
 test peekDelimiterInclusive {
-    return error.Unimplemented;
+    var r: Reader = .fixed("ab\nc");
+    try testing.expectEqualStrings("ab\n", try r.peekDelimiterInclusive('\n'));
+    try testing.expectEqualStrings("ab\n", try r.peekDelimiterInclusive('\n'));
+    r.toss(3);
+    try testing.expectError(error.EndOfStream, r.peekDelimiterInclusive('\n'));
 }
 
 test takeDelimiterExclusive {
-    return error.Unimplemented;
+    var r: Reader = .fixed("ab\nc");
+    try testing.expectEqualStrings("ab", try r.takeDelimiterExclusive('\n'));
+    try testing.expectEqualStrings("c", try r.takeDelimiterExclusive('\n'));
+    try testing.expectError(error.EndOfStream, r.takeDelimiterExclusive('\n'));
 }
 
 test peekDelimiterExclusive {
-    return error.Unimplemented;
+    var r: Reader = .fixed("ab\nc");
+    try testing.expectEqualStrings("ab", try r.peekDelimiterExclusive('\n'));
+    try testing.expectEqualStrings("ab", try r.peekDelimiterExclusive('\n'));
+    r.toss(3);
+    try testing.expectEqualStrings("c", try r.peekDelimiterExclusive('\n'));
 }
 
 test readDelimiter {
@@ -1339,7 +1405,11 @@ test peekStructEndian {
 }
 
 test takeEnum {
-    return error.Unimplemented;
+    var r: Reader = .fixed(&.{ 2, 0, 1 });
+    const E1 = enum(u8) { a, b, c };
+    const E2 = enum(u16) { _ };
+    try testing.expectEqual(E1.c, try r.takeEnum(E1, .little));
+    try testing.expectEqual(@as(E2, @enumFromInt(0x0001)), try r.takeEnum(E2, .big));
 }
 
 test takeLeb128 {
lib/std/io/Writer.zig
@@ -866,35 +866,31 @@ pub fn printValue(
             }
             const enum_info = @typeInfo(T).@"enum";
             if (enum_info.is_exhaustive) {
-                var vecs: [3][]const u8 = .{ @typeName(T), ".", @tagName(value) };
+                var vecs: [2][]const u8 = .{ ".", @tagName(value) };
                 try w.writeVecAll(&vecs);
                 return;
             }
-            try w.writeAll(@typeName(T));
-            @setEvalBranchQuota(3 * enum_info.fields.len);
-            inline for (enum_info.fields) |field| {
-                if (@intFromEnum(value) == field.value) {
-                    try w.writeAll(".");
-                    try w.writeAll(@tagName(value));
-                    return;
-                }
+            if (std.enums.tagName(T, value)) |tag_name| {
+                var vecs: [2][]const u8 = .{ ".", tag_name };
+                try w.writeVecAll(&vecs);
+                return;
             }
-            try w.writeByte('(');
+            try w.writeAll("@enumFromInt(");
             try w.printValue(ANY, options, @intFromEnum(value), max_depth);
             try w.writeByte(')');
+            return;
         },
         .@"union" => |info| {
             if (!is_any) {
                 if (fmt.len != 0) invalidFmtError(fmt, value);
                 return printValue(w, ANY, options, value, max_depth);
             }
-            try w.writeAll(@typeName(T));
             if (max_depth == 0) {
-                try w.writeAll("{ ... }");
+                try w.writeAll(".{ ... }");
                 return;
             }
             if (info.tag_type) |UnionTagType| {
-                try w.writeAll("{ .");
+                try w.writeAll(".{ .");
                 try w.writeAll(@tagName(@as(UnionTagType, value)));
                 try w.writeAll(" = ");
                 inline for (info.fields) |u_field| {
@@ -903,9 +899,22 @@ pub fn printValue(
                     }
                 }
                 try w.writeAll(" }");
-            } else {
-                try w.writeByte('@');
-                try w.printIntOptions(@intFromPtr(&value), 16, .lower, options);
+            } else switch (info.layout) {
+                .auto => {
+                    return w.writeAll(".{ ... }");
+                },
+                .@"extern", .@"packed" => {
+                    if (info.fields.len == 0) return w.writeAll(".{}");
+                    try w.writeAll(".{ ");
+                    inline for (info.fields) |field| {
+                        try w.writeByte('.');
+                        try w.writeAll(field.name);
+                        try w.writeAll(" = ");
+                        try w.printValue(ANY, options, @field(value, field.name), max_depth - 1);
+                        (try w.writableArray(2)).* = ", ".*;
+                    }
+                    w.buffer[w.end - 2 ..][0..2].* = " }".*;
+                },
             }
         },
         .@"struct" => |info| {
@@ -916,10 +925,10 @@ pub fn printValue(
             if (info.is_tuple) {
                 // Skip the type and field names when formatting tuples.
                 if (max_depth == 0) {
-                    try w.writeAll("{ ... }");
+                    try w.writeAll(".{ ... }");
                     return;
                 }
-                try w.writeAll("{");
+                try w.writeAll(".{");
                 inline for (info.fields, 0..) |f, i| {
                     if (i == 0) {
                         try w.writeAll(" ");
@@ -931,12 +940,11 @@ pub fn printValue(
                 try w.writeAll(" }");
                 return;
             }
-            try w.writeAll(@typeName(T));
             if (max_depth == 0) {
-                try w.writeAll("{ ... }");
+                try w.writeAll(".{ ... }");
                 return;
             }
-            try w.writeAll("{");
+            try w.writeAll(".{");
             inline for (info.fields, 0..) |f, i| {
                 if (i == 0) {
                     try w.writeAll(" .");
@@ -1550,7 +1558,7 @@ fn writeMultipleOf7Leb128(w: *Writer, value: anytype) Error!void {
     }
 }
 
-test "formatValue max_depth" {
+test "printValue max_depth" {
     const Vec2 = struct {
         const SelfType = @This();
         x: f32,
@@ -1595,19 +1603,19 @@ test "formatValue max_depth" {
     var buf: [1000]u8 = undefined;
     var w: Writer = .fixed(&buf);
     try w.printValue("", .{}, inst, 0);
-    try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ ... }", w.buffered());
+    try testing.expectEqualStrings(".{ ... }", w.buffered());
 
     w = .fixed(&buf);
     try w.printValue("", .{}, inst, 1);
-    try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered());
+    try testing.expectEqualStrings(".{ .a = .{ ... }, .tu = .{ ... }, .e = .Two, .vec = .{ ... } }", w.buffered());
 
     w = .fixed(&buf);
     try w.printValue("", .{}, inst, 2);
-    try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered());
+    try testing.expectEqualStrings(".{ .a = .{ .a = .{ ... }, .tu = .{ ... }, .e = .Two, .vec = .{ ... } }, .tu = .{ .ptr = .{ ... } }, .e = .Two, .vec = .{ .x = 10.2, .y = 2.22 } }", w.buffered());
 
     w = .fixed(&buf);
     try w.printValue("", .{}, inst, 3);
-    try testing.expectEqualStrings("io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ .a = io.Writer.test.printValue max_depth.S{ ... }, .tu = io.Writer.test.printValue max_depth.TU{ ... }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }, .tu = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ .ptr = io.Writer.test.printValue max_depth.TU{ ... } } }, .e = io.Writer.test.printValue max_depth.E.Two, .vec = (10.200,2.220) }", w.buffered());
+    try testing.expectEqualStrings(".{ .a = .{ .a = .{ .a = .{ ... }, .tu = .{ ... }, .e = .Two, .vec = .{ ... } }, .tu = .{ .ptr = .{ ... } }, .e = .Two, .vec = .{ .x = 10.2, .y = 2.22 } }, .tu = .{ .ptr = .{ .ptr = .{ ... } } }, .e = .Two, .vec = .{ .x = 10.2, .y = 2.22 } }", w.buffered());
 
     const vec: @Vector(4, i32) = .{ 1, 2, 3, 4 };
     w = .fixed(&buf);
lib/std/net/test.zig
@@ -5,7 +5,6 @@ const mem = std.mem;
 const testing = std.testing;
 
 test "parse and render IP addresses at comptime" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
     comptime {
         const ipv6addr = net.Address.parseIp("::1", 0) catch unreachable;
         try std.testing.expectFmt("[::1]:0", "{f}", .{ipv6addr});
@@ -21,42 +20,23 @@ test "parse and render IP addresses at comptime" {
 }
 
 test "format IPv6 address with no zero runs" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
     const addr = try std.net.Address.parseIp6("2001:db8:1:2:3:4:5:6", 0);
     try std.testing.expectFmt("[2001:db8:1:2:3:4:5:6]:0", "{f}", .{addr});
 }
 
 test "parse IPv6 addresses and check compressed form" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
-
-    const alloc = testing.allocator;
-
-    // 1) Parse an IPv6 address that should compress to [2001:db8::1:0:0:2]:0
-    const addr1 = try std.net.Address.parseIp6("2001:0db8:0000:0000:0001:0000:0000:0002", 0);
-
-    // 2) Parse an IPv6 address that should compress to [2001:db8::1:2]:0
-    const addr2 = try std.net.Address.parseIp6("2001:0db8:0000:0000:0000:0000:0001:0002", 0);
-
-    // 3) Parse an IPv6 address that should compress to [2001:db8:1:0:1::2]:0
-    const addr3 = try std.net.Address.parseIp6("2001:0db8:0001:0000:0001:0000:0000:0002", 0);
-
-    // Print each address in Zig's default "[ipv6]:port" form.
-    const printed1 = try std.fmt.allocPrint(alloc, "{any}", .{addr1});
-    defer testing.allocator.free(printed1);
-    const printed2 = try std.fmt.allocPrint(alloc, "{any}", .{addr2});
-    defer testing.allocator.free(printed2);
-    const printed3 = try std.fmt.allocPrint(alloc, "{any}", .{addr3});
-    defer testing.allocator.free(printed3);
-
-    // Check the exact compressed forms we expect.
-    try std.testing.expectEqualStrings("[2001:db8::1:0:0:2]:0", printed1);
-    try std.testing.expectEqualStrings("[2001:db8::1:2]:0", printed2);
-    try std.testing.expectEqualStrings("[2001:db8:1:0:1::2]:0", printed3);
+    try std.testing.expectFmt("[2001:db8::1:0:0:2]:0", "{f}", .{
+        try std.net.Address.parseIp6("2001:0db8:0000:0000:0001:0000:0000:0002", 0),
+    });
+    try std.testing.expectFmt("[2001:db8::1:2]:0", "{f}", .{
+        try std.net.Address.parseIp6("2001:0db8:0000:0000:0000:0000:0001:0002", 0),
+    });
+    try std.testing.expectFmt("[2001:db8:1:0:1::2]:0", "{f}", .{
+        try std.net.Address.parseIp6("2001:0db8:0001:0000:0001:0000:0000:0002", 0),
+    });
 }
 
 test "parse IPv6 address, check raw bytes" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
-
     const expected_raw: [16]u8 = .{
         0x20, 0x01, 0x0d, 0xb8, // 2001:db8
         0x00, 0x00, 0x00, 0x00, // :0000:0000
@@ -71,8 +51,6 @@ test "parse IPv6 address, check raw bytes" {
 }
 
 test "parse and render IPv6 addresses" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
-
     var buffer: [100]u8 = undefined;
     const ips = [_][]const u8{
         "FF01:0:0:0:0:0:0:FB",
@@ -137,8 +115,6 @@ test "invalid but parseable IPv6 scope ids" {
 }
 
 test "parse and render IPv4 addresses" {
-    if (builtin.os.tag == .wasi) return error.SkipZigTest;
-
     var buffer: [18]u8 = undefined;
     for ([_][]const u8{
         "0.0.0.0",
lib/std/fmt.zig
@@ -996,7 +996,7 @@ test "slice" {
             x: u8,
         };
         const struct_slice: []const S1 = &[_]S1{ S1{ .x = 8 }, S1{ .x = 42 } };
-        try expectFmt("slice: { fmt.test.slice.S1{ .x = 8 }, fmt.test.slice.S1{ .x = 42 } }", "slice: {any}", .{struct_slice});
+        try expectFmt("slice: { .{ .x = 8 }, .{ .x = 42 } }", "slice: {any}", .{struct_slice});
     }
     {
         const S2 = struct {
@@ -1007,7 +1007,7 @@ test "slice" {
             }
         };
         const struct_slice: []const S2 = &[_]S2{ S2{ .x = 8 }, S2{ .x = 42 } };
-        try expectFmt("slice: { fmt.test.slice.S2{ .x = 8 }, fmt.test.slice.S2{ .x = 42 } }", "slice: {any}", .{struct_slice});
+        try expectFmt("slice: { .{ .x = 8 }, .{ .x = 42 } }", "slice: {any}", .{struct_slice});
     }
 }
 
@@ -1047,8 +1047,8 @@ test "struct" {
             field: u8,
         };
         const value = Struct{ .field = 42 };
-        try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{value});
-        try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
+        try expectFmt("struct: .{ .field = 42 }\n", "struct: {}\n", .{value});
+        try expectFmt("struct: .{ .field = 42 }\n", "struct: {}\n", .{&value});
     }
     {
         const Struct = struct {
@@ -1056,7 +1056,7 @@ test "struct" {
             b: u1,
         };
         const value = Struct{ .a = 0, .b = 1 };
-        try expectFmt("struct: fmt.test.struct.Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
+        try expectFmt("struct: .{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
     }
 
     const S = struct {
@@ -1069,11 +1069,11 @@ test "struct" {
         .b = error.Unused,
     };
 
-    try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
+    try expectFmt(".{ .a = 456, .b = error.Unused }", "{}", .{inst});
     // Tuples
-    try expectFmt("{ }", "{}", .{.{}});
-    try expectFmt("{ -1 }", "{}", .{.{-1}});
-    try expectFmt("{ -1, 42, 25000 }", "{}", .{.{ -1, 42, 0.25e5 }});
+    try expectFmt(".{ }", "{}", .{.{}});
+    try expectFmt(".{ -1 }", "{}", .{.{-1}});
+    try expectFmt(".{ -1, 42, 25000 }", "{}", .{.{ -1, 42, 0.25e5 }});
 }
 
 test "enum" {
@@ -1082,15 +1082,15 @@ test "enum" {
         Two,
     };
     const value = Enum.Two;
-    try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{value});
-    try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{&value});
-    try expectFmt("enum: fmt.test.enum.Enum.One\n", "enum: {}\n", .{Enum.One});
-    try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
+    try expectFmt("enum: .Two\n", "enum: {}\n", .{value});
+    try expectFmt("enum: .Two\n", "enum: {}\n", .{&value});
+    try expectFmt("enum: .One\n", "enum: {}\n", .{Enum.One});
+    try expectFmt("enum: .Two\n", "enum: {}\n", .{Enum.Two});
 
     // test very large enum to verify ct branch quota is large enough
     // TODO: https://github.com/ziglang/zig/issues/15609
     if (!((builtin.cpu.arch == .wasm32) and builtin.mode == .Debug)) {
-        try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
+        try expectFmt("enum: .INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
     }
 
     const E = enum {
@@ -1101,7 +1101,7 @@ test "enum" {
 
     const inst = E.Two;
 
-    try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
+    try expectFmt(".Two", "{}", .{inst});
 }
 
 test "non-exhaustive enum" {
@@ -1110,9 +1110,9 @@ test "non-exhaustive enum" {
         Two = 0xbeef,
         _,
     };
-    try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.One\n", "enum: {}\n", .{Enum.One});
-    try expectFmt("enum: fmt.test.non-exhaustive enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
-    try expectFmt("enum: fmt.test.non-exhaustive enum.Enum(4660)\n", "enum: {}\n", .{@as(Enum, @enumFromInt(0x1234))});
+    try expectFmt("enum: .One\n", "enum: {}\n", .{Enum.One});
+    try expectFmt("enum: .Two\n", "enum: {}\n", .{Enum.Two});
+    try expectFmt("enum: @enumFromInt(4660)\n", "enum: {}\n", .{@as(Enum, @enumFromInt(0x1234))});
     try expectFmt("enum: f\n", "enum: {x}\n", .{Enum.One});
     try expectFmt("enum: beef\n", "enum: {x}\n", .{Enum.Two});
     try expectFmt("enum: BEEF\n", "enum: {X}\n", .{Enum.Two});
@@ -1291,18 +1291,13 @@ test "union" {
         int: u32,
     };
 
-    const tu_inst = TU{ .int = 123 };
-    const uu_inst = UU{ .int = 456 };
-    const eu_inst = EU{ .float = 321.123 };
+    const tu_inst: TU = .{ .int = 123 };
+    const uu_inst: UU = .{ .int = 456 };
+    const eu_inst: EU = .{ .float = 321.123 };
 
-    try expectFmt("fmt.test.union.TU{ .int = 123 }", "{}", .{tu_inst});
-
-    var buf: [100]u8 = undefined;
-    const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});
-    try std.testing.expectEqualStrings("fmt.test.union.UU@", uu_result[0..18]);
-
-    const eu_result = try bufPrint(buf[0..], "{}", .{eu_inst});
-    try std.testing.expectEqualStrings("fmt.test.union.EU@", eu_result[0..18]);
+    try expectFmt(".{ .int = 123 }", "{}", .{tu_inst});
+    try expectFmt(".{ ... }", "{}", .{uu_inst});
+    try expectFmt(".{ .float = 321.123, .int = 1134596030 }", "{}", .{eu_inst});
 }
 
 test "struct.self-referential" {
@@ -1316,7 +1311,7 @@ test "struct.self-referential" {
     };
     inst.a = &inst;
 
-    try expectFmt("fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ .a = fmt.test.struct.self-referential.S{ ... } } } }", "{}", .{inst});
+    try expectFmt(".{ .a = .{ .a = .{ .a = .{ ... } } } }", "{}", .{inst});
 }
 
 test "struct.zero-size" {
@@ -1331,7 +1326,7 @@ test "struct.zero-size" {
     const a = A{};
     const b = B{ .a = a, .c = 0 };
 
-    try expectFmt("fmt.test.struct.zero-size.B{ .a = fmt.test.struct.zero-size.A{ }, .c = 0 }", "{}", .{b});
+    try expectFmt(".{ .a = .{ }, .c = 0 }", "{}", .{b});
 }
 
 /// Encodes a sequence of bytes as hexadecimal digits.