June 26, 2023
https://issues.dlang.org/show_bug.cgi?id=24014

          Issue ID: 24014
           Summary: UDAs are lost during IFTI when function pointers are
                    involved
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: andrej.mitrovich@gmail.com

-----
// attribute
struct Struct { string name; }

// try to retrieve attributes here
void test(T)(T t) {
    pragma(msg, __traits(getAttributes, T));
}

@Struct("foo") void foo() { }

void main() {
    test(&foo);  // FAIL: tuple()
}
-----

It seems that when function pointers are involved the UDAs get lost during IFTI.

For regular structure pointers it is possible to capture UDAs even during IFTI. Here's an example:

-----
import std.meta;

// attribute
struct Struct { string name; }

// try to retrieve attributes here
void test(T)(T t) {
    static if (is(T X : E*, E)) {
        pragma(msg, __traits(getAttributes, E));  // ok
    }
}

@Struct("foo") struct Mine { }

void main() {
    Mine mine;
    test(&mine); // ok: tuple(Struct("foo"))
}
-----

However the same is not possible with function pointers:

-----
import std.meta;

// attribute
struct Struct { string name; }

// try to retrieve attributes here
void test(X)(X t) {
    static if (is(X: E*, E)) {
        pragma(msg, __traits(getAttributes, E));
    }
}

@Struct("foo") void foo() { }

void main() {
    test(&foo); // FAIL: tuple()
}
-----

The only alternative is to pass these functions as `alias` parameters. But that can only work with functions in some cases, and won't work with delegates.

--