authorgravatar for 40488299+iceghost@users.noreply.github.comKhang Nguyen Duy <40488299+iceghost@users.noreply.github.com> 2023-07-09 22:18:52+07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-23 01:03:45-08:00
log993a83081a975464d1201597cf6f4cb7f6735284
tree08c07b7ad6c2d8b8e24d8e1ac2fe4ba1603b31ed
parentaef1da1634ae12d90e9d59fc0184dadaea38830c

std.fmt: fix unecessary deref on user-defined format function

When formatting a pointer to user type, currently it needs to be dereferenced first, then call `formatType` on the child type. Fix the problem by checking for "format" function on not only the type itself, but also the struct it points to. Add hasMethod to std.meta.

2 files changed, 10 insertions(+), 1 deletions(-)

lib/std/fmt.zig+1-1
...@@ -489,7 +489,7 @@ pub fn formatType(...@@ -489,7 +489,7 @@ pub fn formatType(
489 return formatAddress(value, options, writer);489 return formatAddress(value, options, writer);
490 }490 }
491491
492 if (std.meta.hasFn(T, "format")) {492 if (std.meta.hasMethod(T, "format")) {
493 return try value.format(actual_fmt, options, writer);493 return try value.format(actual_fmt, options, writer);
494 }494 }
495495
lib/std/meta.zig+9
...@@ -1129,6 +1129,15 @@ pub inline fn hasFn(comptime T: type, comptime name: []const u8) bool {...@@ -1129,6 +1129,15 @@ pub inline fn hasFn(comptime T: type, comptime name: []const u8) bool {
1129 return @typeInfo(@TypeOf(@field(T, name))) == .Fn;1129 return @typeInfo(@TypeOf(@field(T, name))) == .Fn;
1130}1130}
11311131
1132/// Returns true if a type has a `name` method; `false` otherwise.
1133/// Result is always comptime-known.
1134pub inline fn hasMethod(comptime T: type, comptime name: []const u8) bool {
1135 return switch (@typeInfo(T)) {
1136 .Pointer => |P| hasFn(P.child, name),
1137 else => hasFn(T, name),
1138 };
1139}
1140
1132/// True if every value of the type `T` has a unique bit pattern representing it.1141/// True if every value of the type `T` has a unique bit pattern representing it.
1133/// In other words, `T` has no unused bits and no padding.1142/// In other words, `T` has no unused bits and no padding.
1134/// Result is always comptime-known.1143/// Result is always comptime-known.