How to retrieve function names via `@typeInfo` in zig 0.17.0?

I see some posts here example that older versions of zig allowed to retrieve function names via @typeInfo but I try to do it and there are only field names…

const anon = struct {
    tte: u32,
    pub fn ttr() void {}
};

const stripped = stripNamespace(anon);
pub fn main() !void {
    stripped.r(); // just to force evaluation of sstripped var
}

// needs to strip the `tt` prefix
fn stripNamespace(comptime space: type) type {
    const info = @typeInfo(space).@"struct";

    // @as(usize, 1)
    @compileLog(info.decl_names.len);

    // There are no entries for functions
    // @as([:0]const u8, "ttr"[0..3])
    for (info.decl_names) |name| {
        @compileLog(name);
    }

    return @TypeOf(info); // stub
}

Note the result is the same with field_names and decl_names. As far as I understand (from reading old posts and docs) field_names must really contain only field names while decl_names should be a superset of field_names and contain also functions and other stuff? (I am not sure what other stuff it could be except functions). And if this understanding is correct (unlikely) it means a compiler bug?

When you do

    for (info.decl_names) |name| {
        @compileLog(name);
    }

you get @as([:0]const u8, "ttr"[0..3]), which is the function name.

When you do

    for (info.field_names) |name| {
        @compileLog(name);
    }

you get @as([:0]const u8, "tte"[0..3]), which is the field name.

2 Likes

I am definetely stupid sorry

1 Like

I think this old hack that is not using @typeInfo, but @typeName with a generic, probably still works:

But it is still questionable whether you should rely upon it, I guess it would be good to at least add a unity test that makes sure that it still works, so you get notified if it eventually breaks (If it wouldn’t be immediately obvious to how your code uses it).

fn functionName(comptime func: anytype) []const u8 {
    const T = @TypeOf(func);
    std.debug.assert(@typeInfo(T) == .@"fn");
    const wrapper_name = @typeName(Wrapper(func));

    var it = std.mem.splitSequence(u8, wrapper_name, ".Wrapper((function '");
    _ = it.first();
    const rest = it.next().?;
    return rest[0 .. rest.len - 3];
}

test functionName {
    try std.testing.expectEqualStrings("Wrapper", functionName(Wrapper));
    try std.testing.expectEqualStrings("add", functionName(add));
    try std.testing.expectEqualStrings("splitSequence", functionName(std.mem.splitSequence));
}

fn Wrapper(comptime arg: anytype) type {
    return struct {
        const stuff = arg;
    };
}

fn add(a: i32, b: i32) i32 {
    return a + b;
}

const std = @import("std");

related: Getting function name at comptime and stringify

2 Likes