A UDA given to non-typed parameters in lambda expression/function literal cannot be detected:
------------------------
import std;
template detectUDA(alias f)
{
// Can't give the lambda to the Parameters.
// It does not satisfy isCallable
pragma(msg, __traits(getAttributes, Parameters!f[0..1])[0]);
void detectUDA() {}
}
void main()
{
detectUDA!((@(1) int a) => a); // OK
detectUDA!((@(1) a) => a); // Error
detectUDA!(delegate(@(2) int a) {}); // OK
detectUDA!(delegate(@(2) a) {}); // Error
detectUDA!((@(3) int a) {}); // OK
detectUDA!((@(3) a) {}); // Error
}
------------------------
This example deals with Parameters, which, as far as I know, will not be taken out in any way.
In addition, there are few ways to get traits of a non-typed lambda expression other than whether it can be called using arguments of certain types.
New __traits may be needed to solve the problem.
Comment #1 by simen.kjaras — 2020-08-10T07:26:58Z
*** This issue has been marked as a duplicate of issue 20246 ***
Comment #2 by zan77137 — 2020-08-10T10:50:41Z
(In reply to Simen Kjaeraas from comment #1)
>
> *** This issue has been marked as a duplicate of issue 20246 ***
The subject of this issue is not about checking that template functions can be called, as discussed in issue 20246.
This issue is about being able to retrieve UDAs given to parameters of lambda and function literals (or template functions).
Since they cannot be evaluated by `isCallable!func`, and the parameter information by `Paramters!func` cannot be retrieved, an alternative method should be provided.
This issue is not solved by issue 20246, although it is similar in that it is indeed a problem caused by not being treated as a function.
Comment #3 by simen.kjaras — 2020-08-10T11:28:56Z
You're right, my mind was somewhere else when I did that. The problem is, D's templates are complicated beasts (and untyped lambdas are templates), and the information is undecidable in the general case:
template foo(bool b, T) {
static if (b) {
void foo(@(T) T i) {}
} else {
enum T foo = T.init;
}
}
We don't know if the above even is a function, and even if we remove the bool parameter, there's no possible type for the UDA on the parameter 'i' without an explicit instantiation (and figuring out what template arguments are valid is also a hard problem).
We could possibly expose a __traits that gives access to this information in the limited cases where the template body has exactly one member which is a function and whose parameters' UDAs can be determined.
IMO, this is material for a DIP on template introspection, possibly AST macros.
Comment #4 by robert.schadek — 2024-12-13T19:10:42Z