Skip to content

Commit

Permalink
std.fmt: fix unecessary deref on user-defined format function
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
iceghost authored and andrewrk committed Jan 23, 2024
1 parent aef1da1 commit 993a830
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/std/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ pub fn formatType(
return formatAddress(value, options, writer);
}

if (std.meta.hasFn(T, "format")) {
if (std.meta.hasMethod(T, "format")) {
return try value.format(actual_fmt, options, writer);
}

Expand Down
9 changes: 9 additions & 0 deletions lib/std/meta.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,15 @@ pub inline fn hasFn(comptime T: type, comptime name: []const u8) bool {
return @typeInfo(@TypeOf(@field(T, name))) == .Fn;
}

/// Returns true if a type has a `name` method; `false` otherwise.
/// Result is always comptime-known.
pub inline fn hasMethod(comptime T: type, comptime name: []const u8) bool {
return switch (@typeInfo(T)) {
.Pointer => |P| hasFn(P.child, name),
else => hasFn(T, name),
};
}

/// True if every value of the type `T` has a unique bit pattern representing it.
/// In other words, `T` has no unused bits and no padding.
/// Result is always comptime-known.
Expand Down

0 comments on commit 993a830

Please sign in to comment.