aboutsummaryrefslogtreecommitdiff
path: root/lib/std/meta.zig
diff options
context:
space:
mode:
authorChadwain Holness <39384757+chadwain@users.noreply.github.com>2024-02-03 16:47:55 -0500
committerGitHub <noreply@github.com>2024-02-03 21:47:55 +0000
commit60308550978be821515323256af17e0b8a610b1c (patch)
tree20250d90d9eda8f0279fb751829cbc868d99d6d6 /lib/std/meta.zig
parent122387943bf1d00c85aba77f37c93072e43140c9 (diff)
downloadzig-60308550978be821515323256af17e0b8a610b1c.tar.gz
zig-60308550978be821515323256af17e0b8a610b1c.zip
std.fmt: fix formatting slices of structs with custom formatting
`hasMethod` doesn't make sense for pointers to more than one item.
Diffstat (limited to 'lib/std/meta.zig')
-rw-r--r--lib/std/meta.zig53
1 files changed, 52 insertions, 1 deletions
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index 922324c8c3..0df80359ac 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -1122,15 +1122,66 @@ pub inline fn hasFn(comptime T: type, comptime name: []const u8) bool {
return @typeInfo(@TypeOf(@field(T, name))) == .Fn;
}
+test "hasFn" {
+ const S1 = struct {
+ pub fn foo() void {}
+ };
+
+ try std.testing.expect(hasFn(S1, "foo"));
+ try std.testing.expect(!hasFn(S1, "bar"));
+ try std.testing.expect(!hasFn(*S1, "foo"));
+
+ const S2 = struct {
+ foo: fn () void,
+ };
+
+ try std.testing.expect(!hasFn(S2, "foo"));
+}
+
/// 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),
+ .Pointer => |P| switch (P.size) {
+ .One => hasFn(P.child, name),
+ .Many, .Slice, .C => false,
+ },
else => hasFn(T, name),
};
}
+test "hasMethod" {
+ try std.testing.expect(!hasMethod(u32, "foo"));
+ try std.testing.expect(!hasMethod([]u32, "len"));
+ try std.testing.expect(!hasMethod(struct { u32, u64 }, "len"));
+
+ const S1 = struct {
+ pub fn foo() void {}
+ };
+
+ try std.testing.expect(hasMethod(S1, "foo"));
+ try std.testing.expect(hasMethod(*S1, "foo"));
+
+ try std.testing.expect(!hasMethod(S1, "bar"));
+ try std.testing.expect(!hasMethod(*[1]S1, "foo"));
+ try std.testing.expect(!hasMethod(*[10]S1, "foo"));
+ try std.testing.expect(!hasMethod([]S1, "foo"));
+
+ const S2 = struct {
+ foo: fn () void,
+ };
+
+ try std.testing.expect(!hasMethod(S2, "foo"));
+
+ const U = union {
+ pub fn foo() void {}
+ };
+
+ try std.testing.expect(hasMethod(U, "foo"));
+ try std.testing.expect(hasMethod(*U, "foo"));
+ try std.testing.expect(!hasMethod(U, "bar"));
+}
+
/// 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.