Std.meta.eql on types

Why does this return false?

    const A = struct {
        pub fn a(_: u32) u32 {
            return 0;
        }
    };
    const B = struct {
        pub fn a(_: u32) u32 {
            return 0;
        }
    };
    std.debug.print("\n{}\n", .{std.meta.eql(A.a, B.a)});

I want to compare two types and see if they are the same.

I think you are comparing function body values, these seem fairly opaque and don’t really seem to be intended to be inspected/manipulated, it seems to me that they are essentially opaque handles that represent the identity of a specific function at comptime (I haven’t found anything that specifically states that, but that is what they seem to be, from what I have observed).

So if that is true, it makes sense that it would return false, because they are two different functions that happen to be the same code, but still different functions.

Maybe you could instead compare the @TypeOf(A.a) and @TypeOf(B.a)?
But I think that only tells you whether they have a similar signature.

I think A and B are always different types, I don’t think there is an easy way to tell whether A and B are equivalent (apart from having their unique identities) using comptime. I think you essentially would have to compare the parsed structs or diff their internal representations in the compiler.

Do you want to find types that are duplicates, or are there subtle differences between those types you want to ignore?

1 Like

That was it. Thank you. I just want to check the signatures. Do you know if there is a way to generate a string of the signature?

You can just print or format it.

std.debug.print("{}\n", .{@TypeOf(B.a)});

Output:

fn (u32) u32
2 Likes

@typeInfo returns a Type union, since A.a is a function, @typeInfo(@TypeOf(A.a)) returns a type union with .Fn that includes the parameters and return types.

2 Likes

Is there a way to get that dynamically at comptime? Like I don’t know the name of the field or decl when writing the source, but I do know it at comptime. So I can’t do A.a, but like A.some[ ]constu8.

I think you want @field(A, some_const_u8)

No dice. That’s runtime only. I’m basically try to see if a struct passed in has the expected methods, but I want to make it generic.

I can get the fields by iterating through the field array and comparing names until I find the one I want, but apparently the declarations dont have something similar at comptime?

You can access public declarations via @typeInfo

.Struct has decls but it only contains the public declarations.

the Declation is just a name with no type info unlike the fields that have all the type information. Am I missing something?

You can use @field(Type, declname) to access the declaration.
Then use @TypeOf etc. on that.

fn has_same(comptime X: type, comptime Y: type, name: []const u8) bool {
    const x = @field(X, name);
    const y = @field(Y, name);
    return std.meta.eql(x, y);
}

produes this error

root.zig:26:25: error: unable to resolve comptime value
root.zig:26:25: note: field name must be comptime-known

edit: nvm i see the prob

I thought that since it was part of a comptime block it would be assumed comptime, but i misunderstoof that.