#How to verify if a Type has a function has correct name, param types, and return type?

1 messages · Page 1 of 1 (latest)

charred oxide
#

I'm looking at std.builtin.Type structs and I see Fn, but I'm not sure how to get to that info. I'm trying to see if a struct has pub fn init(allocator: std.mem.Allocator) or not at comptime.

plain cedar
#

If you want to check the function signature exactly, you shouldn't need std.builtin.Type at all, you should be able to use

@hasDecl(S, "init") and @TypeOf(S.init) == fn (std.mem.Allocator) Allocator.Error!S

(I'm assuming the intended return type of the init function)

#

If you need to do a more complex check, you can get the std.builtin.Type structure from @typeInfo(@TypeOf(S.init)) for further inspection

charred oxide
#

nice! any way to check if it has an anytype param?

#

oh actually I think you asnswered it with the TypeOf comparison

plain cedar
#

Yeah, that should be covered by the is_generic member of std.builtin.Type.Fn.Param, although as far as I know that won't help you distinguish between a: anytype and comptime T: type, a: T

#

That information seems to be unavailable through type information alone, e.g.

const std = @import("std");

const S = struct {
    fn s(a: anytype) void {
        _ = a;
    }

    fn t(comptime T: type, a: T) void {
        _ = a;
    }
};

pub fn main() !void {
    @compileLog(@TypeOf(S.s));
    @compileLog(@TypeOf(S.t));
}

Compile log output:

@as(type, fn (anytype) void)
@as(type, fn (comptime type, anytype) void)
charred oxide
#

interesting. one last question I think:
how exactly to get Fn off a T type? @typeInfo(T).Struct has declarations slice, but a Declaration only has a name field. I was hoping the init fn would be a Field type, but I wasn't able to identify in a simple test like what you just posted. Perhaps I botched the Type tagged union 'which is it' testing. Haven't really messed with those much yet.

plain cedar
#

If you have a Declaration named decl, then you can get the declaration type using @TypeOf(@field(T, decl.name)) (the @field builtin, despite its name, works for declarations as well: it's actually just the . syntax using a comptime string field/decl name)